.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * TXx9 NAND flash memory controller driver |
---|
3 | 4 | * Based on RBTX49xx patch from CELF patch archive. |
---|
4 | | - * |
---|
5 | | - * This program is free software; you can redistribute it and/or modify |
---|
6 | | - * it under the terms of the GNU General Public License version 2 as |
---|
7 | | - * published by the Free Software Foundation. |
---|
8 | 5 | * |
---|
9 | 6 | * (C) Copyright TOSHIBA CORPORATION 2004-2007 |
---|
10 | 7 | * All Rights Reserved. |
---|
.. | .. |
---|
102 | 99 | __raw_writel(val, ndregaddr(dev, reg)); |
---|
103 | 100 | } |
---|
104 | 101 | |
---|
105 | | -static uint8_t txx9ndfmc_read_byte(struct mtd_info *mtd) |
---|
| 102 | +static uint8_t txx9ndfmc_read_byte(struct nand_chip *chip) |
---|
106 | 103 | { |
---|
107 | | - struct platform_device *dev = mtd_to_platdev(mtd); |
---|
| 104 | + struct platform_device *dev = mtd_to_platdev(nand_to_mtd(chip)); |
---|
108 | 105 | |
---|
109 | 106 | return txx9ndfmc_read(dev, TXX9_NDFDTR); |
---|
110 | 107 | } |
---|
111 | 108 | |
---|
112 | | -static void txx9ndfmc_write_buf(struct mtd_info *mtd, const uint8_t *buf, |
---|
| 109 | +static void txx9ndfmc_write_buf(struct nand_chip *chip, const uint8_t *buf, |
---|
113 | 110 | int len) |
---|
114 | 111 | { |
---|
115 | | - struct platform_device *dev = mtd_to_platdev(mtd); |
---|
| 112 | + struct platform_device *dev = mtd_to_platdev(nand_to_mtd(chip)); |
---|
116 | 113 | void __iomem *ndfdtr = ndregaddr(dev, TXX9_NDFDTR); |
---|
117 | 114 | u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR); |
---|
118 | 115 | |
---|
.. | .. |
---|
122 | 119 | txx9ndfmc_write(dev, mcr, TXX9_NDFMCR); |
---|
123 | 120 | } |
---|
124 | 121 | |
---|
125 | | -static void txx9ndfmc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) |
---|
| 122 | +static void txx9ndfmc_read_buf(struct nand_chip *chip, uint8_t *buf, int len) |
---|
126 | 123 | { |
---|
127 | | - struct platform_device *dev = mtd_to_platdev(mtd); |
---|
| 124 | + struct platform_device *dev = mtd_to_platdev(nand_to_mtd(chip)); |
---|
128 | 125 | void __iomem *ndfdtr = ndregaddr(dev, TXX9_NDFDTR); |
---|
129 | 126 | |
---|
130 | 127 | while (len--) |
---|
131 | 128 | *buf++ = __raw_readl(ndfdtr); |
---|
132 | 129 | } |
---|
133 | 130 | |
---|
134 | | -static void txx9ndfmc_cmd_ctrl(struct mtd_info *mtd, int cmd, |
---|
| 131 | +static void txx9ndfmc_cmd_ctrl(struct nand_chip *chip, int cmd, |
---|
135 | 132 | unsigned int ctrl) |
---|
136 | 133 | { |
---|
137 | | - struct nand_chip *chip = mtd_to_nand(mtd); |
---|
138 | 134 | struct txx9ndfmc_priv *txx9_priv = nand_get_controller_data(chip); |
---|
139 | 135 | struct platform_device *dev = txx9_priv->dev; |
---|
140 | 136 | struct txx9ndfmc_platform_data *plat = dev_get_platdata(&dev->dev); |
---|
.. | .. |
---|
160 | 156 | if ((ctrl & NAND_CTRL_CHANGE) && cmd == NAND_CMD_NONE) |
---|
161 | 157 | txx9ndfmc_write(dev, 0, TXX9_NDFDTR); |
---|
162 | 158 | } |
---|
163 | | - mmiowb(); |
---|
164 | 159 | } |
---|
165 | 160 | |
---|
166 | | -static int txx9ndfmc_dev_ready(struct mtd_info *mtd) |
---|
| 161 | +static int txx9ndfmc_dev_ready(struct nand_chip *chip) |
---|
167 | 162 | { |
---|
168 | | - struct platform_device *dev = mtd_to_platdev(mtd); |
---|
| 163 | + struct platform_device *dev = mtd_to_platdev(nand_to_mtd(chip)); |
---|
169 | 164 | |
---|
170 | 165 | return !(txx9ndfmc_read(dev, TXX9_NDFSR) & TXX9_NDFSR_BUSY); |
---|
171 | 166 | } |
---|
172 | 167 | |
---|
173 | | -static int txx9ndfmc_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat, |
---|
| 168 | +static int txx9ndfmc_calculate_ecc(struct nand_chip *chip, const uint8_t *dat, |
---|
174 | 169 | uint8_t *ecc_code) |
---|
175 | 170 | { |
---|
176 | | - struct platform_device *dev = mtd_to_platdev(mtd); |
---|
177 | | - struct nand_chip *chip = mtd_to_nand(mtd); |
---|
| 171 | + struct platform_device *dev = mtd_to_platdev(nand_to_mtd(chip)); |
---|
178 | 172 | int eccbytes; |
---|
179 | 173 | u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR); |
---|
180 | 174 | |
---|
.. | .. |
---|
191 | 185 | return 0; |
---|
192 | 186 | } |
---|
193 | 187 | |
---|
194 | | -static int txx9ndfmc_correct_data(struct mtd_info *mtd, unsigned char *buf, |
---|
195 | | - unsigned char *read_ecc, unsigned char *calc_ecc) |
---|
| 188 | +static int txx9ndfmc_correct_data(struct nand_chip *chip, unsigned char *buf, |
---|
| 189 | + unsigned char *read_ecc, |
---|
| 190 | + unsigned char *calc_ecc) |
---|
196 | 191 | { |
---|
197 | | - struct nand_chip *chip = mtd_to_nand(mtd); |
---|
198 | 192 | int eccsize; |
---|
199 | 193 | int corrected = 0; |
---|
200 | 194 | int stat; |
---|
201 | 195 | |
---|
202 | 196 | for (eccsize = chip->ecc.size; eccsize > 0; eccsize -= 256) { |
---|
203 | | - stat = __nand_correct_data(buf, read_ecc, calc_ecc, 256); |
---|
| 197 | + stat = __nand_correct_data(buf, read_ecc, calc_ecc, 256, |
---|
| 198 | + false); |
---|
204 | 199 | if (stat < 0) |
---|
205 | 200 | return stat; |
---|
206 | 201 | corrected += stat; |
---|
.. | .. |
---|
211 | 206 | return corrected; |
---|
212 | 207 | } |
---|
213 | 208 | |
---|
214 | | -static void txx9ndfmc_enable_hwecc(struct mtd_info *mtd, int mode) |
---|
| 209 | +static void txx9ndfmc_enable_hwecc(struct nand_chip *chip, int mode) |
---|
215 | 210 | { |
---|
216 | | - struct platform_device *dev = mtd_to_platdev(mtd); |
---|
| 211 | + struct platform_device *dev = mtd_to_platdev(nand_to_mtd(chip)); |
---|
217 | 212 | u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR); |
---|
218 | 213 | |
---|
219 | 214 | mcr &= ~TXX9_NDFMCR_ECC_ALL; |
---|
.. | .. |
---|
258 | 253 | { |
---|
259 | 254 | struct mtd_info *mtd = nand_to_mtd(chip); |
---|
260 | 255 | |
---|
| 256 | + if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST) |
---|
| 257 | + return 0; |
---|
| 258 | + |
---|
| 259 | + chip->ecc.strength = 1; |
---|
| 260 | + |
---|
261 | 261 | if (mtd->writesize >= 512) { |
---|
262 | 262 | chip->ecc.size = 512; |
---|
263 | 263 | chip->ecc.bytes = 6; |
---|
.. | .. |
---|
265 | 265 | chip->ecc.size = 256; |
---|
266 | 266 | chip->ecc.bytes = 3; |
---|
267 | 267 | } |
---|
| 268 | + |
---|
| 269 | + chip->ecc.calculate = txx9ndfmc_calculate_ecc; |
---|
| 270 | + chip->ecc.correct = txx9ndfmc_correct_data; |
---|
| 271 | + chip->ecc.hwctl = txx9ndfmc_enable_hwecc; |
---|
268 | 272 | |
---|
269 | 273 | return 0; |
---|
270 | 274 | } |
---|
.. | .. |
---|
326 | 330 | mtd = nand_to_mtd(chip); |
---|
327 | 331 | mtd->dev.parent = &dev->dev; |
---|
328 | 332 | |
---|
329 | | - chip->read_byte = txx9ndfmc_read_byte; |
---|
330 | | - chip->read_buf = txx9ndfmc_read_buf; |
---|
331 | | - chip->write_buf = txx9ndfmc_write_buf; |
---|
332 | | - chip->cmd_ctrl = txx9ndfmc_cmd_ctrl; |
---|
333 | | - chip->dev_ready = txx9ndfmc_dev_ready; |
---|
334 | | - chip->ecc.calculate = txx9ndfmc_calculate_ecc; |
---|
335 | | - chip->ecc.correct = txx9ndfmc_correct_data; |
---|
336 | | - chip->ecc.hwctl = txx9ndfmc_enable_hwecc; |
---|
337 | | - chip->ecc.mode = NAND_ECC_HW; |
---|
338 | | - chip->ecc.strength = 1; |
---|
339 | | - chip->chip_delay = 100; |
---|
| 333 | + chip->legacy.read_byte = txx9ndfmc_read_byte; |
---|
| 334 | + chip->legacy.read_buf = txx9ndfmc_read_buf; |
---|
| 335 | + chip->legacy.write_buf = txx9ndfmc_write_buf; |
---|
| 336 | + chip->legacy.cmd_ctrl = txx9ndfmc_cmd_ctrl; |
---|
| 337 | + chip->legacy.dev_ready = txx9ndfmc_dev_ready; |
---|
| 338 | + chip->legacy.chip_delay = 100; |
---|
340 | 339 | chip->controller = &drvdata->controller; |
---|
341 | 340 | |
---|
342 | 341 | nand_set_controller_data(chip, txx9_priv); |
---|
.. | .. |
---|
376 | 375 | static int __exit txx9ndfmc_remove(struct platform_device *dev) |
---|
377 | 376 | { |
---|
378 | 377 | struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev); |
---|
379 | | - int i; |
---|
| 378 | + int ret, i; |
---|
380 | 379 | |
---|
381 | 380 | if (!drvdata) |
---|
382 | 381 | return 0; |
---|
.. | .. |
---|
390 | 389 | chip = mtd_to_nand(mtd); |
---|
391 | 390 | txx9_priv = nand_get_controller_data(chip); |
---|
392 | 391 | |
---|
393 | | - nand_release(chip); |
---|
| 392 | + ret = mtd_device_unregister(nand_to_mtd(chip)); |
---|
| 393 | + WARN_ON(ret); |
---|
| 394 | + nand_cleanup(chip); |
---|
394 | 395 | kfree(txx9_priv->mtdname); |
---|
395 | 396 | kfree(txx9_priv); |
---|
396 | 397 | } |
---|