aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/sharpsl.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-06-20 17:50:31 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-20 17:50:31 -0400
commitbe967b7e2f7747a5ebf2a07ee627d9338491e784 (patch)
treef42b82601209a52b8ee478e36d8b21543ab03060 /drivers/mtd/nand/sharpsl.c
parenteef11427edcb821b63920219f89379fab84198b9 (diff)
parent7bc3312bef4d6f220812500c0de7868fb7625a41 (diff)
Merge git://git.infradead.org/mtd-2.6
* git://git.infradead.org/mtd-2.6: (199 commits) [MTD] NAND: Fix breakage all over the place [PATCH] NAND: fix remaining OOB length calculation [MTD] NAND Fixup NDFC merge brokeness [MTD NAND] S3C2410 driver cleanup [MTD NAND] s3c24x0 board: Fix clock handling, ensure proper initialisation. [JFFS2] Check CRC32 on dirent and data nodes each time they're read [JFFS2] When retiring nextblock, allocate a node_ref for the wasted space [JFFS2] Mark XATTR support as experimental, for now [JFFS2] Don't trust node headers before the CRC is checked. [MTD] Restore MTD_ROM and MTD_RAM types [MTD] assume mtd->writesize is 1 for NOR flashes [MTD NAND] Fix s3c2410 NAND driver so it at least _looks_ like it compiles [MTD] Prepare physmap for 64-bit-resources [JFFS2] Fix more breakage caused by janitorial meddling. [JFFS2] Remove stray __exit from jffs2_compressors_exit() [MTD] Allow alternate JFFS2 mount variant for root filesystem. [MTD] Disconnect struct mtd_info from ABI [MTD] replace MTD_RAM with MTD_GENERIC_TYPE [MTD] replace MTD_ROM with MTD_GENERIC_TYPE [MTD] remove a forgotten MTD_XIP ...
Diffstat (limited to 'drivers/mtd/nand/sharpsl.c')
-rw-r--r--drivers/mtd/nand/sharpsl.c146
1 files changed, 66 insertions, 80 deletions
diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c
index 1924a4f137c7..21743658d150 100644
--- a/drivers/mtd/nand/sharpsl.c
+++ b/drivers/mtd/nand/sharpsl.c
@@ -46,7 +46,6 @@ static int sharpsl_phys_base = 0x0C000000;
46#define FLCLE (1 << 1) 46#define FLCLE (1 << 1)
47#define FLCE0 (1 << 0) 47#define FLCE0 (1 << 0)
48 48
49
50/* 49/*
51 * MTD structure for SharpSL 50 * MTD structure for SharpSL
52 */ 51 */
@@ -60,50 +59,44 @@ static struct mtd_info *sharpsl_mtd = NULL;
60static int nr_partitions; 59static int nr_partitions;
61static struct mtd_partition sharpsl_nand_default_partition_info[] = { 60static struct mtd_partition sharpsl_nand_default_partition_info[] = {
62 { 61 {
63 .name = "System Area", 62 .name = "System Area",
64 .offset = 0, 63 .offset = 0,
65 .size = 7 * 1024 * 1024, 64 .size = 7 * 1024 * 1024,
66 }, 65 },
67 { 66 {
68 .name = "Root Filesystem", 67 .name = "Root Filesystem",
69 .offset = 7 * 1024 * 1024, 68 .offset = 7 * 1024 * 1024,
70 .size = 30 * 1024 * 1024, 69 .size = 30 * 1024 * 1024,
71 }, 70 },
72 { 71 {
73 .name = "Home Filesystem", 72 .name = "Home Filesystem",
74 .offset = MTDPART_OFS_APPEND , 73 .offset = MTDPART_OFS_APPEND,
75 .size = MTDPART_SIZ_FULL , 74 .size = MTDPART_SIZ_FULL,
76 }, 75 },
77}; 76};
78 77
79/* 78/*
80 * hardware specific access to control-lines 79 * hardware specific access to control-lines
80 * ctrl:
81 * NAND_CNE: bit 0 -> bit 0 & 4
82 * NAND_CLE: bit 1 -> bit 1
83 * NAND_ALE: bit 2 -> bit 2
84 *
81 */ 85 */
82static void 86static void sharpsl_nand_hwcontrol(struct mtd_info *mtd, int cmd,
83sharpsl_nand_hwcontrol(struct mtd_info* mtd, int cmd) 87 unsigned int ctrl)
84{ 88{
85 switch (cmd) { 89 struct nand_chip *chip = mtd->priv;
86 case NAND_CTL_SETCLE: 90
87 writeb(readb(FLASHCTL) | FLCLE, FLASHCTL); 91 if (ctrl & NAND_CTRL_CHANGE) {
88 break; 92 unsigned char bits = ctrl & 0x07;
89 case NAND_CTL_CLRCLE: 93
90 writeb(readb(FLASHCTL) & ~FLCLE, FLASHCTL); 94 bits |= (ctrl & 0x01) << 4;
91 break; 95 writeb((readb(FLASHCTL) & 0x17) | bits, FLASHCTL);
92
93 case NAND_CTL_SETALE:
94 writeb(readb(FLASHCTL) | FLALE, FLASHCTL);
95 break;
96 case NAND_CTL_CLRALE:
97 writeb(readb(FLASHCTL) & ~FLALE, FLASHCTL);
98 break;
99
100 case NAND_CTL_SETNCE:
101 writeb(readb(FLASHCTL) & ~(FLCE0|FLCE1), FLASHCTL);
102 break;
103 case NAND_CTL_CLRNCE:
104 writeb(readb(FLASHCTL) | (FLCE0|FLCE1), FLASHCTL);
105 break;
106 } 96 }
97
98 if (cmd != NAND_CMD_NONE)
99 writeb(cmd, chip->IO_ADDR_W);
107} 100}
108 101
109static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; 102static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
@@ -122,31 +115,26 @@ static struct nand_bbt_descr sharpsl_akita_bbt = {
122 .pattern = scan_ff_pattern 115 .pattern = scan_ff_pattern
123}; 116};
124 117
125static struct nand_oobinfo akita_oobinfo = { 118static struct nand_ecclayout akita_oobinfo = {
126 .useecc = MTD_NANDECC_AUTOPLACE,
127 .eccbytes = 24, 119 .eccbytes = 24,
128 .eccpos = { 120 .eccpos = {
129 0x5, 0x1, 0x2, 0x3, 0x6, 0x7, 0x15, 0x11, 121 0x5, 0x1, 0x2, 0x3, 0x6, 0x7, 0x15, 0x11,
130 0x12, 0x13, 0x16, 0x17, 0x25, 0x21, 0x22, 0x23, 122 0x12, 0x13, 0x16, 0x17, 0x25, 0x21, 0x22, 0x23,
131 0x26, 0x27, 0x35, 0x31, 0x32, 0x33, 0x36, 0x37}, 123 0x26, 0x27, 0x35, 0x31, 0x32, 0x33, 0x36, 0x37},
132 .oobfree = { {0x08, 0x09} } 124 .oobfree = {{0x08, 0x09}}
133}; 125};
134 126
135static int 127static int sharpsl_nand_dev_ready(struct mtd_info *mtd)
136sharpsl_nand_dev_ready(struct mtd_info* mtd)
137{ 128{
138 return !((readb(FLASHCTL) & FLRYBY) == 0); 129 return !((readb(FLASHCTL) & FLRYBY) == 0);
139} 130}
140 131
141static void 132static void sharpsl_nand_enable_hwecc(struct mtd_info *mtd, int mode)
142sharpsl_nand_enable_hwecc(struct mtd_info* mtd, int mode)
143{ 133{
144 writeb(0 ,ECCCLRR); 134 writeb(0, ECCCLRR);
145} 135}
146 136
147static int 137static int sharpsl_nand_calculate_ecc(struct mtd_info *mtd, const u_char * dat, u_char * ecc_code)
148sharpsl_nand_calculate_ecc(struct mtd_info* mtd, const u_char* dat,
149 u_char* ecc_code)
150{ 138{
151 ecc_code[0] = ~readb(ECCLPUB); 139 ecc_code[0] = ~readb(ECCLPUB);
152 ecc_code[1] = ~readb(ECCLPLB); 140 ecc_code[1] = ~readb(ECCLPLB);
@@ -154,47 +142,44 @@ sharpsl_nand_calculate_ecc(struct mtd_info* mtd, const u_char* dat,
154 return readb(ECCCNTR) != 0; 142 return readb(ECCCNTR) != 0;
155} 143}
156 144
157
158#ifdef CONFIG_MTD_PARTITIONS 145#ifdef CONFIG_MTD_PARTITIONS
159const char *part_probes[] = { "cmdlinepart", NULL }; 146const char *part_probes[] = { "cmdlinepart", NULL };
160#endif 147#endif
161 148
162
163/* 149/*
164 * Main initialization routine 150 * Main initialization routine
165 */ 151 */
166int __init 152static int __init sharpsl_nand_init(void)
167sharpsl_nand_init(void)
168{ 153{
169 struct nand_chip *this; 154 struct nand_chip *this;
170 struct mtd_partition* sharpsl_partition_info; 155 struct mtd_partition *sharpsl_partition_info;
171 int err = 0; 156 int err = 0;
172 157
173 /* Allocate memory for MTD device structure and private data */ 158 /* Allocate memory for MTD device structure and private data */
174 sharpsl_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), 159 sharpsl_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
175 GFP_KERNEL);
176 if (!sharpsl_mtd) { 160 if (!sharpsl_mtd) {
177 printk ("Unable to allocate SharpSL NAND MTD device structure.\n"); 161 printk("Unable to allocate SharpSL NAND MTD device structure.\n");
178 return -ENOMEM; 162 return -ENOMEM;
179 } 163 }
180 164
181 /* map physical adress */ 165 /* map physical adress */
182 sharpsl_io_base = ioremap(sharpsl_phys_base, 0x1000); 166 sharpsl_io_base = ioremap(sharpsl_phys_base, 0x1000);
183 if(!sharpsl_io_base){ 167 if (!sharpsl_io_base) {
184 printk("ioremap to access Sharp SL NAND chip failed\n"); 168 printk("ioremap to access Sharp SL NAND chip failed\n");
185 kfree(sharpsl_mtd); 169 kfree(sharpsl_mtd);
186 return -EIO; 170 return -EIO;
187 } 171 }
188 172
189 /* Get pointer to private data */ 173 /* Get pointer to private data */
190 this = (struct nand_chip *) (&sharpsl_mtd[1]); 174 this = (struct nand_chip *)(&sharpsl_mtd[1]);
191 175
192 /* Initialize structures */ 176 /* Initialize structures */
193 memset((char *) sharpsl_mtd, 0, sizeof(struct mtd_info)); 177 memset(sharpsl_mtd, 0, sizeof(struct mtd_info));
194 memset((char *) this, 0, sizeof(struct nand_chip)); 178 memset(this, 0, sizeof(struct nand_chip));
195 179
196 /* Link the private data with the MTD structure */ 180 /* Link the private data with the MTD structure */
197 sharpsl_mtd->priv = this; 181 sharpsl_mtd->priv = this;
182 sharpsl_mtd->owner = THIS_MODULE;
198 183
199 /* 184 /*
200 * PXA initialize 185 * PXA initialize
@@ -205,23 +190,25 @@ sharpsl_nand_init(void)
205 this->IO_ADDR_R = FLASHIO; 190 this->IO_ADDR_R = FLASHIO;
206 this->IO_ADDR_W = FLASHIO; 191 this->IO_ADDR_W = FLASHIO;
207 /* Set address of hardware control function */ 192 /* Set address of hardware control function */
208 this->hwcontrol = sharpsl_nand_hwcontrol; 193 this->cmd_ctrl = sharpsl_nand_hwcontrol;
209 this->dev_ready = sharpsl_nand_dev_ready; 194 this->dev_ready = sharpsl_nand_dev_ready;
210 /* 15 us command delay time */ 195 /* 15 us command delay time */
211 this->chip_delay = 15; 196 this->chip_delay = 15;
212 /* set eccmode using hardware ECC */ 197 /* set eccmode using hardware ECC */
213 this->eccmode = NAND_ECC_HW3_256; 198 this->ecc.mode = NAND_ECC_HW;
199 this->ecc.size = 256;
200 this->ecc.bytes = 3;
214 this->badblock_pattern = &sharpsl_bbt; 201 this->badblock_pattern = &sharpsl_bbt;
215 if (machine_is_akita() || machine_is_borzoi()) { 202 if (machine_is_akita() || machine_is_borzoi()) {
216 this->badblock_pattern = &sharpsl_akita_bbt; 203 this->badblock_pattern = &sharpsl_akita_bbt;
217 this->autooob = &akita_oobinfo; 204 this->ecc.layout = &akita_oobinfo;
218 } 205 }
219 this->enable_hwecc = sharpsl_nand_enable_hwecc; 206 this->ecc.hwctl = sharpsl_nand_enable_hwecc;
220 this->calculate_ecc = sharpsl_nand_calculate_ecc; 207 this->ecc.calculate = sharpsl_nand_calculate_ecc;
221 this->correct_data = nand_correct_data; 208 this->ecc.correct = nand_correct_data;
222 209
223 /* Scan to find existence of the device */ 210 /* Scan to find existence of the device */
224 err=nand_scan(sharpsl_mtd,1); 211 err = nand_scan(sharpsl_mtd, 1);
225 if (err) { 212 if (err) {
226 iounmap(sharpsl_io_base); 213 iounmap(sharpsl_io_base);
227 kfree(sharpsl_mtd); 214 kfree(sharpsl_mtd);
@@ -230,24 +217,23 @@ sharpsl_nand_init(void)
230 217
231 /* Register the partitions */ 218 /* Register the partitions */
232 sharpsl_mtd->name = "sharpsl-nand"; 219 sharpsl_mtd->name = "sharpsl-nand";
233 nr_partitions = parse_mtd_partitions(sharpsl_mtd, part_probes, 220 nr_partitions = parse_mtd_partitions(sharpsl_mtd, part_probes, &sharpsl_partition_info, 0);
234 &sharpsl_partition_info, 0);
235 221
236 if (nr_partitions <= 0) { 222 if (nr_partitions <= 0) {
237 nr_partitions = DEFAULT_NUM_PARTITIONS; 223 nr_partitions = DEFAULT_NUM_PARTITIONS;
238 sharpsl_partition_info = sharpsl_nand_default_partition_info; 224 sharpsl_partition_info = sharpsl_nand_default_partition_info;
239 if (machine_is_poodle()) { 225 if (machine_is_poodle()) {
240 sharpsl_partition_info[1].size=30 * 1024 * 1024; 226 sharpsl_partition_info[1].size = 22 * 1024 * 1024;
241 } else if (machine_is_corgi() || machine_is_shepherd()) { 227 } else if (machine_is_corgi() || machine_is_shepherd()) {
242 sharpsl_partition_info[1].size=25 * 1024 * 1024; 228 sharpsl_partition_info[1].size = 25 * 1024 * 1024;
243 } else if (machine_is_husky()) { 229 } else if (machine_is_husky()) {
244 sharpsl_partition_info[1].size=53 * 1024 * 1024; 230 sharpsl_partition_info[1].size = 53 * 1024 * 1024;
245 } else if (machine_is_spitz()) { 231 } else if (machine_is_spitz()) {
246 sharpsl_partition_info[1].size=5 * 1024 * 1024; 232 sharpsl_partition_info[1].size = 5 * 1024 * 1024;
247 } else if (machine_is_akita()) { 233 } else if (machine_is_akita()) {
248 sharpsl_partition_info[1].size=58 * 1024 * 1024; 234 sharpsl_partition_info[1].size = 58 * 1024 * 1024;
249 } else if (machine_is_borzoi()) { 235 } else if (machine_is_borzoi()) {
250 sharpsl_partition_info[1].size=32 * 1024 * 1024; 236 sharpsl_partition_info[1].size = 32 * 1024 * 1024;
251 } 237 }
252 } 238 }
253 239
@@ -261,15 +247,15 @@ sharpsl_nand_init(void)
261 /* Return happy */ 247 /* Return happy */
262 return 0; 248 return 0;
263} 249}
250
264module_init(sharpsl_nand_init); 251module_init(sharpsl_nand_init);
265 252
266/* 253/*
267 * Clean up routine 254 * Clean up routine
268 */ 255 */
269#ifdef MODULE
270static void __exit sharpsl_nand_cleanup(void) 256static void __exit sharpsl_nand_cleanup(void)
271{ 257{
272 struct nand_chip *this = (struct nand_chip *) &sharpsl_mtd[1]; 258 struct nand_chip *this = (struct nand_chip *)&sharpsl_mtd[1];
273 259
274 /* Release resources, unregister device */ 260 /* Release resources, unregister device */
275 nand_release(sharpsl_mtd); 261 nand_release(sharpsl_mtd);
@@ -279,8 +265,8 @@ static void __exit sharpsl_nand_cleanup(void)
279 /* Free the MTD device structure */ 265 /* Free the MTD device structure */
280 kfree(sharpsl_mtd); 266 kfree(sharpsl_mtd);
281} 267}
268
282module_exit(sharpsl_nand_cleanup); 269module_exit(sharpsl_nand_cleanup);
283#endif
284 270
285MODULE_LICENSE("GPL"); 271MODULE_LICENSE("GPL");
286MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); 272MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");