diff options
Diffstat (limited to 'drivers/mtd/nand/raw/xway_nand.c')
| -rw-r--r-- | drivers/mtd/nand/raw/xway_nand.c | 52 |
1 files changed, 36 insertions, 16 deletions
diff --git a/drivers/mtd/nand/raw/xway_nand.c b/drivers/mtd/nand/raw/xway_nand.c index 4cb78106af14..af84395dc66e 100644 --- a/drivers/mtd/nand/raw/xway_nand.c +++ b/drivers/mtd/nand/raw/xway_nand.c @@ -1,15 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0-only /* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. * * Copyright © 2012 John Crispin <john@phrozen.org> * Copyright © 2016 Hauke Mehrtens <hauke@hauke-m.de> */ #include <linux/mtd/rawnand.h> -#include <linux/of_gpio.h> -#include <linux/of_platform.h> +#include <linux/of.h> +#include <linux/platform_device.h> #include <lantiq_soc.h> @@ -64,6 +62,7 @@ #define NAND_CON_NANDM 1 struct xway_nand_data { + struct nand_controller controller; struct nand_chip chip; unsigned long csflags; void __iomem *nandaddr; @@ -147,6 +146,19 @@ static void xway_write_buf(struct nand_chip *chip, const u_char *buf, int len) xway_writeb(nand_to_mtd(chip), NAND_WRITE_DATA, buf[i]); } +static int xway_attach_chip(struct nand_chip *chip) +{ + if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT && + chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN) + chip->ecc.algo = NAND_ECC_ALGO_HAMMING; + + return 0; +} + +static const struct nand_controller_ops xway_nand_ops = { + .attach_chip = xway_attach_chip, +}; + /* * Probe for the NAND device. */ @@ -154,7 +166,6 @@ static int xway_nand_probe(struct platform_device *pdev) { struct xway_nand_data *data; struct mtd_info *mtd; - struct resource *res; int err; u32 cs; u32 cs_flag = 0; @@ -165,8 +176,7 @@ static int xway_nand_probe(struct platform_device *pdev) if (!data) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - data->nandaddr = devm_ioremap_resource(&pdev->dev, res); + data->nandaddr = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(data->nandaddr)) return PTR_ERR(data->nandaddr); @@ -182,8 +192,9 @@ static int xway_nand_probe(struct platform_device *pdev) data->chip.legacy.read_byte = xway_read_byte; data->chip.legacy.chip_delay = 30; - data->chip.ecc.mode = NAND_ECC_SOFT; - data->chip.ecc.algo = NAND_ECC_HAMMING; + nand_controller_init(&data->controller); + data->controller.ops = &xway_nand_ops; + data->chip.controller = &data->controller; platform_set_drvdata(pdev, data); nand_set_controller_data(&data->chip, data); @@ -205,6 +216,13 @@ static int xway_nand_probe(struct platform_device *pdev) | NAND_CON_SE_P | NAND_CON_WP_P | NAND_CON_PRE_P | cs_flag, EBU_NAND_CON); + /* + * This driver assumes that the default ECC engine should be TYPE_SOFT. + * Set ->engine_type before registering the NAND devices in order to + * provide a driver specific default value. + */ + data->chip.ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; + /* Scan to find existence of the device */ err = nand_scan(&data->chip, 1); if (err) @@ -212,7 +230,7 @@ static int xway_nand_probe(struct platform_device *pdev) err = mtd_device_register(mtd, NULL, 0); if (err) - nand_release(&data->chip); + nand_cleanup(&data->chip); return err; } @@ -220,13 +238,15 @@ static int xway_nand_probe(struct platform_device *pdev) /* * Remove a NAND device. */ -static int xway_nand_remove(struct platform_device *pdev) +static void xway_nand_remove(struct platform_device *pdev) { struct xway_nand_data *data = platform_get_drvdata(pdev); + struct nand_chip *chip = &data->chip; + int ret; - nand_release(&data->chip); - - return 0; + ret = mtd_device_unregister(nand_to_mtd(chip)); + WARN_ON(ret); + nand_cleanup(chip); } static const struct of_device_id xway_nand_match[] = { @@ -236,7 +256,7 @@ static const struct of_device_id xway_nand_match[] = { static struct platform_driver xway_nand_driver = { .probe = xway_nand_probe, - .remove = xway_nand_remove, + .remove = xway_nand_remove, .driver = { .name = "lantiq,nand-xway", .of_match_table = xway_nand_match, |
