| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 3 | | - * under the terms of the GNU General Public License version 2 as published |
|---|
| 4 | | - * by the Free Software Foundation. |
|---|
| 5 | 3 | * |
|---|
| 6 | 4 | * Copyright © 2012 John Crispin <john@phrozen.org> |
|---|
| 7 | 5 | * Copyright © 2016 Hauke Mehrtens <hauke@hauke-m.de> |
|---|
| .. | .. |
|---|
| 64 | 62 | #define NAND_CON_NANDM 1 |
|---|
| 65 | 63 | |
|---|
| 66 | 64 | struct xway_nand_data { |
|---|
| 65 | + struct nand_controller controller; |
|---|
| 67 | 66 | struct nand_chip chip; |
|---|
| 68 | 67 | unsigned long csflags; |
|---|
| 69 | 68 | void __iomem *nandaddr; |
|---|
| .. | .. |
|---|
| 85 | 84 | writeb(value, data->nandaddr + op); |
|---|
| 86 | 85 | } |
|---|
| 87 | 86 | |
|---|
| 88 | | -static void xway_select_chip(struct mtd_info *mtd, int select) |
|---|
| 87 | +static void xway_select_chip(struct nand_chip *chip, int select) |
|---|
| 89 | 88 | { |
|---|
| 90 | | - struct nand_chip *chip = mtd_to_nand(mtd); |
|---|
| 91 | 89 | struct xway_nand_data *data = nand_get_controller_data(chip); |
|---|
| 92 | 90 | |
|---|
| 93 | 91 | switch (select) { |
|---|
| .. | .. |
|---|
| 106 | 104 | } |
|---|
| 107 | 105 | } |
|---|
| 108 | 106 | |
|---|
| 109 | | -static void xway_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
|---|
| 107 | +static void xway_cmd_ctrl(struct nand_chip *chip, int cmd, unsigned int ctrl) |
|---|
| 110 | 108 | { |
|---|
| 109 | + struct mtd_info *mtd = nand_to_mtd(chip); |
|---|
| 110 | + |
|---|
| 111 | 111 | if (cmd == NAND_CMD_NONE) |
|---|
| 112 | 112 | return; |
|---|
| 113 | 113 | |
|---|
| .. | .. |
|---|
| 120 | 120 | ; |
|---|
| 121 | 121 | } |
|---|
| 122 | 122 | |
|---|
| 123 | | -static int xway_dev_ready(struct mtd_info *mtd) |
|---|
| 123 | +static int xway_dev_ready(struct nand_chip *chip) |
|---|
| 124 | 124 | { |
|---|
| 125 | 125 | return ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_RD; |
|---|
| 126 | 126 | } |
|---|
| 127 | 127 | |
|---|
| 128 | | -static unsigned char xway_read_byte(struct mtd_info *mtd) |
|---|
| 128 | +static unsigned char xway_read_byte(struct nand_chip *chip) |
|---|
| 129 | 129 | { |
|---|
| 130 | | - return xway_readb(mtd, NAND_READ_DATA); |
|---|
| 130 | + return xway_readb(nand_to_mtd(chip), NAND_READ_DATA); |
|---|
| 131 | 131 | } |
|---|
| 132 | 132 | |
|---|
| 133 | | -static void xway_read_buf(struct mtd_info *mtd, u_char *buf, int len) |
|---|
| 133 | +static void xway_read_buf(struct nand_chip *chip, u_char *buf, int len) |
|---|
| 134 | 134 | { |
|---|
| 135 | 135 | int i; |
|---|
| 136 | 136 | |
|---|
| 137 | 137 | for (i = 0; i < len; i++) |
|---|
| 138 | | - buf[i] = xway_readb(mtd, NAND_WRITE_DATA); |
|---|
| 138 | + buf[i] = xway_readb(nand_to_mtd(chip), NAND_WRITE_DATA); |
|---|
| 139 | 139 | } |
|---|
| 140 | 140 | |
|---|
| 141 | | -static void xway_write_buf(struct mtd_info *mtd, const u_char *buf, int len) |
|---|
| 141 | +static void xway_write_buf(struct nand_chip *chip, const u_char *buf, int len) |
|---|
| 142 | 142 | { |
|---|
| 143 | 143 | int i; |
|---|
| 144 | 144 | |
|---|
| 145 | 145 | for (i = 0; i < len; i++) |
|---|
| 146 | | - xway_writeb(mtd, NAND_WRITE_DATA, buf[i]); |
|---|
| 146 | + xway_writeb(nand_to_mtd(chip), NAND_WRITE_DATA, buf[i]); |
|---|
| 147 | 147 | } |
|---|
| 148 | + |
|---|
| 149 | +static int xway_attach_chip(struct nand_chip *chip) |
|---|
| 150 | +{ |
|---|
| 151 | + if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT && |
|---|
| 152 | + chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN) |
|---|
| 153 | + chip->ecc.algo = NAND_ECC_ALGO_HAMMING; |
|---|
| 154 | + |
|---|
| 155 | + return 0; |
|---|
| 156 | +} |
|---|
| 157 | + |
|---|
| 158 | +static const struct nand_controller_ops xway_nand_ops = { |
|---|
| 159 | + .attach_chip = xway_attach_chip, |
|---|
| 160 | +}; |
|---|
| 148 | 161 | |
|---|
| 149 | 162 | /* |
|---|
| 150 | 163 | * Probe for the NAND device. |
|---|
| .. | .. |
|---|
| 173 | 186 | mtd = nand_to_mtd(&data->chip); |
|---|
| 174 | 187 | mtd->dev.parent = &pdev->dev; |
|---|
| 175 | 188 | |
|---|
| 176 | | - data->chip.cmd_ctrl = xway_cmd_ctrl; |
|---|
| 177 | | - data->chip.dev_ready = xway_dev_ready; |
|---|
| 178 | | - data->chip.select_chip = xway_select_chip; |
|---|
| 179 | | - data->chip.write_buf = xway_write_buf; |
|---|
| 180 | | - data->chip.read_buf = xway_read_buf; |
|---|
| 181 | | - data->chip.read_byte = xway_read_byte; |
|---|
| 182 | | - data->chip.chip_delay = 30; |
|---|
| 189 | + data->chip.legacy.cmd_ctrl = xway_cmd_ctrl; |
|---|
| 190 | + data->chip.legacy.dev_ready = xway_dev_ready; |
|---|
| 191 | + data->chip.legacy.select_chip = xway_select_chip; |
|---|
| 192 | + data->chip.legacy.write_buf = xway_write_buf; |
|---|
| 193 | + data->chip.legacy.read_buf = xway_read_buf; |
|---|
| 194 | + data->chip.legacy.read_byte = xway_read_byte; |
|---|
| 195 | + data->chip.legacy.chip_delay = 30; |
|---|
| 183 | 196 | |
|---|
| 184 | | - data->chip.ecc.mode = NAND_ECC_SOFT; |
|---|
| 185 | | - data->chip.ecc.algo = NAND_ECC_HAMMING; |
|---|
| 197 | + nand_controller_init(&data->controller); |
|---|
| 198 | + data->controller.ops = &xway_nand_ops; |
|---|
| 199 | + data->chip.controller = &data->controller; |
|---|
| 186 | 200 | |
|---|
| 187 | 201 | platform_set_drvdata(pdev, data); |
|---|
| 188 | 202 | nand_set_controller_data(&data->chip, data); |
|---|
| .. | .. |
|---|
| 204 | 218 | | NAND_CON_SE_P | NAND_CON_WP_P | NAND_CON_PRE_P |
|---|
| 205 | 219 | | cs_flag, EBU_NAND_CON); |
|---|
| 206 | 220 | |
|---|
| 221 | + /* |
|---|
| 222 | + * This driver assumes that the default ECC engine should be TYPE_SOFT. |
|---|
| 223 | + * Set ->engine_type before registering the NAND devices in order to |
|---|
| 224 | + * provide a driver specific default value. |
|---|
| 225 | + */ |
|---|
| 226 | + data->chip.ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; |
|---|
| 227 | + |
|---|
| 207 | 228 | /* Scan to find existence of the device */ |
|---|
| 208 | 229 | err = nand_scan(&data->chip, 1); |
|---|
| 209 | 230 | if (err) |
|---|
| .. | .. |
|---|
| 222 | 243 | static int xway_nand_remove(struct platform_device *pdev) |
|---|
| 223 | 244 | { |
|---|
| 224 | 245 | struct xway_nand_data *data = platform_get_drvdata(pdev); |
|---|
| 246 | + struct nand_chip *chip = &data->chip; |
|---|
| 247 | + int ret; |
|---|
| 225 | 248 | |
|---|
| 226 | | - nand_release(&data->chip); |
|---|
| 249 | + ret = mtd_device_unregister(nand_to_mtd(chip)); |
|---|
| 250 | + WARN_ON(ret); |
|---|
| 251 | + nand_cleanup(chip); |
|---|
| 227 | 252 | |
|---|
| 228 | 253 | return 0; |
|---|
| 229 | 254 | } |
|---|