diff options
| author | Takashi Iwai <tiwai@suse.de> | 2012-01-31 09:13:14 -0500 |
|---|---|---|
| committer | Takashi Iwai <tiwai@suse.de> | 2012-01-31 09:13:14 -0500 |
| commit | ea51e5040e24eefe44d70bc654a237ca1f0225b0 (patch) | |
| tree | df2e5922dcdfafae62a10d8cd97f98121064fc23 /include/linux/mtd | |
| parent | 3422a47041b8cb8f14ac1e3926bcf711121df6dc (diff) | |
| parent | 8dbd52daee38adaae4d5a674bcca837e694a4f4c (diff) | |
Merge branch 'fix/asoc' into for-linus
Diffstat (limited to 'include/linux/mtd')
| -rw-r--r-- | include/linux/mtd/cfi.h | 16 | ||||
| -rw-r--r-- | include/linux/mtd/cfi_endian.h | 76 | ||||
| -rw-r--r-- | include/linux/mtd/gpmi-nand.h | 68 | ||||
| -rw-r--r-- | include/linux/mtd/map.h | 3 | ||||
| -rw-r--r-- | include/linux/mtd/mtd.h | 334 | ||||
| -rw-r--r-- | include/linux/mtd/nand.h | 1 | ||||
| -rw-r--r-- | include/linux/mtd/physmap.h | 1 |
7 files changed, 364 insertions, 135 deletions
diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h index d24925492972..d5d2ec6494bb 100644 --- a/include/linux/mtd/cfi.h +++ b/include/linux/mtd/cfi.h | |||
| @@ -354,10 +354,10 @@ static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cf | |||
| 354 | onecmd = cmd; | 354 | onecmd = cmd; |
| 355 | break; | 355 | break; |
| 356 | case 2: | 356 | case 2: |
| 357 | onecmd = cpu_to_cfi16(cmd); | 357 | onecmd = cpu_to_cfi16(map, cmd); |
| 358 | break; | 358 | break; |
| 359 | case 4: | 359 | case 4: |
| 360 | onecmd = cpu_to_cfi32(cmd); | 360 | onecmd = cpu_to_cfi32(map, cmd); |
| 361 | break; | 361 | break; |
| 362 | } | 362 | } |
| 363 | 363 | ||
| @@ -437,10 +437,10 @@ static inline unsigned long cfi_merge_status(map_word val, struct map_info *map, | |||
| 437 | case 1: | 437 | case 1: |
| 438 | break; | 438 | break; |
| 439 | case 2: | 439 | case 2: |
| 440 | res = cfi16_to_cpu(res); | 440 | res = cfi16_to_cpu(map, res); |
| 441 | break; | 441 | break; |
| 442 | case 4: | 442 | case 4: |
| 443 | res = cfi32_to_cpu(res); | 443 | res = cfi32_to_cpu(map, res); |
| 444 | break; | 444 | break; |
| 445 | default: BUG(); | 445 | default: BUG(); |
| 446 | } | 446 | } |
| @@ -480,12 +480,12 @@ static inline uint8_t cfi_read_query(struct map_info *map, uint32_t addr) | |||
| 480 | if (map_bankwidth_is_1(map)) { | 480 | if (map_bankwidth_is_1(map)) { |
| 481 | return val.x[0]; | 481 | return val.x[0]; |
| 482 | } else if (map_bankwidth_is_2(map)) { | 482 | } else if (map_bankwidth_is_2(map)) { |
| 483 | return cfi16_to_cpu(val.x[0]); | 483 | return cfi16_to_cpu(map, val.x[0]); |
| 484 | } else { | 484 | } else { |
| 485 | /* No point in a 64-bit byteswap since that would just be | 485 | /* No point in a 64-bit byteswap since that would just be |
| 486 | swapping the responses from different chips, and we are | 486 | swapping the responses from different chips, and we are |
| 487 | only interested in one chip (a representative sample) */ | 487 | only interested in one chip (a representative sample) */ |
| 488 | return cfi32_to_cpu(val.x[0]); | 488 | return cfi32_to_cpu(map, val.x[0]); |
| 489 | } | 489 | } |
| 490 | } | 490 | } |
| 491 | 491 | ||
| @@ -496,12 +496,12 @@ static inline uint16_t cfi_read_query16(struct map_info *map, uint32_t addr) | |||
| 496 | if (map_bankwidth_is_1(map)) { | 496 | if (map_bankwidth_is_1(map)) { |
| 497 | return val.x[0] & 0xff; | 497 | return val.x[0] & 0xff; |
| 498 | } else if (map_bankwidth_is_2(map)) { | 498 | } else if (map_bankwidth_is_2(map)) { |
| 499 | return cfi16_to_cpu(val.x[0]); | 499 | return cfi16_to_cpu(map, val.x[0]); |
| 500 | } else { | 500 | } else { |
| 501 | /* No point in a 64-bit byteswap since that would just be | 501 | /* No point in a 64-bit byteswap since that would just be |
| 502 | swapping the responses from different chips, and we are | 502 | swapping the responses from different chips, and we are |
| 503 | only interested in one chip (a representative sample) */ | 503 | only interested in one chip (a representative sample) */ |
| 504 | return cfi32_to_cpu(val.x[0]); | 504 | return cfi32_to_cpu(map, val.x[0]); |
| 505 | } | 505 | } |
| 506 | } | 506 | } |
| 507 | 507 | ||
diff --git a/include/linux/mtd/cfi_endian.h b/include/linux/mtd/cfi_endian.h index 51cc3f5917a8..b97a625071f8 100644 --- a/include/linux/mtd/cfi_endian.h +++ b/include/linux/mtd/cfi_endian.h | |||
| @@ -19,53 +19,35 @@ | |||
| 19 | 19 | ||
| 20 | #include <asm/byteorder.h> | 20 | #include <asm/byteorder.h> |
| 21 | 21 | ||
| 22 | #ifndef CONFIG_MTD_CFI_ADV_OPTIONS | 22 | #define CFI_HOST_ENDIAN 1 |
| 23 | 23 | #define CFI_LITTLE_ENDIAN 2 | |
| 24 | #define CFI_HOST_ENDIAN | 24 | #define CFI_BIG_ENDIAN 3 |
| 25 | 25 | ||
| 26 | #else | 26 | #if !defined(CONFIG_MTD_CFI_ADV_OPTIONS) || defined(CONFIG_MTD_CFI_NOSWAP) |
| 27 | 27 | #define CFI_DEFAULT_ENDIAN CFI_HOST_ENDIAN | |
| 28 | #ifdef CONFIG_MTD_CFI_NOSWAP | 28 | #elif defined(CONFIG_MTD_CFI_LE_BYTE_SWAP) |
| 29 | #define CFI_HOST_ENDIAN | 29 | #define CFI_DEFAULT_ENDIAN CFI_LITTLE_ENDIAN |
| 30 | #endif | 30 | #elif defined(CONFIG_MTD_CFI_BE_BYTE_SWAP) |
| 31 | 31 | #define CFI_DEFAULT_ENDIAN CFI_BIG_ENDIAN | |
| 32 | #ifdef CONFIG_MTD_CFI_LE_BYTE_SWAP | ||
| 33 | #define CFI_LITTLE_ENDIAN | ||
| 34 | #endif | ||
| 35 | |||
| 36 | #ifdef CONFIG_MTD_CFI_BE_BYTE_SWAP | ||
| 37 | #define CFI_BIG_ENDIAN | ||
| 38 | #endif | ||
| 39 | |||
| 40 | #endif | ||
| 41 | |||
| 42 | #if defined(CFI_LITTLE_ENDIAN) | ||
| 43 | #define cpu_to_cfi8(x) (x) | ||
| 44 | #define cfi8_to_cpu(x) (x) | ||
| 45 | #define cpu_to_cfi16(x) cpu_to_le16(x) | ||
| 46 | #define cpu_to_cfi32(x) cpu_to_le32(x) | ||
| 47 | #define cpu_to_cfi64(x) cpu_to_le64(x) | ||
| 48 | #define cfi16_to_cpu(x) le16_to_cpu(x) | ||
| 49 | #define cfi32_to_cpu(x) le32_to_cpu(x) | ||
| 50 | #define cfi64_to_cpu(x) le64_to_cpu(x) | ||
| 51 | #elif defined (CFI_BIG_ENDIAN) | ||
| 52 | #define cpu_to_cfi8(x) (x) | ||
| 53 | #define cfi8_to_cpu(x) (x) | ||
| 54 | #define cpu_to_cfi16(x) cpu_to_be16(x) | ||
| 55 | #define cpu_to_cfi32(x) cpu_to_be32(x) | ||
| 56 | #define cpu_to_cfi64(x) cpu_to_be64(x) | ||
| 57 | #define cfi16_to_cpu(x) be16_to_cpu(x) | ||
| 58 | #define cfi32_to_cpu(x) be32_to_cpu(x) | ||
| 59 | #define cfi64_to_cpu(x) be64_to_cpu(x) | ||
| 60 | #elif defined (CFI_HOST_ENDIAN) | ||
| 61 | #define cpu_to_cfi8(x) (x) | ||
| 62 | #define cfi8_to_cpu(x) (x) | ||
| 63 | #define cpu_to_cfi16(x) (x) | ||
| 64 | #define cpu_to_cfi32(x) (x) | ||
| 65 | #define cpu_to_cfi64(x) (x) | ||
| 66 | #define cfi16_to_cpu(x) (x) | ||
| 67 | #define cfi32_to_cpu(x) (x) | ||
| 68 | #define cfi64_to_cpu(x) (x) | ||
| 69 | #else | 32 | #else |
| 70 | #error No CFI endianness defined | 33 | #error No CFI endianness defined |
| 71 | #endif | 34 | #endif |
| 35 | |||
| 36 | #define cfi_default(s) ((s)?:CFI_DEFAULT_ENDIAN) | ||
| 37 | #define cfi_be(s) (cfi_default(s) == CFI_BIG_ENDIAN) | ||
| 38 | #define cfi_le(s) (cfi_default(s) == CFI_LITTLE_ENDIAN) | ||
| 39 | #define cfi_host(s) (cfi_default(s) == CFI_HOST_ENDIAN) | ||
| 40 | |||
| 41 | #define cpu_to_cfi8(map, x) (x) | ||
| 42 | #define cfi8_to_cpu(map, x) (x) | ||
| 43 | #define cpu_to_cfi16(map, x) _cpu_to_cfi(16, (map)->swap, (x)) | ||
| 44 | #define cpu_to_cfi32(map, x) _cpu_to_cfi(32, (map)->swap, (x)) | ||
| 45 | #define cpu_to_cfi64(map, x) _cpu_to_cfi(64, (map)->swap, (x)) | ||
| 46 | #define cfi16_to_cpu(map, x) _cfi_to_cpu(16, (map)->swap, (x)) | ||
| 47 | #define cfi32_to_cpu(map, x) _cfi_to_cpu(32, (map)->swap, (x)) | ||
| 48 | #define cfi64_to_cpu(map, x) _cfi_to_cpu(64, (map)->swap, (x)) | ||
| 49 | |||
| 50 | #define _cpu_to_cfi(w, s, x) (cfi_host(s)?(x):_swap_to_cfi(w, s, x)) | ||
| 51 | #define _cfi_to_cpu(w, s, x) (cfi_host(s)?(x):_swap_to_cpu(w, s, x)) | ||
| 52 | #define _swap_to_cfi(w, s, x) (cfi_be(s)?cpu_to_be##w(x):cpu_to_le##w(x)) | ||
| 53 | #define _swap_to_cpu(w, s, x) (cfi_be(s)?be##w##_to_cpu(x):le##w##_to_cpu(x)) | ||
diff --git a/include/linux/mtd/gpmi-nand.h b/include/linux/mtd/gpmi-nand.h new file mode 100644 index 000000000000..69b6dbf46b5e --- /dev/null +++ b/include/linux/mtd/gpmi-nand.h | |||
| @@ -0,0 +1,68 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; either version 2 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License along | ||
| 15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #ifndef __MACH_MXS_GPMI_NAND_H__ | ||
| 20 | #define __MACH_MXS_GPMI_NAND_H__ | ||
| 21 | |||
| 22 | /* The size of the resources is fixed. */ | ||
| 23 | #define GPMI_NAND_RES_SIZE 6 | ||
| 24 | |||
| 25 | /* Resource names for the GPMI NAND driver. */ | ||
| 26 | #define GPMI_NAND_GPMI_REGS_ADDR_RES_NAME "GPMI NAND GPMI Registers" | ||
| 27 | #define GPMI_NAND_GPMI_INTERRUPT_RES_NAME "GPMI NAND GPMI Interrupt" | ||
| 28 | #define GPMI_NAND_BCH_REGS_ADDR_RES_NAME "GPMI NAND BCH Registers" | ||
| 29 | #define GPMI_NAND_BCH_INTERRUPT_RES_NAME "GPMI NAND BCH Interrupt" | ||
| 30 | #define GPMI_NAND_DMA_CHANNELS_RES_NAME "GPMI NAND DMA Channels" | ||
| 31 | #define GPMI_NAND_DMA_INTERRUPT_RES_NAME "GPMI NAND DMA Interrupt" | ||
| 32 | |||
| 33 | /** | ||
| 34 | * struct gpmi_nand_platform_data - GPMI NAND driver platform data. | ||
| 35 | * | ||
| 36 | * This structure communicates platform-specific information to the GPMI NAND | ||
| 37 | * driver that can't be expressed as resources. | ||
| 38 | * | ||
| 39 | * @platform_init: A pointer to a function the driver will call to | ||
| 40 | * initialize the platform (e.g., set up the pin mux). | ||
| 41 | * @min_prop_delay_in_ns: Minimum propagation delay of GPMI signals to and | ||
| 42 | * from the NAND Flash device, in nanoseconds. | ||
| 43 | * @max_prop_delay_in_ns: Maximum propagation delay of GPMI signals to and | ||
| 44 | * from the NAND Flash device, in nanoseconds. | ||
| 45 | * @max_chip_count: The maximum number of chips for which the driver | ||
| 46 | * should configure the hardware. This value most | ||
| 47 | * likely reflects the number of pins that are | ||
| 48 | * connected to a NAND Flash device. If this is | ||
| 49 | * greater than the SoC hardware can support, the | ||
| 50 | * driver will print a message and fail to initialize. | ||
| 51 | * @partitions: An optional pointer to an array of partition | ||
| 52 | * descriptions. | ||
| 53 | * @partition_count: The number of elements in the partitions array. | ||
| 54 | */ | ||
| 55 | struct gpmi_nand_platform_data { | ||
| 56 | /* SoC hardware information. */ | ||
| 57 | int (*platform_init)(void); | ||
| 58 | |||
| 59 | /* NAND Flash information. */ | ||
| 60 | unsigned int min_prop_delay_in_ns; | ||
| 61 | unsigned int max_prop_delay_in_ns; | ||
| 62 | unsigned int max_chip_count; | ||
| 63 | |||
| 64 | /* Medium information. */ | ||
| 65 | struct mtd_partition *partitions; | ||
| 66 | unsigned partition_count; | ||
| 67 | }; | ||
| 68 | #endif | ||
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h index a9e6ba46865e..94e924e2ecd5 100644 --- a/include/linux/mtd/map.h +++ b/include/linux/mtd/map.h | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | #include <linux/list.h> | 26 | #include <linux/list.h> |
| 27 | #include <linux/string.h> | 27 | #include <linux/string.h> |
| 28 | #include <linux/bug.h> | 28 | #include <linux/bug.h> |
| 29 | 29 | #include <linux/kernel.h> | |
| 30 | 30 | ||
| 31 | #include <asm/unaligned.h> | 31 | #include <asm/unaligned.h> |
| 32 | #include <asm/system.h> | 32 | #include <asm/system.h> |
| @@ -214,6 +214,7 @@ struct map_info { | |||
| 214 | void __iomem *virt; | 214 | void __iomem *virt; |
| 215 | void *cached; | 215 | void *cached; |
| 216 | 216 | ||
| 217 | int swap; /* this mapping's byte-swapping requirement */ | ||
| 217 | int bankwidth; /* in octets. This isn't necessarily the width | 218 | int bankwidth; /* in octets. This isn't necessarily the width |
| 218 | of actual bus cycles -- it's the repeat interval | 219 | of actual bus cycles -- it's the repeat interval |
| 219 | in bytes, before you are talking to the first chip again. | 220 | in bytes, before you are talking to the first chip again. |
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 9f5b312af783..1a81fde8f333 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h | |||
| @@ -171,87 +171,60 @@ struct mtd_info { | |||
| 171 | struct mtd_erase_region_info *eraseregions; | 171 | struct mtd_erase_region_info *eraseregions; |
| 172 | 172 | ||
| 173 | /* | 173 | /* |
| 174 | * Erase is an asynchronous operation. Device drivers are supposed | 174 | * Do not call via these pointers, use corresponding mtd_*() |
| 175 | * to call instr->callback() whenever the operation completes, even | 175 | * wrappers instead. |
| 176 | * if it completes with a failure. | ||
| 177 | * Callers are supposed to pass a callback function and wait for it | ||
| 178 | * to be called before writing to the block. | ||
| 179 | */ | 176 | */ |
| 180 | int (*erase) (struct mtd_info *mtd, struct erase_info *instr); | 177 | int (*erase) (struct mtd_info *mtd, struct erase_info *instr); |
| 181 | |||
| 182 | /* This stuff for eXecute-In-Place */ | ||
| 183 | /* phys is optional and may be set to NULL */ | ||
| 184 | int (*point) (struct mtd_info *mtd, loff_t from, size_t len, | 178 | int (*point) (struct mtd_info *mtd, loff_t from, size_t len, |
| 185 | size_t *retlen, void **virt, resource_size_t *phys); | 179 | size_t *retlen, void **virt, resource_size_t *phys); |
| 186 | |||
| 187 | /* We probably shouldn't allow XIP if the unpoint isn't a NULL */ | ||
| 188 | void (*unpoint) (struct mtd_info *mtd, loff_t from, size_t len); | 180 | void (*unpoint) (struct mtd_info *mtd, loff_t from, size_t len); |
| 189 | |||
| 190 | /* Allow NOMMU mmap() to directly map the device (if not NULL) | ||
| 191 | * - return the address to which the offset maps | ||
| 192 | * - return -ENOSYS to indicate refusal to do the mapping | ||
| 193 | */ | ||
| 194 | unsigned long (*get_unmapped_area) (struct mtd_info *mtd, | 181 | unsigned long (*get_unmapped_area) (struct mtd_info *mtd, |
| 195 | unsigned long len, | 182 | unsigned long len, |
| 196 | unsigned long offset, | 183 | unsigned long offset, |
| 197 | unsigned long flags); | 184 | unsigned long flags); |
| 198 | 185 | int (*read) (struct mtd_info *mtd, loff_t from, size_t len, | |
| 199 | /* Backing device capabilities for this device | 186 | size_t *retlen, u_char *buf); |
| 200 | * - provides mmap capabilities | 187 | int (*write) (struct mtd_info *mtd, loff_t to, size_t len, |
| 201 | */ | 188 | size_t *retlen, const u_char *buf); |
| 202 | struct backing_dev_info *backing_dev_info; | 189 | int (*panic_write) (struct mtd_info *mtd, loff_t to, size_t len, |
| 203 | 190 | size_t *retlen, const u_char *buf); | |
| 204 | |||
| 205 | int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); | ||
| 206 | int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); | ||
| 207 | |||
| 208 | /* In blackbox flight recorder like scenarios we want to make successful | ||
| 209 | writes in interrupt context. panic_write() is only intended to be | ||
| 210 | called when its known the kernel is about to panic and we need the | ||
| 211 | write to succeed. Since the kernel is not going to be running for much | ||
| 212 | longer, this function can break locks and delay to ensure the write | ||
| 213 | succeeds (but not sleep). */ | ||
| 214 | |||
| 215 | int (*panic_write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); | ||
| 216 | |||
| 217 | int (*read_oob) (struct mtd_info *mtd, loff_t from, | 191 | int (*read_oob) (struct mtd_info *mtd, loff_t from, |
| 218 | struct mtd_oob_ops *ops); | 192 | struct mtd_oob_ops *ops); |
| 219 | int (*write_oob) (struct mtd_info *mtd, loff_t to, | 193 | int (*write_oob) (struct mtd_info *mtd, loff_t to, |
| 220 | struct mtd_oob_ops *ops); | 194 | struct mtd_oob_ops *ops); |
| 221 | 195 | int (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, | |
| 222 | /* | 196 | size_t len); |
| 223 | * Methods to access the protection register area, present in some | 197 | int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, |
| 224 | * flash devices. The user data is one time programmable but the | 198 | size_t len, size_t *retlen, u_char *buf); |
| 225 | * factory data is read only. | 199 | int (*get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf, |
| 226 | */ | 200 | size_t len); |
| 227 | int (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len); | 201 | int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, |
| 228 | int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); | 202 | size_t len, size_t *retlen, u_char *buf); |
| 229 | int (*get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len); | 203 | int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t to, size_t len, |
| 230 | int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); | 204 | size_t *retlen, u_char *buf); |
| 231 | int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); | 205 | int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, |
| 232 | int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len); | 206 | size_t len); |
| 233 | 207 | int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, | |
| 234 | /* kvec-based read/write methods. | 208 | unsigned long count, loff_t to, size_t *retlen); |
| 235 | NB: The 'count' parameter is the number of _vectors_, each of | ||
| 236 | which contains an (ofs, len) tuple. | ||
| 237 | */ | ||
| 238 | int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen); | ||
| 239 | |||
| 240 | /* Sync */ | ||
| 241 | void (*sync) (struct mtd_info *mtd); | 209 | void (*sync) (struct mtd_info *mtd); |
| 242 | |||
| 243 | /* Chip-supported device locking */ | ||
| 244 | int (*lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len); | 210 | int (*lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len); |
| 245 | int (*unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len); | 211 | int (*unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len); |
| 246 | int (*is_locked) (struct mtd_info *mtd, loff_t ofs, uint64_t len); | 212 | int (*is_locked) (struct mtd_info *mtd, loff_t ofs, uint64_t len); |
| 247 | 213 | int (*block_isbad) (struct mtd_info *mtd, loff_t ofs); | |
| 248 | /* Power Management functions */ | 214 | int (*block_markbad) (struct mtd_info *mtd, loff_t ofs); |
| 249 | int (*suspend) (struct mtd_info *mtd); | 215 | int (*suspend) (struct mtd_info *mtd); |
| 250 | void (*resume) (struct mtd_info *mtd); | 216 | void (*resume) (struct mtd_info *mtd); |
| 217 | /* | ||
| 218 | * If the driver is something smart, like UBI, it may need to maintain | ||
| 219 | * its own reference counting. The below functions are only for driver. | ||
| 220 | */ | ||
| 221 | int (*get_device) (struct mtd_info *mtd); | ||
| 222 | void (*put_device) (struct mtd_info *mtd); | ||
| 251 | 223 | ||
| 252 | /* Bad block management functions */ | 224 | /* Backing device capabilities for this device |
| 253 | int (*block_isbad) (struct mtd_info *mtd, loff_t ofs); | 225 | * - provides mmap capabilities |
| 254 | int (*block_markbad) (struct mtd_info *mtd, loff_t ofs); | 226 | */ |
| 227 | struct backing_dev_info *backing_dev_info; | ||
| 255 | 228 | ||
| 256 | struct notifier_block reboot_notifier; /* default mode before reboot */ | 229 | struct notifier_block reboot_notifier; /* default mode before reboot */ |
| 257 | 230 | ||
| @@ -265,18 +238,218 @@ struct mtd_info { | |||
| 265 | struct module *owner; | 238 | struct module *owner; |
| 266 | struct device dev; | 239 | struct device dev; |
| 267 | int usecount; | 240 | int usecount; |
| 268 | |||
| 269 | /* If the driver is something smart, like UBI, it may need to maintain | ||
| 270 | * its own reference counting. The below functions are only for driver. | ||
| 271 | * The driver may register its callbacks. These callbacks are not | ||
| 272 | * supposed to be called by MTD users */ | ||
| 273 | int (*get_device) (struct mtd_info *mtd); | ||
| 274 | void (*put_device) (struct mtd_info *mtd); | ||
| 275 | }; | 241 | }; |
| 276 | 242 | ||
| 277 | static inline struct mtd_info *dev_to_mtd(struct device *dev) | 243 | /* |
| 244 | * Erase is an asynchronous operation. Device drivers are supposed | ||
| 245 | * to call instr->callback() whenever the operation completes, even | ||
| 246 | * if it completes with a failure. | ||
| 247 | * Callers are supposed to pass a callback function and wait for it | ||
| 248 | * to be called before writing to the block. | ||
| 249 | */ | ||
| 250 | static inline int mtd_erase(struct mtd_info *mtd, struct erase_info *instr) | ||
| 251 | { | ||
| 252 | return mtd->erase(mtd, instr); | ||
| 253 | } | ||
| 254 | |||
| 255 | /* | ||
| 256 | * This stuff for eXecute-In-Place. phys is optional and may be set to NULL. | ||
| 257 | */ | ||
| 258 | static inline int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, | ||
| 259 | size_t *retlen, void **virt, resource_size_t *phys) | ||
| 260 | { | ||
| 261 | *retlen = 0; | ||
| 262 | if (!mtd->point) | ||
| 263 | return -EOPNOTSUPP; | ||
| 264 | return mtd->point(mtd, from, len, retlen, virt, phys); | ||
| 265 | } | ||
| 266 | |||
| 267 | /* We probably shouldn't allow XIP if the unpoint isn't a NULL */ | ||
| 268 | static inline void mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len) | ||
| 278 | { | 269 | { |
| 279 | return dev ? dev_get_drvdata(dev) : NULL; | 270 | return mtd->unpoint(mtd, from, len); |
| 271 | } | ||
| 272 | |||
| 273 | /* | ||
| 274 | * Allow NOMMU mmap() to directly map the device (if not NULL) | ||
| 275 | * - return the address to which the offset maps | ||
| 276 | * - return -ENOSYS to indicate refusal to do the mapping | ||
| 277 | */ | ||
| 278 | static inline unsigned long mtd_get_unmapped_area(struct mtd_info *mtd, | ||
| 279 | unsigned long len, | ||
| 280 | unsigned long offset, | ||
| 281 | unsigned long flags) | ||
| 282 | { | ||
| 283 | if (!mtd->get_unmapped_area) | ||
| 284 | return -EOPNOTSUPP; | ||
| 285 | return mtd->get_unmapped_area(mtd, len, offset, flags); | ||
| 286 | } | ||
| 287 | |||
| 288 | static inline int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, | ||
| 289 | size_t *retlen, u_char *buf) | ||
| 290 | { | ||
| 291 | return mtd->read(mtd, from, len, retlen, buf); | ||
| 292 | } | ||
| 293 | |||
| 294 | static inline int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, | ||
| 295 | size_t *retlen, const u_char *buf) | ||
| 296 | { | ||
| 297 | *retlen = 0; | ||
| 298 | if (!mtd->write) | ||
| 299 | return -EROFS; | ||
| 300 | return mtd->write(mtd, to, len, retlen, buf); | ||
| 301 | } | ||
| 302 | |||
| 303 | /* | ||
| 304 | * In blackbox flight recorder like scenarios we want to make successful writes | ||
| 305 | * in interrupt context. panic_write() is only intended to be called when its | ||
| 306 | * known the kernel is about to panic and we need the write to succeed. Since | ||
| 307 | * the kernel is not going to be running for much longer, this function can | ||
| 308 | * break locks and delay to ensure the write succeeds (but not sleep). | ||
| 309 | */ | ||
| 310 | static inline int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, | ||
| 311 | size_t *retlen, const u_char *buf) | ||
| 312 | { | ||
| 313 | *retlen = 0; | ||
| 314 | if (!mtd->panic_write) | ||
| 315 | return -EOPNOTSUPP; | ||
| 316 | return mtd->panic_write(mtd, to, len, retlen, buf); | ||
| 317 | } | ||
| 318 | |||
| 319 | static inline int mtd_read_oob(struct mtd_info *mtd, loff_t from, | ||
| 320 | struct mtd_oob_ops *ops) | ||
| 321 | { | ||
| 322 | ops->retlen = ops->oobretlen = 0; | ||
| 323 | if (!mtd->read_oob) | ||
| 324 | return -EOPNOTSUPP; | ||
| 325 | return mtd->read_oob(mtd, from, ops); | ||
| 326 | } | ||
| 327 | |||
| 328 | static inline int mtd_write_oob(struct mtd_info *mtd, loff_t to, | ||
| 329 | struct mtd_oob_ops *ops) | ||
| 330 | { | ||
| 331 | ops->retlen = ops->oobretlen = 0; | ||
| 332 | if (!mtd->write_oob) | ||
| 333 | return -EOPNOTSUPP; | ||
| 334 | return mtd->write_oob(mtd, to, ops); | ||
| 335 | } | ||
| 336 | |||
| 337 | /* | ||
| 338 | * Method to access the protection register area, present in some flash | ||
| 339 | * devices. The user data is one time programmable but the factory data is read | ||
| 340 | * only. | ||
| 341 | */ | ||
| 342 | static inline int mtd_get_fact_prot_info(struct mtd_info *mtd, | ||
| 343 | struct otp_info *buf, size_t len) | ||
| 344 | { | ||
| 345 | if (!mtd->get_fact_prot_info) | ||
| 346 | return -EOPNOTSUPP; | ||
| 347 | return mtd->get_fact_prot_info(mtd, buf, len); | ||
| 348 | } | ||
| 349 | |||
| 350 | static inline int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, | ||
| 351 | size_t len, size_t *retlen, | ||
| 352 | u_char *buf) | ||
| 353 | { | ||
| 354 | *retlen = 0; | ||
| 355 | if (!mtd->read_fact_prot_reg) | ||
| 356 | return -EOPNOTSUPP; | ||
| 357 | return mtd->read_fact_prot_reg(mtd, from, len, retlen, buf); | ||
| 358 | } | ||
| 359 | |||
| 360 | static inline int mtd_get_user_prot_info(struct mtd_info *mtd, | ||
| 361 | struct otp_info *buf, | ||
| 362 | size_t len) | ||
| 363 | { | ||
| 364 | if (!mtd->get_user_prot_info) | ||
| 365 | return -EOPNOTSUPP; | ||
| 366 | return mtd->get_user_prot_info(mtd, buf, len); | ||
| 367 | } | ||
| 368 | |||
| 369 | static inline int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from, | ||
| 370 | size_t len, size_t *retlen, | ||
| 371 | u_char *buf) | ||
| 372 | { | ||
| 373 | *retlen = 0; | ||
| 374 | if (!mtd->read_user_prot_reg) | ||
| 375 | return -EOPNOTSUPP; | ||
| 376 | return mtd->read_user_prot_reg(mtd, from, len, retlen, buf); | ||
| 377 | } | ||
| 378 | |||
| 379 | static inline int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, | ||
| 380 | size_t len, size_t *retlen, | ||
| 381 | u_char *buf) | ||
| 382 | { | ||
| 383 | *retlen = 0; | ||
| 384 | if (!mtd->write_user_prot_reg) | ||
| 385 | return -EOPNOTSUPP; | ||
| 386 | return mtd->write_user_prot_reg(mtd, to, len, retlen, buf); | ||
| 387 | } | ||
| 388 | |||
| 389 | static inline int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, | ||
| 390 | size_t len) | ||
| 391 | { | ||
| 392 | if (!mtd->lock_user_prot_reg) | ||
| 393 | return -EOPNOTSUPP; | ||
| 394 | return mtd->lock_user_prot_reg(mtd, from, len); | ||
| 395 | } | ||
| 396 | |||
| 397 | int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, | ||
| 398 | unsigned long count, loff_t to, size_t *retlen); | ||
| 399 | |||
| 400 | static inline void mtd_sync(struct mtd_info *mtd) | ||
| 401 | { | ||
| 402 | if (mtd->sync) | ||
| 403 | mtd->sync(mtd); | ||
| 404 | } | ||
| 405 | |||
| 406 | /* Chip-supported device locking */ | ||
| 407 | static inline int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) | ||
| 408 | { | ||
| 409 | if (!mtd->lock) | ||
| 410 | return -EOPNOTSUPP; | ||
| 411 | return mtd->lock(mtd, ofs, len); | ||
| 412 | } | ||
| 413 | |||
| 414 | static inline int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) | ||
| 415 | { | ||
| 416 | if (!mtd->unlock) | ||
| 417 | return -EOPNOTSUPP; | ||
| 418 | return mtd->unlock(mtd, ofs, len); | ||
| 419 | } | ||
| 420 | |||
| 421 | static inline int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) | ||
| 422 | { | ||
| 423 | if (!mtd->is_locked) | ||
| 424 | return -EOPNOTSUPP; | ||
| 425 | return mtd->is_locked(mtd, ofs, len); | ||
| 426 | } | ||
| 427 | |||
| 428 | static inline int mtd_suspend(struct mtd_info *mtd) | ||
| 429 | { | ||
| 430 | if (!mtd->suspend) | ||
| 431 | return -EOPNOTSUPP; | ||
| 432 | return mtd->suspend(mtd); | ||
| 433 | } | ||
| 434 | |||
| 435 | static inline void mtd_resume(struct mtd_info *mtd) | ||
| 436 | { | ||
| 437 | if (mtd->resume) | ||
| 438 | mtd->resume(mtd); | ||
| 439 | } | ||
| 440 | |||
| 441 | static inline int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs) | ||
| 442 | { | ||
| 443 | if (!mtd->block_isbad) | ||
| 444 | return -EOPNOTSUPP; | ||
| 445 | return mtd->block_isbad(mtd, ofs); | ||
| 446 | } | ||
| 447 | |||
| 448 | static inline int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs) | ||
| 449 | { | ||
| 450 | if (!mtd->block_markbad) | ||
| 451 | return -EOPNOTSUPP; | ||
| 452 | return mtd->block_markbad(mtd, ofs); | ||
| 280 | } | 453 | } |
| 281 | 454 | ||
| 282 | static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd) | 455 | static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd) |
| @@ -309,6 +482,16 @@ static inline uint32_t mtd_mod_by_ws(uint64_t sz, struct mtd_info *mtd) | |||
| 309 | return do_div(sz, mtd->writesize); | 482 | return do_div(sz, mtd->writesize); |
| 310 | } | 483 | } |
| 311 | 484 | ||
| 485 | static inline int mtd_has_oob(const struct mtd_info *mtd) | ||
| 486 | { | ||
| 487 | return mtd->read_oob && mtd->write_oob; | ||
| 488 | } | ||
| 489 | |||
| 490 | static inline int mtd_can_have_bb(const struct mtd_info *mtd) | ||
| 491 | { | ||
| 492 | return !!mtd->block_isbad; | ||
| 493 | } | ||
| 494 | |||
| 312 | /* Kernel-side ioctl definitions */ | 495 | /* Kernel-side ioctl definitions */ |
| 313 | 496 | ||
| 314 | struct mtd_partition; | 497 | struct mtd_partition; |
| @@ -338,13 +521,6 @@ struct mtd_notifier { | |||
| 338 | 521 | ||
| 339 | extern void register_mtd_user (struct mtd_notifier *new); | 522 | extern void register_mtd_user (struct mtd_notifier *new); |
| 340 | extern int unregister_mtd_user (struct mtd_notifier *old); | 523 | extern int unregister_mtd_user (struct mtd_notifier *old); |
| 341 | |||
| 342 | int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, | ||
| 343 | unsigned long count, loff_t to, size_t *retlen); | ||
| 344 | |||
| 345 | int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs, | ||
| 346 | unsigned long count, loff_t from, size_t *retlen); | ||
| 347 | |||
| 348 | void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size); | 524 | void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size); |
| 349 | 525 | ||
| 350 | void mtd_erase_callback(struct erase_info *instr); | 526 | void mtd_erase_callback(struct erase_info *instr); |
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 904131bab501..63b5a8b6dfbd 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h | |||
| @@ -555,6 +555,7 @@ struct nand_chip { | |||
| 555 | #define NAND_MFR_HYNIX 0xad | 555 | #define NAND_MFR_HYNIX 0xad |
| 556 | #define NAND_MFR_MICRON 0x2c | 556 | #define NAND_MFR_MICRON 0x2c |
| 557 | #define NAND_MFR_AMD 0x01 | 557 | #define NAND_MFR_AMD 0x01 |
| 558 | #define NAND_MFR_MACRONIX 0xc2 | ||
| 558 | 559 | ||
| 559 | /** | 560 | /** |
| 560 | * struct nand_flash_dev - NAND Flash Device ID Structure | 561 | * struct nand_flash_dev - NAND Flash Device ID Structure |
diff --git a/include/linux/mtd/physmap.h b/include/linux/mtd/physmap.h index 04e018160e2b..d2887e76b7f6 100644 --- a/include/linux/mtd/physmap.h +++ b/include/linux/mtd/physmap.h | |||
| @@ -30,6 +30,7 @@ struct physmap_flash_data { | |||
| 30 | unsigned int pfow_base; | 30 | unsigned int pfow_base; |
| 31 | char *probe_type; | 31 | char *probe_type; |
| 32 | struct mtd_partition *parts; | 32 | struct mtd_partition *parts; |
| 33 | const char **part_probe_types; | ||
| 33 | }; | 34 | }; |
| 34 | 35 | ||
| 35 | #endif /* __LINUX_MTD_PHYSMAP__ */ | 36 | #endif /* __LINUX_MTD_PHYSMAP__ */ |
