X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmtd%2Fmaps%2Fsun_uflash.c;fp=drivers%2Fmtd%2Fmaps%2Fsun_uflash.c;h=0758cb1d01056568dfda74d55297f7e9a6daa791;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=4db2055cee31ef9e68967e9d56a3e4c7d4b731c6;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c index 4db2055ce..0758cb1d0 100644 --- a/drivers/mtd/maps/sun_uflash.c +++ b/drivers/mtd/maps/sun_uflash.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -31,141 +30,146 @@ #define UFLASH_WINDOW_SIZE 0x200000 #define UFLASH_BUSWIDTH 1 /* EBus is 8-bit */ -MODULE_AUTHOR("Eric Brower "); -MODULE_DESCRIPTION("User-programmable flash device on Sun Microsystems boardsets"); -MODULE_SUPPORTED_DEVICE("userflash"); -MODULE_LICENSE("GPL"); -MODULE_VERSION("2.0"); +MODULE_AUTHOR + ("Eric Brower "); +MODULE_DESCRIPTION + ("User-programmable flash device on Sun Microsystems boardsets"); +MODULE_SUPPORTED_DEVICE + ("userflash"); +MODULE_LICENSE + ("GPL"); 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 mtd_info * mtd; /* mtd info */ + struct list_head list; }; 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, struct device_node *dp) +int uflash_devinit(struct linux_ebus_device* edev) { - struct uflash_dev *up; - struct resource *res; + 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; + } - res = &edev->resource[0]; + nregs = iTmp / sizeof(regs[0]); - if (edev->num_addrs != 1) { + if (nregs != 1) { /* Non-CFI userflash device-- once I find one we * can work on supporting it. */ - printk("%s: unsupported device at 0x%llx (%d regs): " \ + printk("%s: unsupported device at 0x%lx (%d regs): " \ "email ebrower@usa.net\n", - dp->full_name, (unsigned long long)res->start, - edev->num_addrs); - + UFLASH_DEVNAME, edev->resource[0].start, nregs); return -ENODEV; } - up = kzalloc(sizeof(struct uflash_dev), GFP_KERNEL); - if (!up) - return -ENOMEM; + if(0 == (pdev = kmalloc(sizeof(struct uflash_dev), GFP_KERNEL))) { + printk("%s: unable to kmalloc new device\n", UFLASH_DEVNAME); + return(-ENOMEM); + } /* copy defaults and tweak parameters */ - 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; + 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); } - simple_map_init(&up->map); + simple_map_init(&pdev->map); /* MTD registration */ - up->mtd = do_map_probe("cfi_probe", &up->map); - if (!up->mtd) { - iounmap(up->map.virt); - kfree(up); - - return -ENXIO; + 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->owner = THIS_MODULE; + list_add(&pdev->list, &device_list); - add_mtd_device(up->mtd); + pdev->mtd->owner = THIS_MODULE; - dev_set_drvdata(&edev->ofdev.dev, up); - - return 0; + add_mtd_device(pdev->mtd); + return(0); } -static int __devinit uflash_probe(struct of_device *dev, const struct of_device_id *match) +static int __init uflash_init(void) { - struct linux_ebus_device *edev = to_ebus_device(&dev->dev); - struct device_node *dp = dev->node; + 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); + } + } + } + } - if (of_find_property(dp, "user", NULL)) + if(list_empty(&device_list)) { + printk("%s: unable to locate device\n", UFLASH_DEVNAME); return -ENODEV; - - return uflash_devinit(edev, dp); -} - -static int __devexit uflash_remove(struct of_device *dev) -{ - 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; + 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) +static void __exit uflash_cleanup(void) { - return of_register_driver(&uflash_driver, &ebus_bus_type); -} - -static void __exit uflash_exit(void) -{ - of_unregister_driver(&uflash_driver); + 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); + } } module_init(uflash_init); -module_exit(uflash_exit); +module_exit(uflash_cleanup);