1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* Freescale Enhanced Local Bus Controller NAND driver |
3 | * |
4 | * Copyright © 2006-2007, 2010 Freescale Semiconductor |
5 | * |
6 | * Authors: Nick Spence <nick.spence@freescale.com>, |
7 | * Scott Wood <scottwood@freescale.com> |
8 | * Jack Lan <jack.lan@freescale.com> |
9 | * Roy Zang <tie-fei.zang@freescale.com> |
10 | */ |
11 | |
12 | #include <linux/module.h> |
13 | #include <linux/types.h> |
14 | #include <linux/kernel.h> |
15 | #include <linux/string.h> |
16 | #include <linux/ioport.h> |
17 | #include <linux/of_address.h> |
18 | #include <linux/of_platform.h> |
19 | #include <linux/platform_device.h> |
20 | #include <linux/slab.h> |
21 | #include <linux/interrupt.h> |
22 | |
23 | #include <linux/mtd/mtd.h> |
24 | #include <linux/mtd/rawnand.h> |
25 | #include <linux/mtd/partitions.h> |
26 | |
27 | #include <asm/io.h> |
28 | #include <asm/fsl_lbc.h> |
29 | |
30 | #define MAX_BANKS 8 |
31 | #define ERR_BYTE 0xFF /* Value returned for read bytes when read failed */ |
32 | #define FCM_TIMEOUT_MSECS 500 /* Maximum number of mSecs to wait for FCM */ |
33 | |
34 | /* mtd information per set */ |
35 | |
36 | struct fsl_elbc_mtd { |
37 | struct nand_chip chip; |
38 | struct fsl_lbc_ctrl *ctrl; |
39 | |
40 | struct device *dev; |
41 | int bank; /* Chip select bank number */ |
42 | u8 __iomem *vbase; /* Chip select base virtual address */ |
43 | int page_size; /* NAND page size (0=512, 1=2048) */ |
44 | unsigned int fmr; /* FCM Flash Mode Register value */ |
45 | }; |
46 | |
47 | /* Freescale eLBC FCM controller information */ |
48 | |
49 | struct fsl_elbc_fcm_ctrl { |
50 | struct nand_controller controller; |
51 | struct fsl_elbc_mtd *chips[MAX_BANKS]; |
52 | |
53 | u8 __iomem *addr; /* Address of assigned FCM buffer */ |
54 | unsigned int page; /* Last page written to / read from */ |
55 | unsigned int read_bytes; /* Number of bytes read during command */ |
56 | unsigned int column; /* Saved column from SEQIN */ |
57 | unsigned int index; /* Pointer to next byte to 'read' */ |
58 | unsigned int status; /* status read from LTESR after last op */ |
59 | unsigned int mdr; /* UPM/FCM Data Register value */ |
60 | unsigned int use_mdr; /* Non zero if the MDR is to be set */ |
61 | unsigned int oob; /* Non zero if operating on OOB data */ |
62 | unsigned int counter; /* counter for the initializations */ |
63 | unsigned int max_bitflips; /* Saved during READ0 cmd */ |
64 | }; |
65 | |
66 | /* These map to the positions used by the FCM hardware ECC generator */ |
67 | |
68 | static int fsl_elbc_ooblayout_ecc(struct mtd_info *mtd, int section, |
69 | struct mtd_oob_region *oobregion) |
70 | { |
71 | struct nand_chip *chip = mtd_to_nand(mtd); |
72 | struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); |
73 | |
74 | if (section >= chip->ecc.steps) |
75 | return -ERANGE; |
76 | |
77 | oobregion->offset = (16 * section) + 6; |
78 | if (priv->fmr & FMR_ECCM) |
79 | oobregion->offset += 2; |
80 | |
81 | oobregion->length = chip->ecc.bytes; |
82 | |
83 | return 0; |
84 | } |
85 | |
86 | static int fsl_elbc_ooblayout_free(struct mtd_info *mtd, int section, |
87 | struct mtd_oob_region *oobregion) |
88 | { |
89 | struct nand_chip *chip = mtd_to_nand(mtd); |
90 | struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); |
91 | |
92 | if (section > chip->ecc.steps) |
93 | return -ERANGE; |
94 | |
95 | if (!section) { |
96 | oobregion->offset = 0; |
97 | if (mtd->writesize > 512) |
98 | oobregion->offset++; |
99 | oobregion->length = (priv->fmr & FMR_ECCM) ? 7 : 5; |
100 | } else { |
101 | oobregion->offset = (16 * section) - |
102 | ((priv->fmr & FMR_ECCM) ? 5 : 7); |
103 | if (section < chip->ecc.steps) |
104 | oobregion->length = 13; |
105 | else |
106 | oobregion->length = mtd->oobsize - oobregion->offset; |
107 | } |
108 | |
109 | return 0; |
110 | } |
111 | |
112 | static const struct mtd_ooblayout_ops fsl_elbc_ooblayout_ops = { |
113 | .ecc = fsl_elbc_ooblayout_ecc, |
114 | .free = fsl_elbc_ooblayout_free, |
115 | }; |
116 | |
117 | /* |
118 | * ELBC may use HW ECC, so that OOB offsets, that NAND core uses for bbt, |
119 | * interfere with ECC positions, that's why we implement our own descriptors. |
120 | * OOB {11, 5}, works for both SP and LP chips, with ECCM = 1 and ECCM = 0. |
121 | */ |
122 | static u8 bbt_pattern[] = {'B', 'b', 't', '0' }; |
123 | static u8 mirror_pattern[] = {'1', 't', 'b', 'B' }; |
124 | |
125 | static struct nand_bbt_descr bbt_main_descr = { |
126 | .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | |
127 | NAND_BBT_2BIT | NAND_BBT_VERSION, |
128 | .offs = 11, |
129 | .len = 4, |
130 | .veroffs = 15, |
131 | .maxblocks = 4, |
132 | .pattern = bbt_pattern, |
133 | }; |
134 | |
135 | static struct nand_bbt_descr bbt_mirror_descr = { |
136 | .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | |
137 | NAND_BBT_2BIT | NAND_BBT_VERSION, |
138 | .offs = 11, |
139 | .len = 4, |
140 | .veroffs = 15, |
141 | .maxblocks = 4, |
142 | .pattern = mirror_pattern, |
143 | }; |
144 | |
145 | /*=================================*/ |
146 | |
147 | /* |
148 | * Set up the FCM hardware block and page address fields, and the fcm |
149 | * structure addr field to point to the correct FCM buffer in memory |
150 | */ |
151 | static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) |
152 | { |
153 | struct nand_chip *chip = mtd_to_nand(mtd); |
154 | struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); |
155 | struct fsl_lbc_ctrl *ctrl = priv->ctrl; |
156 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; |
157 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; |
158 | int buf_num; |
159 | |
160 | elbc_fcm_ctrl->page = page_addr; |
161 | |
162 | if (priv->page_size) { |
163 | /* |
164 | * large page size chip : FPAR[PI] save the lowest 6 bits, |
165 | * FBAR[BLK] save the other bits. |
166 | */ |
167 | out_be32(&lbc->fbar, page_addr >> 6); |
168 | out_be32(&lbc->fpar, |
169 | ((page_addr << FPAR_LP_PI_SHIFT) & FPAR_LP_PI) | |
170 | (oob ? FPAR_LP_MS : 0) | column); |
171 | buf_num = (page_addr & 1) << 2; |
172 | } else { |
173 | /* |
174 | * small page size chip : FPAR[PI] save the lowest 5 bits, |
175 | * FBAR[BLK] save the other bits. |
176 | */ |
177 | out_be32(&lbc->fbar, page_addr >> 5); |
178 | out_be32(&lbc->fpar, |
179 | ((page_addr << FPAR_SP_PI_SHIFT) & FPAR_SP_PI) | |
180 | (oob ? FPAR_SP_MS : 0) | column); |
181 | buf_num = page_addr & 7; |
182 | } |
183 | |
184 | elbc_fcm_ctrl->addr = priv->vbase + buf_num * 1024; |
185 | elbc_fcm_ctrl->index = column; |
186 | |
187 | /* for OOB data point to the second half of the buffer */ |
188 | if (oob) |
189 | elbc_fcm_ctrl->index += priv->page_size ? 2048 : 512; |
190 | |
191 | dev_vdbg(priv->dev, "set_addr: bank=%d, " |
192 | "elbc_fcm_ctrl->addr=0x%p (0x%p), " |
193 | "index %x, pes %d ps %d\n" , |
194 | buf_num, elbc_fcm_ctrl->addr, priv->vbase, |
195 | elbc_fcm_ctrl->index, |
196 | chip->phys_erase_shift, chip->page_shift); |
197 | } |
198 | |
199 | /* |
200 | * execute FCM command and wait for it to complete |
201 | */ |
202 | static int fsl_elbc_run_command(struct mtd_info *mtd) |
203 | { |
204 | struct nand_chip *chip = mtd_to_nand(mtd); |
205 | struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); |
206 | struct fsl_lbc_ctrl *ctrl = priv->ctrl; |
207 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; |
208 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; |
209 | |
210 | /* Setup the FMR[OP] to execute without write protection */ |
211 | out_be32(&lbc->fmr, priv->fmr | 3); |
212 | if (elbc_fcm_ctrl->use_mdr) |
213 | out_be32(&lbc->mdr, elbc_fcm_ctrl->mdr); |
214 | |
215 | dev_vdbg(priv->dev, |
216 | "fsl_elbc_run_command: fmr=%08x fir=%08x fcr=%08x\n" , |
217 | in_be32(&lbc->fmr), in_be32(&lbc->fir), in_be32(&lbc->fcr)); |
218 | dev_vdbg(priv->dev, |
219 | "fsl_elbc_run_command: fbar=%08x fpar=%08x " |
220 | "fbcr=%08x bank=%d\n" , |
221 | in_be32(&lbc->fbar), in_be32(&lbc->fpar), |
222 | in_be32(&lbc->fbcr), priv->bank); |
223 | |
224 | ctrl->irq_status = 0; |
225 | /* execute special operation */ |
226 | out_be32(&lbc->lsor, priv->bank); |
227 | |
228 | /* wait for FCM complete flag or timeout */ |
229 | wait_event_timeout(ctrl->irq_wait, ctrl->irq_status, |
230 | FCM_TIMEOUT_MSECS * HZ/1000); |
231 | elbc_fcm_ctrl->status = ctrl->irq_status; |
232 | /* store mdr value in case it was needed */ |
233 | if (elbc_fcm_ctrl->use_mdr) |
234 | elbc_fcm_ctrl->mdr = in_be32(&lbc->mdr); |
235 | |
236 | elbc_fcm_ctrl->use_mdr = 0; |
237 | |
238 | if (elbc_fcm_ctrl->status != LTESR_CC) { |
239 | dev_info(priv->dev, |
240 | "command failed: fir %x fcr %x status %x mdr %x\n" , |
241 | in_be32(&lbc->fir), in_be32(&lbc->fcr), |
242 | elbc_fcm_ctrl->status, elbc_fcm_ctrl->mdr); |
243 | return -EIO; |
244 | } |
245 | |
246 | if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST) |
247 | return 0; |
248 | |
249 | elbc_fcm_ctrl->max_bitflips = 0; |
250 | |
251 | if (elbc_fcm_ctrl->read_bytes == mtd->writesize + mtd->oobsize) { |
252 | uint32_t lteccr = in_be32(&lbc->lteccr); |
253 | /* |
254 | * if command was a full page read and the ELBC |
255 | * has the LTECCR register, then bits 12-15 (ppc order) of |
256 | * LTECCR indicates which 512 byte sub-pages had fixed errors. |
257 | * bits 28-31 are uncorrectable errors, marked elsewhere. |
258 | * for small page nand only 1 bit is used. |
259 | * if the ELBC doesn't have the lteccr register it reads 0 |
260 | * FIXME: 4 bits can be corrected on NANDs with 2k pages, so |
261 | * count the number of sub-pages with bitflips and update |
262 | * ecc_stats.corrected accordingly. |
263 | */ |
264 | if (lteccr & 0x000F000F) |
265 | out_be32(&lbc->lteccr, 0x000F000F); /* clear lteccr */ |
266 | if (lteccr & 0x000F0000) { |
267 | mtd->ecc_stats.corrected++; |
268 | elbc_fcm_ctrl->max_bitflips = 1; |
269 | } |
270 | } |
271 | |
272 | return 0; |
273 | } |
274 | |
275 | static void fsl_elbc_do_read(struct nand_chip *chip, int oob) |
276 | { |
277 | struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); |
278 | struct fsl_lbc_ctrl *ctrl = priv->ctrl; |
279 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; |
280 | |
281 | if (priv->page_size) { |
282 | out_be32(&lbc->fir, |
283 | (FIR_OP_CM0 << FIR_OP0_SHIFT) | |
284 | (FIR_OP_CA << FIR_OP1_SHIFT) | |
285 | (FIR_OP_PA << FIR_OP2_SHIFT) | |
286 | (FIR_OP_CM1 << FIR_OP3_SHIFT) | |
287 | (FIR_OP_RBW << FIR_OP4_SHIFT)); |
288 | |
289 | out_be32(&lbc->fcr, (NAND_CMD_READ0 << FCR_CMD0_SHIFT) | |
290 | (NAND_CMD_READSTART << FCR_CMD1_SHIFT)); |
291 | } else { |
292 | out_be32(&lbc->fir, |
293 | (FIR_OP_CM0 << FIR_OP0_SHIFT) | |
294 | (FIR_OP_CA << FIR_OP1_SHIFT) | |
295 | (FIR_OP_PA << FIR_OP2_SHIFT) | |
296 | (FIR_OP_RBW << FIR_OP3_SHIFT)); |
297 | |
298 | if (oob) |
299 | out_be32(&lbc->fcr, NAND_CMD_READOOB << FCR_CMD0_SHIFT); |
300 | else |
301 | out_be32(&lbc->fcr, NAND_CMD_READ0 << FCR_CMD0_SHIFT); |
302 | } |
303 | } |
304 | |
305 | /* cmdfunc send commands to the FCM */ |
306 | static void fsl_elbc_cmdfunc(struct nand_chip *chip, unsigned int command, |
307 | int column, int page_addr) |
308 | { |
309 | struct mtd_info *mtd = nand_to_mtd(chip); |
310 | struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); |
311 | struct fsl_lbc_ctrl *ctrl = priv->ctrl; |
312 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; |
313 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; |
314 | |
315 | elbc_fcm_ctrl->use_mdr = 0; |
316 | |
317 | /* clear the read buffer */ |
318 | elbc_fcm_ctrl->read_bytes = 0; |
319 | if (command != NAND_CMD_PAGEPROG) |
320 | elbc_fcm_ctrl->index = 0; |
321 | |
322 | switch (command) { |
323 | /* READ0 and READ1 read the entire buffer to use hardware ECC. */ |
324 | case NAND_CMD_READ1: |
325 | column += 256; |
326 | fallthrough; |
327 | case NAND_CMD_READ0: |
328 | dev_dbg(priv->dev, |
329 | "fsl_elbc_cmdfunc: NAND_CMD_READ0, page_addr:" |
330 | " 0x%x, column: 0x%x.\n" , page_addr, column); |
331 | |
332 | |
333 | out_be32(&lbc->fbcr, 0); /* read entire page to enable ECC */ |
334 | set_addr(mtd, column: 0, page_addr, oob: 0); |
335 | |
336 | elbc_fcm_ctrl->read_bytes = mtd->writesize + mtd->oobsize; |
337 | elbc_fcm_ctrl->index += column; |
338 | |
339 | fsl_elbc_do_read(chip, oob: 0); |
340 | fsl_elbc_run_command(mtd); |
341 | return; |
342 | |
343 | /* RNDOUT moves the pointer inside the page */ |
344 | case NAND_CMD_RNDOUT: |
345 | dev_dbg(priv->dev, |
346 | "fsl_elbc_cmdfunc: NAND_CMD_RNDOUT, column: 0x%x.\n" , |
347 | column); |
348 | |
349 | elbc_fcm_ctrl->index = column; |
350 | return; |
351 | |
352 | /* READOOB reads only the OOB because no ECC is performed. */ |
353 | case NAND_CMD_READOOB: |
354 | dev_vdbg(priv->dev, |
355 | "fsl_elbc_cmdfunc: NAND_CMD_READOOB, page_addr:" |
356 | " 0x%x, column: 0x%x.\n" , page_addr, column); |
357 | |
358 | out_be32(&lbc->fbcr, mtd->oobsize - column); |
359 | set_addr(mtd, column, page_addr, oob: 1); |
360 | |
361 | elbc_fcm_ctrl->read_bytes = mtd->writesize + mtd->oobsize; |
362 | |
363 | fsl_elbc_do_read(chip, oob: 1); |
364 | fsl_elbc_run_command(mtd); |
365 | return; |
366 | |
367 | case NAND_CMD_READID: |
368 | case NAND_CMD_PARAM: |
369 | dev_vdbg(priv->dev, "fsl_elbc_cmdfunc: NAND_CMD %x\n" , command); |
370 | |
371 | out_be32(&lbc->fir, (FIR_OP_CM0 << FIR_OP0_SHIFT) | |
372 | (FIR_OP_UA << FIR_OP1_SHIFT) | |
373 | (FIR_OP_RBW << FIR_OP2_SHIFT)); |
374 | out_be32(&lbc->fcr, command << FCR_CMD0_SHIFT); |
375 | /* |
376 | * although currently it's 8 bytes for READID, we always read |
377 | * the maximum 256 bytes(for PARAM) |
378 | */ |
379 | out_be32(&lbc->fbcr, 256); |
380 | elbc_fcm_ctrl->read_bytes = 256; |
381 | elbc_fcm_ctrl->use_mdr = 1; |
382 | elbc_fcm_ctrl->mdr = column; |
383 | set_addr(mtd, column: 0, page_addr: 0, oob: 0); |
384 | fsl_elbc_run_command(mtd); |
385 | return; |
386 | |
387 | /* ERASE1 stores the block and page address */ |
388 | case NAND_CMD_ERASE1: |
389 | dev_vdbg(priv->dev, |
390 | "fsl_elbc_cmdfunc: NAND_CMD_ERASE1, " |
391 | "page_addr: 0x%x.\n" , page_addr); |
392 | set_addr(mtd, column: 0, page_addr, oob: 0); |
393 | return; |
394 | |
395 | /* ERASE2 uses the block and page address from ERASE1 */ |
396 | case NAND_CMD_ERASE2: |
397 | dev_vdbg(priv->dev, "fsl_elbc_cmdfunc: NAND_CMD_ERASE2.\n" ); |
398 | |
399 | out_be32(&lbc->fir, |
400 | (FIR_OP_CM0 << FIR_OP0_SHIFT) | |
401 | (FIR_OP_PA << FIR_OP1_SHIFT) | |
402 | (FIR_OP_CM2 << FIR_OP2_SHIFT) | |
403 | (FIR_OP_CW1 << FIR_OP3_SHIFT) | |
404 | (FIR_OP_RS << FIR_OP4_SHIFT)); |
405 | |
406 | out_be32(&lbc->fcr, |
407 | (NAND_CMD_ERASE1 << FCR_CMD0_SHIFT) | |
408 | (NAND_CMD_STATUS << FCR_CMD1_SHIFT) | |
409 | (NAND_CMD_ERASE2 << FCR_CMD2_SHIFT)); |
410 | |
411 | out_be32(&lbc->fbcr, 0); |
412 | elbc_fcm_ctrl->read_bytes = 0; |
413 | elbc_fcm_ctrl->use_mdr = 1; |
414 | |
415 | fsl_elbc_run_command(mtd); |
416 | return; |
417 | |
418 | /* SEQIN sets up the addr buffer and all registers except the length */ |
419 | case NAND_CMD_SEQIN: { |
420 | __be32 fcr; |
421 | dev_vdbg(priv->dev, |
422 | "fsl_elbc_cmdfunc: NAND_CMD_SEQIN/PAGE_PROG, " |
423 | "page_addr: 0x%x, column: 0x%x.\n" , |
424 | page_addr, column); |
425 | |
426 | elbc_fcm_ctrl->column = column; |
427 | elbc_fcm_ctrl->use_mdr = 1; |
428 | |
429 | if (column >= mtd->writesize) { |
430 | /* OOB area */ |
431 | column -= mtd->writesize; |
432 | elbc_fcm_ctrl->oob = 1; |
433 | } else { |
434 | WARN_ON(column != 0); |
435 | elbc_fcm_ctrl->oob = 0; |
436 | } |
437 | |
438 | fcr = (NAND_CMD_STATUS << FCR_CMD1_SHIFT) | |
439 | (NAND_CMD_SEQIN << FCR_CMD2_SHIFT) | |
440 | (NAND_CMD_PAGEPROG << FCR_CMD3_SHIFT); |
441 | |
442 | if (priv->page_size) { |
443 | out_be32(&lbc->fir, |
444 | (FIR_OP_CM2 << FIR_OP0_SHIFT) | |
445 | (FIR_OP_CA << FIR_OP1_SHIFT) | |
446 | (FIR_OP_PA << FIR_OP2_SHIFT) | |
447 | (FIR_OP_WB << FIR_OP3_SHIFT) | |
448 | (FIR_OP_CM3 << FIR_OP4_SHIFT) | |
449 | (FIR_OP_CW1 << FIR_OP5_SHIFT) | |
450 | (FIR_OP_RS << FIR_OP6_SHIFT)); |
451 | } else { |
452 | out_be32(&lbc->fir, |
453 | (FIR_OP_CM0 << FIR_OP0_SHIFT) | |
454 | (FIR_OP_CM2 << FIR_OP1_SHIFT) | |
455 | (FIR_OP_CA << FIR_OP2_SHIFT) | |
456 | (FIR_OP_PA << FIR_OP3_SHIFT) | |
457 | (FIR_OP_WB << FIR_OP4_SHIFT) | |
458 | (FIR_OP_CM3 << FIR_OP5_SHIFT) | |
459 | (FIR_OP_CW1 << FIR_OP6_SHIFT) | |
460 | (FIR_OP_RS << FIR_OP7_SHIFT)); |
461 | |
462 | if (elbc_fcm_ctrl->oob) |
463 | /* OOB area --> READOOB */ |
464 | fcr |= NAND_CMD_READOOB << FCR_CMD0_SHIFT; |
465 | else |
466 | /* First 256 bytes --> READ0 */ |
467 | fcr |= NAND_CMD_READ0 << FCR_CMD0_SHIFT; |
468 | } |
469 | |
470 | out_be32(&lbc->fcr, fcr); |
471 | set_addr(mtd, column, page_addr, oob: elbc_fcm_ctrl->oob); |
472 | return; |
473 | } |
474 | |
475 | /* PAGEPROG reuses all of the setup from SEQIN and adds the length */ |
476 | case NAND_CMD_PAGEPROG: { |
477 | dev_vdbg(priv->dev, |
478 | "fsl_elbc_cmdfunc: NAND_CMD_PAGEPROG " |
479 | "writing %d bytes.\n" , elbc_fcm_ctrl->index); |
480 | |
481 | /* if the write did not start at 0 or is not a full page |
482 | * then set the exact length, otherwise use a full page |
483 | * write so the HW generates the ECC. |
484 | */ |
485 | if (elbc_fcm_ctrl->oob || elbc_fcm_ctrl->column != 0 || |
486 | elbc_fcm_ctrl->index != mtd->writesize + mtd->oobsize) |
487 | out_be32(&lbc->fbcr, |
488 | elbc_fcm_ctrl->index - elbc_fcm_ctrl->column); |
489 | else |
490 | out_be32(&lbc->fbcr, 0); |
491 | |
492 | fsl_elbc_run_command(mtd); |
493 | return; |
494 | } |
495 | |
496 | /* CMD_STATUS must read the status byte while CEB is active */ |
497 | /* Note - it does not wait for the ready line */ |
498 | case NAND_CMD_STATUS: |
499 | out_be32(&lbc->fir, |
500 | (FIR_OP_CM0 << FIR_OP0_SHIFT) | |
501 | (FIR_OP_RBW << FIR_OP1_SHIFT)); |
502 | out_be32(&lbc->fcr, NAND_CMD_STATUS << FCR_CMD0_SHIFT); |
503 | out_be32(&lbc->fbcr, 1); |
504 | set_addr(mtd, column: 0, page_addr: 0, oob: 0); |
505 | elbc_fcm_ctrl->read_bytes = 1; |
506 | |
507 | fsl_elbc_run_command(mtd); |
508 | |
509 | /* The chip always seems to report that it is |
510 | * write-protected, even when it is not. |
511 | */ |
512 | setbits8(elbc_fcm_ctrl->addr, NAND_STATUS_WP); |
513 | return; |
514 | |
515 | /* RESET without waiting for the ready line */ |
516 | case NAND_CMD_RESET: |
517 | dev_dbg(priv->dev, "fsl_elbc_cmdfunc: NAND_CMD_RESET.\n" ); |
518 | out_be32(&lbc->fir, FIR_OP_CM0 << FIR_OP0_SHIFT); |
519 | out_be32(&lbc->fcr, NAND_CMD_RESET << FCR_CMD0_SHIFT); |
520 | fsl_elbc_run_command(mtd); |
521 | return; |
522 | |
523 | default: |
524 | dev_err(priv->dev, |
525 | "fsl_elbc_cmdfunc: error, unsupported command 0x%x.\n" , |
526 | command); |
527 | } |
528 | } |
529 | |
530 | static void fsl_elbc_select_chip(struct nand_chip *chip, int cs) |
531 | { |
532 | /* The hardware does not seem to support multiple |
533 | * chips per bank. |
534 | */ |
535 | } |
536 | |
537 | /* |
538 | * Write buf to the FCM Controller Data Buffer |
539 | */ |
540 | static void fsl_elbc_write_buf(struct nand_chip *chip, const u8 *buf, int len) |
541 | { |
542 | struct mtd_info *mtd = nand_to_mtd(chip); |
543 | struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); |
544 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; |
545 | unsigned int bufsize = mtd->writesize + mtd->oobsize; |
546 | |
547 | if (len <= 0) { |
548 | dev_err(priv->dev, "write_buf of %d bytes" , len); |
549 | elbc_fcm_ctrl->status = 0; |
550 | return; |
551 | } |
552 | |
553 | if ((unsigned int)len > bufsize - elbc_fcm_ctrl->index) { |
554 | dev_err(priv->dev, |
555 | "write_buf beyond end of buffer " |
556 | "(%d requested, %u available)\n" , |
557 | len, bufsize - elbc_fcm_ctrl->index); |
558 | len = bufsize - elbc_fcm_ctrl->index; |
559 | } |
560 | |
561 | memcpy_toio(&elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index], buf, len); |
562 | /* |
563 | * This is workaround for the weird elbc hangs during nand write, |
564 | * Scott Wood says: "...perhaps difference in how long it takes a |
565 | * write to make it through the localbus compared to a write to IMMR |
566 | * is causing problems, and sync isn't helping for some reason." |
567 | * Reading back the last byte helps though. |
568 | */ |
569 | in_8(&elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index] + len - 1); |
570 | |
571 | elbc_fcm_ctrl->index += len; |
572 | } |
573 | |
574 | /* |
575 | * read a byte from either the FCM hardware buffer if it has any data left |
576 | * otherwise issue a command to read a single byte. |
577 | */ |
578 | static u8 fsl_elbc_read_byte(struct nand_chip *chip) |
579 | { |
580 | struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); |
581 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; |
582 | |
583 | /* If there are still bytes in the FCM, then use the next byte. */ |
584 | if (elbc_fcm_ctrl->index < elbc_fcm_ctrl->read_bytes) |
585 | return in_8(&elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index++]); |
586 | |
587 | dev_err(priv->dev, "read_byte beyond end of buffer\n" ); |
588 | return ERR_BYTE; |
589 | } |
590 | |
591 | /* |
592 | * Read from the FCM Controller Data Buffer |
593 | */ |
594 | static void fsl_elbc_read_buf(struct nand_chip *chip, u8 *buf, int len) |
595 | { |
596 | struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); |
597 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; |
598 | int avail; |
599 | |
600 | if (len < 0) |
601 | return; |
602 | |
603 | avail = min((unsigned int)len, |
604 | elbc_fcm_ctrl->read_bytes - elbc_fcm_ctrl->index); |
605 | memcpy_fromio(buf, &elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index], avail); |
606 | elbc_fcm_ctrl->index += avail; |
607 | |
608 | if (len > avail) |
609 | dev_err(priv->dev, |
610 | "read_buf beyond end of buffer " |
611 | "(%d requested, %d available)\n" , |
612 | len, avail); |
613 | } |
614 | |
615 | /* This function is called after Program and Erase Operations to |
616 | * check for success or failure. |
617 | */ |
618 | static int fsl_elbc_wait(struct nand_chip *chip) |
619 | { |
620 | struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); |
621 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; |
622 | |
623 | if (elbc_fcm_ctrl->status != LTESR_CC) |
624 | return NAND_STATUS_FAIL; |
625 | |
626 | /* The chip always seems to report that it is |
627 | * write-protected, even when it is not. |
628 | */ |
629 | return (elbc_fcm_ctrl->mdr & 0xff) | NAND_STATUS_WP; |
630 | } |
631 | |
632 | static int fsl_elbc_read_page(struct nand_chip *chip, uint8_t *buf, |
633 | int oob_required, int page) |
634 | { |
635 | struct mtd_info *mtd = nand_to_mtd(chip); |
636 | struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); |
637 | struct fsl_lbc_ctrl *ctrl = priv->ctrl; |
638 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; |
639 | |
640 | nand_read_page_op(chip, page, offset_in_page: 0, buf, len: mtd->writesize); |
641 | if (oob_required) |
642 | fsl_elbc_read_buf(chip, buf: chip->oob_poi, len: mtd->oobsize); |
643 | |
644 | if (fsl_elbc_wait(chip) & NAND_STATUS_FAIL) |
645 | mtd->ecc_stats.failed++; |
646 | |
647 | return elbc_fcm_ctrl->max_bitflips; |
648 | } |
649 | |
650 | /* ECC will be calculated automatically, and errors will be detected in |
651 | * waitfunc. |
652 | */ |
653 | static int fsl_elbc_write_page(struct nand_chip *chip, const uint8_t *buf, |
654 | int oob_required, int page) |
655 | { |
656 | struct mtd_info *mtd = nand_to_mtd(chip); |
657 | |
658 | nand_prog_page_begin_op(chip, page, offset_in_page: 0, buf, len: mtd->writesize); |
659 | fsl_elbc_write_buf(chip, buf: chip->oob_poi, len: mtd->oobsize); |
660 | |
661 | return nand_prog_page_end_op(chip); |
662 | } |
663 | |
664 | /* ECC will be calculated automatically, and errors will be detected in |
665 | * waitfunc. |
666 | */ |
667 | static int fsl_elbc_write_subpage(struct nand_chip *chip, uint32_t offset, |
668 | uint32_t data_len, const uint8_t *buf, |
669 | int oob_required, int page) |
670 | { |
671 | struct mtd_info *mtd = nand_to_mtd(chip); |
672 | |
673 | nand_prog_page_begin_op(chip, page, offset_in_page: 0, NULL, len: 0); |
674 | fsl_elbc_write_buf(chip, buf, len: mtd->writesize); |
675 | fsl_elbc_write_buf(chip, buf: chip->oob_poi, len: mtd->oobsize); |
676 | return nand_prog_page_end_op(chip); |
677 | } |
678 | |
679 | static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv) |
680 | { |
681 | struct fsl_lbc_ctrl *ctrl = priv->ctrl; |
682 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; |
683 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; |
684 | struct nand_chip *chip = &priv->chip; |
685 | struct mtd_info *mtd = nand_to_mtd(chip); |
686 | |
687 | dev_dbg(priv->dev, "eLBC Set Information for bank %d\n" , priv->bank); |
688 | |
689 | /* Fill in fsl_elbc_mtd structure */ |
690 | mtd->dev.parent = priv->dev; |
691 | nand_set_flash_node(chip, np: priv->dev->of_node); |
692 | |
693 | /* set timeout to maximum */ |
694 | priv->fmr = 15 << FMR_CWTO_SHIFT; |
695 | if (in_be32(&lbc->bank[priv->bank].or) & OR_FCM_PGS) |
696 | priv->fmr |= FMR_ECCM; |
697 | |
698 | /* fill in nand_chip structure */ |
699 | /* set up function call table */ |
700 | chip->legacy.read_byte = fsl_elbc_read_byte; |
701 | chip->legacy.write_buf = fsl_elbc_write_buf; |
702 | chip->legacy.read_buf = fsl_elbc_read_buf; |
703 | chip->legacy.select_chip = fsl_elbc_select_chip; |
704 | chip->legacy.cmdfunc = fsl_elbc_cmdfunc; |
705 | chip->legacy.waitfunc = fsl_elbc_wait; |
706 | chip->legacy.set_features = nand_get_set_features_notsupp; |
707 | chip->legacy.get_features = nand_get_set_features_notsupp; |
708 | |
709 | chip->bbt_td = &bbt_main_descr; |
710 | chip->bbt_md = &bbt_mirror_descr; |
711 | |
712 | /* set up nand options */ |
713 | chip->bbt_options = NAND_BBT_USE_FLASH; |
714 | |
715 | chip->controller = &elbc_fcm_ctrl->controller; |
716 | nand_set_controller_data(chip, priv); |
717 | |
718 | return 0; |
719 | } |
720 | |
721 | static int fsl_elbc_attach_chip(struct nand_chip *chip) |
722 | { |
723 | struct mtd_info *mtd = nand_to_mtd(chip); |
724 | struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); |
725 | struct fsl_lbc_ctrl *ctrl = priv->ctrl; |
726 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; |
727 | unsigned int al; |
728 | u32 br; |
729 | |
730 | /* |
731 | * if ECC was not chosen in DT, decide whether to use HW or SW ECC from |
732 | * CS Base Register |
733 | */ |
734 | if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_INVALID) { |
735 | /* If CS Base Register selects full hardware ECC then use it */ |
736 | if ((in_be32(&lbc->bank[priv->bank].br) & BR_DECC) == |
737 | BR_DECC_CHK_GEN) { |
738 | chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; |
739 | } else { |
740 | /* otherwise fall back to default software ECC */ |
741 | chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; |
742 | chip->ecc.algo = NAND_ECC_ALGO_HAMMING; |
743 | } |
744 | } |
745 | |
746 | switch (chip->ecc.engine_type) { |
747 | /* if HW ECC was chosen, setup ecc and oob layout */ |
748 | case NAND_ECC_ENGINE_TYPE_ON_HOST: |
749 | chip->ecc.read_page = fsl_elbc_read_page; |
750 | chip->ecc.write_page = fsl_elbc_write_page; |
751 | chip->ecc.write_subpage = fsl_elbc_write_subpage; |
752 | mtd_set_ooblayout(mtd, ooblayout: &fsl_elbc_ooblayout_ops); |
753 | chip->ecc.size = 512; |
754 | chip->ecc.bytes = 3; |
755 | chip->ecc.strength = 1; |
756 | break; |
757 | |
758 | /* if none or SW ECC was chosen, we do not need to set anything here */ |
759 | case NAND_ECC_ENGINE_TYPE_NONE: |
760 | case NAND_ECC_ENGINE_TYPE_SOFT: |
761 | case NAND_ECC_ENGINE_TYPE_ON_DIE: |
762 | break; |
763 | |
764 | default: |
765 | return -EINVAL; |
766 | } |
767 | |
768 | /* enable/disable HW ECC checking and generating based on if HW ECC was chosen */ |
769 | br = in_be32(&lbc->bank[priv->bank].br) & ~BR_DECC; |
770 | if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST) |
771 | out_be32(&lbc->bank[priv->bank].br, br | BR_DECC_CHK_GEN); |
772 | else |
773 | out_be32(&lbc->bank[priv->bank].br, br | BR_DECC_OFF); |
774 | |
775 | /* calculate FMR Address Length field */ |
776 | al = 0; |
777 | if (chip->pagemask & 0xffff0000) |
778 | al++; |
779 | if (chip->pagemask & 0xff000000) |
780 | al++; |
781 | |
782 | priv->fmr |= al << FMR_AL_SHIFT; |
783 | |
784 | dev_dbg(priv->dev, "fsl_elbc_init: nand->numchips = %d\n" , |
785 | nanddev_ntargets(&chip->base)); |
786 | dev_dbg(priv->dev, "fsl_elbc_init: nand->chipsize = %lld\n" , |
787 | nanddev_target_size(&chip->base)); |
788 | dev_dbg(priv->dev, "fsl_elbc_init: nand->pagemask = %8x\n" , |
789 | chip->pagemask); |
790 | dev_dbg(priv->dev, "fsl_elbc_init: nand->legacy.chip_delay = %d\n" , |
791 | chip->legacy.chip_delay); |
792 | dev_dbg(priv->dev, "fsl_elbc_init: nand->badblockpos = %d\n" , |
793 | chip->badblockpos); |
794 | dev_dbg(priv->dev, "fsl_elbc_init: nand->chip_shift = %d\n" , |
795 | chip->chip_shift); |
796 | dev_dbg(priv->dev, "fsl_elbc_init: nand->page_shift = %d\n" , |
797 | chip->page_shift); |
798 | dev_dbg(priv->dev, "fsl_elbc_init: nand->phys_erase_shift = %d\n" , |
799 | chip->phys_erase_shift); |
800 | dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.engine_type = %d\n" , |
801 | chip->ecc.engine_type); |
802 | dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.steps = %d\n" , |
803 | chip->ecc.steps); |
804 | dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.bytes = %d\n" , |
805 | chip->ecc.bytes); |
806 | dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.total = %d\n" , |
807 | chip->ecc.total); |
808 | dev_dbg(priv->dev, "fsl_elbc_init: mtd->ooblayout = %p\n" , |
809 | mtd->ooblayout); |
810 | dev_dbg(priv->dev, "fsl_elbc_init: mtd->flags = %08x\n" , mtd->flags); |
811 | dev_dbg(priv->dev, "fsl_elbc_init: mtd->size = %lld\n" , mtd->size); |
812 | dev_dbg(priv->dev, "fsl_elbc_init: mtd->erasesize = %d\n" , |
813 | mtd->erasesize); |
814 | dev_dbg(priv->dev, "fsl_elbc_init: mtd->writesize = %d\n" , |
815 | mtd->writesize); |
816 | dev_dbg(priv->dev, "fsl_elbc_init: mtd->oobsize = %d\n" , |
817 | mtd->oobsize); |
818 | |
819 | /* adjust Option Register and ECC to match Flash page size */ |
820 | if (mtd->writesize == 512) { |
821 | priv->page_size = 0; |
822 | clrbits32(&lbc->bank[priv->bank].or, OR_FCM_PGS); |
823 | } else if (mtd->writesize == 2048) { |
824 | priv->page_size = 1; |
825 | setbits32(&lbc->bank[priv->bank].or, OR_FCM_PGS); |
826 | } else { |
827 | dev_err(priv->dev, |
828 | "fsl_elbc_init: page size %d is not supported\n" , |
829 | mtd->writesize); |
830 | return -ENOTSUPP; |
831 | } |
832 | |
833 | return 0; |
834 | } |
835 | |
836 | static const struct nand_controller_ops fsl_elbc_controller_ops = { |
837 | .attach_chip = fsl_elbc_attach_chip, |
838 | }; |
839 | |
840 | static int fsl_elbc_chip_remove(struct fsl_elbc_mtd *priv) |
841 | { |
842 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; |
843 | struct mtd_info *mtd = nand_to_mtd(chip: &priv->chip); |
844 | |
845 | kfree(objp: mtd->name); |
846 | |
847 | if (priv->vbase) |
848 | iounmap(addr: priv->vbase); |
849 | |
850 | elbc_fcm_ctrl->chips[priv->bank] = NULL; |
851 | kfree(objp: priv); |
852 | return 0; |
853 | } |
854 | |
855 | static DEFINE_MUTEX(fsl_elbc_nand_mutex); |
856 | |
857 | static int fsl_elbc_nand_probe(struct platform_device *pdev) |
858 | { |
859 | struct fsl_lbc_regs __iomem *lbc; |
860 | struct fsl_elbc_mtd *priv; |
861 | struct resource res; |
862 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl; |
863 | static const char *part_probe_types[] |
864 | = { "cmdlinepart" , "RedBoot" , "ofpart" , NULL }; |
865 | int ret; |
866 | int bank; |
867 | struct device *dev; |
868 | struct device_node *node = pdev->dev.of_node; |
869 | struct mtd_info *mtd; |
870 | |
871 | if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs) |
872 | return dev_err_probe(dev: &pdev->dev, err: -EPROBE_DEFER, fmt: "lbc_ctrl_dev missing\n" ); |
873 | |
874 | lbc = fsl_lbc_ctrl_dev->regs; |
875 | dev = fsl_lbc_ctrl_dev->dev; |
876 | |
877 | /* get, allocate and map the memory resource */ |
878 | ret = of_address_to_resource(dev: node, index: 0, r: &res); |
879 | if (ret) { |
880 | dev_err(dev, "failed to get resource\n" ); |
881 | return ret; |
882 | } |
883 | |
884 | /* find which chip select it is connected to */ |
885 | for (bank = 0; bank < MAX_BANKS; bank++) |
886 | if ((in_be32(&lbc->bank[bank].br) & BR_V) && |
887 | (in_be32(&lbc->bank[bank].br) & BR_MSEL) == BR_MS_FCM && |
888 | (in_be32(&lbc->bank[bank].br) & |
889 | in_be32(&lbc->bank[bank].or) & BR_BA) |
890 | == fsl_lbc_addr(res.start)) |
891 | break; |
892 | |
893 | if (bank >= MAX_BANKS) { |
894 | dev_err(dev, "address did not match any chip selects\n" ); |
895 | return -ENODEV; |
896 | } |
897 | |
898 | priv = kzalloc(size: sizeof(*priv), GFP_KERNEL); |
899 | if (!priv) |
900 | return -ENOMEM; |
901 | |
902 | mutex_lock(&fsl_elbc_nand_mutex); |
903 | if (!fsl_lbc_ctrl_dev->nand) { |
904 | elbc_fcm_ctrl = kzalloc(size: sizeof(*elbc_fcm_ctrl), GFP_KERNEL); |
905 | if (!elbc_fcm_ctrl) { |
906 | mutex_unlock(lock: &fsl_elbc_nand_mutex); |
907 | ret = -ENOMEM; |
908 | goto err; |
909 | } |
910 | elbc_fcm_ctrl->counter++; |
911 | |
912 | nand_controller_init(nfc: &elbc_fcm_ctrl->controller); |
913 | fsl_lbc_ctrl_dev->nand = elbc_fcm_ctrl; |
914 | } else { |
915 | elbc_fcm_ctrl = fsl_lbc_ctrl_dev->nand; |
916 | } |
917 | mutex_unlock(lock: &fsl_elbc_nand_mutex); |
918 | |
919 | elbc_fcm_ctrl->chips[bank] = priv; |
920 | priv->bank = bank; |
921 | priv->ctrl = fsl_lbc_ctrl_dev; |
922 | priv->dev = &pdev->dev; |
923 | dev_set_drvdata(dev: priv->dev, data: priv); |
924 | |
925 | priv->vbase = ioremap(offset: res.start, size: resource_size(res: &res)); |
926 | if (!priv->vbase) { |
927 | dev_err(dev, "failed to map chip region\n" ); |
928 | ret = -ENOMEM; |
929 | goto err; |
930 | } |
931 | |
932 | mtd = nand_to_mtd(chip: &priv->chip); |
933 | mtd->name = kasprintf(GFP_KERNEL, fmt: "%llx.flash" , (u64)res.start); |
934 | if (!nand_to_mtd(chip: &priv->chip)->name) { |
935 | ret = -ENOMEM; |
936 | goto err; |
937 | } |
938 | |
939 | ret = fsl_elbc_chip_init(priv); |
940 | if (ret) |
941 | goto err; |
942 | |
943 | priv->chip.controller->ops = &fsl_elbc_controller_ops; |
944 | ret = nand_scan(chip: &priv->chip, max_chips: 1); |
945 | if (ret) |
946 | goto err; |
947 | |
948 | /* First look for RedBoot table or partitions on the command |
949 | * line, these take precedence over device tree information */ |
950 | ret = mtd_device_parse_register(mtd, part_probe_types, NULL, NULL, defnr_parts: 0); |
951 | if (ret) |
952 | goto cleanup_nand; |
953 | |
954 | pr_info("eLBC NAND device at 0x%llx, bank %d\n" , |
955 | (unsigned long long)res.start, priv->bank); |
956 | |
957 | return 0; |
958 | |
959 | cleanup_nand: |
960 | nand_cleanup(chip: &priv->chip); |
961 | err: |
962 | fsl_elbc_chip_remove(priv); |
963 | |
964 | return ret; |
965 | } |
966 | |
967 | static void fsl_elbc_nand_remove(struct platform_device *pdev) |
968 | { |
969 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = fsl_lbc_ctrl_dev->nand; |
970 | struct fsl_elbc_mtd *priv = dev_get_drvdata(dev: &pdev->dev); |
971 | struct nand_chip *chip = &priv->chip; |
972 | int ret; |
973 | |
974 | ret = mtd_device_unregister(master: nand_to_mtd(chip)); |
975 | WARN_ON(ret); |
976 | nand_cleanup(chip); |
977 | |
978 | fsl_elbc_chip_remove(priv); |
979 | |
980 | mutex_lock(&fsl_elbc_nand_mutex); |
981 | elbc_fcm_ctrl->counter--; |
982 | if (!elbc_fcm_ctrl->counter) { |
983 | fsl_lbc_ctrl_dev->nand = NULL; |
984 | kfree(objp: elbc_fcm_ctrl); |
985 | } |
986 | mutex_unlock(lock: &fsl_elbc_nand_mutex); |
987 | |
988 | } |
989 | |
990 | static const struct of_device_id fsl_elbc_nand_match[] = { |
991 | { .compatible = "fsl,elbc-fcm-nand" , }, |
992 | {} |
993 | }; |
994 | MODULE_DEVICE_TABLE(of, fsl_elbc_nand_match); |
995 | |
996 | static struct platform_driver fsl_elbc_nand_driver = { |
997 | .driver = { |
998 | .name = "fsl,elbc-fcm-nand" , |
999 | .of_match_table = fsl_elbc_nand_match, |
1000 | }, |
1001 | .probe = fsl_elbc_nand_probe, |
1002 | .remove_new = fsl_elbc_nand_remove, |
1003 | }; |
1004 | |
1005 | module_platform_driver(fsl_elbc_nand_driver); |
1006 | |
1007 | MODULE_LICENSE("GPL" ); |
1008 | MODULE_AUTHOR("Freescale" ); |
1009 | MODULE_DESCRIPTION("Freescale Enhanced Local Bus Controller MTD NAND driver" ); |
1010 | |