Commit 02436675 authored by Hauke Mehrtens's avatar Hauke Mehrtens Committed by Boris Brezillon
Browse files

mtd: nand: xway: convert to normal platform driver



Instead of hacking this into the plat_nand driver just make this a
normal nand driver.

Signed-off-by: default avatarHauke Mehrtens <hauke@hauke-m.de>
Signed-off-by: default avatarBoris Brezillon <boris.brezillon@free-electrons.com>
parent 3d8cec22
Loading
Loading
Loading
Loading
+0 −1
Original line number Original line Diff line number Diff line
@@ -539,7 +539,6 @@ config MTD_NAND_FSMC
config MTD_NAND_XWAY
config MTD_NAND_XWAY
	tristate "Support for NAND on Lantiq XWAY SoC"
	tristate "Support for NAND on Lantiq XWAY SoC"
	depends on LANTIQ && SOC_TYPE_XWAY
	depends on LANTIQ && SOC_TYPE_XWAY
	select MTD_NAND_PLATFORM
	help
	help
	  Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached
	  Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached
	  to the External Bus Unit (EBU).
	  to the External Bus Unit (EBU).
+80 −36
Original line number Original line Diff line number Diff line
@@ -4,6 +4,7 @@
 *  by the Free Software Foundation.
 *  by the Free Software Foundation.
 *
 *
 *  Copyright © 2012 John Crispin <blogic@openwrt.org>
 *  Copyright © 2012 John Crispin <blogic@openwrt.org>
 *  Copyright © 2016 Hauke Mehrtens <hauke@hauke-m.de>
 */
 */


#include <linux/mtd/nand.h>
#include <linux/mtd/nand.h>
@@ -63,6 +64,10 @@
#define NAND_CON_CSMUX		(1 << 1)
#define NAND_CON_CSMUX		(1 << 1)
#define NAND_CON_NANDM		1
#define NAND_CON_NANDM		1


struct xway_nand_data {
	struct nand_chip	chip;
};

static void xway_reset_chip(struct nand_chip *chip)
static void xway_reset_chip(struct nand_chip *chip)
{
{
	unsigned long nandaddr = (unsigned long) chip->IO_ADDR_W;
	unsigned long nandaddr = (unsigned long) chip->IO_ADDR_W;
@@ -139,16 +144,51 @@ static unsigned char xway_read_byte(struct mtd_info *mtd)
	return ret;
	return ret;
}
}


/*
 * Probe for the NAND device.
 */
static int xway_nand_probe(struct platform_device *pdev)
static int xway_nand_probe(struct platform_device *pdev)
{
{
	struct nand_chip *this = platform_get_drvdata(pdev);
	struct xway_nand_data *data;
	unsigned long nandaddr = (unsigned long) this->IO_ADDR_W;
	struct mtd_info *mtd;
	const __be32 *cs = of_get_property(pdev->dev.of_node,
	struct resource *res;
					"lantiq,cs", NULL);
	int err;
	void __iomem *nandaddr;
	u32 cs;
	u32 cs_flag = 0;
	u32 cs_flag = 0;


	/* Allocate memory for the device structure (and zero it) */
	data = devm_kzalloc(&pdev->dev, sizeof(struct xway_nand_data),
			    GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	nandaddr = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(nandaddr))
		return PTR_ERR(nandaddr);

	nand_set_flash_node(&data->chip, pdev->dev.of_node);
	mtd = nand_to_mtd(&data->chip);
	mtd->dev.parent = &pdev->dev;

	data->chip.IO_ADDR_R = nandaddr;
	data->chip.IO_ADDR_W = nandaddr;
	data->chip.cmd_ctrl = xway_cmd_ctrl;
	data->chip.dev_ready = xway_dev_ready;
	data->chip.select_chip = xway_select_chip;
	data->chip.read_byte = xway_read_byte;
	data->chip.chip_delay = 30;

	data->chip.ecc.mode = NAND_ECC_SOFT;
	data->chip.ecc.algo = NAND_ECC_HAMMING;

	platform_set_drvdata(pdev, data);
	nand_set_controller_data(&data->chip, data);

	/* load our CS from the DT. Either we find a valid 1 or default to 0 */
	/* load our CS from the DT. Either we find a valid 1 or default to 0 */
	if (cs && (*cs == 1))
	err = of_property_read_u32(pdev->dev.of_node, "lantiq,cs", &cs);
	if (!err && cs == 1)
		cs_flag = NAND_CON_IN_CS1 | NAND_CON_OUT_CS1;
		cs_flag = NAND_CON_IN_CS1 | NAND_CON_OUT_CS1;


	/* setup the EBU to run in NAND mode on our base addr */
	/* setup the EBU to run in NAND mode on our base addr */
@@ -164,43 +204,47 @@ static int xway_nand_probe(struct platform_device *pdev)
		| cs_flag, EBU_NAND_CON);
		| cs_flag, EBU_NAND_CON);


	/* finish with a reset */
	/* finish with a reset */
	xway_reset_chip(this);
	xway_reset_chip(&data->chip);


	return 0;
	/* Scan to find existence of the device */
}
	err = nand_scan(mtd, 1);
	if (err)
		return err;


static struct platform_nand_data xway_nand_data = {
	err = mtd_device_register(mtd, NULL, 0);
	.chip = {
	if (err)
		.nr_chips		= 1,
		nand_release(mtd);
		.chip_delay		= 30,

	},
	return err;
	.ctrl = {
		.probe		= xway_nand_probe,
		.cmd_ctrl	= xway_cmd_ctrl,
		.dev_ready	= xway_dev_ready,
		.select_chip	= xway_select_chip,
		.read_byte	= xway_read_byte,
}
}
};


/*
/*
 * Try to find the node inside the DT. If it is available attach out
 * Remove a NAND device.
 * platform_nand_data
 */
 */
static int __init xway_register_nand(void)
static int xway_nand_remove(struct platform_device *pdev)
{
{
	struct device_node *node;
	struct xway_nand_data *data = platform_get_drvdata(pdev);
	struct platform_device *pdev;


	nand_release(nand_to_mtd(&data->chip));
	node = of_find_compatible_node(NULL, NULL, "lantiq,nand-xway");

	if (!node)
		return -ENOENT;
	pdev = of_find_device_by_node(node);
	if (!pdev)
		return -EINVAL;
	pdev->dev.platform_data = &xway_nand_data;
	of_node_put(node);
	return 0;
	return 0;
}
}


subsys_initcall(xway_register_nand);
static const struct of_device_id xway_nand_match[] = {
	{ .compatible = "lantiq,nand-xway" },
	{},
};
MODULE_DEVICE_TABLE(of, xway_nand_match);

static struct platform_driver xway_nand_driver = {
	.probe	= xway_nand_probe,
	.remove	= xway_nand_remove,
	.driver	= {
		.name		= "lantiq,nand-xway",
		.of_match_table = xway_nand_match,
	},
};

module_platform_driver(xway_nand_driver);

MODULE_LICENSE("GPL");