| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Overview: |
|---|
| 3 | 4 | * Platform independent driver for NDFC (NanD Flash Controller) |
|---|
| .. | .. |
|---|
| 14 | 15 | * Copyright 2006 IBM |
|---|
| 15 | 16 | * Copyright 2008 PIKA Technologies |
|---|
| 16 | 17 | * Sean MacLennan <smaclennan@pikatech.com> |
|---|
| 17 | | - * |
|---|
| 18 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 19 | | - * under the terms of the GNU General Public License as published by the |
|---|
| 20 | | - * Free Software Foundation; either version 2 of the License, or (at your |
|---|
| 21 | | - * option) any later version. |
|---|
| 22 | | - * |
|---|
| 23 | 18 | */ |
|---|
| 24 | 19 | #include <linux/module.h> |
|---|
| 25 | 20 | #include <linux/mtd/rawnand.h> |
|---|
| .. | .. |
|---|
| 44 | 39 | |
|---|
| 45 | 40 | static struct ndfc_controller ndfc_ctrl[NDFC_MAX_CS]; |
|---|
| 46 | 41 | |
|---|
| 47 | | -static void ndfc_select_chip(struct mtd_info *mtd, int chip) |
|---|
| 42 | +static void ndfc_select_chip(struct nand_chip *nchip, int chip) |
|---|
| 48 | 43 | { |
|---|
| 49 | 44 | uint32_t ccr; |
|---|
| 50 | | - struct nand_chip *nchip = mtd_to_nand(mtd); |
|---|
| 51 | 45 | struct ndfc_controller *ndfc = nand_get_controller_data(nchip); |
|---|
| 52 | 46 | |
|---|
| 53 | 47 | ccr = in_be32(ndfc->ndfcbase + NDFC_CCR); |
|---|
| .. | .. |
|---|
| 59 | 53 | out_be32(ndfc->ndfcbase + NDFC_CCR, ccr); |
|---|
| 60 | 54 | } |
|---|
| 61 | 55 | |
|---|
| 62 | | -static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
|---|
| 56 | +static void ndfc_hwcontrol(struct nand_chip *chip, int cmd, unsigned int ctrl) |
|---|
| 63 | 57 | { |
|---|
| 64 | | - struct nand_chip *chip = mtd_to_nand(mtd); |
|---|
| 65 | 58 | struct ndfc_controller *ndfc = nand_get_controller_data(chip); |
|---|
| 66 | 59 | |
|---|
| 67 | 60 | if (cmd == NAND_CMD_NONE) |
|---|
| .. | .. |
|---|
| 73 | 66 | writel(cmd & 0xFF, ndfc->ndfcbase + NDFC_ALE); |
|---|
| 74 | 67 | } |
|---|
| 75 | 68 | |
|---|
| 76 | | -static int ndfc_ready(struct mtd_info *mtd) |
|---|
| 69 | +static int ndfc_ready(struct nand_chip *chip) |
|---|
| 77 | 70 | { |
|---|
| 78 | | - struct nand_chip *chip = mtd_to_nand(mtd); |
|---|
| 79 | 71 | struct ndfc_controller *ndfc = nand_get_controller_data(chip); |
|---|
| 80 | 72 | |
|---|
| 81 | 73 | return in_be32(ndfc->ndfcbase + NDFC_STAT) & NDFC_STAT_IS_READY; |
|---|
| 82 | 74 | } |
|---|
| 83 | 75 | |
|---|
| 84 | | -static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode) |
|---|
| 76 | +static void ndfc_enable_hwecc(struct nand_chip *chip, int mode) |
|---|
| 85 | 77 | { |
|---|
| 86 | 78 | uint32_t ccr; |
|---|
| 87 | | - struct nand_chip *chip = mtd_to_nand(mtd); |
|---|
| 88 | 79 | struct ndfc_controller *ndfc = nand_get_controller_data(chip); |
|---|
| 89 | 80 | |
|---|
| 90 | 81 | ccr = in_be32(ndfc->ndfcbase + NDFC_CCR); |
|---|
| .. | .. |
|---|
| 93 | 84 | wmb(); |
|---|
| 94 | 85 | } |
|---|
| 95 | 86 | |
|---|
| 96 | | -static int ndfc_calculate_ecc(struct mtd_info *mtd, |
|---|
| 87 | +static int ndfc_calculate_ecc(struct nand_chip *chip, |
|---|
| 97 | 88 | const u_char *dat, u_char *ecc_code) |
|---|
| 98 | 89 | { |
|---|
| 99 | | - struct nand_chip *chip = mtd_to_nand(mtd); |
|---|
| 100 | 90 | struct ndfc_controller *ndfc = nand_get_controller_data(chip); |
|---|
| 101 | 91 | uint32_t ecc; |
|---|
| 102 | 92 | uint8_t *p = (uint8_t *)&ecc; |
|---|
| .. | .. |
|---|
| 118 | 108 | * functions. No further checking, as nand_base will always read/write |
|---|
| 119 | 109 | * page aligned. |
|---|
| 120 | 110 | */ |
|---|
| 121 | | -static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) |
|---|
| 111 | +static void ndfc_read_buf(struct nand_chip *chip, uint8_t *buf, int len) |
|---|
| 122 | 112 | { |
|---|
| 123 | | - struct nand_chip *chip = mtd_to_nand(mtd); |
|---|
| 124 | 113 | struct ndfc_controller *ndfc = nand_get_controller_data(chip); |
|---|
| 125 | 114 | uint32_t *p = (uint32_t *) buf; |
|---|
| 126 | 115 | |
|---|
| .. | .. |
|---|
| 128 | 117 | *p++ = in_be32(ndfc->ndfcbase + NDFC_DATA); |
|---|
| 129 | 118 | } |
|---|
| 130 | 119 | |
|---|
| 131 | | -static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) |
|---|
| 120 | +static void ndfc_write_buf(struct nand_chip *chip, const uint8_t *buf, int len) |
|---|
| 132 | 121 | { |
|---|
| 133 | | - struct nand_chip *chip = mtd_to_nand(mtd); |
|---|
| 134 | 122 | struct ndfc_controller *ndfc = nand_get_controller_data(chip); |
|---|
| 135 | 123 | uint32_t *p = (uint32_t *) buf; |
|---|
| 136 | 124 | |
|---|
| .. | .. |
|---|
| 149 | 137 | struct mtd_info *mtd = nand_to_mtd(chip); |
|---|
| 150 | 138 | int ret; |
|---|
| 151 | 139 | |
|---|
| 152 | | - chip->IO_ADDR_R = ndfc->ndfcbase + NDFC_DATA; |
|---|
| 153 | | - chip->IO_ADDR_W = ndfc->ndfcbase + NDFC_DATA; |
|---|
| 154 | | - chip->cmd_ctrl = ndfc_hwcontrol; |
|---|
| 155 | | - chip->dev_ready = ndfc_ready; |
|---|
| 156 | | - chip->select_chip = ndfc_select_chip; |
|---|
| 157 | | - chip->chip_delay = 50; |
|---|
| 140 | + chip->legacy.IO_ADDR_R = ndfc->ndfcbase + NDFC_DATA; |
|---|
| 141 | + chip->legacy.IO_ADDR_W = ndfc->ndfcbase + NDFC_DATA; |
|---|
| 142 | + chip->legacy.cmd_ctrl = ndfc_hwcontrol; |
|---|
| 143 | + chip->legacy.dev_ready = ndfc_ready; |
|---|
| 144 | + chip->legacy.select_chip = ndfc_select_chip; |
|---|
| 145 | + chip->legacy.chip_delay = 50; |
|---|
| 158 | 146 | chip->controller = &ndfc->ndfc_control; |
|---|
| 159 | | - chip->read_buf = ndfc_read_buf; |
|---|
| 160 | | - chip->write_buf = ndfc_write_buf; |
|---|
| 147 | + chip->legacy.read_buf = ndfc_read_buf; |
|---|
| 148 | + chip->legacy.write_buf = ndfc_write_buf; |
|---|
| 161 | 149 | chip->ecc.correct = nand_correct_data; |
|---|
| 162 | 150 | chip->ecc.hwctl = ndfc_enable_hwecc; |
|---|
| 163 | 151 | chip->ecc.calculate = ndfc_calculate_ecc; |
|---|
| 164 | | - chip->ecc.mode = NAND_ECC_HW; |
|---|
| 152 | + chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; |
|---|
| 165 | 153 | chip->ecc.size = 256; |
|---|
| 166 | 154 | chip->ecc.bytes = 3; |
|---|
| 167 | 155 | chip->ecc.strength = 1; |
|---|
| .. | .. |
|---|
| 174 | 162 | return -ENODEV; |
|---|
| 175 | 163 | nand_set_flash_node(chip, flash_np); |
|---|
| 176 | 164 | |
|---|
| 177 | | - mtd->name = kasprintf(GFP_KERNEL, "%s.%s", dev_name(&ndfc->ofdev->dev), |
|---|
| 178 | | - flash_np->name); |
|---|
| 165 | + mtd->name = kasprintf(GFP_KERNEL, "%s.%pOFn", dev_name(&ndfc->ofdev->dev), |
|---|
| 166 | + flash_np); |
|---|
| 179 | 167 | if (!mtd->name) { |
|---|
| 180 | 168 | ret = -ENOMEM; |
|---|
| 181 | 169 | goto err; |
|---|
| .. | .. |
|---|
| 256 | 244 | static int ndfc_remove(struct platform_device *ofdev) |
|---|
| 257 | 245 | { |
|---|
| 258 | 246 | struct ndfc_controller *ndfc = dev_get_drvdata(&ofdev->dev); |
|---|
| 259 | | - struct mtd_info *mtd = nand_to_mtd(&ndfc->chip); |
|---|
| 247 | + struct nand_chip *chip = &ndfc->chip; |
|---|
| 248 | + struct mtd_info *mtd = nand_to_mtd(chip); |
|---|
| 249 | + int ret; |
|---|
| 260 | 250 | |
|---|
| 261 | | - nand_release(&ndfc->chip); |
|---|
| 251 | + ret = mtd_device_unregister(mtd); |
|---|
| 252 | + WARN_ON(ret); |
|---|
| 253 | + nand_cleanup(chip); |
|---|
| 262 | 254 | kfree(mtd->name); |
|---|
| 263 | 255 | |
|---|
| 264 | 256 | return 0; |
|---|