diff options
| author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
| commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
| tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /include/linux/mtd | |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'include/linux/mtd')
| -rw-r--r-- | include/linux/mtd/blktrans.h | 72 | ||||
| -rw-r--r-- | include/linux/mtd/cfi.h | 394 | ||||
| -rw-r--r-- | include/linux/mtd/cfi_endian.h | 57 | ||||
| -rw-r--r-- | include/linux/mtd/compatmac.h | 10 | ||||
| -rw-r--r-- | include/linux/mtd/concat.h | 23 | ||||
| -rw-r--r-- | include/linux/mtd/doc2000.h | 195 | ||||
| -rw-r--r-- | include/linux/mtd/flashchip.h | 89 | ||||
| -rw-r--r-- | include/linux/mtd/ftl.h | 76 | ||||
| -rw-r--r-- | include/linux/mtd/gen_probe.h | 23 | ||||
| -rw-r--r-- | include/linux/mtd/iflash.h | 98 | ||||
| -rw-r--r-- | include/linux/mtd/inftl.h | 57 | ||||
| -rw-r--r-- | include/linux/mtd/jedec.h | 66 | ||||
| -rw-r--r-- | include/linux/mtd/map.h | 412 | ||||
| -rw-r--r-- | include/linux/mtd/mtd.h | 226 | ||||
| -rw-r--r-- | include/linux/mtd/nand.h | 469 | ||||
| -rw-r--r-- | include/linux/mtd/nand_ecc.h | 30 | ||||
| -rw-r--r-- | include/linux/mtd/nftl.h | 54 | ||||
| -rw-r--r-- | include/linux/mtd/partitions.h | 75 | ||||
| -rw-r--r-- | include/linux/mtd/physmap.h | 61 | ||||
| -rw-r--r-- | include/linux/mtd/pmc551.h | 79 | ||||
| -rw-r--r-- | include/linux/mtd/xip.h | 107 |
21 files changed, 2673 insertions, 0 deletions
diff --git a/include/linux/mtd/blktrans.h b/include/linux/mtd/blktrans.h new file mode 100644 index 000000000000..4ebc2e5a16e2 --- /dev/null +++ b/include/linux/mtd/blktrans.h | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | /* | ||
| 2 | * $Id: blktrans.h,v 1.5 2003/06/23 12:00:08 dwmw2 Exp $ | ||
| 3 | * | ||
| 4 | * (C) 2003 David Woodhouse <dwmw2@infradead.org> | ||
| 5 | * | ||
| 6 | * Interface to Linux block layer for MTD 'translation layers'. | ||
| 7 | * | ||
| 8 | */ | ||
| 9 | |||
| 10 | #ifndef __MTD_TRANS_H__ | ||
| 11 | #define __MTD_TRANS_H__ | ||
| 12 | |||
| 13 | #include <asm/semaphore.h> | ||
| 14 | |||
| 15 | struct hd_geometry; | ||
| 16 | struct mtd_info; | ||
| 17 | struct mtd_blktrans_ops; | ||
| 18 | struct file; | ||
| 19 | struct inode; | ||
| 20 | |||
| 21 | struct mtd_blktrans_dev { | ||
| 22 | struct mtd_blktrans_ops *tr; | ||
| 23 | struct list_head list; | ||
| 24 | struct mtd_info *mtd; | ||
| 25 | struct semaphore sem; | ||
| 26 | int devnum; | ||
| 27 | int blksize; | ||
| 28 | unsigned long size; | ||
| 29 | int readonly; | ||
| 30 | void *blkcore_priv; /* gendisk in 2.5, devfs_handle in 2.4 */ | ||
| 31 | }; | ||
| 32 | |||
| 33 | struct blkcore_priv; /* Differs for 2.4 and 2.5 kernels; private */ | ||
| 34 | |||
| 35 | struct mtd_blktrans_ops { | ||
| 36 | char *name; | ||
| 37 | int major; | ||
| 38 | int part_bits; | ||
| 39 | |||
| 40 | /* Access functions */ | ||
| 41 | int (*readsect)(struct mtd_blktrans_dev *dev, | ||
| 42 | unsigned long block, char *buffer); | ||
| 43 | int (*writesect)(struct mtd_blktrans_dev *dev, | ||
| 44 | unsigned long block, char *buffer); | ||
| 45 | |||
| 46 | /* Block layer ioctls */ | ||
| 47 | int (*getgeo)(struct mtd_blktrans_dev *dev, struct hd_geometry *geo); | ||
| 48 | int (*flush)(struct mtd_blktrans_dev *dev); | ||
| 49 | |||
| 50 | /* Called with mtd_table_mutex held; no race with add/remove */ | ||
| 51 | int (*open)(struct mtd_blktrans_dev *dev); | ||
| 52 | int (*release)(struct mtd_blktrans_dev *dev); | ||
| 53 | |||
| 54 | /* Called on {de,}registration and on subsequent addition/removal | ||
| 55 | of devices, with mtd_table_mutex held. */ | ||
| 56 | void (*add_mtd)(struct mtd_blktrans_ops *tr, struct mtd_info *mtd); | ||
| 57 | void (*remove_dev)(struct mtd_blktrans_dev *dev); | ||
| 58 | |||
| 59 | struct list_head devs; | ||
| 60 | struct list_head list; | ||
| 61 | struct module *owner; | ||
| 62 | |||
| 63 | struct mtd_blkcore_priv *blkcore_priv; | ||
| 64 | }; | ||
| 65 | |||
| 66 | extern int register_mtd_blktrans(struct mtd_blktrans_ops *tr); | ||
| 67 | extern int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr); | ||
| 68 | extern int add_mtd_blktrans_dev(struct mtd_blktrans_dev *dev); | ||
| 69 | extern int del_mtd_blktrans_dev(struct mtd_blktrans_dev *dev); | ||
| 70 | |||
| 71 | |||
| 72 | #endif /* __MTD_TRANS_H__ */ | ||
diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h new file mode 100644 index 000000000000..2ed8c585021e --- /dev/null +++ b/include/linux/mtd/cfi.h | |||
| @@ -0,0 +1,394 @@ | |||
| 1 | |||
| 2 | /* Common Flash Interface structures | ||
| 3 | * See http://support.intel.com/design/flash/technote/index.htm | ||
| 4 | * $Id: cfi.h,v 1.50 2004/11/20 12:46:51 dwmw2 Exp $ | ||
| 5 | */ | ||
| 6 | |||
| 7 | #ifndef __MTD_CFI_H__ | ||
| 8 | #define __MTD_CFI_H__ | ||
| 9 | |||
| 10 | #include <linux/config.h> | ||
| 11 | #include <linux/version.h> | ||
| 12 | #include <linux/delay.h> | ||
| 13 | #include <linux/types.h> | ||
| 14 | #include <linux/interrupt.h> | ||
| 15 | #include <linux/mtd/flashchip.h> | ||
| 16 | #include <linux/mtd/map.h> | ||
| 17 | #include <linux/mtd/cfi_endian.h> | ||
| 18 | |||
| 19 | #ifdef CONFIG_MTD_CFI_I1 | ||
| 20 | #define cfi_interleave(cfi) 1 | ||
| 21 | #define cfi_interleave_is_1(cfi) (cfi_interleave(cfi) == 1) | ||
| 22 | #else | ||
| 23 | #define cfi_interleave_is_1(cfi) (0) | ||
| 24 | #endif | ||
| 25 | |||
| 26 | #ifdef CONFIG_MTD_CFI_I2 | ||
| 27 | # ifdef cfi_interleave | ||
| 28 | # undef cfi_interleave | ||
| 29 | # define cfi_interleave(cfi) ((cfi)->interleave) | ||
| 30 | # else | ||
| 31 | # define cfi_interleave(cfi) 2 | ||
| 32 | # endif | ||
| 33 | #define cfi_interleave_is_2(cfi) (cfi_interleave(cfi) == 2) | ||
| 34 | #else | ||
| 35 | #define cfi_interleave_is_2(cfi) (0) | ||
| 36 | #endif | ||
| 37 | |||
| 38 | #ifdef CONFIG_MTD_CFI_I4 | ||
| 39 | # ifdef cfi_interleave | ||
| 40 | # undef cfi_interleave | ||
| 41 | # define cfi_interleave(cfi) ((cfi)->interleave) | ||
| 42 | # else | ||
| 43 | # define cfi_interleave(cfi) 4 | ||
| 44 | # endif | ||
| 45 | #define cfi_interleave_is_4(cfi) (cfi_interleave(cfi) == 4) | ||
| 46 | #else | ||
| 47 | #define cfi_interleave_is_4(cfi) (0) | ||
| 48 | #endif | ||
| 49 | |||
| 50 | #ifdef CONFIG_MTD_CFI_I8 | ||
| 51 | # ifdef cfi_interleave | ||
| 52 | # undef cfi_interleave | ||
| 53 | # define cfi_interleave(cfi) ((cfi)->interleave) | ||
| 54 | # else | ||
| 55 | # define cfi_interleave(cfi) 8 | ||
| 56 | # endif | ||
| 57 | #define cfi_interleave_is_8(cfi) (cfi_interleave(cfi) == 8) | ||
| 58 | #else | ||
| 59 | #define cfi_interleave_is_8(cfi) (0) | ||
| 60 | #endif | ||
| 61 | |||
| 62 | static inline int cfi_interleave_supported(int i) | ||
| 63 | { | ||
| 64 | switch (i) { | ||
| 65 | #ifdef CONFIG_MTD_CFI_I1 | ||
| 66 | case 1: | ||
| 67 | #endif | ||
| 68 | #ifdef CONFIG_MTD_CFI_I2 | ||
| 69 | case 2: | ||
| 70 | #endif | ||
| 71 | #ifdef CONFIG_MTD_CFI_I4 | ||
| 72 | case 4: | ||
| 73 | #endif | ||
| 74 | #ifdef CONFIG_MTD_CFI_I8 | ||
| 75 | case 8: | ||
| 76 | #endif | ||
| 77 | return 1; | ||
| 78 | |||
| 79 | default: | ||
| 80 | return 0; | ||
| 81 | } | ||
| 82 | } | ||
| 83 | |||
| 84 | |||
| 85 | /* NB: these values must represents the number of bytes needed to meet the | ||
| 86 | * device type (x8, x16, x32). Eg. a 32 bit device is 4 x 8 bytes. | ||
| 87 | * These numbers are used in calculations. | ||
| 88 | */ | ||
| 89 | #define CFI_DEVICETYPE_X8 (8 / 8) | ||
| 90 | #define CFI_DEVICETYPE_X16 (16 / 8) | ||
| 91 | #define CFI_DEVICETYPE_X32 (32 / 8) | ||
| 92 | #define CFI_DEVICETYPE_X64 (64 / 8) | ||
| 93 | |||
| 94 | /* NB: We keep these structures in memory in HOST byteorder, except | ||
| 95 | * where individually noted. | ||
| 96 | */ | ||
| 97 | |||
| 98 | /* Basic Query Structure */ | ||
| 99 | struct cfi_ident { | ||
| 100 | uint8_t qry[3]; | ||
| 101 | uint16_t P_ID; | ||
| 102 | uint16_t P_ADR; | ||
| 103 | uint16_t A_ID; | ||
| 104 | uint16_t A_ADR; | ||
| 105 | uint8_t VccMin; | ||
| 106 | uint8_t VccMax; | ||
| 107 | uint8_t VppMin; | ||
| 108 | uint8_t VppMax; | ||
| 109 | uint8_t WordWriteTimeoutTyp; | ||
| 110 | uint8_t BufWriteTimeoutTyp; | ||
| 111 | uint8_t BlockEraseTimeoutTyp; | ||
| 112 | uint8_t ChipEraseTimeoutTyp; | ||
| 113 | uint8_t WordWriteTimeoutMax; | ||
| 114 | uint8_t BufWriteTimeoutMax; | ||
| 115 | uint8_t BlockEraseTimeoutMax; | ||
| 116 | uint8_t ChipEraseTimeoutMax; | ||
| 117 | uint8_t DevSize; | ||
| 118 | uint16_t InterfaceDesc; | ||
| 119 | uint16_t MaxBufWriteSize; | ||
| 120 | uint8_t NumEraseRegions; | ||
| 121 | uint32_t EraseRegionInfo[0]; /* Not host ordered */ | ||
| 122 | } __attribute__((packed)); | ||
| 123 | |||
| 124 | /* Extended Query Structure for both PRI and ALT */ | ||
| 125 | |||
| 126 | struct cfi_extquery { | ||
| 127 | uint8_t pri[3]; | ||
| 128 | uint8_t MajorVersion; | ||
| 129 | uint8_t MinorVersion; | ||
| 130 | } __attribute__((packed)); | ||
| 131 | |||
| 132 | /* Vendor-Specific PRI for Intel/Sharp Extended Command Set (0x0001) */ | ||
| 133 | |||
| 134 | struct cfi_pri_intelext { | ||
| 135 | uint8_t pri[3]; | ||
| 136 | uint8_t MajorVersion; | ||
| 137 | uint8_t MinorVersion; | ||
| 138 | uint32_t FeatureSupport; /* if bit 31 is set then an additional uint32_t feature | ||
| 139 | block follows - FIXME - not currently supported */ | ||
| 140 | uint8_t SuspendCmdSupport; | ||
| 141 | uint16_t BlkStatusRegMask; | ||
| 142 | uint8_t VccOptimal; | ||
| 143 | uint8_t VppOptimal; | ||
| 144 | uint8_t NumProtectionFields; | ||
| 145 | uint16_t ProtRegAddr; | ||
| 146 | uint8_t FactProtRegSize; | ||
| 147 | uint8_t UserProtRegSize; | ||
| 148 | uint8_t extra[0]; | ||
| 149 | } __attribute__((packed)); | ||
| 150 | |||
| 151 | struct cfi_intelext_blockinfo { | ||
| 152 | uint16_t NumIdentBlocks; | ||
| 153 | uint16_t BlockSize; | ||
| 154 | uint16_t MinBlockEraseCycles; | ||
| 155 | uint8_t BitsPerCell; | ||
| 156 | uint8_t BlockCap; | ||
| 157 | } __attribute__((packed)); | ||
| 158 | |||
| 159 | struct cfi_intelext_regioninfo { | ||
| 160 | uint16_t NumIdentPartitions; | ||
| 161 | uint8_t NumOpAllowed; | ||
| 162 | uint8_t NumOpAllowedSimProgMode; | ||
| 163 | uint8_t NumOpAllowedSimEraMode; | ||
| 164 | uint8_t NumBlockTypes; | ||
| 165 | struct cfi_intelext_blockinfo BlockTypes[1]; | ||
| 166 | } __attribute__((packed)); | ||
| 167 | |||
| 168 | /* Vendor-Specific PRI for AMD/Fujitsu Extended Command Set (0x0002) */ | ||
| 169 | |||
| 170 | struct cfi_pri_amdstd { | ||
| 171 | uint8_t pri[3]; | ||
| 172 | uint8_t MajorVersion; | ||
| 173 | uint8_t MinorVersion; | ||
| 174 | uint8_t SiliconRevision; /* bits 1-0: Address Sensitive Unlock */ | ||
| 175 | uint8_t EraseSuspend; | ||
| 176 | uint8_t BlkProt; | ||
| 177 | uint8_t TmpBlkUnprotect; | ||
| 178 | uint8_t BlkProtUnprot; | ||
| 179 | uint8_t SimultaneousOps; | ||
| 180 | uint8_t BurstMode; | ||
| 181 | uint8_t PageMode; | ||
| 182 | uint8_t VppMin; | ||
| 183 | uint8_t VppMax; | ||
| 184 | uint8_t TopBottom; | ||
| 185 | } __attribute__((packed)); | ||
| 186 | |||
| 187 | struct cfi_pri_query { | ||
| 188 | uint8_t NumFields; | ||
| 189 | uint32_t ProtField[1]; /* Not host ordered */ | ||
| 190 | } __attribute__((packed)); | ||
| 191 | |||
| 192 | struct cfi_bri_query { | ||
| 193 | uint8_t PageModeReadCap; | ||
| 194 | uint8_t NumFields; | ||
| 195 | uint32_t ConfField[1]; /* Not host ordered */ | ||
| 196 | } __attribute__((packed)); | ||
| 197 | |||
| 198 | #define P_ID_NONE 0x0000 | ||
| 199 | #define P_ID_INTEL_EXT 0x0001 | ||
| 200 | #define P_ID_AMD_STD 0x0002 | ||
| 201 | #define P_ID_INTEL_STD 0x0003 | ||
| 202 | #define P_ID_AMD_EXT 0x0004 | ||
| 203 | #define P_ID_WINBOND 0x0006 | ||
| 204 | #define P_ID_ST_ADV 0x0020 | ||
| 205 | #define P_ID_MITSUBISHI_STD 0x0100 | ||
| 206 | #define P_ID_MITSUBISHI_EXT 0x0101 | ||
| 207 | #define P_ID_SST_PAGE 0x0102 | ||
| 208 | #define P_ID_INTEL_PERFORMANCE 0x0200 | ||
| 209 | #define P_ID_INTEL_DATA 0x0210 | ||
| 210 | #define P_ID_RESERVED 0xffff | ||
| 211 | |||
| 212 | |||
| 213 | #define CFI_MODE_CFI 1 | ||
| 214 | #define CFI_MODE_JEDEC 0 | ||
| 215 | |||
| 216 | struct cfi_private { | ||
| 217 | uint16_t cmdset; | ||
| 218 | void *cmdset_priv; | ||
| 219 | int interleave; | ||
| 220 | int device_type; | ||
| 221 | int cfi_mode; /* Are we a JEDEC device pretending to be CFI? */ | ||
| 222 | int addr_unlock1; | ||
| 223 | int addr_unlock2; | ||
| 224 | struct mtd_info *(*cmdset_setup)(struct map_info *); | ||
| 225 | struct cfi_ident *cfiq; /* For now only one. We insist that all devs | ||
| 226 | must be of the same type. */ | ||
| 227 | int mfr, id; | ||
| 228 | int numchips; | ||
| 229 | unsigned long chipshift; /* Because they're of the same type */ | ||
| 230 | const char *im_name; /* inter_module name for cmdset_setup */ | ||
| 231 | struct flchip chips[0]; /* per-chip data structure for each chip */ | ||
| 232 | }; | ||
| 233 | |||
| 234 | /* | ||
| 235 | * Returns the command address according to the given geometry. | ||
| 236 | */ | ||
| 237 | static inline uint32_t cfi_build_cmd_addr(uint32_t cmd_ofs, int interleave, int type) | ||
| 238 | { | ||
| 239 | return (cmd_ofs * type) * interleave; | ||
| 240 | } | ||
| 241 | |||
| 242 | /* | ||
| 243 | * Transforms the CFI command for the given geometry (bus width & interleave). | ||
| 244 | * It looks too long to be inline, but in the common case it should almost all | ||
| 245 | * get optimised away. | ||
| 246 | */ | ||
| 247 | static inline map_word cfi_build_cmd(u_char cmd, struct map_info *map, struct cfi_private *cfi) | ||
| 248 | { | ||
| 249 | map_word val = { {0} }; | ||
| 250 | int wordwidth, words_per_bus, chip_mode, chips_per_word; | ||
| 251 | unsigned long onecmd; | ||
| 252 | int i; | ||
| 253 | |||
| 254 | /* We do it this way to give the compiler a fighting chance | ||
| 255 | of optimising away all the crap for 'bankwidth' larger than | ||
| 256 | an unsigned long, in the common case where that support is | ||
| 257 | disabled */ | ||
| 258 | if (map_bankwidth_is_large(map)) { | ||
| 259 | wordwidth = sizeof(unsigned long); | ||
| 260 | words_per_bus = (map_bankwidth(map)) / wordwidth; // i.e. normally 1 | ||
| 261 | } else { | ||
| 262 | wordwidth = map_bankwidth(map); | ||
| 263 | words_per_bus = 1; | ||
| 264 | } | ||
| 265 | |||
| 266 | chip_mode = map_bankwidth(map) / cfi_interleave(cfi); | ||
| 267 | chips_per_word = wordwidth * cfi_interleave(cfi) / map_bankwidth(map); | ||
| 268 | |||
| 269 | /* First, determine what the bit-pattern should be for a single | ||
| 270 | device, according to chip mode and endianness... */ | ||
| 271 | switch (chip_mode) { | ||
| 272 | default: BUG(); | ||
| 273 | case 1: | ||
| 274 | onecmd = cmd; | ||
| 275 | break; | ||
| 276 | case 2: | ||
| 277 | onecmd = cpu_to_cfi16(cmd); | ||
| 278 | break; | ||
| 279 | case 4: | ||
| 280 | onecmd = cpu_to_cfi32(cmd); | ||
| 281 | break; | ||
| 282 | } | ||
| 283 | |||
| 284 | /* Now replicate it across the size of an unsigned long, or | ||
| 285 | just to the bus width as appropriate */ | ||
| 286 | switch (chips_per_word) { | ||
| 287 | default: BUG(); | ||
| 288 | #if BITS_PER_LONG >= 64 | ||
| 289 | case 8: | ||
| 290 | onecmd |= (onecmd << (chip_mode * 32)); | ||
| 291 | #endif | ||
| 292 | case 4: | ||
| 293 | onecmd |= (onecmd << (chip_mode * 16)); | ||
| 294 | case 2: | ||
| 295 | onecmd |= (onecmd << (chip_mode * 8)); | ||
| 296 | case 1: | ||
| 297 | ; | ||
| 298 | } | ||
| 299 | |||
| 300 | /* And finally, for the multi-word case, replicate it | ||
| 301 | in all words in the structure */ | ||
| 302 | for (i=0; i < words_per_bus; i++) { | ||
| 303 | val.x[i] = onecmd; | ||
| 304 | } | ||
| 305 | |||
| 306 | return val; | ||
| 307 | } | ||
| 308 | #define CMD(x) cfi_build_cmd((x), map, cfi) | ||
| 309 | |||
| 310 | /* | ||
| 311 | * Sends a CFI command to a bank of flash for the given geometry. | ||
| 312 | * | ||
| 313 | * Returns the offset in flash where the command was written. | ||
| 314 | * If prev_val is non-null, it will be set to the value at the command address, | ||
| 315 | * before the command was written. | ||
| 316 | */ | ||
| 317 | static inline uint32_t cfi_send_gen_cmd(u_char cmd, uint32_t cmd_addr, uint32_t base, | ||
| 318 | struct map_info *map, struct cfi_private *cfi, | ||
| 319 | int type, map_word *prev_val) | ||
| 320 | { | ||
| 321 | map_word val; | ||
| 322 | uint32_t addr = base + cfi_build_cmd_addr(cmd_addr, cfi_interleave(cfi), type); | ||
| 323 | |||
| 324 | val = cfi_build_cmd(cmd, map, cfi); | ||
| 325 | |||
| 326 | if (prev_val) | ||
| 327 | *prev_val = map_read(map, addr); | ||
| 328 | |||
| 329 | map_write(map, val, addr); | ||
| 330 | |||
| 331 | return addr - base; | ||
| 332 | } | ||
| 333 | |||
| 334 | static inline uint8_t cfi_read_query(struct map_info *map, uint32_t addr) | ||
| 335 | { | ||
| 336 | map_word val = map_read(map, addr); | ||
| 337 | |||
| 338 | if (map_bankwidth_is_1(map)) { | ||
| 339 | return val.x[0]; | ||
| 340 | } else if (map_bankwidth_is_2(map)) { | ||
| 341 | return cfi16_to_cpu(val.x[0]); | ||
| 342 | } else { | ||
| 343 | /* No point in a 64-bit byteswap since that would just be | ||
| 344 | swapping the responses from different chips, and we are | ||
| 345 | only interested in one chip (a representative sample) */ | ||
| 346 | return cfi32_to_cpu(val.x[0]); | ||
| 347 | } | ||
| 348 | } | ||
| 349 | |||
| 350 | static inline void cfi_udelay(int us) | ||
| 351 | { | ||
| 352 | if (us >= 1000) { | ||
| 353 | msleep((us+999)/1000); | ||
| 354 | } else { | ||
| 355 | udelay(us); | ||
| 356 | cond_resched(); | ||
| 357 | } | ||
| 358 | } | ||
| 359 | |||
| 360 | static inline void cfi_spin_lock(spinlock_t *mutex) | ||
| 361 | { | ||
| 362 | spin_lock_bh(mutex); | ||
| 363 | } | ||
| 364 | |||
| 365 | static inline void cfi_spin_unlock(spinlock_t *mutex) | ||
| 366 | { | ||
| 367 | spin_unlock_bh(mutex); | ||
| 368 | } | ||
| 369 | |||
| 370 | struct cfi_extquery *cfi_read_pri(struct map_info *map, uint16_t adr, uint16_t size, | ||
| 371 | const char* name); | ||
| 372 | struct cfi_fixup { | ||
| 373 | uint16_t mfr; | ||
| 374 | uint16_t id; | ||
| 375 | void (*fixup)(struct mtd_info *mtd, void* param); | ||
| 376 | void* param; | ||
| 377 | }; | ||
| 378 | |||
| 379 | #define CFI_MFR_ANY 0xffff | ||
| 380 | #define CFI_ID_ANY 0xffff | ||
| 381 | |||
| 382 | #define CFI_MFR_AMD 0x0001 | ||
| 383 | #define CFI_MFR_ST 0x0020 /* STMicroelectronics */ | ||
| 384 | |||
| 385 | void cfi_fixup(struct mtd_info *mtd, struct cfi_fixup* fixups); | ||
| 386 | |||
| 387 | typedef int (*varsize_frob_t)(struct map_info *map, struct flchip *chip, | ||
| 388 | unsigned long adr, int len, void *thunk); | ||
| 389 | |||
| 390 | int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob, | ||
| 391 | loff_t ofs, size_t len, void *thunk); | ||
| 392 | |||
| 393 | |||
| 394 | #endif /* __MTD_CFI_H__ */ | ||
diff --git a/include/linux/mtd/cfi_endian.h b/include/linux/mtd/cfi_endian.h new file mode 100644 index 000000000000..25724f7d3867 --- /dev/null +++ b/include/linux/mtd/cfi_endian.h | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | /* | ||
| 2 | * $Id: cfi_endian.h,v 1.11 2002/01/30 23:20:48 awozniak Exp $ | ||
| 3 | * | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <asm/byteorder.h> | ||
| 7 | |||
| 8 | #ifndef CONFIG_MTD_CFI_ADV_OPTIONS | ||
| 9 | |||
| 10 | #define CFI_HOST_ENDIAN | ||
| 11 | |||
| 12 | #else | ||
| 13 | |||
| 14 | #ifdef CONFIG_MTD_CFI_NOSWAP | ||
| 15 | #define CFI_HOST_ENDIAN | ||
| 16 | #endif | ||
| 17 | |||
| 18 | #ifdef CONFIG_MTD_CFI_LE_BYTE_SWAP | ||
| 19 | #define CFI_LITTLE_ENDIAN | ||
| 20 | #endif | ||
| 21 | |||
| 22 | #ifdef CONFIG_MTD_CFI_BE_BYTE_SWAP | ||
| 23 | #define CFI_BIG_ENDIAN | ||
| 24 | #endif | ||
| 25 | |||
| 26 | #endif | ||
| 27 | |||
| 28 | #if defined(CFI_LITTLE_ENDIAN) | ||
| 29 | #define cpu_to_cfi8(x) (x) | ||
| 30 | #define cfi8_to_cpu(x) (x) | ||
| 31 | #define cpu_to_cfi16(x) cpu_to_le16(x) | ||
| 32 | #define cpu_to_cfi32(x) cpu_to_le32(x) | ||
| 33 | #define cpu_to_cfi64(x) cpu_to_le64(x) | ||
| 34 | #define cfi16_to_cpu(x) le16_to_cpu(x) | ||
| 35 | #define cfi32_to_cpu(x) le32_to_cpu(x) | ||
| 36 | #define cfi64_to_cpu(x) le64_to_cpu(x) | ||
| 37 | #elif defined (CFI_BIG_ENDIAN) | ||
| 38 | #define cpu_to_cfi8(x) (x) | ||
| 39 | #define cfi8_to_cpu(x) (x) | ||
| 40 | #define cpu_to_cfi16(x) cpu_to_be16(x) | ||
| 41 | #define cpu_to_cfi32(x) cpu_to_be32(x) | ||
| 42 | #define cpu_to_cfi64(x) cpu_to_be64(x) | ||
| 43 | #define cfi16_to_cpu(x) be16_to_cpu(x) | ||
| 44 | #define cfi32_to_cpu(x) be32_to_cpu(x) | ||
| 45 | #define cfi64_to_cpu(x) be64_to_cpu(x) | ||
| 46 | #elif defined (CFI_HOST_ENDIAN) | ||
| 47 | #define cpu_to_cfi8(x) (x) | ||
| 48 | #define cfi8_to_cpu(x) (x) | ||
| 49 | #define cpu_to_cfi16(x) (x) | ||
| 50 | #define cpu_to_cfi32(x) (x) | ||
| 51 | #define cpu_to_cfi64(x) (x) | ||
| 52 | #define cfi16_to_cpu(x) (x) | ||
| 53 | #define cfi32_to_cpu(x) (x) | ||
| 54 | #define cfi64_to_cpu(x) (x) | ||
| 55 | #else | ||
| 56 | #error No CFI endianness defined | ||
| 57 | #endif | ||
diff --git a/include/linux/mtd/compatmac.h b/include/linux/mtd/compatmac.h new file mode 100644 index 000000000000..7d1300d9bd51 --- /dev/null +++ b/include/linux/mtd/compatmac.h | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | |||
| 2 | #ifndef __LINUX_MTD_COMPATMAC_H__ | ||
| 3 | #define __LINUX_MTD_COMPATMAC_H__ | ||
| 4 | |||
| 5 | /* Nothing to see here. We write 2.5-compatible code and this | ||
| 6 | file makes it all OK in older kernels, but it's empty in _current_ | ||
| 7 | kernels. Include guard just to make GCC ignore it in future inclusions | ||
| 8 | anyway... */ | ||
| 9 | |||
| 10 | #endif /* __LINUX_MTD_COMPATMAC_H__ */ | ||
diff --git a/include/linux/mtd/concat.h b/include/linux/mtd/concat.h new file mode 100644 index 000000000000..ed8dc6755219 --- /dev/null +++ b/include/linux/mtd/concat.h | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | /* | ||
| 2 | * MTD device concatenation layer definitions | ||
| 3 | * | ||
| 4 | * (C) 2002 Robert Kaiser <rkaiser@sysgo.de> | ||
| 5 | * | ||
| 6 | * This code is GPL | ||
| 7 | * | ||
| 8 | * $Id: concat.h,v 1.1 2002/03/08 16:34:36 rkaiser Exp $ | ||
| 9 | */ | ||
| 10 | |||
| 11 | #ifndef MTD_CONCAT_H | ||
| 12 | #define MTD_CONCAT_H | ||
| 13 | |||
| 14 | |||
| 15 | struct mtd_info *mtd_concat_create( | ||
| 16 | struct mtd_info *subdev[], /* subdevices to concatenate */ | ||
| 17 | int num_devs, /* number of subdevices */ | ||
| 18 | char *name); /* name for the new device */ | ||
| 19 | |||
| 20 | void mtd_concat_destroy(struct mtd_info *mtd); | ||
| 21 | |||
| 22 | #endif | ||
| 23 | |||
diff --git a/include/linux/mtd/doc2000.h b/include/linux/mtd/doc2000.h new file mode 100644 index 000000000000..953e64fb8ac5 --- /dev/null +++ b/include/linux/mtd/doc2000.h | |||
| @@ -0,0 +1,195 @@ | |||
| 1 | /* | ||
| 2 | * Linux driver for Disk-On-Chip devices | ||
| 3 | * | ||
| 4 | * Copyright (C) 1999 Machine Vision Holdings, Inc. | ||
| 5 | * Copyright (C) 2001-2003 David Woodhouse <dwmw2@infradead.org> | ||
| 6 | * Copyright (C) 2002-2003 Greg Ungerer <gerg@snapgear.com> | ||
| 7 | * Copyright (C) 2002-2003 SnapGear Inc | ||
| 8 | * | ||
| 9 | * $Id: doc2000.h,v 1.24 2005/01/05 12:40:38 dwmw2 Exp $ | ||
| 10 | * | ||
| 11 | * Released under GPL | ||
| 12 | */ | ||
| 13 | |||
| 14 | #ifndef __MTD_DOC2000_H__ | ||
| 15 | #define __MTD_DOC2000_H__ | ||
| 16 | |||
| 17 | #include <linux/mtd/mtd.h> | ||
| 18 | #include <asm/semaphore.h> | ||
| 19 | |||
| 20 | #define DoC_Sig1 0 | ||
| 21 | #define DoC_Sig2 1 | ||
| 22 | |||
| 23 | #define DoC_ChipID 0x1000 | ||
| 24 | #define DoC_DOCStatus 0x1001 | ||
| 25 | #define DoC_DOCControl 0x1002 | ||
| 26 | #define DoC_FloorSelect 0x1003 | ||
| 27 | #define DoC_CDSNControl 0x1004 | ||
| 28 | #define DoC_CDSNDeviceSelect 0x1005 | ||
| 29 | #define DoC_ECCConf 0x1006 | ||
| 30 | #define DoC_2k_ECCStatus 0x1007 | ||
| 31 | |||
| 32 | #define DoC_CDSNSlowIO 0x100d | ||
| 33 | #define DoC_ECCSyndrome0 0x1010 | ||
| 34 | #define DoC_ECCSyndrome1 0x1011 | ||
| 35 | #define DoC_ECCSyndrome2 0x1012 | ||
| 36 | #define DoC_ECCSyndrome3 0x1013 | ||
| 37 | #define DoC_ECCSyndrome4 0x1014 | ||
| 38 | #define DoC_ECCSyndrome5 0x1015 | ||
| 39 | #define DoC_AliasResolution 0x101b | ||
| 40 | #define DoC_ConfigInput 0x101c | ||
| 41 | #define DoC_ReadPipeInit 0x101d | ||
| 42 | #define DoC_WritePipeTerm 0x101e | ||
| 43 | #define DoC_LastDataRead 0x101f | ||
| 44 | #define DoC_NOP 0x1020 | ||
| 45 | |||
| 46 | #define DoC_Mil_CDSN_IO 0x0800 | ||
| 47 | #define DoC_2k_CDSN_IO 0x1800 | ||
| 48 | |||
| 49 | #define DoC_Mplus_NOP 0x1002 | ||
| 50 | #define DoC_Mplus_AliasResolution 0x1004 | ||
| 51 | #define DoC_Mplus_DOCControl 0x1006 | ||
| 52 | #define DoC_Mplus_AccessStatus 0x1008 | ||
| 53 | #define DoC_Mplus_DeviceSelect 0x1008 | ||
| 54 | #define DoC_Mplus_Configuration 0x100a | ||
| 55 | #define DoC_Mplus_OutputControl 0x100c | ||
| 56 | #define DoC_Mplus_FlashControl 0x1020 | ||
| 57 | #define DoC_Mplus_FlashSelect 0x1022 | ||
| 58 | #define DoC_Mplus_FlashCmd 0x1024 | ||
| 59 | #define DoC_Mplus_FlashAddress 0x1026 | ||
| 60 | #define DoC_Mplus_FlashData0 0x1028 | ||
| 61 | #define DoC_Mplus_FlashData1 0x1029 | ||
| 62 | #define DoC_Mplus_ReadPipeInit 0x102a | ||
| 63 | #define DoC_Mplus_LastDataRead 0x102c | ||
| 64 | #define DoC_Mplus_LastDataRead1 0x102d | ||
| 65 | #define DoC_Mplus_WritePipeTerm 0x102e | ||
| 66 | #define DoC_Mplus_ECCSyndrome0 0x1040 | ||
| 67 | #define DoC_Mplus_ECCSyndrome1 0x1041 | ||
| 68 | #define DoC_Mplus_ECCSyndrome2 0x1042 | ||
| 69 | #define DoC_Mplus_ECCSyndrome3 0x1043 | ||
| 70 | #define DoC_Mplus_ECCSyndrome4 0x1044 | ||
| 71 | #define DoC_Mplus_ECCSyndrome5 0x1045 | ||
| 72 | #define DoC_Mplus_ECCConf 0x1046 | ||
| 73 | #define DoC_Mplus_Toggle 0x1046 | ||
| 74 | #define DoC_Mplus_DownloadStatus 0x1074 | ||
| 75 | #define DoC_Mplus_CtrlConfirm 0x1076 | ||
| 76 | #define DoC_Mplus_Power 0x1fff | ||
| 77 | |||
| 78 | /* How to access the device? | ||
| 79 | * On ARM, it'll be mmap'd directly with 32-bit wide accesses. | ||
| 80 | * On PPC, it's mmap'd and 16-bit wide. | ||
| 81 | * Others use readb/writeb | ||
| 82 | */ | ||
| 83 | #if defined(__arm__) | ||
| 84 | #define ReadDOC_(adr, reg) ((unsigned char)(*(volatile __u32 *)(((unsigned long)adr)+((reg)<<2)))) | ||
| 85 | #define WriteDOC_(d, adr, reg) do{ *(volatile __u32 *)(((unsigned long)adr)+((reg)<<2)) = (__u32)d; wmb();} while(0) | ||
| 86 | #define DOC_IOREMAP_LEN 0x8000 | ||
| 87 | #elif defined(__ppc__) | ||
| 88 | #define ReadDOC_(adr, reg) ((unsigned char)(*(volatile __u16 *)(((unsigned long)adr)+((reg)<<1)))) | ||
| 89 | #define WriteDOC_(d, adr, reg) do{ *(volatile __u16 *)(((unsigned long)adr)+((reg)<<1)) = (__u16)d; wmb();} while(0) | ||
| 90 | #define DOC_IOREMAP_LEN 0x4000 | ||
| 91 | #else | ||
| 92 | #define ReadDOC_(adr, reg) readb((void __iomem *)(adr) + (reg)) | ||
| 93 | #define WriteDOC_(d, adr, reg) writeb(d, (void __iomem *)(adr) + (reg)) | ||
| 94 | #define DOC_IOREMAP_LEN 0x2000 | ||
| 95 | |||
| 96 | #endif | ||
| 97 | |||
| 98 | #if defined(__i386__) || defined(__x86_64__) | ||
| 99 | #define USE_MEMCPY | ||
| 100 | #endif | ||
| 101 | |||
| 102 | /* These are provided to directly use the DoC_xxx defines */ | ||
| 103 | #define ReadDOC(adr, reg) ReadDOC_(adr,DoC_##reg) | ||
| 104 | #define WriteDOC(d, adr, reg) WriteDOC_(d,adr,DoC_##reg) | ||
| 105 | |||
| 106 | #define DOC_MODE_RESET 0 | ||
| 107 | #define DOC_MODE_NORMAL 1 | ||
| 108 | #define DOC_MODE_RESERVED1 2 | ||
| 109 | #define DOC_MODE_RESERVED2 3 | ||
| 110 | |||
| 111 | #define DOC_MODE_CLR_ERR 0x80 | ||
| 112 | #define DOC_MODE_RST_LAT 0x10 | ||
| 113 | #define DOC_MODE_BDECT 0x08 | ||
| 114 | #define DOC_MODE_MDWREN 0x04 | ||
| 115 | |||
| 116 | #define DOC_ChipID_Doc2k 0x20 | ||
| 117 | #define DOC_ChipID_Doc2kTSOP 0x21 /* internal number for MTD */ | ||
| 118 | #define DOC_ChipID_DocMil 0x30 | ||
| 119 | #define DOC_ChipID_DocMilPlus32 0x40 | ||
| 120 | #define DOC_ChipID_DocMilPlus16 0x41 | ||
| 121 | |||
| 122 | #define CDSN_CTRL_FR_B 0x80 | ||
| 123 | #define CDSN_CTRL_FR_B0 0x40 | ||
| 124 | #define CDSN_CTRL_FR_B1 0x80 | ||
| 125 | |||
| 126 | #define CDSN_CTRL_ECC_IO 0x20 | ||
| 127 | #define CDSN_CTRL_FLASH_IO 0x10 | ||
| 128 | #define CDSN_CTRL_WP 0x08 | ||
| 129 | #define CDSN_CTRL_ALE 0x04 | ||
| 130 | #define CDSN_CTRL_CLE 0x02 | ||
| 131 | #define CDSN_CTRL_CE 0x01 | ||
| 132 | |||
| 133 | #define DOC_ECC_RESET 0 | ||
| 134 | #define DOC_ECC_ERROR 0x80 | ||
| 135 | #define DOC_ECC_RW 0x20 | ||
| 136 | #define DOC_ECC__EN 0x08 | ||
| 137 | #define DOC_TOGGLE_BIT 0x04 | ||
| 138 | #define DOC_ECC_RESV 0x02 | ||
| 139 | #define DOC_ECC_IGNORE 0x01 | ||
| 140 | |||
| 141 | #define DOC_FLASH_CE 0x80 | ||
| 142 | #define DOC_FLASH_WP 0x40 | ||
| 143 | #define DOC_FLASH_BANK 0x02 | ||
| 144 | |||
| 145 | /* We have to also set the reserved bit 1 for enable */ | ||
| 146 | #define DOC_ECC_EN (DOC_ECC__EN | DOC_ECC_RESV) | ||
| 147 | #define DOC_ECC_DIS (DOC_ECC_RESV) | ||
| 148 | |||
| 149 | struct Nand { | ||
| 150 | char floor, chip; | ||
| 151 | unsigned long curadr; | ||
| 152 | unsigned char curmode; | ||
| 153 | /* Also some erase/write/pipeline info when we get that far */ | ||
| 154 | }; | ||
| 155 | |||
| 156 | #define MAX_FLOORS 4 | ||
| 157 | #define MAX_CHIPS 4 | ||
| 158 | |||
| 159 | #define MAX_FLOORS_MIL 1 | ||
| 160 | #define MAX_CHIPS_MIL 1 | ||
| 161 | |||
| 162 | #define MAX_FLOORS_MPLUS 2 | ||
| 163 | #define MAX_CHIPS_MPLUS 1 | ||
| 164 | |||
| 165 | #define ADDR_COLUMN 1 | ||
| 166 | #define ADDR_PAGE 2 | ||
| 167 | #define ADDR_COLUMN_PAGE 3 | ||
| 168 | |||
| 169 | struct DiskOnChip { | ||
| 170 | unsigned long physadr; | ||
| 171 | void __iomem *virtadr; | ||
| 172 | unsigned long totlen; | ||
| 173 | unsigned char ChipID; /* Type of DiskOnChip */ | ||
| 174 | int ioreg; | ||
| 175 | |||
| 176 | unsigned long mfr; /* Flash IDs - only one type of flash per device */ | ||
| 177 | unsigned long id; | ||
| 178 | int chipshift; | ||
| 179 | char page256; | ||
| 180 | char pageadrlen; | ||
| 181 | char interleave; /* Internal interleaving - Millennium Plus style */ | ||
| 182 | unsigned long erasesize; | ||
| 183 | |||
| 184 | int curfloor; | ||
| 185 | int curchip; | ||
| 186 | |||
| 187 | int numchips; | ||
| 188 | struct Nand *chips; | ||
| 189 | struct mtd_info *nextdoc; | ||
| 190 | struct semaphore lock; | ||
| 191 | }; | ||
| 192 | |||
| 193 | int doc_decode_ecc(unsigned char sector[512], unsigned char ecc1[6]); | ||
| 194 | |||
| 195 | #endif /* __MTD_DOC2000_H__ */ | ||
diff --git a/include/linux/mtd/flashchip.h b/include/linux/mtd/flashchip.h new file mode 100644 index 000000000000..c66ba812bf90 --- /dev/null +++ b/include/linux/mtd/flashchip.h | |||
| @@ -0,0 +1,89 @@ | |||
| 1 | |||
| 2 | /* | ||
| 3 | * struct flchip definition | ||
| 4 | * | ||
| 5 | * Contains information about the location and state of a given flash device | ||
| 6 | * | ||
| 7 | * (C) 2000 Red Hat. GPLd. | ||
| 8 | * | ||
| 9 | * $Id: flashchip.h,v 1.15 2004/11/05 22:41:06 nico Exp $ | ||
| 10 | * | ||
| 11 | */ | ||
| 12 | |||
| 13 | #ifndef __MTD_FLASHCHIP_H__ | ||
| 14 | #define __MTD_FLASHCHIP_H__ | ||
| 15 | |||
| 16 | /* For spinlocks. sched.h includes spinlock.h from whichever directory it | ||
| 17 | * happens to be in - so we don't have to care whether we're on 2.2, which | ||
| 18 | * has asm/spinlock.h, or 2.4, which has linux/spinlock.h | ||
| 19 | */ | ||
| 20 | #include <linux/sched.h> | ||
| 21 | |||
| 22 | typedef enum { | ||
| 23 | FL_READY, | ||
| 24 | FL_STATUS, | ||
| 25 | FL_CFI_QUERY, | ||
| 26 | FL_JEDEC_QUERY, | ||
| 27 | FL_ERASING, | ||
| 28 | FL_ERASE_SUSPENDING, | ||
| 29 | FL_ERASE_SUSPENDED, | ||
| 30 | FL_WRITING, | ||
| 31 | FL_WRITING_TO_BUFFER, | ||
| 32 | FL_WRITE_SUSPENDING, | ||
| 33 | FL_WRITE_SUSPENDED, | ||
| 34 | FL_PM_SUSPENDED, | ||
| 35 | FL_SYNCING, | ||
| 36 | FL_UNLOADING, | ||
| 37 | FL_LOCKING, | ||
| 38 | FL_UNLOCKING, | ||
| 39 | FL_POINT, | ||
| 40 | FL_XIP_WHILE_ERASING, | ||
| 41 | FL_XIP_WHILE_WRITING, | ||
| 42 | FL_UNKNOWN | ||
| 43 | } flstate_t; | ||
| 44 | |||
| 45 | |||
| 46 | |||
| 47 | /* NOTE: confusingly, this can be used to refer to more than one chip at a time, | ||
| 48 | if they're interleaved. This can even refer to individual partitions on | ||
| 49 | the same physical chip when present. */ | ||
| 50 | |||
| 51 | struct flchip { | ||
| 52 | unsigned long start; /* Offset within the map */ | ||
| 53 | // unsigned long len; | ||
| 54 | /* We omit len for now, because when we group them together | ||
| 55 | we insist that they're all of the same size, and the chip size | ||
| 56 | is held in the next level up. If we get more versatile later, | ||
| 57 | it'll make it a damn sight harder to find which chip we want from | ||
| 58 | a given offset, and we'll want to add the per-chip length field | ||
| 59 | back in. | ||
| 60 | */ | ||
| 61 | int ref_point_counter; | ||
| 62 | flstate_t state; | ||
| 63 | flstate_t oldstate; | ||
| 64 | |||
| 65 | int write_suspended:1; | ||
| 66 | int erase_suspended:1; | ||
| 67 | unsigned long in_progress_block_addr; | ||
| 68 | |||
| 69 | spinlock_t *mutex; | ||
| 70 | spinlock_t _spinlock; /* We do it like this because sometimes they'll be shared. */ | ||
| 71 | wait_queue_head_t wq; /* Wait on here when we're waiting for the chip | ||
| 72 | to be ready */ | ||
| 73 | int word_write_time; | ||
| 74 | int buffer_write_time; | ||
| 75 | int erase_time; | ||
| 76 | |||
| 77 | void *priv; | ||
| 78 | }; | ||
| 79 | |||
| 80 | /* This is used to handle contention on write/erase operations | ||
| 81 | between partitions of the same physical chip. */ | ||
| 82 | struct flchip_shared { | ||
| 83 | spinlock_t lock; | ||
| 84 | struct flchip *writing; | ||
| 85 | struct flchip *erasing; | ||
| 86 | }; | ||
| 87 | |||
| 88 | |||
| 89 | #endif /* __MTD_FLASHCHIP_H__ */ | ||
diff --git a/include/linux/mtd/ftl.h b/include/linux/mtd/ftl.h new file mode 100644 index 000000000000..3678459b4535 --- /dev/null +++ b/include/linux/mtd/ftl.h | |||
| @@ -0,0 +1,76 @@ | |||
| 1 | /* | ||
| 2 | * $Id: ftl.h,v 1.6 2003/01/24 13:20:04 dwmw2 Exp $ | ||
| 3 | * | ||
| 4 | * Derived from (and probably identical to): | ||
| 5 | * ftl.h 1.7 1999/10/25 20:23:17 | ||
| 6 | * | ||
| 7 | * The contents of this file are subject to the Mozilla Public License | ||
| 8 | * Version 1.1 (the "License"); you may not use this file except in | ||
| 9 | * compliance with the License. You may obtain a copy of the License | ||
| 10 | * at http://www.mozilla.org/MPL/ | ||
| 11 | * | ||
| 12 | * Software distributed under the License is distributed on an "AS IS" | ||
| 13 | * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See | ||
| 14 | * the License for the specific language governing rights and | ||
| 15 | * limitations under the License. | ||
| 16 | * | ||
| 17 | * The initial developer of the original code is David A. Hinds | ||
| 18 | * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds | ||
| 19 | * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. | ||
| 20 | * | ||
| 21 | * Alternatively, the contents of this file may be used under the | ||
| 22 | * terms of the GNU General Public License version 2 (the "GPL"), in | ||
| 23 | * which case the provisions of the GPL are applicable instead of the | ||
| 24 | * above. If you wish to allow the use of your version of this file | ||
| 25 | * only under the terms of the GPL and not to allow others to use | ||
| 26 | * your version of this file under the MPL, indicate your decision by | ||
| 27 | * deleting the provisions above and replace them with the notice and | ||
| 28 | * other provisions required by the GPL. If you do not delete the | ||
| 29 | * provisions above, a recipient may use your version of this file | ||
| 30 | * under either the MPL or the GPL. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #ifndef _LINUX_FTL_H | ||
| 34 | #define _LINUX_FTL_H | ||
| 35 | |||
| 36 | typedef struct erase_unit_header_t { | ||
| 37 | u_int8_t LinkTargetTuple[5]; | ||
| 38 | u_int8_t DataOrgTuple[10]; | ||
| 39 | u_int8_t NumTransferUnits; | ||
| 40 | u_int32_t EraseCount; | ||
| 41 | u_int16_t LogicalEUN; | ||
| 42 | u_int8_t BlockSize; | ||
| 43 | u_int8_t EraseUnitSize; | ||
| 44 | u_int16_t FirstPhysicalEUN; | ||
| 45 | u_int16_t NumEraseUnits; | ||
| 46 | u_int32_t FormattedSize; | ||
| 47 | u_int32_t FirstVMAddress; | ||
| 48 | u_int16_t NumVMPages; | ||
| 49 | u_int8_t Flags; | ||
| 50 | u_int8_t Code; | ||
| 51 | u_int32_t SerialNumber; | ||
| 52 | u_int32_t AltEUHOffset; | ||
| 53 | u_int32_t BAMOffset; | ||
| 54 | u_int8_t Reserved[12]; | ||
| 55 | u_int8_t EndTuple[2]; | ||
| 56 | } erase_unit_header_t; | ||
| 57 | |||
| 58 | /* Flags in erase_unit_header_t */ | ||
| 59 | #define HIDDEN_AREA 0x01 | ||
| 60 | #define REVERSE_POLARITY 0x02 | ||
| 61 | #define DOUBLE_BAI 0x04 | ||
| 62 | |||
| 63 | /* Definitions for block allocation information */ | ||
| 64 | |||
| 65 | #define BLOCK_FREE(b) ((b) == 0xffffffff) | ||
| 66 | #define BLOCK_DELETED(b) (((b) == 0) || ((b) == 0xfffffffe)) | ||
| 67 | |||
| 68 | #define BLOCK_TYPE(b) ((b) & 0x7f) | ||
| 69 | #define BLOCK_ADDRESS(b) ((b) & ~0x7f) | ||
| 70 | #define BLOCK_NUMBER(b) ((b) >> 9) | ||
| 71 | #define BLOCK_CONTROL 0x30 | ||
| 72 | #define BLOCK_DATA 0x40 | ||
| 73 | #define BLOCK_REPLACEMENT 0x60 | ||
| 74 | #define BLOCK_BAD 0x70 | ||
| 75 | |||
| 76 | #endif /* _LINUX_FTL_H */ | ||
diff --git a/include/linux/mtd/gen_probe.h b/include/linux/mtd/gen_probe.h new file mode 100644 index 000000000000..3d7bdec14f97 --- /dev/null +++ b/include/linux/mtd/gen_probe.h | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | /* | ||
| 2 | * (C) 2001, 2001 Red Hat, Inc. | ||
| 3 | * GPL'd | ||
| 4 | * $Id: gen_probe.h,v 1.3 2004/10/20 22:10:33 dwmw2 Exp $ | ||
| 5 | */ | ||
| 6 | |||
| 7 | #ifndef __LINUX_MTD_GEN_PROBE_H__ | ||
| 8 | #define __LINUX_MTD_GEN_PROBE_H__ | ||
| 9 | |||
| 10 | #include <linux/mtd/flashchip.h> | ||
| 11 | #include <linux/mtd/map.h> | ||
| 12 | #include <linux/mtd/cfi.h> | ||
| 13 | #include <linux/bitops.h> | ||
| 14 | |||
| 15 | struct chip_probe { | ||
| 16 | char *name; | ||
| 17 | int (*probe_chip)(struct map_info *map, __u32 base, | ||
| 18 | unsigned long *chip_map, struct cfi_private *cfi); | ||
| 19 | }; | ||
| 20 | |||
| 21 | struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp); | ||
| 22 | |||
| 23 | #endif /* __LINUX_MTD_GEN_PROBE_H__ */ | ||
diff --git a/include/linux/mtd/iflash.h b/include/linux/mtd/iflash.h new file mode 100644 index 000000000000..9aa5b4f02666 --- /dev/null +++ b/include/linux/mtd/iflash.h | |||
| @@ -0,0 +1,98 @@ | |||
| 1 | /* $Id: iflash.h,v 1.2 2000/11/13 18:01:54 dwmw2 Exp $ */ | ||
| 2 | |||
| 3 | #ifndef __MTD_IFLASH_H__ | ||
| 4 | #define __MTD_IFLASH_H__ | ||
| 5 | |||
| 6 | /* Extended CIS registers for Series 2 and 2+ cards */ | ||
| 7 | /* The registers are all offsets from 0x4000 */ | ||
| 8 | #define CISREG_CSR 0x0100 | ||
| 9 | #define CISREG_WP 0x0104 | ||
| 10 | #define CISREG_RDYBSY 0x0140 | ||
| 11 | |||
| 12 | /* Extended CIS registers for Series 2 cards */ | ||
| 13 | #define CISREG_SLEEP 0x0118 | ||
| 14 | #define CISREG_RDY_MASK 0x0120 | ||
| 15 | #define CISREG_RDY_STATUS 0x0130 | ||
| 16 | |||
| 17 | /* Extended CIS registers for Series 2+ cards */ | ||
| 18 | #define CISREG_VCR 0x010c | ||
| 19 | |||
| 20 | /* Card Status Register */ | ||
| 21 | #define CSR_SRESET 0x20 /* Soft reset */ | ||
| 22 | #define CSR_CMWP 0x10 /* Common memory write protect */ | ||
| 23 | #define CSR_PWRDOWN 0x08 /* Power down status */ | ||
| 24 | #define CSR_CISWP 0x04 /* Common memory CIS WP */ | ||
| 25 | #define CSR_WP 0x02 /* Mechanical write protect */ | ||
| 26 | #define CSR_READY 0x01 /* Ready/busy status */ | ||
| 27 | |||
| 28 | /* Write Protection Register */ | ||
| 29 | #define WP_BLKEN 0x04 /* Enable block locking */ | ||
| 30 | #define WP_CMWP 0x02 /* Common memory write protect */ | ||
| 31 | #define WP_CISWP 0x01 /* Common memory CIS WP */ | ||
| 32 | |||
| 33 | /* Voltage Control Register */ | ||
| 34 | #define VCR_VCC_LEVEL 0x80 /* 0 = 5V, 1 = 3.3V */ | ||
| 35 | #define VCR_VPP_VALID 0x02 /* Vpp Valid */ | ||
| 36 | #define VCR_VPP_GEN 0x01 /* Integrated Vpp generator */ | ||
| 37 | |||
| 38 | /* Ready/Busy Mode Register */ | ||
| 39 | #define RDYBSY_RACK 0x02 /* Ready acknowledge */ | ||
| 40 | #define RDYBSY_MODE 0x01 /* 1 = high performance */ | ||
| 41 | |||
| 42 | #define LOW(x) ((x) & 0xff) | ||
| 43 | |||
| 44 | /* 28F008SA-Compatible Command Set */ | ||
| 45 | #define IF_READ_ARRAY 0xffff | ||
| 46 | #define IF_INTEL_ID 0x9090 | ||
| 47 | #define IF_READ_CSR 0x7070 | ||
| 48 | #define IF_CLEAR_CSR 0x5050 | ||
| 49 | #define IF_WRITE 0x4040 | ||
| 50 | #define IF_BLOCK_ERASE 0x2020 | ||
| 51 | #define IF_ERASE_SUSPEND 0xb0b0 | ||
| 52 | #define IF_CONFIRM 0xd0d0 | ||
| 53 | |||
| 54 | /* 28F016SA Performance Enhancement Commands */ | ||
| 55 | #define IF_READ_PAGE 0x7575 | ||
| 56 | #define IF_PAGE_SWAP 0x7272 | ||
| 57 | #define IF_SINGLE_LOAD 0x7474 | ||
| 58 | #define IF_SEQ_LOAD 0xe0e0 | ||
| 59 | #define IF_PAGE_WRITE 0x0c0c | ||
| 60 | #define IF_RDY_MODE 0x9696 | ||
| 61 | #define IF_RDY_LEVEL 0x0101 | ||
| 62 | #define IF_RDY_PULSE_WRITE 0x0202 | ||
| 63 | #define IF_RDY_PULSE_ERASE 0x0303 | ||
| 64 | #define IF_RDY_DISABLE 0x0404 | ||
| 65 | #define IF_LOCK_BLOCK 0x7777 | ||
| 66 | #define IF_UPLOAD_STATUS 0x9797 | ||
| 67 | #define IF_READ_ESR 0x7171 | ||
| 68 | #define IF_ERASE_UNLOCKED 0xa7a7 | ||
| 69 | #define IF_SLEEP 0xf0f0 | ||
| 70 | #define IF_ABORT 0x8080 | ||
| 71 | #define IF_UPLOAD_DEVINFO 0x9999 | ||
| 72 | |||
| 73 | /* Definitions for Compatible Status Register */ | ||
| 74 | #define CSR_WR_READY 0x8080 /* Write state machine status */ | ||
| 75 | #define CSR_ERA_SUSPEND 0x4040 /* Erase suspend status */ | ||
| 76 | #define CSR_ERA_ERR 0x2020 /* Erase status */ | ||
| 77 | #define CSR_WR_ERR 0x1010 /* Data write status */ | ||
| 78 | #define CSR_VPP_LOW 0x0808 /* Vpp status */ | ||
| 79 | |||
| 80 | /* Definitions for Global Status Register */ | ||
| 81 | #define GSR_WR_READY 0x8080 /* Write state machine status */ | ||
| 82 | #define GSR_OP_SUSPEND 0x4040 /* Operation suspend status */ | ||
| 83 | #define GSR_OP_ERR 0x2020 /* Device operation status */ | ||
| 84 | #define GSR_SLEEP 0x1010 /* Device sleep status */ | ||
| 85 | #define GSR_QUEUE_FULL 0x0808 /* Queue status */ | ||
| 86 | #define GSR_PAGE_AVAIL 0x0404 /* Page buffer available status */ | ||
| 87 | #define GSR_PAGE_READY 0x0202 /* Page buffer status */ | ||
| 88 | #define GSR_PAGE_SELECT 0x0101 /* Page buffer select status */ | ||
| 89 | |||
| 90 | /* Definitions for Block Status Register */ | ||
| 91 | #define BSR_READY 0x8080 /* Block status */ | ||
| 92 | #define BSR_UNLOCK 0x4040 /* Block lock status */ | ||
| 93 | #define BSR_FAILED 0x2020 /* Block operation status */ | ||
| 94 | #define BSR_ABORTED 0x1010 /* Operation abort status */ | ||
| 95 | #define BSR_QUEUE_FULL 0x0808 /* Queue status */ | ||
| 96 | #define BSR_VPP_LOW 0x0404 /* Vpp status */ | ||
| 97 | |||
| 98 | #endif /* __MTD_IFLASH_H__ */ | ||
diff --git a/include/linux/mtd/inftl.h b/include/linux/mtd/inftl.h new file mode 100644 index 000000000000..b52c8cbd235c --- /dev/null +++ b/include/linux/mtd/inftl.h | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | /* | ||
| 2 | * inftl.h -- defines to support the Inverse NAND Flash Translation Layer | ||
| 3 | * | ||
| 4 | * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) | ||
| 5 | * | ||
| 6 | * $Id: inftl.h,v 1.6 2004/06/30 14:49:00 dbrown Exp $ | ||
| 7 | */ | ||
| 8 | |||
| 9 | #ifndef __MTD_INFTL_H__ | ||
| 10 | #define __MTD_INFTL_H__ | ||
| 11 | |||
| 12 | #ifndef __KERNEL__ | ||
| 13 | #error This is a kernel header. Perhaps include nftl-user.h instead? | ||
| 14 | #endif | ||
| 15 | |||
| 16 | #include <linux/mtd/blktrans.h> | ||
| 17 | #include <linux/mtd/mtd.h> | ||
| 18 | #include <linux/mtd/nftl.h> | ||
| 19 | |||
| 20 | #include <mtd/inftl-user.h> | ||
| 21 | |||
| 22 | #ifndef INFTL_MAJOR | ||
| 23 | #define INFTL_MAJOR 94 | ||
| 24 | #endif | ||
| 25 | #define INFTL_PARTN_BITS 4 | ||
| 26 | |||
| 27 | #ifdef __KERNEL__ | ||
| 28 | |||
| 29 | struct INFTLrecord { | ||
| 30 | struct mtd_blktrans_dev mbd; | ||
| 31 | __u16 MediaUnit; | ||
| 32 | __u32 EraseSize; | ||
| 33 | struct INFTLMediaHeader MediaHdr; | ||
| 34 | int usecount; | ||
| 35 | unsigned char heads; | ||
| 36 | unsigned char sectors; | ||
| 37 | unsigned short cylinders; | ||
| 38 | __u16 numvunits; | ||
| 39 | __u16 firstEUN; | ||
| 40 | __u16 lastEUN; | ||
| 41 | __u16 numfreeEUNs; | ||
| 42 | __u16 LastFreeEUN; /* To speed up finding a free EUN */ | ||
| 43 | int head,sect,cyl; | ||
| 44 | __u16 *PUtable; /* Physical Unit Table */ | ||
| 45 | __u16 *VUtable; /* Virtual Unit Table */ | ||
| 46 | unsigned int nb_blocks; /* number of physical blocks */ | ||
| 47 | unsigned int nb_boot_blocks; /* number of blocks used by the bios */ | ||
| 48 | struct erase_info instr; | ||
| 49 | struct nand_oobinfo oobinfo; | ||
| 50 | }; | ||
| 51 | |||
| 52 | int INFTL_mount(struct INFTLrecord *s); | ||
| 53 | int INFTL_formatblock(struct INFTLrecord *s, int block); | ||
| 54 | |||
| 55 | #endif /* __KERNEL__ */ | ||
| 56 | |||
| 57 | #endif /* __MTD_INFTL_H__ */ | ||
diff --git a/include/linux/mtd/jedec.h b/include/linux/mtd/jedec.h new file mode 100644 index 000000000000..2ba0f700ddbc --- /dev/null +++ b/include/linux/mtd/jedec.h | |||
| @@ -0,0 +1,66 @@ | |||
| 1 | |||
| 2 | /* JEDEC Flash Interface. | ||
| 3 | * This is an older type of interface for self programming flash. It is | ||
| 4 | * commonly use in older AMD chips and is obsolete compared with CFI. | ||
| 5 | * It is called JEDEC because the JEDEC association distributes the ID codes | ||
| 6 | * for the chips. | ||
| 7 | * | ||
| 8 | * See the AMD flash databook for information on how to operate the interface. | ||
| 9 | * | ||
| 10 | * $Id: jedec.h,v 1.3 2003/05/21 11:51:01 dwmw2 Exp $ | ||
| 11 | */ | ||
| 12 | |||
| 13 | #ifndef __LINUX_MTD_JEDEC_H__ | ||
| 14 | #define __LINUX_MTD_JEDEC_H__ | ||
| 15 | |||
| 16 | #include <linux/types.h> | ||
| 17 | |||
| 18 | #define MAX_JEDEC_CHIPS 16 | ||
| 19 | |||
| 20 | // Listing of all supported chips and their information | ||
| 21 | struct JEDECTable | ||
| 22 | { | ||
| 23 | __u16 jedec; | ||
| 24 | char *name; | ||
| 25 | unsigned long size; | ||
| 26 | unsigned long sectorsize; | ||
| 27 | __u32 capabilities; | ||
| 28 | }; | ||
| 29 | |||
| 30 | // JEDEC being 0 is the end of the chip array | ||
| 31 | struct jedec_flash_chip | ||
| 32 | { | ||
| 33 | __u16 jedec; | ||
| 34 | unsigned long size; | ||
| 35 | unsigned long sectorsize; | ||
| 36 | |||
| 37 | // *(__u8*)(base + (adder << addrshift)) = data << datashift | ||
| 38 | // Address size = size << addrshift | ||
| 39 | unsigned long base; // Byte 0 of the flash, will be unaligned | ||
| 40 | unsigned int datashift; // Useful for 32bit/16bit accesses | ||
| 41 | unsigned int addrshift; | ||
| 42 | unsigned long offset; // linerized start. base==offset for unbanked, uninterleaved flash | ||
| 43 | |||
| 44 | __u32 capabilities; | ||
| 45 | |||
| 46 | // These markers are filled in by the flash_chip_scan function | ||
| 47 | unsigned long start; | ||
| 48 | unsigned long length; | ||
| 49 | }; | ||
| 50 | |||
| 51 | struct jedec_private | ||
| 52 | { | ||
| 53 | unsigned long size; // Total size of all the devices | ||
| 54 | |||
| 55 | /* Bank handling. If sum(bank_fill) == size then this is linear flash. | ||
| 56 | Otherwise the mapping has holes in it. bank_fill may be used to | ||
| 57 | find the holes, but in the common symetric case | ||
| 58 | bank_fill[0] == bank_fill[*], thus addresses may be computed | ||
| 59 | mathmatically. bank_fill must be powers of two */ | ||
| 60 | unsigned is_banked; | ||
| 61 | unsigned long bank_fill[MAX_JEDEC_CHIPS]; | ||
| 62 | |||
| 63 | struct jedec_flash_chip chips[MAX_JEDEC_CHIPS]; | ||
| 64 | }; | ||
| 65 | |||
| 66 | #endif | ||
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h new file mode 100644 index 000000000000..f0268b99c900 --- /dev/null +++ b/include/linux/mtd/map.h | |||
| @@ -0,0 +1,412 @@ | |||
| 1 | |||
| 2 | /* Overhauled routines for dealing with different mmap regions of flash */ | ||
| 3 | /* $Id: map.h,v 1.46 2005/01/05 17:09:44 dwmw2 Exp $ */ | ||
| 4 | |||
| 5 | #ifndef __LINUX_MTD_MAP_H__ | ||
| 6 | #define __LINUX_MTD_MAP_H__ | ||
| 7 | |||
| 8 | #include <linux/config.h> | ||
| 9 | #include <linux/types.h> | ||
| 10 | #include <linux/list.h> | ||
| 11 | #include <linux/mtd/compatmac.h> | ||
| 12 | #include <asm/unaligned.h> | ||
| 13 | #include <asm/system.h> | ||
| 14 | #include <asm/io.h> | ||
| 15 | #include <asm/bug.h> | ||
| 16 | |||
| 17 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_1 | ||
| 18 | #define map_bankwidth(map) 1 | ||
| 19 | #define map_bankwidth_is_1(map) (map_bankwidth(map) == 1) | ||
| 20 | #define map_bankwidth_is_large(map) (0) | ||
| 21 | #define map_words(map) (1) | ||
| 22 | #define MAX_MAP_BANKWIDTH 1 | ||
| 23 | #else | ||
| 24 | #define map_bankwidth_is_1(map) (0) | ||
| 25 | #endif | ||
| 26 | |||
| 27 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_2 | ||
| 28 | # ifdef map_bankwidth | ||
| 29 | # undef map_bankwidth | ||
| 30 | # define map_bankwidth(map) ((map)->bankwidth) | ||
| 31 | # else | ||
| 32 | # define map_bankwidth(map) 2 | ||
| 33 | # define map_bankwidth_is_large(map) (0) | ||
| 34 | # define map_words(map) (1) | ||
| 35 | # endif | ||
| 36 | #define map_bankwidth_is_2(map) (map_bankwidth(map) == 2) | ||
| 37 | #undef MAX_MAP_BANKWIDTH | ||
| 38 | #define MAX_MAP_BANKWIDTH 2 | ||
| 39 | #else | ||
| 40 | #define map_bankwidth_is_2(map) (0) | ||
| 41 | #endif | ||
| 42 | |||
| 43 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_4 | ||
| 44 | # ifdef map_bankwidth | ||
| 45 | # undef map_bankwidth | ||
| 46 | # define map_bankwidth(map) ((map)->bankwidth) | ||
| 47 | # else | ||
| 48 | # define map_bankwidth(map) 4 | ||
| 49 | # define map_bankwidth_is_large(map) (0) | ||
| 50 | # define map_words(map) (1) | ||
| 51 | # endif | ||
| 52 | #define map_bankwidth_is_4(map) (map_bankwidth(map) == 4) | ||
| 53 | #undef MAX_MAP_BANKWIDTH | ||
| 54 | #define MAX_MAP_BANKWIDTH 4 | ||
| 55 | #else | ||
| 56 | #define map_bankwidth_is_4(map) (0) | ||
| 57 | #endif | ||
| 58 | |||
| 59 | /* ensure we never evaluate anything shorted than an unsigned long | ||
| 60 | * to zero, and ensure we'll never miss the end of an comparison (bjd) */ | ||
| 61 | |||
| 62 | #define map_calc_words(map) ((map_bankwidth(map) + (sizeof(unsigned long)-1))/ sizeof(unsigned long)) | ||
| 63 | |||
| 64 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_8 | ||
| 65 | # ifdef map_bankwidth | ||
| 66 | # undef map_bankwidth | ||
| 67 | # define map_bankwidth(map) ((map)->bankwidth) | ||
| 68 | # if BITS_PER_LONG < 64 | ||
| 69 | # undef map_bankwidth_is_large | ||
| 70 | # define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8) | ||
| 71 | # undef map_words | ||
| 72 | # define map_words(map) map_calc_words(map) | ||
| 73 | # endif | ||
| 74 | # else | ||
| 75 | # define map_bankwidth(map) 8 | ||
| 76 | # define map_bankwidth_is_large(map) (BITS_PER_LONG < 64) | ||
| 77 | # define map_words(map) map_calc_words(map) | ||
| 78 | # endif | ||
| 79 | #define map_bankwidth_is_8(map) (map_bankwidth(map) == 8) | ||
| 80 | #undef MAX_MAP_BANKWIDTH | ||
| 81 | #define MAX_MAP_BANKWIDTH 8 | ||
| 82 | #else | ||
| 83 | #define map_bankwidth_is_8(map) (0) | ||
| 84 | #endif | ||
| 85 | |||
| 86 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_16 | ||
| 87 | # ifdef map_bankwidth | ||
| 88 | # undef map_bankwidth | ||
| 89 | # define map_bankwidth(map) ((map)->bankwidth) | ||
| 90 | # undef map_bankwidth_is_large | ||
| 91 | # define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8) | ||
| 92 | # undef map_words | ||
| 93 | # define map_words(map) map_calc_words(map) | ||
| 94 | # else | ||
| 95 | # define map_bankwidth(map) 16 | ||
| 96 | # define map_bankwidth_is_large(map) (1) | ||
| 97 | # define map_words(map) map_calc_words(map) | ||
| 98 | # endif | ||
| 99 | #define map_bankwidth_is_16(map) (map_bankwidth(map) == 16) | ||
| 100 | #undef MAX_MAP_BANKWIDTH | ||
| 101 | #define MAX_MAP_BANKWIDTH 16 | ||
| 102 | #else | ||
| 103 | #define map_bankwidth_is_16(map) (0) | ||
| 104 | #endif | ||
| 105 | |||
| 106 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_32 | ||
| 107 | # ifdef map_bankwidth | ||
| 108 | # undef map_bankwidth | ||
| 109 | # define map_bankwidth(map) ((map)->bankwidth) | ||
| 110 | # undef map_bankwidth_is_large | ||
| 111 | # define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8) | ||
| 112 | # undef map_words | ||
| 113 | # define map_words(map) map_calc_words(map) | ||
| 114 | # else | ||
| 115 | # define map_bankwidth(map) 32 | ||
| 116 | # define map_bankwidth_is_large(map) (1) | ||
| 117 | # define map_words(map) map_calc_words(map) | ||
| 118 | # endif | ||
| 119 | #define map_bankwidth_is_32(map) (map_bankwidth(map) == 32) | ||
| 120 | #undef MAX_MAP_BANKWIDTH | ||
| 121 | #define MAX_MAP_BANKWIDTH 32 | ||
| 122 | #else | ||
| 123 | #define map_bankwidth_is_32(map) (0) | ||
| 124 | #endif | ||
| 125 | |||
| 126 | #ifndef map_bankwidth | ||
| 127 | #error "No bus width supported. What's the point?" | ||
| 128 | #endif | ||
| 129 | |||
| 130 | static inline int map_bankwidth_supported(int w) | ||
| 131 | { | ||
| 132 | switch (w) { | ||
| 133 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_1 | ||
| 134 | case 1: | ||
| 135 | #endif | ||
| 136 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_2 | ||
| 137 | case 2: | ||
| 138 | #endif | ||
| 139 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_4 | ||
| 140 | case 4: | ||
| 141 | #endif | ||
| 142 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_8 | ||
| 143 | case 8: | ||
| 144 | #endif | ||
| 145 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_16 | ||
| 146 | case 16: | ||
| 147 | #endif | ||
| 148 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_32 | ||
| 149 | case 32: | ||
| 150 | #endif | ||
| 151 | return 1; | ||
| 152 | |||
| 153 | default: | ||
| 154 | return 0; | ||
| 155 | } | ||
| 156 | } | ||
| 157 | |||
| 158 | #define MAX_MAP_LONGS ( ((MAX_MAP_BANKWIDTH*8) + BITS_PER_LONG - 1) / BITS_PER_LONG ) | ||
| 159 | |||
| 160 | typedef union { | ||
| 161 | unsigned long x[MAX_MAP_LONGS]; | ||
| 162 | } map_word; | ||
| 163 | |||
| 164 | /* The map stuff is very simple. You fill in your struct map_info with | ||
| 165 | a handful of routines for accessing the device, making sure they handle | ||
| 166 | paging etc. correctly if your device needs it. Then you pass it off | ||
| 167 | to a chip probe routine -- either JEDEC or CFI probe or both -- via | ||
| 168 | do_map_probe(). If a chip is recognised, the probe code will invoke the | ||
| 169 | appropriate chip driver (if present) and return a struct mtd_info. | ||
| 170 | At which point, you fill in the mtd->module with your own module | ||
| 171 | address, and register it with the MTD core code. Or you could partition | ||
| 172 | it and register the partitions instead, or keep it for your own private | ||
| 173 | use; whatever. | ||
| 174 | |||
| 175 | The mtd->priv field will point to the struct map_info, and any further | ||
| 176 | private data required by the chip driver is linked from the | ||
| 177 | mtd->priv->fldrv_priv field. This allows the map driver to get at | ||
| 178 | the destructor function map->fldrv_destroy() when it's tired | ||
| 179 | of living. | ||
| 180 | */ | ||
| 181 | |||
| 182 | struct map_info { | ||
| 183 | char *name; | ||
| 184 | unsigned long size; | ||
| 185 | unsigned long phys; | ||
| 186 | #define NO_XIP (-1UL) | ||
| 187 | |||
| 188 | void __iomem *virt; | ||
| 189 | void *cached; | ||
| 190 | |||
| 191 | int bankwidth; /* in octets. This isn't necessarily the width | ||
| 192 | of actual bus cycles -- it's the repeat interval | ||
| 193 | in bytes, before you are talking to the first chip again. | ||
| 194 | */ | ||
| 195 | |||
| 196 | #ifdef CONFIG_MTD_COMPLEX_MAPPINGS | ||
| 197 | map_word (*read)(struct map_info *, unsigned long); | ||
| 198 | void (*copy_from)(struct map_info *, void *, unsigned long, ssize_t); | ||
| 199 | |||
| 200 | void (*write)(struct map_info *, const map_word, unsigned long); | ||
| 201 | void (*copy_to)(struct map_info *, unsigned long, const void *, ssize_t); | ||
| 202 | |||
| 203 | /* We can perhaps put in 'point' and 'unpoint' methods, if we really | ||
| 204 | want to enable XIP for non-linear mappings. Not yet though. */ | ||
| 205 | #endif | ||
| 206 | /* It's possible for the map driver to use cached memory in its | ||
| 207 | copy_from implementation (and _only_ with copy_from). However, | ||
| 208 | when the chip driver knows some flash area has changed contents, | ||
| 209 | it will signal it to the map driver through this routine to let | ||
| 210 | the map driver invalidate the corresponding cache as needed. | ||
| 211 | If there is no cache to care about this can be set to NULL. */ | ||
| 212 | void (*inval_cache)(struct map_info *, unsigned long, ssize_t); | ||
| 213 | |||
| 214 | /* set_vpp() must handle being reentered -- enable, enable, disable | ||
| 215 | must leave it enabled. */ | ||
| 216 | void (*set_vpp)(struct map_info *, int); | ||
| 217 | |||
| 218 | unsigned long map_priv_1; | ||
| 219 | unsigned long map_priv_2; | ||
| 220 | void *fldrv_priv; | ||
| 221 | struct mtd_chip_driver *fldrv; | ||
| 222 | }; | ||
| 223 | |||
| 224 | struct mtd_chip_driver { | ||
| 225 | struct mtd_info *(*probe)(struct map_info *map); | ||
| 226 | void (*destroy)(struct mtd_info *); | ||
| 227 | struct module *module; | ||
| 228 | char *name; | ||
| 229 | struct list_head list; | ||
| 230 | }; | ||
| 231 | |||
| 232 | void register_mtd_chip_driver(struct mtd_chip_driver *); | ||
| 233 | void unregister_mtd_chip_driver(struct mtd_chip_driver *); | ||
| 234 | |||
| 235 | struct mtd_info *do_map_probe(const char *name, struct map_info *map); | ||
| 236 | void map_destroy(struct mtd_info *mtd); | ||
| 237 | |||
| 238 | #define ENABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 1); } while(0) | ||
| 239 | #define DISABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 0); } while(0) | ||
| 240 | |||
| 241 | #define INVALIDATE_CACHED_RANGE(map, from, size) \ | ||
| 242 | do { if(map->inval_cache) map->inval_cache(map, from, size); } while(0) | ||
| 243 | |||
| 244 | |||
| 245 | static inline int map_word_equal(struct map_info *map, map_word val1, map_word val2) | ||
| 246 | { | ||
| 247 | int i; | ||
| 248 | for (i=0; i<map_words(map); i++) { | ||
| 249 | if (val1.x[i] != val2.x[i]) | ||
| 250 | return 0; | ||
| 251 | } | ||
| 252 | return 1; | ||
| 253 | } | ||
| 254 | |||
| 255 | static inline map_word map_word_and(struct map_info *map, map_word val1, map_word val2) | ||
| 256 | { | ||
| 257 | map_word r; | ||
| 258 | int i; | ||
| 259 | |||
| 260 | for (i=0; i<map_words(map); i++) { | ||
| 261 | r.x[i] = val1.x[i] & val2.x[i]; | ||
| 262 | } | ||
| 263 | return r; | ||
| 264 | } | ||
| 265 | |||
| 266 | static inline map_word map_word_or(struct map_info *map, map_word val1, map_word val2) | ||
| 267 | { | ||
| 268 | map_word r; | ||
| 269 | int i; | ||
| 270 | |||
| 271 | for (i=0; i<map_words(map); i++) { | ||
| 272 | r.x[i] = val1.x[i] | val2.x[i]; | ||
| 273 | } | ||
| 274 | return r; | ||
| 275 | } | ||
| 276 | #define map_word_andequal(m, a, b, z) map_word_equal(m, z, map_word_and(m, a, b)) | ||
| 277 | |||
| 278 | static inline int map_word_bitsset(struct map_info *map, map_word val1, map_word val2) | ||
| 279 | { | ||
| 280 | int i; | ||
| 281 | |||
| 282 | for (i=0; i<map_words(map); i++) { | ||
| 283 | if (val1.x[i] & val2.x[i]) | ||
| 284 | return 1; | ||
| 285 | } | ||
| 286 | return 0; | ||
| 287 | } | ||
| 288 | |||
| 289 | static inline map_word map_word_load(struct map_info *map, const void *ptr) | ||
| 290 | { | ||
| 291 | map_word r; | ||
| 292 | |||
| 293 | if (map_bankwidth_is_1(map)) | ||
| 294 | r.x[0] = *(unsigned char *)ptr; | ||
| 295 | else if (map_bankwidth_is_2(map)) | ||
| 296 | r.x[0] = get_unaligned((uint16_t *)ptr); | ||
| 297 | else if (map_bankwidth_is_4(map)) | ||
| 298 | r.x[0] = get_unaligned((uint32_t *)ptr); | ||
| 299 | #if BITS_PER_LONG >= 64 | ||
| 300 | else if (map_bankwidth_is_8(map)) | ||
| 301 | r.x[0] = get_unaligned((uint64_t *)ptr); | ||
| 302 | #endif | ||
| 303 | else if (map_bankwidth_is_large(map)) | ||
| 304 | memcpy(r.x, ptr, map->bankwidth); | ||
| 305 | |||
| 306 | return r; | ||
| 307 | } | ||
| 308 | |||
| 309 | static inline map_word map_word_load_partial(struct map_info *map, map_word orig, const unsigned char *buf, int start, int len) | ||
| 310 | { | ||
| 311 | int i; | ||
| 312 | |||
| 313 | if (map_bankwidth_is_large(map)) { | ||
| 314 | char *dest = (char *)&orig; | ||
| 315 | memcpy(dest+start, buf, len); | ||
| 316 | } else { | ||
| 317 | for (i=start; i < start+len; i++) { | ||
| 318 | int bitpos; | ||
| 319 | #ifdef __LITTLE_ENDIAN | ||
| 320 | bitpos = i*8; | ||
| 321 | #else /* __BIG_ENDIAN */ | ||
| 322 | bitpos = (map_bankwidth(map)-1-i)*8; | ||
| 323 | #endif | ||
| 324 | orig.x[0] &= ~(0xff << bitpos); | ||
| 325 | orig.x[0] |= buf[i-start] << bitpos; | ||
| 326 | } | ||
| 327 | } | ||
| 328 | return orig; | ||
| 329 | } | ||
| 330 | |||
| 331 | static inline map_word map_word_ff(struct map_info *map) | ||
| 332 | { | ||
| 333 | map_word r; | ||
| 334 | int i; | ||
| 335 | |||
| 336 | for (i=0; i<map_words(map); i++) { | ||
| 337 | r.x[i] = ~0UL; | ||
| 338 | } | ||
| 339 | return r; | ||
| 340 | } | ||
| 341 | static inline map_word inline_map_read(struct map_info *map, unsigned long ofs) | ||
| 342 | { | ||
| 343 | map_word r; | ||
| 344 | |||
| 345 | if (map_bankwidth_is_1(map)) | ||
| 346 | r.x[0] = __raw_readb(map->virt + ofs); | ||
| 347 | else if (map_bankwidth_is_2(map)) | ||
| 348 | r.x[0] = __raw_readw(map->virt + ofs); | ||
| 349 | else if (map_bankwidth_is_4(map)) | ||
| 350 | r.x[0] = __raw_readl(map->virt + ofs); | ||
| 351 | #if BITS_PER_LONG >= 64 | ||
| 352 | else if (map_bankwidth_is_8(map)) | ||
| 353 | r.x[0] = __raw_readq(map->virt + ofs); | ||
| 354 | #endif | ||
| 355 | else if (map_bankwidth_is_large(map)) | ||
| 356 | memcpy_fromio(r.x, map->virt+ofs, map->bankwidth); | ||
| 357 | |||
| 358 | return r; | ||
| 359 | } | ||
| 360 | |||
| 361 | static inline void inline_map_write(struct map_info *map, const map_word datum, unsigned long ofs) | ||
| 362 | { | ||
| 363 | if (map_bankwidth_is_1(map)) | ||
| 364 | __raw_writeb(datum.x[0], map->virt + ofs); | ||
| 365 | else if (map_bankwidth_is_2(map)) | ||
| 366 | __raw_writew(datum.x[0], map->virt + ofs); | ||
| 367 | else if (map_bankwidth_is_4(map)) | ||
| 368 | __raw_writel(datum.x[0], map->virt + ofs); | ||
| 369 | #if BITS_PER_LONG >= 64 | ||
| 370 | else if (map_bankwidth_is_8(map)) | ||
| 371 | __raw_writeq(datum.x[0], map->virt + ofs); | ||
| 372 | #endif | ||
| 373 | else if (map_bankwidth_is_large(map)) | ||
| 374 | memcpy_toio(map->virt+ofs, datum.x, map->bankwidth); | ||
| 375 | mb(); | ||
| 376 | } | ||
| 377 | |||
| 378 | static inline void inline_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) | ||
| 379 | { | ||
| 380 | if (map->cached) | ||
| 381 | memcpy(to, (char *)map->cached + from, len); | ||
| 382 | else | ||
| 383 | memcpy_fromio(to, map->virt + from, len); | ||
| 384 | } | ||
| 385 | |||
| 386 | static inline void inline_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) | ||
| 387 | { | ||
| 388 | memcpy_toio(map->virt + to, from, len); | ||
| 389 | } | ||
| 390 | |||
| 391 | #ifdef CONFIG_MTD_COMPLEX_MAPPINGS | ||
| 392 | #define map_read(map, ofs) (map)->read(map, ofs) | ||
| 393 | #define map_copy_from(map, to, from, len) (map)->copy_from(map, to, from, len) | ||
| 394 | #define map_write(map, datum, ofs) (map)->write(map, datum, ofs) | ||
| 395 | #define map_copy_to(map, to, from, len) (map)->copy_to(map, to, from, len) | ||
| 396 | |||
| 397 | extern void simple_map_init(struct map_info *); | ||
| 398 | #define map_is_linear(map) (map->phys != NO_XIP) | ||
| 399 | |||
| 400 | #else | ||
| 401 | #define map_read(map, ofs) inline_map_read(map, ofs) | ||
| 402 | #define map_copy_from(map, to, from, len) inline_map_copy_from(map, to, from, len) | ||
| 403 | #define map_write(map, datum, ofs) inline_map_write(map, datum, ofs) | ||
| 404 | #define map_copy_to(map, to, from, len) inline_map_copy_to(map, to, from, len) | ||
| 405 | |||
| 406 | |||
| 407 | #define simple_map_init(map) BUG_ON(!map_bankwidth_supported((map)->bankwidth)) | ||
| 408 | #define map_is_linear(map) (1) | ||
| 409 | |||
| 410 | #endif /* !CONFIG_MTD_COMPLEX_MAPPINGS */ | ||
| 411 | |||
| 412 | #endif /* __LINUX_MTD_MAP_H__ */ | ||
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h new file mode 100644 index 000000000000..b3d134392b31 --- /dev/null +++ b/include/linux/mtd/mtd.h | |||
| @@ -0,0 +1,226 @@ | |||
| 1 | /* | ||
| 2 | * $Id: mtd.h,v 1.56 2004/08/09 18:46:04 dmarlin Exp $ | ||
| 3 | * | ||
| 4 | * Copyright (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> et al. | ||
| 5 | * | ||
| 6 | * Released under GPL | ||
| 7 | */ | ||
| 8 | |||
| 9 | #ifndef __MTD_MTD_H__ | ||
| 10 | #define __MTD_MTD_H__ | ||
| 11 | |||
| 12 | #ifndef __KERNEL__ | ||
| 13 | #error This is a kernel header. Perhaps include mtd-user.h instead? | ||
| 14 | #endif | ||
| 15 | |||
| 16 | #include <linux/config.h> | ||
| 17 | #include <linux/version.h> | ||
| 18 | #include <linux/types.h> | ||
| 19 | #include <linux/module.h> | ||
| 20 | #include <linux/uio.h> | ||
| 21 | |||
| 22 | #include <linux/mtd/compatmac.h> | ||
| 23 | #include <mtd/mtd-abi.h> | ||
| 24 | |||
| 25 | #define MTD_CHAR_MAJOR 90 | ||
| 26 | #define MTD_BLOCK_MAJOR 31 | ||
| 27 | #define MAX_MTD_DEVICES 16 | ||
| 28 | |||
| 29 | #define MTD_ERASE_PENDING 0x01 | ||
| 30 | #define MTD_ERASING 0x02 | ||
| 31 | #define MTD_ERASE_SUSPEND 0x04 | ||
| 32 | #define MTD_ERASE_DONE 0x08 | ||
| 33 | #define MTD_ERASE_FAILED 0x10 | ||
| 34 | |||
| 35 | /* If the erase fails, fail_addr might indicate exactly which block failed. If | ||
| 36 | fail_addr = 0xffffffff, the failure was not at the device level or was not | ||
| 37 | specific to any particular block. */ | ||
| 38 | struct erase_info { | ||
| 39 | struct mtd_info *mtd; | ||
| 40 | u_int32_t addr; | ||
| 41 | u_int32_t len; | ||
| 42 | u_int32_t fail_addr; | ||
| 43 | u_long time; | ||
| 44 | u_long retries; | ||
| 45 | u_int dev; | ||
| 46 | u_int cell; | ||
| 47 | void (*callback) (struct erase_info *self); | ||
| 48 | u_long priv; | ||
| 49 | u_char state; | ||
| 50 | struct erase_info *next; | ||
| 51 | }; | ||
| 52 | |||
| 53 | struct mtd_erase_region_info { | ||
| 54 | u_int32_t offset; /* At which this region starts, from the beginning of the MTD */ | ||
| 55 | u_int32_t erasesize; /* For this region */ | ||
| 56 | u_int32_t numblocks; /* Number of blocks of erasesize in this region */ | ||
| 57 | }; | ||
| 58 | |||
| 59 | struct mtd_info { | ||
| 60 | u_char type; | ||
| 61 | u_int32_t flags; | ||
| 62 | u_int32_t size; // Total size of the MTD | ||
| 63 | |||
| 64 | /* "Major" erase size for the device. Naïve users may take this | ||
| 65 | * to be the only erase size available, or may use the more detailed | ||
| 66 | * information below if they desire | ||
| 67 | */ | ||
| 68 | u_int32_t erasesize; | ||
| 69 | |||
| 70 | u_int32_t oobblock; // Size of OOB blocks (e.g. 512) | ||
| 71 | u_int32_t oobsize; // Amount of OOB data per block (e.g. 16) | ||
| 72 | u_int32_t oobavail; // Number of bytes in OOB area available for fs | ||
| 73 | u_int32_t ecctype; | ||
| 74 | u_int32_t eccsize; | ||
| 75 | |||
| 76 | |||
| 77 | // Kernel-only stuff starts here. | ||
| 78 | char *name; | ||
| 79 | int index; | ||
| 80 | |||
| 81 | // oobinfo is a nand_oobinfo structure, which can be set by iotcl (MEMSETOOBINFO) | ||
| 82 | struct nand_oobinfo oobinfo; | ||
| 83 | |||
| 84 | /* Data for variable erase regions. If numeraseregions is zero, | ||
| 85 | * it means that the whole device has erasesize as given above. | ||
| 86 | */ | ||
| 87 | int numeraseregions; | ||
| 88 | struct mtd_erase_region_info *eraseregions; | ||
| 89 | |||
| 90 | /* This really shouldn't be here. It can go away in 2.5 */ | ||
| 91 | u_int32_t bank_size; | ||
| 92 | |||
| 93 | int (*erase) (struct mtd_info *mtd, struct erase_info *instr); | ||
| 94 | |||
| 95 | /* This stuff for eXecute-In-Place */ | ||
| 96 | int (*point) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf); | ||
| 97 | |||
| 98 | /* We probably shouldn't allow XIP if the unpoint isn't a NULL */ | ||
| 99 | void (*unpoint) (struct mtd_info *mtd, u_char * addr, loff_t from, size_t len); | ||
| 100 | |||
| 101 | |||
| 102 | int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); | ||
| 103 | int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); | ||
| 104 | |||
| 105 | int (*read_ecc) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); | ||
| 106 | int (*write_ecc) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); | ||
| 107 | |||
| 108 | int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); | ||
| 109 | int (*write_oob) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); | ||
| 110 | |||
| 111 | /* | ||
| 112 | * Methods to access the protection register area, present in some | ||
| 113 | * flash devices. The user data is one time programmable but the | ||
| 114 | * factory data is read only. | ||
| 115 | */ | ||
| 116 | int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); | ||
| 117 | |||
| 118 | int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); | ||
| 119 | |||
| 120 | /* This function is not yet implemented */ | ||
| 121 | int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); | ||
| 122 | |||
| 123 | /* kvec-based read/write methods. We need these especially for NAND flash, | ||
| 124 | with its limited number of write cycles per erase. | ||
| 125 | NB: The 'count' parameter is the number of _vectors_, each of | ||
| 126 | which contains an (ofs, len) tuple. | ||
| 127 | */ | ||
| 128 | int (*readv) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen); | ||
| 129 | int (*readv_ecc) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, | ||
| 130 | size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel); | ||
| 131 | int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen); | ||
| 132 | int (*writev_ecc) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, | ||
| 133 | size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel); | ||
| 134 | |||
| 135 | /* Sync */ | ||
| 136 | void (*sync) (struct mtd_info *mtd); | ||
| 137 | |||
| 138 | /* Chip-supported device locking */ | ||
| 139 | int (*lock) (struct mtd_info *mtd, loff_t ofs, size_t len); | ||
| 140 | int (*unlock) (struct mtd_info *mtd, loff_t ofs, size_t len); | ||
| 141 | |||
| 142 | /* Power Management functions */ | ||
| 143 | int (*suspend) (struct mtd_info *mtd); | ||
| 144 | void (*resume) (struct mtd_info *mtd); | ||
| 145 | |||
| 146 | /* Bad block management functions */ | ||
| 147 | int (*block_isbad) (struct mtd_info *mtd, loff_t ofs); | ||
| 148 | int (*block_markbad) (struct mtd_info *mtd, loff_t ofs); | ||
| 149 | |||
| 150 | void *priv; | ||
| 151 | |||
| 152 | struct module *owner; | ||
| 153 | int usecount; | ||
| 154 | }; | ||
| 155 | |||
| 156 | |||
| 157 | /* Kernel-side ioctl definitions */ | ||
| 158 | |||
| 159 | extern int add_mtd_device(struct mtd_info *mtd); | ||
| 160 | extern int del_mtd_device (struct mtd_info *mtd); | ||
| 161 | |||
| 162 | extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num); | ||
| 163 | |||
| 164 | extern void put_mtd_device(struct mtd_info *mtd); | ||
| 165 | |||
| 166 | |||
| 167 | struct mtd_notifier { | ||
| 168 | void (*add)(struct mtd_info *mtd); | ||
| 169 | void (*remove)(struct mtd_info *mtd); | ||
| 170 | struct list_head list; | ||
| 171 | }; | ||
| 172 | |||
| 173 | |||
| 174 | extern void register_mtd_user (struct mtd_notifier *new); | ||
| 175 | extern int unregister_mtd_user (struct mtd_notifier *old); | ||
| 176 | |||
| 177 | int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, | ||
| 178 | unsigned long count, loff_t to, size_t *retlen); | ||
| 179 | |||
| 180 | int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs, | ||
| 181 | unsigned long count, loff_t from, size_t *retlen); | ||
| 182 | |||
| 183 | #define MTD_ERASE(mtd, args...) (*(mtd->erase))(mtd, args) | ||
| 184 | #define MTD_POINT(mtd, a,b,c,d) (*(mtd->point))(mtd, a,b,c, (u_char **)(d)) | ||
| 185 | #define MTD_UNPOINT(mtd, arg) (*(mtd->unpoint))(mtd, (u_char *)arg) | ||
| 186 | #define MTD_READ(mtd, args...) (*(mtd->read))(mtd, args) | ||
| 187 | #define MTD_WRITE(mtd, args...) (*(mtd->write))(mtd, args) | ||
| 188 | #define MTD_READV(mtd, args...) (*(mtd->readv))(mtd, args) | ||
| 189 | #define MTD_WRITEV(mtd, args...) (*(mtd->writev))(mtd, args) | ||
| 190 | #define MTD_READECC(mtd, args...) (*(mtd->read_ecc))(mtd, args) | ||
| 191 | #define MTD_WRITEECC(mtd, args...) (*(mtd->write_ecc))(mtd, args) | ||
| 192 | #define MTD_READOOB(mtd, args...) (*(mtd->read_oob))(mtd, args) | ||
| 193 | #define MTD_WRITEOOB(mtd, args...) (*(mtd->write_oob))(mtd, args) | ||
| 194 | #define MTD_SYNC(mtd) do { if (mtd->sync) (*(mtd->sync))(mtd); } while (0) | ||
| 195 | |||
| 196 | |||
| 197 | #ifdef CONFIG_MTD_PARTITIONS | ||
| 198 | void mtd_erase_callback(struct erase_info *instr); | ||
| 199 | #else | ||
| 200 | static inline void mtd_erase_callback(struct erase_info *instr) | ||
| 201 | { | ||
| 202 | if (instr->callback) | ||
| 203 | instr->callback(instr); | ||
| 204 | } | ||
| 205 | #endif | ||
| 206 | |||
| 207 | /* | ||
| 208 | * Debugging macro and defines | ||
| 209 | */ | ||
| 210 | #define MTD_DEBUG_LEVEL0 (0) /* Quiet */ | ||
| 211 | #define MTD_DEBUG_LEVEL1 (1) /* Audible */ | ||
| 212 | #define MTD_DEBUG_LEVEL2 (2) /* Loud */ | ||
| 213 | #define MTD_DEBUG_LEVEL3 (3) /* Noisy */ | ||
| 214 | |||
| 215 | #ifdef CONFIG_MTD_DEBUG | ||
| 216 | #define DEBUG(n, args...) \ | ||
| 217 | do { \ | ||
| 218 | if (n <= CONFIG_MTD_DEBUG_VERBOSE) \ | ||
| 219 | printk(KERN_INFO args); \ | ||
| 220 | } while(0) | ||
| 221 | #else /* CONFIG_MTD_DEBUG */ | ||
| 222 | #define DEBUG(n, args...) do { } while(0) | ||
| 223 | |||
| 224 | #endif /* CONFIG_MTD_DEBUG */ | ||
| 225 | |||
| 226 | #endif /* __MTD_MTD_H__ */ | ||
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h new file mode 100644 index 000000000000..9a19c65abd74 --- /dev/null +++ b/include/linux/mtd/nand.h | |||
| @@ -0,0 +1,469 @@ | |||
| 1 | /* | ||
| 2 | * linux/include/linux/mtd/nand.h | ||
| 3 | * | ||
| 4 | * Copyright (c) 2000 David Woodhouse <dwmw2@mvhi.com> | ||
| 5 | * Steven J. Hill <sjhill@realitydiluted.com> | ||
| 6 | * Thomas Gleixner <tglx@linutronix.de> | ||
| 7 | * | ||
| 8 | * $Id: nand.h,v 1.68 2004/11/12 10:40:37 gleixner 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 version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | * | ||
| 14 | * Info: | ||
| 15 | * Contains standard defines and IDs for NAND flash devices | ||
| 16 | * | ||
| 17 | * Changelog: | ||
| 18 | * 01-31-2000 DMW Created | ||
| 19 | * 09-18-2000 SJH Moved structure out of the Disk-On-Chip drivers | ||
| 20 | * so it can be used by other NAND flash device | ||
| 21 | * drivers. I also changed the copyright since none | ||
| 22 | * of the original contents of this file are specific | ||
| 23 | * to DoC devices. David can whack me with a baseball | ||
| 24 | * bat later if I did something naughty. | ||
| 25 | * 10-11-2000 SJH Added private NAND flash structure for driver | ||
| 26 | * 10-24-2000 SJH Added prototype for 'nand_scan' function | ||
| 27 | * 10-29-2001 TG changed nand_chip structure to support | ||
| 28 | * hardwarespecific function for accessing control lines | ||
| 29 | * 02-21-2002 TG added support for different read/write adress and | ||
| 30 | * ready/busy line access function | ||
| 31 | * 02-26-2002 TG added chip_delay to nand_chip structure to optimize | ||
| 32 | * command delay times for different chips | ||
| 33 | * 04-28-2002 TG OOB config defines moved from nand.c to avoid duplicate | ||
| 34 | * defines in jffs2/wbuf.c | ||
| 35 | * 08-07-2002 TG forced bad block location to byte 5 of OOB, even if | ||
| 36 | * CONFIG_MTD_NAND_ECC_JFFS2 is not set | ||
| 37 | * 08-10-2002 TG extensions to nand_chip structure to support HW-ECC | ||
| 38 | * | ||
| 39 | * 08-29-2002 tglx nand_chip structure: data_poi for selecting | ||
| 40 | * internal / fs-driver buffer | ||
| 41 | * support for 6byte/512byte hardware ECC | ||
| 42 | * read_ecc, write_ecc extended for different oob-layout | ||
| 43 | * oob layout selections: NAND_NONE_OOB, NAND_JFFS2_OOB, | ||
| 44 | * NAND_YAFFS_OOB | ||
| 45 | * 11-25-2002 tglx Added Manufacturer code FUJITSU, NATIONAL | ||
| 46 | * Split manufacturer and device ID structures | ||
| 47 | * | ||
| 48 | * 02-08-2004 tglx added option field to nand structure for chip anomalities | ||
| 49 | * 05-25-2004 tglx added bad block table support, ST-MICRO manufacturer id | ||
| 50 | * update of nand_chip structure description | ||
| 51 | */ | ||
| 52 | #ifndef __LINUX_MTD_NAND_H | ||
| 53 | #define __LINUX_MTD_NAND_H | ||
| 54 | |||
| 55 | #include <linux/config.h> | ||
| 56 | #include <linux/wait.h> | ||
| 57 | #include <linux/spinlock.h> | ||
| 58 | #include <linux/mtd/mtd.h> | ||
| 59 | |||
| 60 | struct mtd_info; | ||
| 61 | /* Scan and identify a NAND device */ | ||
| 62 | extern int nand_scan (struct mtd_info *mtd, int max_chips); | ||
| 63 | /* Free resources held by the NAND device */ | ||
| 64 | extern void nand_release (struct mtd_info *mtd); | ||
| 65 | |||
| 66 | /* Read raw data from the device without ECC */ | ||
| 67 | extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen); | ||
| 68 | |||
| 69 | |||
| 70 | /* The maximum number of NAND chips in an array */ | ||
| 71 | #define NAND_MAX_CHIPS 8 | ||
| 72 | |||
| 73 | /* This constant declares the max. oobsize / page, which | ||
| 74 | * is supported now. If you add a chip with bigger oobsize/page | ||
| 75 | * adjust this accordingly. | ||
| 76 | */ | ||
| 77 | #define NAND_MAX_OOBSIZE 64 | ||
| 78 | |||
| 79 | /* | ||
| 80 | * Constants for hardware specific CLE/ALE/NCE function | ||
| 81 | */ | ||
| 82 | /* Select the chip by setting nCE to low */ | ||
| 83 | #define NAND_CTL_SETNCE 1 | ||
| 84 | /* Deselect the chip by setting nCE to high */ | ||
| 85 | #define NAND_CTL_CLRNCE 2 | ||
| 86 | /* Select the command latch by setting CLE to high */ | ||
| 87 | #define NAND_CTL_SETCLE 3 | ||
| 88 | /* Deselect the command latch by setting CLE to low */ | ||
| 89 | #define NAND_CTL_CLRCLE 4 | ||
| 90 | /* Select the address latch by setting ALE to high */ | ||
| 91 | #define NAND_CTL_SETALE 5 | ||
| 92 | /* Deselect the address latch by setting ALE to low */ | ||
| 93 | #define NAND_CTL_CLRALE 6 | ||
| 94 | /* Set write protection by setting WP to high. Not used! */ | ||
| 95 | #define NAND_CTL_SETWP 7 | ||
| 96 | /* Clear write protection by setting WP to low. Not used! */ | ||
| 97 | #define NAND_CTL_CLRWP 8 | ||
| 98 | |||
| 99 | /* | ||
| 100 | * Standard NAND flash commands | ||
| 101 | */ | ||
| 102 | #define NAND_CMD_READ0 0 | ||
| 103 | #define NAND_CMD_READ1 1 | ||
| 104 | #define NAND_CMD_PAGEPROG 0x10 | ||
| 105 | #define NAND_CMD_READOOB 0x50 | ||
| 106 | #define NAND_CMD_ERASE1 0x60 | ||
| 107 | #define NAND_CMD_STATUS 0x70 | ||
| 108 | #define NAND_CMD_STATUS_MULTI 0x71 | ||
| 109 | #define NAND_CMD_SEQIN 0x80 | ||
| 110 | #define NAND_CMD_READID 0x90 | ||
| 111 | #define NAND_CMD_ERASE2 0xd0 | ||
| 112 | #define NAND_CMD_RESET 0xff | ||
| 113 | |||
| 114 | /* Extended commands for large page devices */ | ||
| 115 | #define NAND_CMD_READSTART 0x30 | ||
| 116 | #define NAND_CMD_CACHEDPROG 0x15 | ||
| 117 | |||
| 118 | /* Status bits */ | ||
| 119 | #define NAND_STATUS_FAIL 0x01 | ||
| 120 | #define NAND_STATUS_FAIL_N1 0x02 | ||
| 121 | #define NAND_STATUS_TRUE_READY 0x20 | ||
| 122 | #define NAND_STATUS_READY 0x40 | ||
| 123 | #define NAND_STATUS_WP 0x80 | ||
| 124 | |||
| 125 | /* | ||
| 126 | * Constants for ECC_MODES | ||
| 127 | */ | ||
| 128 | |||
| 129 | /* No ECC. Usage is not recommended ! */ | ||
| 130 | #define NAND_ECC_NONE 0 | ||
| 131 | /* Software ECC 3 byte ECC per 256 Byte data */ | ||
| 132 | #define NAND_ECC_SOFT 1 | ||
| 133 | /* Hardware ECC 3 byte ECC per 256 Byte data */ | ||
| 134 | #define NAND_ECC_HW3_256 2 | ||
| 135 | /* Hardware ECC 3 byte ECC per 512 Byte data */ | ||
| 136 | #define NAND_ECC_HW3_512 3 | ||
| 137 | /* Hardware ECC 3 byte ECC per 512 Byte data */ | ||
| 138 | #define NAND_ECC_HW6_512 4 | ||
| 139 | /* Hardware ECC 8 byte ECC per 512 Byte data */ | ||
| 140 | #define NAND_ECC_HW8_512 6 | ||
| 141 | /* Hardware ECC 12 byte ECC per 2048 Byte data */ | ||
| 142 | #define NAND_ECC_HW12_2048 7 | ||
| 143 | |||
| 144 | /* | ||
| 145 | * Constants for Hardware ECC | ||
| 146 | */ | ||
| 147 | /* Reset Hardware ECC for read */ | ||
| 148 | #define NAND_ECC_READ 0 | ||
| 149 | /* Reset Hardware ECC for write */ | ||
| 150 | #define NAND_ECC_WRITE 1 | ||
| 151 | /* Enable Hardware ECC before syndrom is read back from flash */ | ||
| 152 | #define NAND_ECC_READSYN 2 | ||
| 153 | |||
| 154 | /* Option constants for bizarre disfunctionality and real | ||
| 155 | * features | ||
| 156 | */ | ||
| 157 | /* Chip can not auto increment pages */ | ||
| 158 | #define NAND_NO_AUTOINCR 0x00000001 | ||
| 159 | /* Buswitdh is 16 bit */ | ||
| 160 | #define NAND_BUSWIDTH_16 0x00000002 | ||
| 161 | /* Device supports partial programming without padding */ | ||
| 162 | #define NAND_NO_PADDING 0x00000004 | ||
| 163 | /* Chip has cache program function */ | ||
| 164 | #define NAND_CACHEPRG 0x00000008 | ||
| 165 | /* Chip has copy back function */ | ||
| 166 | #define NAND_COPYBACK 0x00000010 | ||
| 167 | /* AND Chip which has 4 banks and a confusing page / block | ||
| 168 | * assignment. See Renesas datasheet for further information */ | ||
| 169 | #define NAND_IS_AND 0x00000020 | ||
| 170 | /* Chip has a array of 4 pages which can be read without | ||
| 171 | * additional ready /busy waits */ | ||
| 172 | #define NAND_4PAGE_ARRAY 0x00000040 | ||
| 173 | |||
| 174 | /* Options valid for Samsung large page devices */ | ||
| 175 | #define NAND_SAMSUNG_LP_OPTIONS \ | ||
| 176 | (NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK) | ||
| 177 | |||
| 178 | /* Macros to identify the above */ | ||
| 179 | #define NAND_CANAUTOINCR(chip) (!(chip->options & NAND_NO_AUTOINCR)) | ||
| 180 | #define NAND_MUST_PAD(chip) (!(chip->options & NAND_NO_PADDING)) | ||
| 181 | #define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG)) | ||
| 182 | #define NAND_HAS_COPYBACK(chip) ((chip->options & NAND_COPYBACK)) | ||
| 183 | |||
| 184 | /* Mask to zero out the chip options, which come from the id table */ | ||
| 185 | #define NAND_CHIPOPTIONS_MSK (0x0000ffff & ~NAND_NO_AUTOINCR) | ||
| 186 | |||
| 187 | /* Non chip related options */ | ||
| 188 | /* Use a flash based bad block table. This option is passed to the | ||
| 189 | * default bad block table function. */ | ||
| 190 | #define NAND_USE_FLASH_BBT 0x00010000 | ||
| 191 | /* The hw ecc generator provides a syndrome instead a ecc value on read | ||
| 192 | * This can only work if we have the ecc bytes directly behind the | ||
| 193 | * data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */ | ||
| 194 | #define NAND_HWECC_SYNDROME 0x00020000 | ||
| 195 | |||
| 196 | |||
| 197 | /* Options set by nand scan */ | ||
| 198 | /* Nand scan has allocated oob_buf */ | ||
| 199 | #define NAND_OOBBUF_ALLOC 0x40000000 | ||
| 200 | /* Nand scan has allocated data_buf */ | ||
| 201 | #define NAND_DATABUF_ALLOC 0x80000000 | ||
| 202 | |||
| 203 | |||
| 204 | /* | ||
| 205 | * nand_state_t - chip states | ||
| 206 | * Enumeration for NAND flash chip state | ||
| 207 | */ | ||
| 208 | typedef enum { | ||
| 209 | FL_READY, | ||
| 210 | FL_READING, | ||
| 211 | FL_WRITING, | ||
| 212 | FL_ERASING, | ||
| 213 | FL_SYNCING, | ||
| 214 | FL_CACHEDPRG, | ||
| 215 | } nand_state_t; | ||
| 216 | |||
| 217 | /* Keep gcc happy */ | ||
| 218 | struct nand_chip; | ||
| 219 | |||
| 220 | /** | ||
| 221 | * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independend devices | ||
| 222 | * @lock: protection lock | ||
| 223 | * @active: the mtd device which holds the controller currently | ||
| 224 | */ | ||
| 225 | struct nand_hw_control { | ||
| 226 | spinlock_t lock; | ||
| 227 | struct nand_chip *active; | ||
| 228 | }; | ||
| 229 | |||
| 230 | /** | ||
| 231 | * struct nand_chip - NAND Private Flash Chip Data | ||
| 232 | * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the flash device | ||
| 233 | * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the flash device | ||
| 234 | * @read_byte: [REPLACEABLE] read one byte from the chip | ||
| 235 | * @write_byte: [REPLACEABLE] write one byte to the chip | ||
| 236 | * @read_word: [REPLACEABLE] read one word from the chip | ||
| 237 | * @write_word: [REPLACEABLE] write one word to the chip | ||
| 238 | * @write_buf: [REPLACEABLE] write data from the buffer to the chip | ||
| 239 | * @read_buf: [REPLACEABLE] read data from the chip into the buffer | ||
| 240 | * @verify_buf: [REPLACEABLE] verify buffer contents against the chip data | ||
| 241 | * @select_chip: [REPLACEABLE] select chip nr | ||
| 242 | * @block_bad: [REPLACEABLE] check, if the block is bad | ||
| 243 | * @block_markbad: [REPLACEABLE] mark the block bad | ||
| 244 | * @hwcontrol: [BOARDSPECIFIC] hardwarespecific function for accesing control-lines | ||
| 245 | * @dev_ready: [BOARDSPECIFIC] hardwarespecific function for accesing device ready/busy line | ||
| 246 | * If set to NULL no access to ready/busy is available and the ready/busy information | ||
| 247 | * is read from the chip status register | ||
| 248 | * @cmdfunc: [REPLACEABLE] hardwarespecific function for writing commands to the chip | ||
| 249 | * @waitfunc: [REPLACEABLE] hardwarespecific function for wait on ready | ||
| 250 | * @calculate_ecc: [REPLACEABLE] function for ecc calculation or readback from ecc hardware | ||
| 251 | * @correct_data: [REPLACEABLE] function for ecc correction, matching to ecc generator (sw/hw) | ||
| 252 | * @enable_hwecc: [BOARDSPECIFIC] function to enable (reset) hardware ecc generator. Must only | ||
| 253 | * be provided if a hardware ECC is available | ||
| 254 | * @erase_cmd: [INTERN] erase command write function, selectable due to AND support | ||
| 255 | * @scan_bbt: [REPLACEABLE] function to scan bad block table | ||
| 256 | * @eccmode: [BOARDSPECIFIC] mode of ecc, see defines | ||
| 257 | * @eccsize: [INTERN] databytes used per ecc-calculation | ||
| 258 | * @eccbytes: [INTERN] number of ecc bytes per ecc-calculation step | ||
| 259 | * @eccsteps: [INTERN] number of ecc calculation steps per page | ||
| 260 | * @chip_delay: [BOARDSPECIFIC] chip dependent delay for transfering data from array to read regs (tR) | ||
| 261 | * @chip_lock: [INTERN] spinlock used to protect access to this structure and the chip | ||
| 262 | * @wq: [INTERN] wait queue to sleep on if a NAND operation is in progress | ||
| 263 | * @state: [INTERN] the current state of the NAND device | ||
| 264 | * @page_shift: [INTERN] number of address bits in a page (column address bits) | ||
| 265 | * @phys_erase_shift: [INTERN] number of address bits in a physical eraseblock | ||
| 266 | * @bbt_erase_shift: [INTERN] number of address bits in a bbt entry | ||
| 267 | * @chip_shift: [INTERN] number of address bits in one chip | ||
| 268 | * @data_buf: [INTERN] internal buffer for one page + oob | ||
| 269 | * @oob_buf: [INTERN] oob buffer for one eraseblock | ||
| 270 | * @oobdirty: [INTERN] indicates that oob_buf must be reinitialized | ||
| 271 | * @data_poi: [INTERN] pointer to a data buffer | ||
| 272 | * @options: [BOARDSPECIFIC] various chip options. They can partly be set to inform nand_scan about | ||
| 273 | * special functionality. See the defines for further explanation | ||
| 274 | * @badblockpos: [INTERN] position of the bad block marker in the oob area | ||
| 275 | * @numchips: [INTERN] number of physical chips | ||
| 276 | * @chipsize: [INTERN] the size of one chip for multichip arrays | ||
| 277 | * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1 | ||
| 278 | * @pagebuf: [INTERN] holds the pagenumber which is currently in data_buf | ||
| 279 | * @autooob: [REPLACEABLE] the default (auto)placement scheme | ||
| 280 | * @bbt: [INTERN] bad block table pointer | ||
| 281 | * @bbt_td: [REPLACEABLE] bad block table descriptor for flash lookup | ||
| 282 | * @bbt_md: [REPLACEABLE] bad block table mirror descriptor | ||
| 283 | * @badblock_pattern: [REPLACEABLE] bad block scan pattern used for initial bad block scan | ||
| 284 | * @controller: [OPTIONAL] a pointer to a hardware controller structure which is shared among multiple independend devices | ||
| 285 | * @priv: [OPTIONAL] pointer to private chip date | ||
| 286 | */ | ||
| 287 | |||
| 288 | struct nand_chip { | ||
| 289 | void __iomem *IO_ADDR_R; | ||
| 290 | void __iomem *IO_ADDR_W; | ||
| 291 | |||
| 292 | u_char (*read_byte)(struct mtd_info *mtd); | ||
| 293 | void (*write_byte)(struct mtd_info *mtd, u_char byte); | ||
| 294 | u16 (*read_word)(struct mtd_info *mtd); | ||
| 295 | void (*write_word)(struct mtd_info *mtd, u16 word); | ||
| 296 | |||
| 297 | void (*write_buf)(struct mtd_info *mtd, const u_char *buf, int len); | ||
| 298 | void (*read_buf)(struct mtd_info *mtd, u_char *buf, int len); | ||
| 299 | int (*verify_buf)(struct mtd_info *mtd, const u_char *buf, int len); | ||
| 300 | void (*select_chip)(struct mtd_info *mtd, int chip); | ||
| 301 | int (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip); | ||
| 302 | int (*block_markbad)(struct mtd_info *mtd, loff_t ofs); | ||
| 303 | void (*hwcontrol)(struct mtd_info *mtd, int cmd); | ||
| 304 | int (*dev_ready)(struct mtd_info *mtd); | ||
| 305 | void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr); | ||
| 306 | int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this, int state); | ||
| 307 | int (*calculate_ecc)(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code); | ||
| 308 | int (*correct_data)(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc); | ||
| 309 | void (*enable_hwecc)(struct mtd_info *mtd, int mode); | ||
| 310 | void (*erase_cmd)(struct mtd_info *mtd, int page); | ||
| 311 | int (*scan_bbt)(struct mtd_info *mtd); | ||
| 312 | int eccmode; | ||
| 313 | int eccsize; | ||
| 314 | int eccbytes; | ||
| 315 | int eccsteps; | ||
| 316 | int chip_delay; | ||
| 317 | spinlock_t chip_lock; | ||
| 318 | wait_queue_head_t wq; | ||
| 319 | nand_state_t state; | ||
| 320 | int page_shift; | ||
| 321 | int phys_erase_shift; | ||
| 322 | int bbt_erase_shift; | ||
| 323 | int chip_shift; | ||
| 324 | u_char *data_buf; | ||
| 325 | u_char *oob_buf; | ||
| 326 | int oobdirty; | ||
| 327 | u_char *data_poi; | ||
| 328 | unsigned int options; | ||
| 329 | int badblockpos; | ||
| 330 | int numchips; | ||
| 331 | unsigned long chipsize; | ||
| 332 | int pagemask; | ||
| 333 | int pagebuf; | ||
| 334 | struct nand_oobinfo *autooob; | ||
| 335 | uint8_t *bbt; | ||
| 336 | struct nand_bbt_descr *bbt_td; | ||
| 337 | struct nand_bbt_descr *bbt_md; | ||
| 338 | struct nand_bbt_descr *badblock_pattern; | ||
| 339 | struct nand_hw_control *controller; | ||
| 340 | void *priv; | ||
| 341 | }; | ||
| 342 | |||
| 343 | /* | ||
| 344 | * NAND Flash Manufacturer ID Codes | ||
| 345 | */ | ||
| 346 | #define NAND_MFR_TOSHIBA 0x98 | ||
| 347 | #define NAND_MFR_SAMSUNG 0xec | ||
| 348 | #define NAND_MFR_FUJITSU 0x04 | ||
| 349 | #define NAND_MFR_NATIONAL 0x8f | ||
| 350 | #define NAND_MFR_RENESAS 0x07 | ||
| 351 | #define NAND_MFR_STMICRO 0x20 | ||
| 352 | |||
| 353 | /** | ||
| 354 | * struct nand_flash_dev - NAND Flash Device ID Structure | ||
| 355 | * | ||
| 356 | * @name: Identify the device type | ||
| 357 | * @id: device ID code | ||
| 358 | * @pagesize: Pagesize in bytes. Either 256 or 512 or 0 | ||
| 359 | * If the pagesize is 0, then the real pagesize | ||
| 360 | * and the eraseize are determined from the | ||
| 361 | * extended id bytes in the chip | ||
| 362 | * @erasesize: Size of an erase block in the flash device. | ||
| 363 | * @chipsize: Total chipsize in Mega Bytes | ||
| 364 | * @options: Bitfield to store chip relevant options | ||
| 365 | */ | ||
| 366 | struct nand_flash_dev { | ||
| 367 | char *name; | ||
| 368 | int id; | ||
| 369 | unsigned long pagesize; | ||
| 370 | unsigned long chipsize; | ||
| 371 | unsigned long erasesize; | ||
| 372 | unsigned long options; | ||
| 373 | }; | ||
| 374 | |||
| 375 | /** | ||
| 376 | * struct nand_manufacturers - NAND Flash Manufacturer ID Structure | ||
| 377 | * @name: Manufacturer name | ||
| 378 | * @id: manufacturer ID code of device. | ||
| 379 | */ | ||
| 380 | struct nand_manufacturers { | ||
| 381 | int id; | ||
| 382 | char * name; | ||
| 383 | }; | ||
| 384 | |||
| 385 | extern struct nand_flash_dev nand_flash_ids[]; | ||
| 386 | extern struct nand_manufacturers nand_manuf_ids[]; | ||
| 387 | |||
| 388 | /** | ||
| 389 | * struct nand_bbt_descr - bad block table descriptor | ||
| 390 | * @options: options for this descriptor | ||
| 391 | * @pages: the page(s) where we find the bbt, used with option BBT_ABSPAGE | ||
| 392 | * when bbt is searched, then we store the found bbts pages here. | ||
| 393 | * Its an array and supports up to 8 chips now | ||
| 394 | * @offs: offset of the pattern in the oob area of the page | ||
| 395 | * @veroffs: offset of the bbt version counter in the oob are of the page | ||
| 396 | * @version: version read from the bbt page during scan | ||
| 397 | * @len: length of the pattern, if 0 no pattern check is performed | ||
| 398 | * @maxblocks: maximum number of blocks to search for a bbt. This number of | ||
| 399 | * blocks is reserved at the end of the device where the tables are | ||
| 400 | * written. | ||
| 401 | * @reserved_block_code: if non-0, this pattern denotes a reserved (rather than | ||
| 402 | * bad) block in the stored bbt | ||
| 403 | * @pattern: pattern to identify bad block table or factory marked good / | ||
| 404 | * bad blocks, can be NULL, if len = 0 | ||
| 405 | * | ||
| 406 | * Descriptor for the bad block table marker and the descriptor for the | ||
| 407 | * pattern which identifies good and bad blocks. The assumption is made | ||
| 408 | * that the pattern and the version count are always located in the oob area | ||
| 409 | * of the first block. | ||
| 410 | */ | ||
| 411 | struct nand_bbt_descr { | ||
| 412 | int options; | ||
| 413 | int pages[NAND_MAX_CHIPS]; | ||
| 414 | int offs; | ||
| 415 | int veroffs; | ||
| 416 | uint8_t version[NAND_MAX_CHIPS]; | ||
| 417 | int len; | ||
| 418 | int maxblocks; | ||
| 419 | int reserved_block_code; | ||
| 420 | uint8_t *pattern; | ||
| 421 | }; | ||
| 422 | |||
| 423 | /* Options for the bad block table descriptors */ | ||
| 424 | |||
| 425 | /* The number of bits used per block in the bbt on the device */ | ||
| 426 | #define NAND_BBT_NRBITS_MSK 0x0000000F | ||
| 427 | #define NAND_BBT_1BIT 0x00000001 | ||
| 428 | #define NAND_BBT_2BIT 0x00000002 | ||
| 429 | #define NAND_BBT_4BIT 0x00000004 | ||
| 430 | #define NAND_BBT_8BIT 0x00000008 | ||
| 431 | /* The bad block table is in the last good block of the device */ | ||
| 432 | #define NAND_BBT_LASTBLOCK 0x00000010 | ||
| 433 | /* The bbt is at the given page, else we must scan for the bbt */ | ||
| 434 | #define NAND_BBT_ABSPAGE 0x00000020 | ||
| 435 | /* The bbt is at the given page, else we must scan for the bbt */ | ||
| 436 | #define NAND_BBT_SEARCH 0x00000040 | ||
| 437 | /* bbt is stored per chip on multichip devices */ | ||
| 438 | #define NAND_BBT_PERCHIP 0x00000080 | ||
| 439 | /* bbt has a version counter at offset veroffs */ | ||
| 440 | #define NAND_BBT_VERSION 0x00000100 | ||
| 441 | /* Create a bbt if none axists */ | ||
| 442 | #define NAND_BBT_CREATE 0x00000200 | ||
| 443 | /* Search good / bad pattern through all pages of a block */ | ||
| 444 | #define NAND_BBT_SCANALLPAGES 0x00000400 | ||
| 445 | /* Scan block empty during good / bad block scan */ | ||
| 446 | #define NAND_BBT_SCANEMPTY 0x00000800 | ||
| 447 | /* Write bbt if neccecary */ | ||
| 448 | #define NAND_BBT_WRITE 0x00001000 | ||
| 449 | /* Read and write back block contents when writing bbt */ | ||
| 450 | #define NAND_BBT_SAVECONTENT 0x00002000 | ||
| 451 | /* Search good / bad pattern on the first and the second page */ | ||
| 452 | #define NAND_BBT_SCAN2NDPAGE 0x00004000 | ||
| 453 | |||
| 454 | /* The maximum number of blocks to scan for a bbt */ | ||
| 455 | #define NAND_BBT_SCAN_MAXBLOCKS 4 | ||
| 456 | |||
| 457 | extern int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd); | ||
| 458 | extern int nand_update_bbt (struct mtd_info *mtd, loff_t offs); | ||
| 459 | extern int nand_default_bbt (struct mtd_info *mtd); | ||
| 460 | extern int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt); | ||
| 461 | extern int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbbt); | ||
| 462 | |||
| 463 | /* | ||
| 464 | * Constants for oob configuration | ||
| 465 | */ | ||
| 466 | #define NAND_SMALL_BADBLOCK_POS 5 | ||
| 467 | #define NAND_LARGE_BADBLOCK_POS 0 | ||
| 468 | |||
| 469 | #endif /* __LINUX_MTD_NAND_H */ | ||
diff --git a/include/linux/mtd/nand_ecc.h b/include/linux/mtd/nand_ecc.h new file mode 100644 index 000000000000..12c5bc342ead --- /dev/null +++ b/include/linux/mtd/nand_ecc.h | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | /* | ||
| 2 | * drivers/mtd/nand_ecc.h | ||
| 3 | * | ||
| 4 | * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) | ||
| 5 | * | ||
| 6 | * $Id: nand_ecc.h,v 1.4 2004/06/17 02:35:02 dbrown Exp $ | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | * | ||
| 12 | * This file is the header for the ECC algorithm. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #ifndef __MTD_NAND_ECC_H__ | ||
| 16 | #define __MTD_NAND_ECC_H__ | ||
| 17 | |||
| 18 | struct mtd_info; | ||
| 19 | |||
| 20 | /* | ||
| 21 | * Calculate 3 byte ECC code for 256 byte block | ||
| 22 | */ | ||
| 23 | int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code); | ||
| 24 | |||
| 25 | /* | ||
| 26 | * Detect and correct a 1 bit error for 256 byte block | ||
| 27 | */ | ||
| 28 | int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc); | ||
| 29 | |||
| 30 | #endif /* __MTD_NAND_ECC_H__ */ | ||
diff --git a/include/linux/mtd/nftl.h b/include/linux/mtd/nftl.h new file mode 100644 index 000000000000..d35d2c21ff3e --- /dev/null +++ b/include/linux/mtd/nftl.h | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | /* | ||
| 2 | * $Id: nftl.h,v 1.16 2004/06/30 14:49:00 dbrown Exp $ | ||
| 3 | * | ||
| 4 | * (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> | ||
| 5 | */ | ||
| 6 | |||
| 7 | #ifndef __MTD_NFTL_H__ | ||
| 8 | #define __MTD_NFTL_H__ | ||
| 9 | |||
| 10 | #include <linux/mtd/mtd.h> | ||
| 11 | #include <linux/mtd/blktrans.h> | ||
| 12 | |||
| 13 | #include <mtd/nftl-user.h> | ||
| 14 | |||
| 15 | /* these info are used in ReplUnitTable */ | ||
| 16 | #define BLOCK_NIL 0xffff /* last block of a chain */ | ||
| 17 | #define BLOCK_FREE 0xfffe /* free block */ | ||
| 18 | #define BLOCK_NOTEXPLORED 0xfffd /* non explored block, only used during mounting */ | ||
| 19 | #define BLOCK_RESERVED 0xfffc /* bios block or bad block */ | ||
| 20 | |||
| 21 | struct NFTLrecord { | ||
| 22 | struct mtd_blktrans_dev mbd; | ||
| 23 | __u16 MediaUnit, SpareMediaUnit; | ||
| 24 | __u32 EraseSize; | ||
| 25 | struct NFTLMediaHeader MediaHdr; | ||
| 26 | int usecount; | ||
| 27 | unsigned char heads; | ||
| 28 | unsigned char sectors; | ||
| 29 | unsigned short cylinders; | ||
| 30 | __u16 numvunits; | ||
| 31 | __u16 lastEUN; /* should be suppressed */ | ||
| 32 | __u16 numfreeEUNs; | ||
| 33 | __u16 LastFreeEUN; /* To speed up finding a free EUN */ | ||
| 34 | int head,sect,cyl; | ||
| 35 | __u16 *EUNtable; /* [numvunits]: First EUN for each virtual unit */ | ||
| 36 | __u16 *ReplUnitTable; /* [numEUNs]: ReplUnitNumber for each */ | ||
| 37 | unsigned int nb_blocks; /* number of physical blocks */ | ||
| 38 | unsigned int nb_boot_blocks; /* number of blocks used by the bios */ | ||
| 39 | struct erase_info instr; | ||
| 40 | struct nand_oobinfo oobinfo; | ||
| 41 | }; | ||
| 42 | |||
| 43 | int NFTL_mount(struct NFTLrecord *s); | ||
| 44 | int NFTL_formatblock(struct NFTLrecord *s, int block); | ||
| 45 | |||
| 46 | #ifndef NFTL_MAJOR | ||
| 47 | #define NFTL_MAJOR 93 | ||
| 48 | #endif | ||
| 49 | |||
| 50 | #define MAX_NFTLS 16 | ||
| 51 | #define MAX_SECTORS_PER_UNIT 64 | ||
| 52 | #define NFTL_PARTN_BITS 4 | ||
| 53 | |||
| 54 | #endif /* __MTD_NFTL_H__ */ | ||
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h new file mode 100644 index 000000000000..50b2edfc8f11 --- /dev/null +++ b/include/linux/mtd/partitions.h | |||
| @@ -0,0 +1,75 @@ | |||
| 1 | /* | ||
| 2 | * MTD partitioning layer definitions | ||
| 3 | * | ||
| 4 | * (C) 2000 Nicolas Pitre <nico@cam.org> | ||
| 5 | * | ||
| 6 | * This code is GPL | ||
| 7 | * | ||
| 8 | * $Id: partitions.h,v 1.16 2004/11/16 18:34:40 dwmw2 Exp $ | ||
| 9 | */ | ||
| 10 | |||
| 11 | #ifndef MTD_PARTITIONS_H | ||
| 12 | #define MTD_PARTITIONS_H | ||
| 13 | |||
| 14 | #include <linux/types.h> | ||
| 15 | |||
| 16 | |||
| 17 | /* | ||
| 18 | * Partition definition structure: | ||
| 19 | * | ||
| 20 | * An array of struct partition is passed along with a MTD object to | ||
| 21 | * add_mtd_partitions() to create them. | ||
| 22 | * | ||
| 23 | * For each partition, these fields are available: | ||
| 24 | * name: string that will be used to label the partition's MTD device. | ||
| 25 | * size: the partition size; if defined as MTDPART_SIZ_FULL, the partition | ||
| 26 | * will extend to the end of the master MTD device. | ||
| 27 | * offset: absolute starting position within the master MTD device; if | ||
| 28 | * defined as MTDPART_OFS_APPEND, the partition will start where the | ||
| 29 | * previous one ended; if MTDPART_OFS_NXTBLK, at the next erase block. | ||
| 30 | * mask_flags: contains flags that have to be masked (removed) from the | ||
| 31 | * master MTD flag set for the corresponding MTD partition. | ||
| 32 | * For example, to force a read-only partition, simply adding | ||
| 33 | * MTD_WRITEABLE to the mask_flags will do the trick. | ||
| 34 | * | ||
| 35 | * Note: writeable partitions require their size and offset be | ||
| 36 | * erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK). | ||
| 37 | */ | ||
| 38 | |||
| 39 | struct mtd_partition { | ||
| 40 | char *name; /* identifier string */ | ||
| 41 | u_int32_t size; /* partition size */ | ||
| 42 | u_int32_t offset; /* offset within the master MTD space */ | ||
| 43 | u_int32_t mask_flags; /* master MTD flags to mask out for this partition */ | ||
| 44 | struct nand_oobinfo *oobsel; /* out of band layout for this partition (NAND only)*/ | ||
| 45 | struct mtd_info **mtdp; /* pointer to store the MTD object */ | ||
| 46 | }; | ||
| 47 | |||
| 48 | #define MTDPART_OFS_NXTBLK (-2) | ||
| 49 | #define MTDPART_OFS_APPEND (-1) | ||
| 50 | #define MTDPART_SIZ_FULL (0) | ||
| 51 | |||
| 52 | |||
| 53 | int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int); | ||
| 54 | int del_mtd_partitions(struct mtd_info *); | ||
| 55 | |||
| 56 | /* | ||
| 57 | * Functions dealing with the various ways of partitioning the space | ||
| 58 | */ | ||
| 59 | |||
| 60 | struct mtd_part_parser { | ||
| 61 | struct list_head list; | ||
| 62 | struct module *owner; | ||
| 63 | const char *name; | ||
| 64 | int (*parse_fn)(struct mtd_info *, struct mtd_partition **, unsigned long); | ||
| 65 | }; | ||
| 66 | |||
| 67 | extern int register_mtd_parser(struct mtd_part_parser *parser); | ||
| 68 | extern int deregister_mtd_parser(struct mtd_part_parser *parser); | ||
| 69 | extern int parse_mtd_partitions(struct mtd_info *master, const char **types, | ||
| 70 | struct mtd_partition **pparts, unsigned long origin); | ||
| 71 | |||
| 72 | #define put_partition_parser(p) do { module_put((p)->owner); } while(0) | ||
| 73 | |||
| 74 | #endif | ||
| 75 | |||
diff --git a/include/linux/mtd/physmap.h b/include/linux/mtd/physmap.h new file mode 100644 index 000000000000..05aa4970677f --- /dev/null +++ b/include/linux/mtd/physmap.h | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | /* | ||
| 2 | * For boards with physically mapped flash and using | ||
| 3 | * drivers/mtd/maps/physmap.c mapping driver. | ||
| 4 | * | ||
| 5 | * $Id: physmap.h,v 1.3 2004/07/21 00:16:15 jwboyer Exp $ | ||
| 6 | * | ||
| 7 | * Copyright (C) 2003 MontaVista Software Inc. | ||
| 8 | * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify it | ||
| 11 | * under the terms of the GNU General Public License as published by the | ||
| 12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 13 | * option) any later version. | ||
| 14 | * | ||
| 15 | */ | ||
| 16 | |||
| 17 | #ifndef __LINUX_MTD_PHYSMAP__ | ||
| 18 | |||
| 19 | #include <linux/config.h> | ||
| 20 | |||
| 21 | #if defined(CONFIG_MTD_PHYSMAP) | ||
| 22 | |||
| 23 | #include <linux/mtd/mtd.h> | ||
| 24 | #include <linux/mtd/map.h> | ||
| 25 | #include <linux/mtd/partitions.h> | ||
| 26 | |||
| 27 | /* | ||
| 28 | * The map_info for physmap. Board can override size, buswidth, phys, | ||
| 29 | * (*set_vpp)(), etc in their initial setup routine. | ||
| 30 | */ | ||
| 31 | extern struct map_info physmap_map; | ||
| 32 | |||
| 33 | /* | ||
| 34 | * Board needs to specify the exact mapping during their setup time. | ||
| 35 | */ | ||
| 36 | static inline void physmap_configure(unsigned long addr, unsigned long size, int bankwidth, void (*set_vpp)(struct map_info *, int) ) | ||
| 37 | { | ||
| 38 | physmap_map.phys = addr; | ||
| 39 | physmap_map.size = size; | ||
| 40 | physmap_map.bankwidth = bankwidth; | ||
| 41 | physmap_map.set_vpp = set_vpp; | ||
| 42 | } | ||
| 43 | |||
| 44 | #if defined(CONFIG_MTD_PARTITIONS) | ||
| 45 | |||
| 46 | /* | ||
| 47 | * Machines that wish to do flash partition may want to call this function in | ||
| 48 | * their setup routine. | ||
| 49 | * | ||
| 50 | * physmap_set_partitions(mypartitions, num_parts); | ||
| 51 | * | ||
| 52 | * Note that one can always override this hard-coded partition with | ||
| 53 | * command line partition (you need to enable CONFIG_MTD_CMDLINE_PARTS). | ||
| 54 | */ | ||
| 55 | void physmap_set_partitions(struct mtd_partition *parts, int num_parts); | ||
| 56 | |||
| 57 | #endif /* defined(CONFIG_MTD_PARTITIONS) */ | ||
| 58 | #endif /* defined(CONFIG_MTD) */ | ||
| 59 | |||
| 60 | #endif /* __LINUX_MTD_PHYSMAP__ */ | ||
| 61 | |||
diff --git a/include/linux/mtd/pmc551.h b/include/linux/mtd/pmc551.h new file mode 100644 index 000000000000..113e3087f68a --- /dev/null +++ b/include/linux/mtd/pmc551.h | |||
| @@ -0,0 +1,79 @@ | |||
| 1 | /* | ||
| 2 | * $Id: pmc551.h,v 1.5 2003/01/24 16:49:53 dwmw2 Exp $ | ||
| 3 | * | ||
| 4 | * PMC551 PCI Mezzanine Ram Device | ||
| 5 | * | ||
| 6 | * Author: | ||
| 7 | * Mark Ferrell | ||
| 8 | * Copyright 1999,2000 Nortel Networks | ||
| 9 | * | ||
| 10 | * License: | ||
| 11 | * As part of this driver was derrived from the slram.c driver it falls | ||
| 12 | * under the same license, which is GNU General Public License v2 | ||
| 13 | */ | ||
| 14 | |||
| 15 | #ifndef __MTD_PMC551_H__ | ||
| 16 | #define __MTD_PMC551_H__ | ||
| 17 | |||
| 18 | #include <linux/mtd/mtd.h> | ||
| 19 | |||
| 20 | #define PMC551_VERSION "$Id: pmc551.h,v 1.5 2003/01/24 16:49:53 dwmw2 Exp $\n"\ | ||
| 21 | "Ramix PMC551 PCI Mezzanine Ram Driver. (C) 1999,2000 Nortel Networks.\n" | ||
| 22 | |||
| 23 | /* | ||
| 24 | * Our personal and private information | ||
| 25 | */ | ||
| 26 | struct mypriv { | ||
| 27 | struct pci_dev *dev; | ||
| 28 | u_char *start; | ||
| 29 | u32 base_map0; | ||
| 30 | u32 curr_map0; | ||
| 31 | u32 asize; | ||
| 32 | struct mtd_info *nextpmc551; | ||
| 33 | }; | ||
| 34 | |||
| 35 | /* | ||
| 36 | * Function Prototypes | ||
| 37 | */ | ||
| 38 | static int pmc551_erase(struct mtd_info *, struct erase_info *); | ||
| 39 | static void pmc551_unpoint(struct mtd_info *, u_char *, loff_t, size_t); | ||
| 40 | static int pmc551_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf); | ||
| 41 | static int pmc551_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *); | ||
| 42 | static int pmc551_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); | ||
| 43 | |||
| 44 | |||
| 45 | /* | ||
| 46 | * Define the PCI ID's if the kernel doesn't define them for us | ||
| 47 | */ | ||
| 48 | #ifndef PCI_VENDOR_ID_V3_SEMI | ||
| 49 | #define PCI_VENDOR_ID_V3_SEMI 0x11b0 | ||
| 50 | #endif | ||
| 51 | |||
| 52 | #ifndef PCI_DEVICE_ID_V3_SEMI_V370PDC | ||
| 53 | #define PCI_DEVICE_ID_V3_SEMI_V370PDC 0x0200 | ||
| 54 | #endif | ||
| 55 | |||
| 56 | |||
| 57 | #define PMC551_PCI_MEM_MAP0 0x50 | ||
| 58 | #define PMC551_PCI_MEM_MAP1 0x54 | ||
| 59 | #define PMC551_PCI_MEM_MAP_MAP_ADDR_MASK 0x3ff00000 | ||
| 60 | #define PMC551_PCI_MEM_MAP_APERTURE_MASK 0x000000f0 | ||
| 61 | #define PMC551_PCI_MEM_MAP_REG_EN 0x00000002 | ||
| 62 | #define PMC551_PCI_MEM_MAP_ENABLE 0x00000001 | ||
| 63 | |||
| 64 | #define PMC551_SDRAM_MA 0x60 | ||
| 65 | #define PMC551_SDRAM_CMD 0x62 | ||
| 66 | #define PMC551_DRAM_CFG 0x64 | ||
| 67 | #define PMC551_SYS_CTRL_REG 0x78 | ||
| 68 | |||
| 69 | #define PMC551_DRAM_BLK0 0x68 | ||
| 70 | #define PMC551_DRAM_BLK1 0x6c | ||
| 71 | #define PMC551_DRAM_BLK2 0x70 | ||
| 72 | #define PMC551_DRAM_BLK3 0x74 | ||
| 73 | #define PMC551_DRAM_BLK_GET_SIZE(x) (524288<<((x>>4)&0x0f)) | ||
| 74 | #define PMC551_DRAM_BLK_SET_COL_MUX(x,v) (((x) & ~0x00007000) | (((v) & 0x7) << 12)) | ||
| 75 | #define PMC551_DRAM_BLK_SET_ROW_MUX(x,v) (((x) & ~0x00000f00) | (((v) & 0xf) << 8)) | ||
| 76 | |||
| 77 | |||
| 78 | #endif /* __MTD_PMC551_H__ */ | ||
| 79 | |||
diff --git a/include/linux/mtd/xip.h b/include/linux/mtd/xip.h new file mode 100644 index 000000000000..fc071125cbcc --- /dev/null +++ b/include/linux/mtd/xip.h | |||
| @@ -0,0 +1,107 @@ | |||
| 1 | /* | ||
| 2 | * MTD primitives for XIP support | ||
| 3 | * | ||
| 4 | * Author: Nicolas Pitre | ||
| 5 | * Created: Nov 2, 2004 | ||
| 6 | * Copyright: (C) 2004 MontaVista Software, Inc. | ||
| 7 | * | ||
| 8 | * This XIP support for MTD has been loosely inspired | ||
| 9 | * by an earlier patch authored by David Woodhouse. | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License version 2 as | ||
| 13 | * published by the Free Software Foundation. | ||
| 14 | * | ||
| 15 | * $Id: xip.h,v 1.2 2004/12/01 15:49:10 nico Exp $ | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifndef __LINUX_MTD_XIP_H__ | ||
| 19 | #define __LINUX_MTD_XIP_H__ | ||
| 20 | |||
| 21 | #include <linux/config.h> | ||
| 22 | |||
| 23 | #ifdef CONFIG_MTD_XIP | ||
| 24 | |||
| 25 | /* | ||
| 26 | * Function that are modifying the flash state away from array mode must | ||
| 27 | * obviously not be running from flash. The __xipram is therefore marking | ||
| 28 | * those functions so they get relocated to ram. | ||
| 29 | */ | ||
| 30 | #define __xipram __attribute__ ((__section__ (".data"))) | ||
| 31 | |||
| 32 | /* | ||
| 33 | * We really don't want gcc to guess anything. | ||
| 34 | * We absolutely _need_ proper inlining. | ||
| 35 | */ | ||
| 36 | #include <linux/compiler.h> | ||
| 37 | |||
| 38 | /* | ||
| 39 | * Each architecture has to provide the following macros. They must access | ||
| 40 | * the hardware directly and not rely on any other (XIP) functions since they | ||
| 41 | * won't be available when used (flash not in array mode). | ||
| 42 | * | ||
| 43 | * xip_irqpending() | ||
| 44 | * | ||
| 45 | * return non zero when any hardware interrupt is pending. | ||
| 46 | * | ||
| 47 | * xip_currtime() | ||
| 48 | * | ||
| 49 | * return a platform specific time reference to be used with | ||
| 50 | * xip_elapsed_since(). | ||
| 51 | * | ||
| 52 | * xip_elapsed_since(x) | ||
| 53 | * | ||
| 54 | * return in usecs the elapsed timebetween now and the reference x as | ||
| 55 | * returned by xip_currtime(). | ||
| 56 | * | ||
| 57 | * note 1: convertion to usec can be approximated, as long as the | ||
| 58 | * returned value is <= the real elapsed time. | ||
| 59 | * note 2: this should be able to cope with a few seconds without | ||
| 60 | * overflowing. | ||
| 61 | */ | ||
| 62 | |||
| 63 | #if defined(CONFIG_ARCH_SA1100) || defined(CONFIG_ARCH_PXA) | ||
| 64 | |||
| 65 | #include <asm/hardware.h> | ||
| 66 | #ifdef CONFIG_ARCH_PXA | ||
| 67 | #include <asm/arch/pxa-regs.h> | ||
| 68 | #endif | ||
| 69 | |||
| 70 | #define xip_irqpending() (ICIP & ICMR) | ||
| 71 | |||
| 72 | /* we sample OSCR and convert desired delta to usec (1/4 ~= 1000000/3686400) */ | ||
| 73 | #define xip_currtime() (OSCR) | ||
| 74 | #define xip_elapsed_since(x) (signed)((OSCR - (x)) / 4) | ||
| 75 | |||
| 76 | #else | ||
| 77 | |||
| 78 | #warning "missing IRQ and timer primitives for XIP MTD support" | ||
| 79 | #warning "some of the XIP MTD support code will be disabled" | ||
| 80 | #warning "your system will therefore be unresponsive when writing or erasing flash" | ||
| 81 | |||
| 82 | #define xip_irqpending() (0) | ||
| 83 | #define xip_currtime() (0) | ||
| 84 | #define xip_elapsed_since(x) (0) | ||
| 85 | |||
| 86 | #endif | ||
| 87 | |||
| 88 | /* | ||
| 89 | * xip_cpu_idle() is used when waiting for a delay equal or larger than | ||
| 90 | * the system timer tick period. This should put the CPU into idle mode | ||
| 91 | * to save power and to be woken up only when some interrupts are pending. | ||
| 92 | * As above, this should not rely upon standard kernel code. | ||
| 93 | */ | ||
| 94 | |||
| 95 | #if defined(CONFIG_CPU_XSCALE) | ||
| 96 | #define xip_cpu_idle() asm volatile ("mcr p14, 0, %0, c7, c0, 0" :: "r" (1)) | ||
| 97 | #else | ||
| 98 | #define xip_cpu_idle() do { } while (0) | ||
| 99 | #endif | ||
| 100 | |||
| 101 | #else | ||
| 102 | |||
| 103 | #define __xipram | ||
| 104 | |||
| 105 | #endif /* CONFIG_MTD_XIP */ | ||
| 106 | |||
| 107 | #endif /* __LINUX_MTD_XIP_H__ */ | ||
