Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a0fabf72 authored by Jamie Lentin's avatar Jamie Lentin Committed by Jason Cooper
Browse files

mtd: Add orion_nand devicetree bindings



Allow a NAND chip using the orion_nand driver to be described using devicetree.

Changes since last submission (V4) [Addressing comments by]:-
* WARN when bank-width is out of range [Andrew Lunn]

Changes since last submission (V3):-
* Document all parameters [Grant Likely]
* Convert bank-width to be in bytes
* Add explicit defaults for cle, ale and bank-width

Signed-off-by: default avatarJamie Lentin <jm@lentin.co.uk>
Signed-off-by: default avatarJason Cooper <jason@lakedaemon.net>
parent 9007d100
Loading
Loading
Loading
Loading
+50 −0
Original line number Diff line number Diff line
NAND support for Marvell Orion SoC platforms

Required properties:
- compatible : "mrvl,orion-nand".
- reg : Base physical address of the NAND and length of memory mapped
	region

Optional properties:
- cle : Address line number connected to CLE. Default is 0
- ale : Address line number connected to ALE. Default is 1
- bank-width : Width in bytes of the device. Default is 1
- chip-delay : Chip dependent delay for transferring data from array to read
               registers in usecs

The device tree may optionally contain sub-nodes describing partitions of the
address space. See partition.txt for more detail.

Example:

nand@f4000000 {
	#address-cells = <1>;
	#size-cells = <1>;
	cle = <0>;
	ale = <1>;
	bank-width = <1>;
	chip-delay = <25>;
	compatible = "mrvl,orion-nand";
	reg = <0xf4000000 0x400>;

	partition@0 {
		label = "u-boot";
		reg = <0x0000000 0x100000>;
		read-only;
	};

	partition@100000 {
		label = "uImage";
		reg = <0x0100000 0x200000>;
	};

	partition@300000 {
		label = "dtb";
		reg = <0x0300000 0x100000>;
	};

	partition@400000 {
		label = "root";
		reg = <0x0400000 0x7d00000>;
	};
};
+44 −3
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
@@ -74,11 +75,13 @@ static void orion_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
static int __init orion_nand_probe(struct platform_device *pdev)
{
	struct mtd_info *mtd;
	struct mtd_part_parser_data ppdata = {};
	struct nand_chip *nc;
	struct orion_nand_data *board;
	struct resource *res;
	void __iomem *io_base;
	int ret = 0;
	u32 val = 0;

	nc = kzalloc(sizeof(struct nand_chip) + sizeof(struct mtd_info), GFP_KERNEL);
	if (!nc) {
@@ -101,6 +104,31 @@ static int __init orion_nand_probe(struct platform_device *pdev)
		goto no_res;
	}

	if (pdev->dev.of_node) {
		board = devm_kzalloc(&pdev->dev, sizeof(struct orion_nand_data),
					GFP_KERNEL);
		if (!board) {
			printk(KERN_ERR "orion_nand: failed to allocate board structure.\n");
			ret = -ENOMEM;
			goto no_res;
		}
		if (!of_property_read_u32(pdev->dev.of_node, "cle", &val))
			board->cle = (u8)val;
		else
			board->cle = 0;
		if (!of_property_read_u32(pdev->dev.of_node, "ale", &val))
			board->ale = (u8)val;
		else
			board->ale = 1;
		if (!of_property_read_u32(pdev->dev.of_node,
						"bank-width", &val))
			board->width = (u8)val * 8;
		else
			board->width = 8;
		if (!of_property_read_u32(pdev->dev.of_node,
						"chip-delay", &val))
			board->chip_delay = (u8)val;
	} else
		board = pdev->dev.platform_data;

	mtd->priv = nc;
@@ -115,6 +143,10 @@ static int __init orion_nand_probe(struct platform_device *pdev)
	if (board->chip_delay)
		nc->chip_delay = board->chip_delay;

	WARN(board->width > 16,
		"%d bit bus width out of range",
		board->width);

	if (board->width == 16)
		nc->options |= NAND_BUSWIDTH_16;

@@ -129,8 +161,9 @@ static int __init orion_nand_probe(struct platform_device *pdev)
	}

	mtd->name = "orion_nand";
	ret = mtd_device_parse_register(mtd, NULL, NULL, board->parts,
					board->nr_parts);
	ppdata.of_node = pdev->dev.of_node;
	ret = mtd_device_parse_register(mtd, NULL, &ppdata,
			board->parts, board->nr_parts);
	if (ret) {
		nand_release(mtd);
		goto no_dev;
@@ -161,11 +194,19 @@ static int __devexit orion_nand_remove(struct platform_device *pdev)
	return 0;
}

#ifdef CONFIG_OF
static struct of_device_id orion_nand_of_match_table[] = {
	{ .compatible = "mrvl,orion-nand", },
	{},
};
#endif

static struct platform_driver orion_nand_driver = {
	.remove		= __devexit_p(orion_nand_remove),
	.driver		= {
		.name	= "orion_nand",
		.owner	= THIS_MODULE,
		.of_match_table = of_match_ptr(orion_nand_of_match_table),
	},
};