sbc8240.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /*
  2. * Handle mapping of the flash memory access routines on the SBC8240 board.
  3. *
  4. * Carolyn Smith, Tektronix, Inc.
  5. *
  6. * This code is GPLed
  7. */
  8. /*
  9. * The SBC8240 has 2 flash banks.
  10. * Bank 0 is a 512 KiB AMD AM29F040B; 8 x 64 KiB sectors.
  11. * It contains the U-Boot code (7 sectors) and the environment (1 sector).
  12. * Bank 1 is 4 x 1 MiB AMD AM29LV800BT; 15 x 64 KiB sectors, 1 x 32 KiB sector,
  13. * 2 x 8 KiB sectors, 1 x 16 KiB sectors.
  14. * Both parts are JEDEC compatible.
  15. */
  16. #include <linux/module.h>
  17. #include <linux/types.h>
  18. #include <linux/kernel.h>
  19. #include <asm/io.h>
  20. #include <linux/mtd/mtd.h>
  21. #include <linux/mtd/map.h>
  22. #include <linux/mtd/cfi.h>
  23. #ifdef CONFIG_MTD_PARTITIONS
  24. #include <linux/mtd/partitions.h>
  25. #endif
  26. #define DEBUG
  27. #ifdef DEBUG
  28. # define debugk(fmt,args...) printk(fmt ,##args)
  29. #else
  30. # define debugk(fmt,args...)
  31. #endif
  32. #define WINDOW_ADDR0 0xFFF00000 /* 512 KiB */
  33. #define WINDOW_SIZE0 0x00080000
  34. #define BUSWIDTH0 1
  35. #define WINDOW_ADDR1 0xFF000000 /* 4 MiB */
  36. #define WINDOW_SIZE1 0x00400000
  37. #define BUSWIDTH1 8
  38. #define MSG_PREFIX "sbc8240:" /* prefix for our printk()'s */
  39. #define MTDID "sbc8240-%d" /* for mtdparts= partitioning */
  40. static struct map_info sbc8240_map[2] = {
  41. {
  42. .name = "sbc8240 Flash Bank #0",
  43. .size = WINDOW_SIZE0,
  44. .bankwidth = BUSWIDTH0,
  45. },
  46. {
  47. .name = "sbc8240 Flash Bank #1",
  48. .size = WINDOW_SIZE1,
  49. .bankwidth = BUSWIDTH1,
  50. }
  51. };
  52. #define NUM_FLASH_BANKS ARRAY_SIZE(sbc8240_map)
  53. /*
  54. * The following defines the partition layout of SBC8240 boards.
  55. *
  56. * See include/linux/mtd/partitions.h for definition of the
  57. * mtd_partition structure.
  58. *
  59. * The *_max_flash_size is the maximum possible mapped flash size
  60. * which is not necessarily the actual flash size. It must correspond
  61. * to the value specified in the mapping definition defined by the
  62. * "struct map_desc *_io_desc" for the corresponding machine.
  63. */
  64. #ifdef CONFIG_MTD_PARTITIONS
  65. static struct mtd_partition sbc8240_uboot_partitions [] = {
  66. /* Bank 0 */
  67. {
  68. .name = "U-boot", /* U-Boot Firmware */
  69. .offset = 0,
  70. .size = 0x00070000, /* 7 x 64 KiB sectors */
  71. .mask_flags = MTD_WRITEABLE, /* force read-only */
  72. },
  73. {
  74. .name = "environment", /* U-Boot environment */
  75. .offset = 0x00070000,
  76. .size = 0x00010000, /* 1 x 64 KiB sector */
  77. },
  78. };
  79. static struct mtd_partition sbc8240_fs_partitions [] = {
  80. {
  81. .name = "jffs", /* JFFS filesystem */
  82. .offset = 0,
  83. .size = 0x003C0000, /* 4 * 15 * 64KiB */
  84. },
  85. {
  86. .name = "tmp32",
  87. .offset = 0x003C0000,
  88. .size = 0x00020000, /* 4 * 32KiB */
  89. },
  90. {
  91. .name = "tmp8a",
  92. .offset = 0x003E0000,
  93. .size = 0x00008000, /* 4 * 8KiB */
  94. },
  95. {
  96. .name = "tmp8b",
  97. .offset = 0x003E8000,
  98. .size = 0x00008000, /* 4 * 8KiB */
  99. },
  100. {
  101. .name = "tmp16",
  102. .offset = 0x003F0000,
  103. .size = 0x00010000, /* 4 * 16KiB */
  104. }
  105. };
  106. /* trivial struct to describe partition information */
  107. struct mtd_part_def
  108. {
  109. int nums;
  110. unsigned char *type;
  111. struct mtd_partition* mtd_part;
  112. };
  113. static struct mtd_info *sbc8240_mtd[NUM_FLASH_BANKS];
  114. static struct mtd_part_def sbc8240_part_banks[NUM_FLASH_BANKS];
  115. #endif /* CONFIG_MTD_PARTITIONS */
  116. int __init init_sbc8240_mtd (void)
  117. {
  118. static struct _cjs {
  119. u_long addr;
  120. u_long size;
  121. } pt[NUM_FLASH_BANKS] = {
  122. {
  123. .addr = WINDOW_ADDR0,
  124. .size = WINDOW_SIZE0
  125. },
  126. {
  127. .addr = WINDOW_ADDR1,
  128. .size = WINDOW_SIZE1
  129. },
  130. };
  131. int devicesfound = 0;
  132. int i,j;
  133. for (i = 0; i < NUM_FLASH_BANKS; i++) {
  134. printk (KERN_NOTICE MSG_PREFIX
  135. "Probing 0x%08lx at 0x%08lx\n", pt[i].size, pt[i].addr);
  136. sbc8240_map[i].map_priv_1 =
  137. (unsigned long) ioremap (pt[i].addr, pt[i].size);
  138. if (!sbc8240_map[i].map_priv_1) {
  139. printk (MSG_PREFIX "failed to ioremap\n");
  140. for (j = 0; j < i; j++) {
  141. iounmap((void *) sbc8240_map[j].map_priv_1);
  142. sbc8240_map[j].map_priv_1 = 0;
  143. }
  144. return -EIO;
  145. }
  146. simple_map_init(&sbc8240_mtd[i]);
  147. sbc8240_mtd[i] = do_map_probe("jedec_probe", &sbc8240_map[i]);
  148. if (sbc8240_mtd[i]) {
  149. sbc8240_mtd[i]->module = THIS_MODULE;
  150. devicesfound++;
  151. } else {
  152. if (sbc8240_map[i].map_priv_1) {
  153. iounmap((void *) sbc8240_map[i].map_priv_1);
  154. sbc8240_map[i].map_priv_1 = 0;
  155. }
  156. }
  157. }
  158. if (!devicesfound) {
  159. printk(KERN_NOTICE MSG_PREFIX
  160. "No suppported flash chips found!\n");
  161. return -ENXIO;
  162. }
  163. #ifdef CONFIG_MTD_PARTITIONS
  164. sbc8240_part_banks[0].mtd_part = sbc8240_uboot_partitions;
  165. sbc8240_part_banks[0].type = "static image";
  166. sbc8240_part_banks[0].nums = ARRAY_SIZE(sbc8240_uboot_partitions);
  167. sbc8240_part_banks[1].mtd_part = sbc8240_fs_partitions;
  168. sbc8240_part_banks[1].type = "static file system";
  169. sbc8240_part_banks[1].nums = ARRAY_SIZE(sbc8240_fs_partitions);
  170. for (i = 0; i < NUM_FLASH_BANKS; i++) {
  171. if (!sbc8240_mtd[i]) continue;
  172. if (sbc8240_part_banks[i].nums == 0) {
  173. printk (KERN_NOTICE MSG_PREFIX
  174. "No partition info available, registering whole device\n");
  175. add_mtd_device(sbc8240_mtd[i]);
  176. } else {
  177. printk (KERN_NOTICE MSG_PREFIX
  178. "Using %s partition definition\n", sbc8240_part_banks[i].mtd_part->name);
  179. add_mtd_partitions (sbc8240_mtd[i],
  180. sbc8240_part_banks[i].mtd_part,
  181. sbc8240_part_banks[i].nums);
  182. }
  183. }
  184. #else
  185. printk(KERN_NOTICE MSG_PREFIX
  186. "Registering %d flash banks at once\n", devicesfound);
  187. for (i = 0; i < devicesfound; i++) {
  188. add_mtd_device(sbc8240_mtd[i]);
  189. }
  190. #endif /* CONFIG_MTD_PARTITIONS */
  191. return devicesfound == 0 ? -ENXIO : 0;
  192. }
  193. static void __exit cleanup_sbc8240_mtd (void)
  194. {
  195. int i;
  196. for (i = 0; i < NUM_FLASH_BANKS; i++) {
  197. if (sbc8240_mtd[i]) {
  198. del_mtd_device (sbc8240_mtd[i]);
  199. map_destroy (sbc8240_mtd[i]);
  200. }
  201. if (sbc8240_map[i].map_priv_1) {
  202. iounmap ((void *) sbc8240_map[i].map_priv_1);
  203. sbc8240_map[i].map_priv_1 = 0;
  204. }
  205. }
  206. }
  207. module_init (init_sbc8240_mtd);
  208. module_exit (cleanup_sbc8240_mtd);
  209. MODULE_LICENSE ("GPL");
  210. MODULE_AUTHOR ("Carolyn Smith <carolyn.smith@tektronix.com>");
  211. MODULE_DESCRIPTION ("MTD map driver for SBC8240 boards");