#include <linux/module.h>
#include <linux/dma-mapping.h>
#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
#include <linux/platform_device.h>
nfc->buf[0] = status;
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
-static void ar934x_nfc_cmdfunc(struct mtd_info *mtd, unsigned int command,
- int column, int page_addr)
-{
- struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd);
- struct nand_chip *nand = &nfc->nand_chip;
-#else
static void ar934x_nfc_cmdfunc(struct nand_chip *nand, unsigned int command,
int column, int page_addr)
{
struct mtd_info *mtd = nand_to_mtd(nand);
struct ar934x_nfc *nfc = nand->priv;
-#endif
nfc->read_id = false;
if (command != NAND_CMD_PAGEPROG)
break;
case NAND_CMD_PAGEPROG:
- if (nand->ecc.mode == NAND_ECC_HW) {
+ if (nand->ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST) {
/* the data is already written */
break;
}
}
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
-static int ar934x_nfc_dev_ready(struct mtd_info *mtd)
-{
- struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd);
-#else
static int ar934x_nfc_dev_ready(struct nand_chip *chip)
{
struct ar934x_nfc *nfc = chip->priv;
-#endif
return __ar934x_nfc_dev_ready(nfc);
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
-static u8 ar934x_nfc_read_byte(struct mtd_info *mtd)
-{
- struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd);
-#else
static u8 ar934x_nfc_read_byte(struct nand_chip *chip)
{
struct ar934x_nfc *nfc = chip->priv;
-#endif
u8 data;
WARN_ON(nfc->buf_index >= nfc->buf_size);
return data;
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
-static void ar934x_nfc_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
-{
- struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd);
-#else
static void ar934x_nfc_write_buf(struct nand_chip *chip, const u8 *buf, int len)
{
struct ar934x_nfc *nfc = chip->priv;
-#endif
int i;
WARN_ON(nfc->buf_index + len > nfc->buf_size);
}
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
-static void ar934x_nfc_read_buf(struct mtd_info *mtd, u8 *buf, int len)
-{
- struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd);
-#else
static void ar934x_nfc_read_buf(struct nand_chip *chip, u8 *buf, int len)
{
struct ar934x_nfc *nfc = chip->priv;
-#endif
int buf_index;
int i;
nfc->ctrl_reg |= AR934X_NFC_CTRL_CUSTOM_SIZE_EN;
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
-static int ar934x_nfc_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
- int page)
-{
- struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd);
-#else
static int ar934x_nfc_read_oob(struct nand_chip *chip,
int page)
{
struct ar934x_nfc *nfc = chip->priv;
struct mtd_info *mtd = ar934x_nfc_to_mtd(nfc);
-#endif
int err;
nfc_dbg(nfc, "read_oob: page:%d\n", page);
return 0;
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
-static int ar934x_nfc_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
- int page)
-{
- struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd);
-#else
static int ar934x_nfc_write_oob(struct nand_chip *chip,
int page)
{
struct ar934x_nfc *nfc = chip->priv;
struct mtd_info *mtd = ar934x_nfc_to_mtd(nfc);
-#endif
nfc_dbg(nfc, "write_oob: page:%d\n", page);
memcpy(nfc->buf, chip->oob_poi, mtd->oobsize);
page, mtd->oobsize);
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
-static int ar934x_nfc_read_page_raw(struct mtd_info *mtd,
- struct nand_chip *chip, u8 *buf,
- int oob_required, int page)
-{
- struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd);
-#else
static int ar934x_nfc_read_page_raw(
struct nand_chip *chip, u8 *buf,
int oob_required, int page)
{
struct ar934x_nfc *nfc = chip->priv;
struct mtd_info *mtd = ar934x_nfc_to_mtd(nfc);
-#endif
int len;
int err;
return 0;
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
-static int ar934x_nfc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
- u8 *buf, int oob_required, int page)
-{
- struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd);
-#else
static int ar934x_nfc_read_page(struct nand_chip *chip,
u8 *buf, int oob_required, int page)
{
struct ar934x_nfc *nfc = chip->priv;
struct mtd_info *mtd = ar934x_nfc_to_mtd(nfc);
-#endif
u32 ecc_ctrl;
int max_bitflips = 0;
bool ecc_failed;
return max_bitflips;
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
-static int ar934x_nfc_write_page_raw(struct mtd_info *mtd,
- struct nand_chip *chip, const u8 *buf,
- int oob_required, int page)
-{
- struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd);
-#else
static int ar934x_nfc_write_page_raw(
struct nand_chip *chip, const u8 *buf,
int oob_required, int page)
{
struct ar934x_nfc *nfc = chip->priv;
struct mtd_info *mtd = ar934x_nfc_to_mtd(nfc);
-#endif
int len;
nfc_dbg(nfc, "write_page_raw: page:%d oob:%d\n", page, oob_required);
return ar934x_nfc_send_write(nfc, NAND_CMD_PAGEPROG, 0, page, len);
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
-static int ar934x_nfc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
- const u8 *buf, int oob_required, int page)
-{
- struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd);
-#else
static int ar934x_nfc_write_page(struct nand_chip *chip,
const u8 *buf, int oob_required, int page)
{
struct ar934x_nfc *nfc = chip->priv;
struct mtd_info *mtd = ar934x_nfc_to_mtd(nfc);
-#endif
int err;
nfc_dbg(nfc, "write_page: page:%d oob:%d\n", page, oob_required);
/* write OOB first */
if (oob_required &&
!is_all_ff(chip->oob_poi, mtd->oobsize)) {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
- err = ar934x_nfc_write_oob(mtd, chip, page);
-#else
err = ar934x_nfc_write_oob(chip, page);
-#endif
if (err)
return err;
}
return err;
}
-static int ar934x_nfc_hw_reset_assert(struct ar934x_nfc *nfc) {
- reset_control_assert(nfc->rst);
+static int ar934x_nfc_hw_reset_assert(struct ar934x_nfc *nfc)
+{
+ int err;
+
+ err = reset_control_assert(nfc->rst);
udelay(250);
+ return err;
}
-static int ar934x_nfc_hw_reset_deassert(struct ar934x_nfc *nfc) {
- reset_control_deassert(nfc->rst);
+static int ar934x_nfc_hw_reset_deassert(struct ar934x_nfc *nfc)
+{
+ int err;
+
+ err = reset_control_deassert(nfc->rst);
udelay(250);
+ return err;
}
static int ar934x_nfc_hw_init(struct ar934x_nfc *nfc)
{
struct ar934x_nfc *nfc = mtd_to_ar934x_nfc(mtd);
struct nand_chip *chip = &nfc->nand_chip;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)
- u64 chipsize = chip->chipsize;
-#else
u64 chipsize = nanddev_target_size(&chip->base);
-#endif
u32 ctrl;
u32 t;
int err;
* Writing a subpage separately is not supported, because
* the controller only does ECC on full-page accesses.
*/
- nand->options = NAND_NO_SUBPAGE_WRITE;
nand->ecc.size = 512;
nand->ecc.bytes = 7;
if (ret)
return ret;
- if (nand->ecc.mode == NAND_ECC_HW) {
+ if (nand->ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST) {
+ if (mtd->writesize == 2048)
+ nand->options |= NAND_NO_SUBPAGE_WRITE;
+
ret = ar934x_nfc_setup_hwecc(nfc);
if (ret)
return ret;
- } else if (nand->ecc.mode != NAND_ECC_SOFT) {
- dev_err(dev, "unknown ECC mode %d\n", nand->ecc.mode);
+ } else if (nand->ecc.engine_type != NAND_ECC_ENGINE_TYPE_SOFT) {
+ dev_err(dev, "unknown ECC mode %d\n", nand->ecc.engine_type);
return -EINVAL;
- } else if ((nand->ecc.algo != NAND_ECC_BCH) &&
- (nand->ecc.algo != NAND_ECC_HAMMING)) {
+ } else if ((nand->ecc.algo != NAND_ECC_ALGO_BCH) &&
+ (nand->ecc.algo != NAND_ECC_ALGO_HAMMING)) {
dev_err(dev, "unknown software ECC algo %d\n", nand->ecc.algo);
return -EINVAL;
}
static u64 ar934x_nfc_dma_mask = DMA_BIT_MASK(32);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
-static void ar934x_nfc_cmd_ctrl(struct mtd_info *mtd, int dat,
- unsigned int ctrl)
-#else
static void ar934x_nfc_cmd_ctrl(struct nand_chip *chip, int dat,
unsigned int ctrl)
-#endif
{
WARN_ON(dat != NAND_CMD_NONE);
}
nand_set_controller_data(nand, nfc);
nand_set_flash_node(nand, pdev->dev.of_node);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
- nand->chip_delay = 25;
- nand->dev_ready = ar934x_nfc_dev_ready;
- nand->cmdfunc = ar934x_nfc_cmdfunc;
- nand->cmd_ctrl = ar934x_nfc_cmd_ctrl; /* dummy */
- nand->read_byte = ar934x_nfc_read_byte;
- nand->write_buf = ar934x_nfc_write_buf;
- nand->read_buf = ar934x_nfc_read_buf;
-#else
nand->legacy.chip_delay = 25;
nand->legacy.dev_ready = ar934x_nfc_dev_ready;
nand->legacy.cmdfunc = ar934x_nfc_cmdfunc;
nand->legacy.read_byte = ar934x_nfc_read_byte;
nand->legacy.write_buf = ar934x_nfc_write_buf;
nand->legacy.read_buf = ar934x_nfc_read_buf;
-#endif
- nand->ecc.mode = NAND_ECC_HW; /* default */
+ nand->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; /* default */
nand->priv = nfc;
platform_set_drvdata(pdev, nfc);
goto err_free_buf;
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
- nand->dummy_controller.ops = &ar934x_nfc_controller_ops;
- ret = nand_scan(mtd, 1);
-#else
nand->legacy.dummy_controller.ops = &ar934x_nfc_controller_ops;
ret = nand_scan(nand, 1);
-#endif
if (ret) {
dev_err(&pdev->dev, "nand_scan failed, err:%d\n", ret);
goto err_free_buf;
static int ar934x_nfc_remove(struct platform_device *pdev)
{
struct ar934x_nfc *nfc;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
- struct mtd_info *mtd;
-#endif
nfc = platform_get_drvdata(pdev);
if (nfc) {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0)
- mtd = ar934x_nfc_to_mtd(nfc);
- nand_release(mtd);
-#else
- nand_release(&nfc->nand_chip);
-#endif
+ mtd_device_unregister(nand_to_mtd(&nfc->nand_chip));
+ nand_cleanup(&nfc->nand_chip);
ar934x_nfc_free_buf(nfc);
}