epxa10db-flash.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:5k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Flash memory access on EPXA based devices
  3.  *
  4.  * (C) 2000 Nicolas Pitre <nico@cam.org>
  5.  *  Copyright (C) 2001 Altera Corporation
  6.  *  Copyright (C) 2001 Red Hat, Inc.
  7.  *
  8.  * $Id: epxa10db-flash.c,v 1.2 2001/12/19 13:00:19 jskov Exp $ 
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  23.  */
  24. #include <linux/config.h>
  25. #include <linux/module.h>
  26. #include <linux/types.h>
  27. #include <linux/kernel.h>
  28. #include <asm/io.h>
  29. #include <linux/mtd/mtd.h>
  30. #include <linux/mtd/map.h>
  31. #include <linux/mtd/partitions.h>
  32. #include <asm/hardware.h>
  33. static int nr_parts = 0;
  34. static struct mtd_partition *parts;
  35. static struct mtd_info *mymtd;
  36. extern int parse_redboot_partitions(struct mtd_info *, struct mtd_partition **);
  37. static int epxa10db_default_partitions(struct mtd_info *master, struct mtd_partition **pparts);
  38. static __u8 epxa10db_read8(struct map_info *map, unsigned long ofs)
  39. {
  40. return __raw_readb(map->map_priv_1 + ofs);
  41. }
  42. static __u16 epxa10db_read16(struct map_info *map, unsigned long ofs)
  43. {
  44. return __raw_readw(map->map_priv_1 + ofs);
  45. }
  46. static __u32 epxa10db_read32(struct map_info *map, unsigned long ofs)
  47. {
  48. return __raw_readl(map->map_priv_1 + ofs);
  49. }
  50. static void epxa10db_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
  51. {
  52. memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);
  53. }
  54. static void epxa10db_write8(struct map_info *map, __u8 d, unsigned long adr)
  55. {
  56. __raw_writeb(d, map->map_priv_1 + adr);
  57. mb();
  58. }
  59. static void epxa10db_write16(struct map_info *map, __u16 d, unsigned long adr)
  60. {
  61. __raw_writew(d, map->map_priv_1 + adr);
  62. mb();
  63. }
  64. static void epxa10db_write32(struct map_info *map, __u32 d, unsigned long adr)
  65. {
  66. __raw_writel(d, map->map_priv_1 + adr);
  67. mb();
  68. }
  69. static void epxa10db_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
  70. {
  71. memcpy_toio((void *)(map->map_priv_1 + to), from, len);
  72. }
  73. static struct map_info epxa10db_map = {
  74. name: "EPXA10DB flash",
  75. size: FLASH_SIZE,
  76. buswidth: 2,
  77. read8: epxa10db_read8,
  78. read16: epxa10db_read16,
  79. read32: epxa10db_read32,
  80. copy_from: epxa10db_copy_from,
  81. write8: epxa10db_write8,
  82. write16: epxa10db_write16,
  83. write32: epxa10db_write32,
  84. copy_to: epxa10db_copy_to
  85. };
  86. static int __init epxa10db_mtd_init(void)
  87. {
  88. int i;
  89. printk(KERN_NOTICE "Epxa10db flash device: %x at %xn", FLASH_SIZE, FLASH_START);
  90. epxa10db_map.map_priv_1 = (unsigned long)ioremap(FLASH_START, FLASH_SIZE);
  91. if (!epxa10db_map.map_priv_1) {
  92. printk("Failed to ioremap Epxa10db flashn");
  93. return -EIO;
  94. }
  95. mymtd = do_map_probe("cfi_probe", &epxa10db_map);
  96. if (!mymtd) {
  97. iounmap((void *)epxa10db_map.map_priv_1);
  98. return -ENXIO;
  99. }
  100. mymtd->module = THIS_MODULE;
  101. /* Unlock the flash device. */
  102. for (i=0; i<mymtd->numeraseregions;i++){
  103. int j;
  104. for(j=0;j<mymtd->eraseregions[i].numblocks;j++){
  105. mymtd->unlock(mymtd,mymtd->eraseregions[i].offset + j * mymtd->eraseregions[i].erasesize,4);
  106. }
  107. }
  108. #ifdef CONFIG_MTD_REDBOOT_PARTS
  109. nr_parts = parse_redboot_partitions(mymtd, &parts);
  110. if (nr_parts > 0) {
  111. add_mtd_partitions(mymtd, parts, nr_parts);
  112. return 0;
  113. }
  114. #endif
  115. #ifdef CONFIG_MTD_AFS_PARTS
  116. nr_parts = parse_afs_partitions(mymtd, &parts);
  117. if (nr_parts > 0) {
  118. add_mtd_partitions(mymtd, parts, nr_parts);
  119. return 0;
  120. }
  121. #endif
  122. /* No recognised partitioning schemes found - use defaults */
  123. nr_parts = epxa10db_default_partitions(mymtd, &parts);
  124. if (nr_parts > 0) {
  125. add_mtd_partitions(mymtd, parts, nr_parts);
  126. return 0;
  127. }
  128. /* If all else fails... */
  129. add_mtd_device(mymtd);
  130. return 0;
  131. }
  132. static void __exit epxa10db_mtd_cleanup(void)
  133. {
  134. if (mymtd) {
  135. if (nr_parts)
  136. del_mtd_partitions(mymtd);
  137. else
  138. del_mtd_device(mymtd);
  139. map_destroy(mymtd);
  140. }
  141. if (epxa10db_map.map_priv_1) {
  142. iounmap((void *)epxa10db_map.map_priv_1);
  143. epxa10db_map.map_priv_1 = 0;
  144. }
  145. }
  146. /* 
  147.  * This will do for now, once we decide which bootldr we're finally 
  148.  * going to use then we'll remove this function and do it properly
  149.  *
  150.  * Partions are currently (as offsets from base of flash):
  151.  * 0x00000000 - 0x003FFFFF - bootloader (!)
  152.  * 0x00400000 - 0x00FFFFFF - Flashdisk
  153.  */
  154. static int __init epxa10db_default_partitions(struct mtd_info *master, struct mtd_partition **pparts)
  155. {
  156. struct mtd_partition *parts;
  157. int ret, i;
  158. int npartitions = 0;
  159. char *names; 
  160. const char *name = "jffs";
  161. printk("Using default partitions for epxa10dbn");
  162. npartitions=1;
  163. parts = kmalloc(npartitions*sizeof(*parts)+strlen(name), GFP_KERNEL);
  164. if (!parts) {
  165. ret = -ENOMEM;
  166. goto out;
  167. }
  168. i=0;
  169. names = (char *)&parts[npartitions];
  170. parts[i].name = names;
  171. names += strlen(name) + 1;
  172. strcpy(parts[i].name, name);
  173. parts[i].size = FLASH_SIZE-0x00400000;
  174. parts[i].offset = 0x00400000;
  175. parts[i].mask_flags = 0;
  176.  out:
  177. *pparts = parts;
  178. return npartitions;
  179. }
  180. module_init(epxa10db_mtd_init);
  181. module_exit(epxa10db_mtd_cleanup);
  182. MODULE_AUTHOR("Clive Davies");
  183. MODULE_DESCRIPTION("Altera epxa10db mtd flash map");
  184. MODULE_LICENSE("GPL");