From a0fabf722c9dc73a3eed24ce166476ddb00eda1e Mon Sep 17 00:00:00 2001 From: Jamie Lentin Date: Wed, 18 Apr 2012 11:06:41 +0100 Subject: [PATCH] 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: Jamie Lentin Signed-off-by: Jason Cooper --- .../devicetree/bindings/mtd/orion-nand.txt | 50 +++++++++++++++++++ drivers/mtd/nand/orion_nand.c | 47 +++++++++++++++-- 2 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 Documentation/devicetree/bindings/mtd/orion-nand.txt diff --git a/Documentation/devicetree/bindings/mtd/orion-nand.txt b/Documentation/devicetree/bindings/mtd/orion-nand.txt new file mode 100644 index 000000000000..b2356b7d2fa4 --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/orion-nand.txt @@ -0,0 +1,50 @@ +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>; + }; +}; diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index 1d3bfb26080c..0f50ef38b87b 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -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,7 +104,32 @@ static int __init orion_nand_probe(struct platform_device *pdev) goto no_res; } - board = pdev->dev.platform_data; + 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; mtd->owner = THIS_MODULE; @@ -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), }, }; -- 2.20.1