Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /* sun_uflash.c - Driver for user-programmable flash on
0003  *                Sun Microsystems SME boardsets.
0004  *
0005  * This driver does NOT provide access to the OBP-flash for
0006  * safety reasons-- use <linux>/drivers/sbus/char/flash.c instead.
0007  *
0008  * Copyright (c) 2001 Eric Brower (ebrower@usa.net)
0009  */
0010 
0011 #include <linux/kernel.h>
0012 #include <linux/module.h>
0013 #include <linux/fs.h>
0014 #include <linux/errno.h>
0015 #include <linux/ioport.h>
0016 #include <linux/of.h>
0017 #include <linux/of_device.h>
0018 #include <linux/slab.h>
0019 #include <asm/prom.h>
0020 #include <linux/uaccess.h>
0021 #include <asm/io.h>
0022 
0023 #include <linux/mtd/mtd.h>
0024 #include <linux/mtd/map.h>
0025 
0026 #define UFLASH_OBPNAME  "flashprom"
0027 #define DRIVER_NAME "sun_uflash"
0028 #define PFX     DRIVER_NAME ": "
0029 
0030 #define UFLASH_WINDOW_SIZE  0x200000
0031 #define UFLASH_BUSWIDTH     1           /* EBus is 8-bit */
0032 
0033 MODULE_AUTHOR("Eric Brower <ebrower@usa.net>");
0034 MODULE_DESCRIPTION("User-programmable flash device on Sun Microsystems boardsets");
0035 MODULE_LICENSE("GPL");
0036 MODULE_VERSION("2.1");
0037 
0038 struct uflash_dev {
0039     const char      *name;  /* device name */
0040     struct map_info     map;    /* mtd map info */
0041     struct mtd_info     *mtd;   /* mtd info */
0042 };
0043 
0044 struct map_info uflash_map_templ = {
0045     .name =     "SUNW,???-????",
0046     .size =     UFLASH_WINDOW_SIZE,
0047     .bankwidth =    UFLASH_BUSWIDTH,
0048 };
0049 
0050 int uflash_devinit(struct platform_device *op, struct device_node *dp)
0051 {
0052     struct uflash_dev *up;
0053 
0054     if (op->resource[1].flags) {
0055         /* Non-CFI userflash device-- once I find one we
0056          * can work on supporting it.
0057          */
0058         printk(KERN_ERR PFX "Unsupported device at %pOF, 0x%llx\n",
0059                dp, (unsigned long long)op->resource[0].start);
0060 
0061         return -ENODEV;
0062     }
0063 
0064     up = kzalloc(sizeof(struct uflash_dev), GFP_KERNEL);
0065     if (!up)
0066         return -ENOMEM;
0067 
0068     /* copy defaults and tweak parameters */
0069     memcpy(&up->map, &uflash_map_templ, sizeof(uflash_map_templ));
0070 
0071     up->map.size = resource_size(&op->resource[0]);
0072 
0073     up->name = of_get_property(dp, "model", NULL);
0074     if (up->name && 0 < strlen(up->name))
0075         up->map.name = up->name;
0076 
0077     up->map.phys = op->resource[0].start;
0078 
0079     up->map.virt = of_ioremap(&op->resource[0], 0, up->map.size,
0080                   DRIVER_NAME);
0081     if (!up->map.virt) {
0082         printk(KERN_ERR PFX "Failed to map device.\n");
0083         kfree(up);
0084 
0085         return -EINVAL;
0086     }
0087 
0088     simple_map_init(&up->map);
0089 
0090     /* MTD registration */
0091     up->mtd = do_map_probe("cfi_probe", &up->map);
0092     if (!up->mtd) {
0093         of_iounmap(&op->resource[0], up->map.virt, up->map.size);
0094         kfree(up);
0095 
0096         return -ENXIO;
0097     }
0098 
0099     up->mtd->owner = THIS_MODULE;
0100 
0101     mtd_device_register(up->mtd, NULL, 0);
0102 
0103     dev_set_drvdata(&op->dev, up);
0104 
0105     return 0;
0106 }
0107 
0108 static int uflash_probe(struct platform_device *op)
0109 {
0110     struct device_node *dp = op->dev.of_node;
0111 
0112     /* Flashprom must have the "user" property in order to
0113      * be used by this driver.
0114      */
0115     if (!of_find_property(dp, "user", NULL))
0116         return -ENODEV;
0117 
0118     return uflash_devinit(op, dp);
0119 }
0120 
0121 static int uflash_remove(struct platform_device *op)
0122 {
0123     struct uflash_dev *up = dev_get_drvdata(&op->dev);
0124 
0125     if (up->mtd) {
0126         mtd_device_unregister(up->mtd);
0127         map_destroy(up->mtd);
0128     }
0129     if (up->map.virt) {
0130         of_iounmap(&op->resource[0], up->map.virt, up->map.size);
0131         up->map.virt = NULL;
0132     }
0133 
0134     kfree(up);
0135 
0136     return 0;
0137 }
0138 
0139 static const struct of_device_id uflash_match[] = {
0140     {
0141         .name = UFLASH_OBPNAME,
0142     },
0143     {},
0144 };
0145 
0146 MODULE_DEVICE_TABLE(of, uflash_match);
0147 
0148 static struct platform_driver uflash_driver = {
0149     .driver = {
0150         .name = DRIVER_NAME,
0151         .of_match_table = uflash_match,
0152     },
0153     .probe      = uflash_probe,
0154     .remove     = uflash_remove,
0155 };
0156 
0157 module_platform_driver(uflash_driver);