aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/nand_base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/nand/nand_base.c')
-rw-r--r--drivers/mtd/nand/nand_base.c73
1 files changed, 43 insertions, 30 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 50c0d5f1c80a..922b890c8fcb 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -45,7 +45,7 @@
45#include <linux/interrupt.h> 45#include <linux/interrupt.h>
46#include <linux/bitops.h> 46#include <linux/bitops.h>
47#include <linux/leds.h> 47#include <linux/leds.h>
48#include <asm/io.h> 48#include <linux/io.h>
49 49
50#ifdef CONFIG_MTD_PARTITIONS 50#ifdef CONFIG_MTD_PARTITIONS
51#include <linux/mtd/partitions.h> 51#include <linux/mtd/partitions.h>
@@ -786,7 +786,7 @@ nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state)
786 spinlock_t *lock = &chip->controller->lock; 786 spinlock_t *lock = &chip->controller->lock;
787 wait_queue_head_t *wq = &chip->controller->wq; 787 wait_queue_head_t *wq = &chip->controller->wq;
788 DECLARE_WAITQUEUE(wait, current); 788 DECLARE_WAITQUEUE(wait, current);
789 retry: 789retry:
790 spin_lock(lock); 790 spin_lock(lock);
791 791
792 /* Hardware controller shared among independent devices */ 792 /* Hardware controller shared among independent devices */
@@ -982,6 +982,7 @@ out:
982 982
983 return ret; 983 return ret;
984} 984}
985EXPORT_SYMBOL(nand_unlock);
985 986
986/** 987/**
987 * nand_lock - [REPLACEABLE] locks all blocks present in the device 988 * nand_lock - [REPLACEABLE] locks all blocks present in the device
@@ -1051,6 +1052,7 @@ out:
1051 1052
1052 return ret; 1053 return ret;
1053} 1054}
1055EXPORT_SYMBOL(nand_lock);
1054 1056
1055/** 1057/**
1056 * nand_read_page_raw - [Intern] read raw page data without ecc 1058 * nand_read_page_raw - [Intern] read raw page data without ecc
@@ -1078,8 +1080,9 @@ static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
1078 * 1080 *
1079 * We need a special oob layout and handling even when OOB isn't used. 1081 * We need a special oob layout and handling even when OOB isn't used.
1080 */ 1082 */
1081static int nand_read_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *chip, 1083static int nand_read_page_raw_syndrome(struct mtd_info *mtd,
1082 uint8_t *buf, int page) 1084 struct nand_chip *chip,
1085 uint8_t *buf, int page)
1083{ 1086{
1084 int eccsize = chip->ecc.size; 1087 int eccsize = chip->ecc.size;
1085 int eccbytes = chip->ecc.bytes; 1088 int eccbytes = chip->ecc.bytes;
@@ -1160,7 +1163,8 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
1160 * @readlen: data length 1163 * @readlen: data length
1161 * @bufpoi: buffer to store read data 1164 * @bufpoi: buffer to store read data
1162 */ 1165 */
1163static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi) 1166static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
1167 uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi)
1164{ 1168{
1165 int start_step, end_step, num_steps; 1169 int start_step, end_step, num_steps;
1166 uint32_t *eccpos = chip->ecc.layout->eccpos; 1170 uint32_t *eccpos = chip->ecc.layout->eccpos;
@@ -1168,6 +1172,7 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint3
1168 int data_col_addr, i, gaps = 0; 1172 int data_col_addr, i, gaps = 0;
1169 int datafrag_len, eccfrag_len, aligned_len, aligned_pos; 1173 int datafrag_len, eccfrag_len, aligned_len, aligned_pos;
1170 int busw = (chip->options & NAND_BUSWIDTH_16) ? 2 : 1; 1174 int busw = (chip->options & NAND_BUSWIDTH_16) ? 2 : 1;
1175 int index = 0;
1171 1176
1172 /* Column address wihin the page aligned to ECC size (256bytes). */ 1177 /* Column address wihin the page aligned to ECC size (256bytes). */
1173 start_step = data_offs / chip->ecc.size; 1178 start_step = data_offs / chip->ecc.size;
@@ -1206,25 +1211,29 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint3
1206 } else { 1211 } else {
1207 /* send the command to read the particular ecc bytes */ 1212 /* send the command to read the particular ecc bytes */
1208 /* take care about buswidth alignment in read_buf */ 1213 /* take care about buswidth alignment in read_buf */
1209 aligned_pos = eccpos[start_step * chip->ecc.bytes] & ~(busw - 1); 1214 index = start_step * chip->ecc.bytes;
1215
1216 aligned_pos = eccpos[index] & ~(busw - 1);
1210 aligned_len = eccfrag_len; 1217 aligned_len = eccfrag_len;
1211 if (eccpos[start_step * chip->ecc.bytes] & (busw - 1)) 1218 if (eccpos[index] & (busw - 1))
1212 aligned_len++; 1219 aligned_len++;
1213 if (eccpos[(start_step + num_steps) * chip->ecc.bytes] & (busw - 1)) 1220 if (eccpos[index + (num_steps * chip->ecc.bytes)] & (busw - 1))
1214 aligned_len++; 1221 aligned_len++;
1215 1222
1216 chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize + aligned_pos, -1); 1223 chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
1224 mtd->writesize + aligned_pos, -1);
1217 chip->read_buf(mtd, &chip->oob_poi[aligned_pos], aligned_len); 1225 chip->read_buf(mtd, &chip->oob_poi[aligned_pos], aligned_len);
1218 } 1226 }
1219 1227
1220 for (i = 0; i < eccfrag_len; i++) 1228 for (i = 0; i < eccfrag_len; i++)
1221 chip->buffers->ecccode[i] = chip->oob_poi[eccpos[i + start_step * chip->ecc.bytes]]; 1229 chip->buffers->ecccode[i] = chip->oob_poi[eccpos[i + index]];
1222 1230
1223 p = bufpoi + data_col_addr; 1231 p = bufpoi + data_col_addr;
1224 for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size) { 1232 for (i = 0; i < eccfrag_len ; i += chip->ecc.bytes, p += chip->ecc.size) {
1225 int stat; 1233 int stat;
1226 1234
1227 stat = chip->ecc.correct(mtd, p, &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]); 1235 stat = chip->ecc.correct(mtd, p,
1236 &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]);
1228 if (stat < 0) 1237 if (stat < 0)
1229 mtd->ecc_stats.failed++; 1238 mtd->ecc_stats.failed++;
1230 else 1239 else
@@ -1486,7 +1495,8 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
1486 ret = chip->ecc.read_page_raw(mtd, chip, 1495 ret = chip->ecc.read_page_raw(mtd, chip,
1487 bufpoi, page); 1496 bufpoi, page);
1488 else if (!aligned && NAND_SUBPAGE_READ(chip) && !oob) 1497 else if (!aligned && NAND_SUBPAGE_READ(chip) && !oob)
1489 ret = chip->ecc.read_subpage(mtd, chip, col, bytes, bufpoi); 1498 ret = chip->ecc.read_subpage(mtd, chip,
1499 col, bytes, bufpoi);
1490 else 1500 else
1491 ret = chip->ecc.read_page(mtd, chip, bufpoi, 1501 ret = chip->ecc.read_page(mtd, chip, bufpoi,
1492 page); 1502 page);
@@ -1878,7 +1888,7 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,
1878 else 1888 else
1879 ret = nand_do_read_ops(mtd, from, ops); 1889 ret = nand_do_read_ops(mtd, from, ops);
1880 1890
1881 out: 1891out:
1882 nand_release_device(mtd); 1892 nand_release_device(mtd);
1883 return ret; 1893 return ret;
1884} 1894}
@@ -1907,8 +1917,9 @@ static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
1907 * 1917 *
1908 * We need a special oob layout and handling even when ECC isn't checked. 1918 * We need a special oob layout and handling even when ECC isn't checked.
1909 */ 1919 */
1910static void nand_write_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *chip, 1920static void nand_write_page_raw_syndrome(struct mtd_info *mtd,
1911 const uint8_t *buf) 1921 struct nand_chip *chip,
1922 const uint8_t *buf)
1912{ 1923{
1913 int eccsize = chip->ecc.size; 1924 int eccsize = chip->ecc.size;
1914 int eccbytes = chip->ecc.bytes; 1925 int eccbytes = chip->ecc.bytes;
@@ -2448,7 +2459,7 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,
2448 else 2459 else
2449 ret = nand_do_write_ops(mtd, to, ops); 2460 ret = nand_do_write_ops(mtd, to, ops);
2450 2461
2451 out: 2462out:
2452 nand_release_device(mtd); 2463 nand_release_device(mtd);
2453 return ret; 2464 return ret;
2454} 2465}
@@ -2634,7 +2645,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
2634 } 2645 }
2635 instr->state = MTD_ERASE_DONE; 2646 instr->state = MTD_ERASE_DONE;
2636 2647
2637 erase_exit: 2648erase_exit:
2638 2649
2639 ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO; 2650 ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
2640 2651
@@ -2892,7 +2903,8 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
2892 */ 2903 */
2893static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, 2904static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
2894 struct nand_chip *chip, 2905 struct nand_chip *chip,
2895 int busw, int *maf_id, int *dev_id, 2906 int busw,
2907 int *maf_id, int *dev_id,
2896 struct nand_flash_dev *type) 2908 struct nand_flash_dev *type)
2897{ 2909{
2898 int i, maf_idx; 2910 int i, maf_idx;
@@ -3087,8 +3099,10 @@ ident_done:
3087 ffs(mtd->erasesize) - 1; 3099 ffs(mtd->erasesize) - 1;
3088 if (chip->chipsize & 0xffffffff) 3100 if (chip->chipsize & 0xffffffff)
3089 chip->chip_shift = ffs((unsigned)chip->chipsize) - 1; 3101 chip->chip_shift = ffs((unsigned)chip->chipsize) - 1;
3090 else 3102 else {
3091 chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32)) + 32 - 1; 3103 chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32));
3104 chip->chip_shift += 32 - 1;
3105 }
3092 3106
3093 /* Set the bad block position */ 3107 /* Set the bad block position */
3094 if (mtd->writesize > 512 || (busw & NAND_BUSWIDTH_16)) 3108 if (mtd->writesize > 512 || (busw & NAND_BUSWIDTH_16))
@@ -3169,7 +3183,8 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
3169 nand_set_defaults(chip, busw); 3183 nand_set_defaults(chip, busw);
3170 3184
3171 /* Read the flash type */ 3185 /* Read the flash type */
3172 type = nand_get_flash_type(mtd, chip, busw, &nand_maf_id, &nand_dev_id, table); 3186 type = nand_get_flash_type(mtd, chip, busw,
3187 &nand_maf_id, &nand_dev_id, table);
3173 3188
3174 if (IS_ERR(type)) { 3189 if (IS_ERR(type)) {
3175 if (!(chip->options & NAND_SCAN_SILENT_NODEV)) 3190 if (!(chip->options & NAND_SCAN_SILENT_NODEV))
@@ -3199,6 +3214,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
3199 3214
3200 return 0; 3215 return 0;
3201} 3216}
3217EXPORT_SYMBOL(nand_scan_ident);
3202 3218
3203 3219
3204/** 3220/**
@@ -3427,10 +3443,11 @@ int nand_scan_tail(struct mtd_info *mtd)
3427 /* Build bad block table */ 3443 /* Build bad block table */
3428 return chip->scan_bbt(mtd); 3444 return chip->scan_bbt(mtd);
3429} 3445}
3446EXPORT_SYMBOL(nand_scan_tail);
3430 3447
3431/* is_module_text_address() isn't exported, and it's mostly a pointless 3448/* is_module_text_address() isn't exported, and it's mostly a pointless
3432 test if this is a module _anyway_ -- they'd have to try _really_ hard 3449 * test if this is a module _anyway_ -- they'd have to try _really_ hard
3433 to call us from in-kernel code if the core NAND support is modular. */ 3450 * to call us from in-kernel code if the core NAND support is modular. */
3434#ifdef MODULE 3451#ifdef MODULE
3435#define caller_is_module() (1) 3452#define caller_is_module() (1)
3436#else 3453#else
@@ -3466,6 +3483,7 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
3466 ret = nand_scan_tail(mtd); 3483 ret = nand_scan_tail(mtd);
3467 return ret; 3484 return ret;
3468} 3485}
3486EXPORT_SYMBOL(nand_scan);
3469 3487
3470/** 3488/**
3471 * nand_release - [NAND Interface] Free resources held by the NAND device 3489 * nand_release - [NAND Interface] Free resources held by the NAND device
@@ -3492,12 +3510,6 @@ void nand_release(struct mtd_info *mtd)
3492 & NAND_BBT_DYNAMICSTRUCT) 3510 & NAND_BBT_DYNAMICSTRUCT)
3493 kfree(chip->badblock_pattern); 3511 kfree(chip->badblock_pattern);
3494} 3512}
3495
3496EXPORT_SYMBOL_GPL(nand_lock);
3497EXPORT_SYMBOL_GPL(nand_unlock);
3498EXPORT_SYMBOL_GPL(nand_scan);
3499EXPORT_SYMBOL_GPL(nand_scan_ident);
3500EXPORT_SYMBOL_GPL(nand_scan_tail);
3501EXPORT_SYMBOL_GPL(nand_release); 3513EXPORT_SYMBOL_GPL(nand_release);
3502 3514
3503static int __init nand_base_init(void) 3515static int __init nand_base_init(void)
@@ -3515,5 +3527,6 @@ module_init(nand_base_init);
3515module_exit(nand_base_exit); 3527module_exit(nand_base_exit);
3516 3528
3517MODULE_LICENSE("GPL"); 3529MODULE_LICENSE("GPL");
3518MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com>, Thomas Gleixner <tglx@linutronix.de>"); 3530MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com>");
3531MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>");
3519MODULE_DESCRIPTION("Generic NAND flash driver code"); 3532MODULE_DESCRIPTION("Generic NAND flash driver code");