ocelot.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:5k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * $Id: ocelot.c,v 1.6 2001/10/02 15:05:14 dwmw2 Exp $
  3.  *
  4.  * Flash on Momenco Ocelot
  5.  */
  6. #include <linux/module.h>
  7. #include <linux/types.h>
  8. #include <linux/kernel.h>
  9. #include <asm/io.h>
  10. #include <linux/mtd/mtd.h>
  11. #include <linux/mtd/map.h>
  12. #include <linux/mtd/partitions.h>
  13. #define OCELOT_PLD 0x2c000000
  14. #define FLASH_WINDOW_ADDR 0x2fc00000
  15. #define FLASH_WINDOW_SIZE 0x00080000
  16. #define FLASH_BUSWIDTH 1
  17. #define NVRAM_WINDOW_ADDR 0x2c800000
  18. #define NVRAM_WINDOW_SIZE 0x00007FF0
  19. #define NVRAM_BUSWIDTH 1
  20. extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
  21. static unsigned int cacheflush = 0;
  22. static struct mtd_info *flash_mtd;
  23. static struct mtd_info *nvram_mtd;
  24. __u8 ocelot_read8(struct map_info *map, unsigned long ofs)
  25. {
  26. return __raw_readb(map->map_priv_1 + ofs);
  27. }
  28. void ocelot_write8(struct map_info *map, __u8 d, unsigned long adr)
  29. {
  30. cacheflush = 1;
  31. __raw_writeb(d, map->map_priv_1 + adr);
  32. mb();
  33. }
  34. void ocelot_copy_from_cache(struct map_info *map, void *to, unsigned long from, ssize_t len)
  35. {
  36. if (cacheflush) {
  37. dma_cache_inv(map->map_priv_2, map->size);
  38. cacheflush = 0;
  39. }
  40. memcpy_fromio(to, map->map_priv_1 + from, len);
  41. }
  42. void ocelot_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
  43. {
  44. memcpy_fromio(to, map->map_priv_1 + from, len);
  45. }
  46. void ocelot_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
  47. {
  48. /* If we use memcpy, it does word-wide writes. Even though we told the 
  49.    GT64120A that it's an 8-bit wide region, word-wide writes don't work.
  50.    We end up just writing the first byte of the four to all four bytes.
  51.    So we have this loop instead */
  52. while(len) {
  53. __raw_writeb(*(unsigned char *) from, map->map_priv_1 + to);
  54. from++;
  55. to++;
  56. len--;
  57. }
  58. }
  59. static struct mtd_partition *parsed_parts;
  60. struct map_info ocelot_flash_map = {
  61. name: "Ocelot boot flash",
  62. size: FLASH_WINDOW_SIZE,
  63. buswidth: FLASH_BUSWIDTH,
  64. read8: ocelot_read8,
  65. copy_from: ocelot_copy_from_cache,
  66. write8: ocelot_write8,
  67. };
  68. struct map_info ocelot_nvram_map = {
  69. name: "Ocelot NVRAM",
  70. size: NVRAM_WINDOW_SIZE,
  71. buswidth: NVRAM_BUSWIDTH,
  72. read8: ocelot_read8,
  73. copy_from: ocelot_copy_from,
  74. write8: ocelot_write8,
  75. copy_to: ocelot_copy_to
  76. };
  77. static int __init init_ocelot_maps(void)
  78. {
  79. void *pld;
  80. int nr_parts;
  81. unsigned char brd_status;
  82.         printk(KERN_INFO "Momenco Ocelot MTD mappings: Flash 0x%x at 0x%x, NVRAM 0x%x at 0x%xn", 
  83.        FLASH_WINDOW_SIZE, FLASH_WINDOW_ADDR, NVRAM_WINDOW_SIZE, NVRAM_WINDOW_ADDR);
  84. /* First check whether the flash jumper is present */
  85. pld = ioremap(OCELOT_PLD, 0x10);
  86. if (!pld) {
  87. printk(KERN_NOTICE "Failed to ioremap Ocelot PLDn");
  88. return -EIO;
  89. }
  90. brd_status = readb(pld+4);
  91. iounmap(pld);
  92. /* Now ioremap the NVRAM space */
  93. ocelot_nvram_map.map_priv_1 = (unsigned long)ioremap_nocache(NVRAM_WINDOW_ADDR, NVRAM_WINDOW_SIZE);
  94. if (!ocelot_nvram_map.map_priv_1) {
  95. printk(KERN_NOTICE "Failed to ioremap Ocelot NVRAM spacen");
  96. return -EIO;
  97. }
  98. // ocelot_nvram_map.map_priv_2 = ocelot_nvram_map.map_priv_1;
  99. /* And do the RAM probe on it to get an MTD device */
  100. nvram_mtd = do_map_probe("map_ram", &ocelot_nvram_map);
  101. if (!nvram_mtd) {
  102. printk("NVRAM probe failedn");
  103. goto fail_1;
  104. }
  105. nvram_mtd->module = THIS_MODULE;
  106. nvram_mtd->erasesize = 16;
  107. /* Now map the flash space */
  108. ocelot_flash_map.map_priv_1 = (unsigned long)ioremap_nocache(FLASH_WINDOW_ADDR, FLASH_WINDOW_SIZE);
  109. if (!ocelot_flash_map.map_priv_1) {
  110. printk(KERN_NOTICE "Failed to ioremap Ocelot flash spacen");
  111. goto fail_2;
  112. }
  113. /* Now the cached version */
  114. ocelot_flash_map.map_priv_2 = (unsigned long)__ioremap(FLASH_WINDOW_ADDR, FLASH_WINDOW_SIZE, 0);
  115. if (!ocelot_flash_map.map_priv_2) {
  116. /* Doesn't matter if it failed. Just use the uncached version */
  117. ocelot_flash_map.map_priv_2 = ocelot_flash_map.map_priv_1;
  118. }
  119. /* Only probe for flash if the write jumper is present */
  120. if (brd_status & 0x40) {
  121. flash_mtd = do_map_probe("jedec", &ocelot_flash_map);
  122. } else {
  123. printk(KERN_NOTICE "Ocelot flash write jumper not present. Treating as ROMn");
  124. }
  125. /* If that failed or the jumper's absent, pretend it's ROM */
  126. if (!flash_mtd) {
  127. flash_mtd = do_map_probe("map_rom", &ocelot_flash_map);
  128. /* If we're treating it as ROM, set the erase size */
  129. if (flash_mtd)
  130. flash_mtd->erasesize = 0x10000;
  131. }
  132. if (!flash_mtd)
  133. goto fail3;
  134. add_mtd_device(nvram_mtd);
  135. flash_mtd->module = THIS_MODULE;
  136. nr_parts = parse_redboot_partitions(flash_mtd, &parsed_parts);
  137. if (nr_parts)
  138. add_mtd_partitions(flash_mtd, parsed_parts, nr_parts);
  139. else
  140. add_mtd_device(flash_mtd);
  141. return 0;
  142.  fail3:
  143. iounmap((void *)ocelot_flash_map.map_priv_1);
  144. if (ocelot_flash_map.map_priv_2 &&
  145.     ocelot_flash_map.map_priv_2 != ocelot_flash_map.map_priv_1)
  146. iounmap((void *)ocelot_flash_map.map_priv_2);
  147.  fail_2:
  148. map_destroy(nvram_mtd);
  149.  fail_1:
  150. iounmap((void *)ocelot_nvram_map.map_priv_1);
  151. return -ENXIO;
  152. }
  153. static void __exit cleanup_ocelot_maps(void)
  154. {
  155. del_mtd_device(nvram_mtd);
  156. map_destroy(nvram_mtd);
  157. iounmap((void *)ocelot_nvram_map.map_priv_1);
  158. if (parsed_parts)
  159. del_mtd_partitions(flash_mtd);
  160. else
  161. del_mtd_device(flash_mtd);
  162. map_destroy(flash_mtd);
  163. iounmap((void *)ocelot_flash_map.map_priv_1);
  164. if (ocelot_flash_map.map_priv_2 != ocelot_flash_map.map_priv_1)
  165. iounmap((void *)ocelot_flash_map.map_priv_2);
  166. }
  167. module_init(init_ocelot_maps);
  168. module_exit(cleanup_ocelot_maps);
  169. MODULE_LICENSE("GPL");
  170. MODULE_AUTHOR("Red Hat, Inc. - David Woodhouse <dwmw2@cambridge.redhat.com>");
  171. MODULE_DESCRIPTION("MTD map driver for Momenco Ocelot board");