[glsdk/meta-ti-glsdk.git] / recipes-kernel / linux / linux-omap-2.6.39 / sakoman / 0025-omap-Fix-mtd-subpage-read-alignment.patch
1 From 5c688ec6e6f046d2c8b3821964971149b0c30fc7 Mon Sep 17 00:00:00 2001
2 From: Charles Manning <cdhmanning@gmail.com>
3 Date: Tue, 18 Jan 2011 11:25:25 +1300
4 Subject: [PATCH 25/30] omap: Fix mtd subpage read alignment
6 This allows the omap2 prefetch engine to work properly for subpage
7 reads. Without this ECC errors will stop UBIFS from working.
9 Signed-off-by: Charles Manning <cdhmanning@gmail.com>
10 ---
11 drivers/mtd/nand/nand_base.c | 19 +++++++++++++++++++
12 drivers/mtd/nand/omap2.c | 1 +
13 include/linux/mtd/nand.h | 3 +++
14 3 files changed, 23 insertions(+), 0 deletions(-)
16 diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
17 index c54a4cb..6ca7098 100644
18 --- a/drivers/mtd/nand/nand_base.c
19 +++ b/drivers/mtd/nand/nand_base.c
20 @@ -1157,6 +1157,22 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
21 }
23 /**
24 + * nand_align_subpage32 - function to align subpage read to 32-bits
25 + * @mtd: mtd info structure
26 + * @buf: pointer to offset that needs to be aligned
27 + * @len: pointer to length that needs to be aligned.
28 + */
29 +
30 +void nand_align_subpage32(int *offs, int *len)
31 +{
32 + int diff = *offs & 3;
33 +
34 + *offs = *offs - diff;
35 + *len = (*len + diff + 3) & ~3;
36 +}
37 +EXPORT_SYMBOL(nand_align_subpage32);
38 +
39 +/**
40 * nand_read_subpage - [REPLACABLE] software ecc based sub-page read function
41 * @mtd: mtd info structure
42 * @chip: nand chip info structure
43 @@ -1221,6 +1237,9 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
44 if (eccpos[index + (num_steps * chip->ecc.bytes)] & (busw - 1))
45 aligned_len++;
47 + if(chip->align_subpage)
48 + chip->align_subpage(&aligned_pos, &aligned_len);
49 +
50 chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
51 mtd->writesize + aligned_pos, -1);
52 chip->read_buf(mtd, &chip->oob_poi[aligned_pos], aligned_len);
53 diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
54 index da9a351..bb89c65 100644
55 --- a/drivers/mtd/nand/omap2.c
56 +++ b/drivers/mtd/nand/omap2.c
57 @@ -1069,6 +1069,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)
58 info->nand.ecc.correct = omap_correct_data;
59 info->nand.ecc.mode = NAND_ECC_HW;
60 }
61 + info->nand.align_subpage = nand_align_subpage32;
63 /* DIP switches on some boards change between 8 and 16 bit
64 * bus widths for flash. Try the other width if the first try fails.
65 diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
66 index d441927..311f211 100644
67 --- a/include/linux/mtd/nand.h
68 +++ b/include/linux/mtd/nand.h
69 @@ -479,6 +479,7 @@ struct nand_buffers {
70 * additional error status checks (determine if errors are
71 * correctable).
72 * @write_page: [REPLACEABLE] High-level page write function
73 + * @align_subpage: [OPTIONAL] Aligns subpage read buffer.
74 */
76 struct nand_chip {
77 @@ -507,6 +508,7 @@ struct nand_chip {
78 int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
79 const uint8_t *buf, int page, int cached, int raw);
81 + void (*align_subpage)(int *offs, int *len);
82 int chip_delay;
83 unsigned int options;
85 @@ -602,6 +604,7 @@ extern int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
86 int allowbbt);
87 extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
88 size_t *retlen, uint8_t *buf);
89 +extern void nand_align_subpage32(int *offs, int *len);
91 /**
92 * struct platform_nand_chip - chip level device structure
93 --
94 1.6.6.1