diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-26 10:08:32 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-26 10:08:32 -0700 |
commit | 8871e73fdbde07d0a41393f7ee30787b65387b36 (patch) | |
tree | c54027e3ceb18f00db886871494d5e7b56e74b45 /drivers/mtd | |
parent | 61a46dc9d1c10d07a2ed6b7d346b868803b52506 (diff) | |
parent | 749805dc10e955b0170573061f9522a6a21cbae0 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6:
[SPARC]: Add iomap interfaces.
[OPENPROM]: Rewrite driver to use in-kernel device tree.
[OPENPROMFS]: Rewrite using in-kernel device tree and seq_file.
[SPARC]: Add unique device_node IDs and a ".node" property.
[SPARC]: Add of_set_property() interface.
[SPARC64]: Export auxio_register to modules.
[SPARC64]: Add missing interfaces to dma-mapping.h
[SPARC64]: Export _PAGE_IE to modules.
[SPARC64]: Allow floppy driver to build modular.
[SPARC]: Export x_bus_type to modules.
[RIOWATCHDOG]: Fix the build.
[CPWATCHDOG]: Fix the build.
[PARPORT] sunbpp: Fix typo.
[MTD] sun_uflash: Port to new EBUS device layer.
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/maps/sun_uflash.c | 195 |
1 files changed, 95 insertions, 100 deletions
diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c index 0758cb1d0105..24a03152d196 100644 --- a/drivers/mtd/maps/sun_uflash.c +++ b/drivers/mtd/maps/sun_uflash.c @@ -18,6 +18,7 @@ #include <linux/ioport.h> #include <asm/ebus.h> #include <asm/oplib.h> +#include <asm/prom.h> #include <asm/uaccess.h> #include <asm/io.h> @@ -30,146 +31,140 @@ #define UFLASH_WINDOW_SIZE 0x200000 #define UFLASH_BUSWIDTH 1 /* EBus is 8-bit */ -MODULE_AUTHOR - ("Eric Brower <ebrower@usa.net>"); -MODULE_DESCRIPTION - ("User-programmable flash device on Sun Microsystems boardsets"); -MODULE_SUPPORTED_DEVICE - ("userflash"); -MODULE_LICENSE - ("GPL"); +MODULE_AUTHOR("Eric Brower <ebrower@usa.net>"); +MODULE_DESCRIPTION("User-programmable flash device on Sun Microsystems boardsets"); +MODULE_SUPPORTED_DEVICE("userflash"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("2.0"); static LIST_HEAD(device_list); struct uflash_dev { - char * name; /* device name */ + char *name; /* device name */ struct map_info map; /* mtd map info */ - struct mtd_info * mtd; /* mtd info */ - struct list_head list; + struct mtd_info *mtd; /* mtd info */ }; struct map_info uflash_map_templ = { - .name = "SUNW,???-????", - .size = UFLASH_WINDOW_SIZE, - .bankwidth = UFLASH_BUSWIDTH, + .name = "SUNW,???-????", + .size = UFLASH_WINDOW_SIZE, + .bankwidth = UFLASH_BUSWIDTH, }; -int uflash_devinit(struct linux_ebus_device* edev) +int uflash_devinit(struct linux_ebus_device *edev, struct device_node *dp) { - int iTmp, nregs; - struct linux_prom_registers regs[2]; - struct uflash_dev *pdev; - - iTmp = prom_getproperty( - edev->prom_node, "reg", (void *)regs, sizeof(regs)); - if ((iTmp % sizeof(regs[0])) != 0) { - printk("%s: Strange reg property size %d\n", - UFLASH_DEVNAME, iTmp); - return -ENODEV; - } + struct uflash_dev *up; + struct resource *res; - nregs = iTmp / sizeof(regs[0]); + res = &edev->resource[0]; - if (nregs != 1) { + if (edev->num_addrs != 1) { /* Non-CFI userflash device-- once I find one we * can work on supporting it. */ printk("%s: unsupported device at 0x%lx (%d regs): " \ "email ebrower@usa.net\n", - UFLASH_DEVNAME, edev->resource[0].start, nregs); + dp->full_name, res->start, edev->num_addrs); + return -ENODEV; } - if(0 == (pdev = kmalloc(sizeof(struct uflash_dev), GFP_KERNEL))) { - printk("%s: unable to kmalloc new device\n", UFLASH_DEVNAME); - return(-ENOMEM); - } + up = kzalloc(sizeof(struct uflash_dev), GFP_KERNEL); + if (!up) + return -ENOMEM; /* copy defaults and tweak parameters */ - memcpy(&pdev->map, &uflash_map_templ, sizeof(uflash_map_templ)); - pdev->map.size = regs[0].reg_size; - - iTmp = prom_getproplen(edev->prom_node, "model"); - pdev->name = kmalloc(iTmp, GFP_KERNEL); - prom_getstring(edev->prom_node, "model", pdev->name, iTmp); - if(0 != pdev->name && 0 < strlen(pdev->name)) { - pdev->map.name = pdev->name; - } - pdev->map.phys = edev->resource[0].start; - pdev->map.virt = ioremap_nocache(edev->resource[0].start, pdev->map.size); - if(0 == pdev->map.virt) { - printk("%s: failed to map device\n", __FUNCTION__); - kfree(pdev->name); - kfree(pdev); - return(-1); + memcpy(&up->map, &uflash_map_templ, sizeof(uflash_map_templ)); + up->map.size = (res->end - res->start) + 1UL; + + up->name = of_get_property(dp, "model", NULL); + if (up->name && 0 < strlen(up->name)) + up->map.name = up->name; + + up->map.phys = res->start; + + up->map.virt = ioremap_nocache(res->start, up->map.size); + if (!up->map.virt) { + printk("%s: Failed to map device.\n", dp->full_name); + kfree(up); + + return -EINVAL; } - simple_map_init(&pdev->map); + simple_map_init(&up->map); /* MTD registration */ - pdev->mtd = do_map_probe("cfi_probe", &pdev->map); - if(0 == pdev->mtd) { - iounmap(pdev->map.virt); - kfree(pdev->name); - kfree(pdev); - return(-ENXIO); + up->mtd = do_map_probe("cfi_probe", &up->map); + if (!up->mtd) { + iounmap(up->map.virt); + kfree(up); + + return -ENXIO; } - list_add(&pdev->list, &device_list); + up->mtd->owner = THIS_MODULE; - pdev->mtd->owner = THIS_MODULE; + add_mtd_device(up->mtd); - add_mtd_device(pdev->mtd); - return(0); + dev_set_drvdata(&edev->ofdev.dev, up); + + return 0; } -static int __init uflash_init(void) +static int __devinit uflash_probe(struct of_device *dev, const struct of_device_id *match) { - struct linux_ebus *ebus = NULL; - struct linux_ebus_device *edev = NULL; - - for_each_ebus(ebus) { - for_each_ebusdev(edev, ebus) { - if (!strcmp(edev->prom_name, UFLASH_OBPNAME)) { - if(0 > prom_getproplen(edev->prom_node, "user")) { - DEBUG(2, "%s: ignoring device at 0x%lx\n", - UFLASH_DEVNAME, edev->resource[0].start); - } else { - uflash_devinit(edev); - } - } - } - } + struct linux_ebus_device *edev = to_ebus_device(&dev->dev); + struct device_node *dp = dev->node; - if(list_empty(&device_list)) { - printk("%s: unable to locate device\n", UFLASH_DEVNAME); + if (of_find_property(dp, "user", NULL)) return -ENODEV; - } - return(0); + + return uflash_devinit(edev, dp); } -static void __exit uflash_cleanup(void) +static int __devexit uflash_remove(struct of_device *dev) { - struct list_head *udevlist; - struct uflash_dev *udev; - - list_for_each(udevlist, &device_list) { - udev = list_entry(udevlist, struct uflash_dev, list); - DEBUG(2, "%s: removing device %s\n", - UFLASH_DEVNAME, udev->name); - - if(0 != udev->mtd) { - del_mtd_device(udev->mtd); - map_destroy(udev->mtd); - } - if(0 != udev->map.virt) { - iounmap(udev->map.virt); - udev->map.virt = NULL; - } - kfree(udev->name); - kfree(udev); + struct uflash_dev *up = dev_get_drvdata(&dev->dev); + + if (up->mtd) { + del_mtd_device(up->mtd); + map_destroy(up->mtd); } + if (up->map.virt) { + iounmap(up->map.virt); + up->map.virt = NULL; + } + + kfree(up); + + return 0; +} + +static struct of_device_id uflash_match[] = { + { + .name = UFLASH_OBPNAME, + }, + {}, +}; + +MODULE_DEVICE_TABLE(of, uflash_match); + +static struct of_platform_driver uflash_driver = { + .name = UFLASH_DEVNAME, + .match_table = uflash_match, + .probe = uflash_probe, + .remove = __devexit_p(uflash_remove), +}; + +static int __init uflash_init(void) +{ + return of_register_driver(&uflash_driver, &ebus_bus_type); +} + +static void __exit uflash_exit(void) +{ + of_unregister_driver(&uflash_driver); } module_init(uflash_init); -module_exit(uflash_cleanup); +module_exit(uflash_exit); |