sun_uflash.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /* $Id: sun_uflash.c,v 1.13 2005/11/07 11:14:28 gleixner Exp $
  2. *
  3. * sun_uflash - Driver implementation for user-programmable flash
  4. * present on many Sun Microsystems SME boardsets.
  5. *
  6. * This driver does NOT provide access to the OBP-flash for
  7. * safety reasons-- use <linux>/drivers/sbus/char/flash.c instead.
  8. *
  9. * Copyright (c) 2001 Eric Brower (ebrower@usa.net)
  10. *
  11. */
  12. #include <linux/kernel.h>
  13. #include <linux/module.h>
  14. #include <linux/fs.h>
  15. #include <linux/errno.h>
  16. #include <linux/init.h>
  17. #include <linux/ioport.h>
  18. #include <asm/ebus.h>
  19. #include <asm/oplib.h>
  20. #include <asm/uaccess.h>
  21. #include <asm/io.h>
  22. #include <linux/mtd/mtd.h>
  23. #include <linux/mtd/map.h>
  24. #define UFLASH_OBPNAME "flashprom"
  25. #define UFLASH_DEVNAME "userflash"
  26. #define UFLASH_WINDOW_SIZE 0x200000
  27. #define UFLASH_BUSWIDTH 1 /* EBus is 8-bit */
  28. MODULE_AUTHOR
  29. ("Eric Brower <ebrower@usa.net>");
  30. MODULE_DESCRIPTION
  31. ("User-programmable flash device on Sun Microsystems boardsets");
  32. MODULE_SUPPORTED_DEVICE
  33. ("userflash");
  34. MODULE_LICENSE
  35. ("GPL");
  36. static LIST_HEAD(device_list);
  37. struct uflash_dev {
  38. char * name; /* device name */
  39. struct map_info map; /* mtd map info */
  40. struct mtd_info * mtd; /* mtd info */
  41. struct list_head list;
  42. };
  43. struct map_info uflash_map_templ = {
  44. .name = "SUNW,???-????",
  45. .size = UFLASH_WINDOW_SIZE,
  46. .bankwidth = UFLASH_BUSWIDTH,
  47. };
  48. int uflash_devinit(struct linux_ebus_device* edev)
  49. {
  50. int iTmp, nregs;
  51. struct linux_prom_registers regs[2];
  52. struct uflash_dev *pdev;
  53. iTmp = prom_getproperty(
  54. edev->prom_node, "reg", (void *)regs, sizeof(regs));
  55. if ((iTmp % sizeof(regs[0])) != 0) {
  56. printk("%s: Strange reg property size %d\n",
  57. UFLASH_DEVNAME, iTmp);
  58. return -ENODEV;
  59. }
  60. nregs = iTmp / sizeof(regs[0]);
  61. if (nregs != 1) {
  62. /* Non-CFI userflash device-- once I find one we
  63. * can work on supporting it.
  64. */
  65. printk("%s: unsupported device at 0x%lx (%d regs): " \
  66. "email ebrower@usa.net\n",
  67. UFLASH_DEVNAME, edev->resource[0].start, nregs);
  68. return -ENODEV;
  69. }
  70. if(0 == (pdev = kmalloc(sizeof(struct uflash_dev), GFP_KERNEL))) {
  71. printk("%s: unable to kmalloc new device\n", UFLASH_DEVNAME);
  72. return(-ENOMEM);
  73. }
  74. /* copy defaults and tweak parameters */
  75. memcpy(&pdev->map, &uflash_map_templ, sizeof(uflash_map_templ));
  76. pdev->map.size = regs[0].reg_size;
  77. iTmp = prom_getproplen(edev->prom_node, "model");
  78. pdev->name = kmalloc(iTmp, GFP_KERNEL);
  79. prom_getstring(edev->prom_node, "model", pdev->name, iTmp);
  80. if(0 != pdev->name && 0 < strlen(pdev->name)) {
  81. pdev->map.name = pdev->name;
  82. }
  83. pdev->map.phys = edev->resource[0].start;
  84. pdev->map.virt = ioremap_nocache(edev->resource[0].start, pdev->map.size);
  85. if(0 == pdev->map.virt) {
  86. printk("%s: failed to map device\n", __FUNCTION__);
  87. kfree(pdev->name);
  88. kfree(pdev);
  89. return(-1);
  90. }
  91. simple_map_init(&pdev->map);
  92. /* MTD registration */
  93. pdev->mtd = do_map_probe("cfi_probe", &pdev->map);
  94. if(0 == pdev->mtd) {
  95. iounmap(pdev->map.virt);
  96. kfree(pdev->name);
  97. kfree(pdev);
  98. return(-ENXIO);
  99. }
  100. list_add(&pdev->list, &device_list);
  101. pdev->mtd->owner = THIS_MODULE;
  102. add_mtd_device(pdev->mtd);
  103. return(0);
  104. }
  105. static int __init uflash_init(void)
  106. {
  107. struct linux_ebus *ebus = NULL;
  108. struct linux_ebus_device *edev = NULL;
  109. for_each_ebus(ebus) {
  110. for_each_ebusdev(edev, ebus) {
  111. if (!strcmp(edev->prom_name, UFLASH_OBPNAME)) {
  112. if(0 > prom_getproplen(edev->prom_node, "user")) {
  113. DEBUG(2, "%s: ignoring device at 0x%lx\n",
  114. UFLASH_DEVNAME, edev->resource[0].start);
  115. } else {
  116. uflash_devinit(edev);
  117. }
  118. }
  119. }
  120. }
  121. if(list_empty(&device_list)) {
  122. printk("%s: unable to locate device\n", UFLASH_DEVNAME);
  123. return -ENODEV;
  124. }
  125. return(0);
  126. }
  127. static void __exit uflash_cleanup(void)
  128. {
  129. struct list_head *udevlist;
  130. struct uflash_dev *udev;
  131. list_for_each(udevlist, &device_list) {
  132. udev = list_entry(udevlist, struct uflash_dev, list);
  133. DEBUG(2, "%s: removing device %s\n",
  134. UFLASH_DEVNAME, udev->name);
  135. if(0 != udev->mtd) {
  136. del_mtd_device(udev->mtd);
  137. map_destroy(udev->mtd);
  138. }
  139. if(0 != udev->map.virt) {
  140. iounmap(udev->map.virt);
  141. udev->map.virt = NULL;
  142. }
  143. kfree(udev->name);
  144. kfree(udev);
  145. }
  146. }
  147. module_init(uflash_init);
  148. module_exit(uflash_cleanup);