diff options
Diffstat (limited to 'drivers/mtd/nand/raw/mpc5121_nfc.c')
| -rw-r--r-- | drivers/mtd/nand/raw/mpc5121_nfc.c | 72 |
1 files changed, 37 insertions, 35 deletions
diff --git a/drivers/mtd/nand/raw/mpc5121_nfc.c b/drivers/mtd/nand/raw/mpc5121_nfc.c index 062cd1eb2861..97b4e7f3e1bb 100644 --- a/drivers/mtd/nand/raw/mpc5121_nfc.c +++ b/drivers/mtd/nand/raw/mpc5121_nfc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright 2004-2008 Freescale Semiconductor, Inc. * Copyright 2009 Semihalf. @@ -8,20 +9,6 @@ * Based on original driver from Freescale Semiconductor * written by John Rigby <jrigby@freescale.com> on basis of mxc_nand.c. * Reworked and extended by Piotr Ziecik <kosmo@semihalf.com>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. */ #include <linux/module.h> @@ -34,10 +21,10 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/rawnand.h> #include <linux/mtd/partitions.h> +#include <linux/of.h> #include <linux/of_address.h> -#include <linux/of_device.h> #include <linux/of_irq.h> -#include <linux/of_platform.h> +#include <linux/platform_device.h> #include <asm/mpc5121.h> @@ -117,6 +104,7 @@ #define NFC_TIMEOUT (HZ / 10) /* 1/10 s */ struct mpc5121_nfc_prv { + struct nand_controller controller; struct nand_chip chip; int irq; void __iomem *regs; @@ -303,7 +291,6 @@ static int ads5121_chipselect_init(struct mtd_info *mtd) /* Control chips select signal on ADS5121 board */ static void ads5121_select_chip(struct nand_chip *nand, int chip) { - struct mtd_info *mtd = nand_to_mtd(nand); struct mpc5121_nfc_prv *prv = nand_get_controller_data(nand); u8 v; @@ -451,7 +438,7 @@ static void mpc5121_nfc_copy_spare(struct mtd_info *mtd, uint offset, buffer += blksize; offset += blksize; size -= blksize; - }; + } } /* Copy data from/to NFC main and spare buffers */ @@ -608,13 +595,23 @@ static void mpc5121_nfc_free(struct device *dev, struct mtd_info *mtd) struct nand_chip *chip = mtd_to_nand(mtd); struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip); - if (prv->clk) - clk_disable_unprepare(prv->clk); - if (prv->csreg) iounmap(prv->csreg); } +static int mpc5121_nfc_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 mpc5121_nfc_ops = { + .attach_chip = mpc5121_nfc_attach_chip, +}; + static int mpc5121_nfc_probe(struct platform_device *op) { struct device_node *dn = op->dev.of_node; @@ -647,6 +644,10 @@ static int mpc5121_nfc_probe(struct platform_device *op) chip = &prv->chip; mtd = nand_to_mtd(chip); + nand_controller_init(&prv->controller); + prv->controller.ops = &mpc5121_nfc_ops; + chip->controller = &prv->controller; + mtd->dev.parent = dev; nand_set_controller_data(chip, prv); nand_set_flash_node(chip, dn); @@ -660,7 +661,7 @@ static int mpc5121_nfc_probe(struct platform_device *op) } prv->irq = irq_of_parse_and_map(dn, 0); - if (prv->irq == NO_IRQ) { + if (!prv->irq) { dev_err(dev, "Error mapping IRQ!\n"); return -EINVAL; } @@ -701,8 +702,6 @@ static int mpc5121_nfc_probe(struct platform_device *op) chip->legacy.set_features = nand_get_set_features_notsupp; chip->legacy.get_features = nand_get_set_features_notsupp; chip->bbt_options = NAND_BBT_USE_FLASH; - chip->ecc.mode = NAND_ECC_SOFT; - chip->ecc.algo = NAND_ECC_HAMMING; /* Support external chip-select logic on ADS5121 board */ if (of_machine_is_compatible("fsl,mpc5121ads")) { @@ -716,17 +715,12 @@ static int mpc5121_nfc_probe(struct platform_device *op) } /* Enable NFC clock */ - clk = devm_clk_get(dev, "ipg"); + clk = devm_clk_get_enabled(dev, "ipg"); if (IS_ERR(clk)) { - dev_err(dev, "Unable to acquire NFC clock!\n"); + dev_err(dev, "Unable to acquire and enable NFC clock!\n"); retval = PTR_ERR(clk); goto error; } - retval = clk_prepare_enable(clk); - if (retval) { - dev_err(dev, "Unable to enable NFC clock!\n"); - goto error; - } prv->clk = clk; /* Reset NAND Flash controller */ @@ -768,6 +762,13 @@ static int mpc5121_nfc_probe(struct platform_device *op) goto error; } + /* + * 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. + */ + chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; + /* Detect NAND chips */ retval = nand_scan(chip, be32_to_cpup(chips_no)); if (retval) { @@ -814,15 +815,16 @@ error: return retval; } -static int mpc5121_nfc_remove(struct platform_device *op) +static void mpc5121_nfc_remove(struct platform_device *op) { struct device *dev = &op->dev; struct mtd_info *mtd = dev_get_drvdata(dev); + int ret; - nand_release(mtd_to_nand(mtd)); + ret = mtd_device_unregister(mtd); + WARN_ON(ret); + nand_cleanup(mtd_to_nand(mtd)); mpc5121_nfc_free(dev, mtd); - - return 0; } static const struct of_device_id mpc5121_nfc_match[] = { |
