From patchwork Sun Sep 24 17:39:12 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 114134 Delivered-To: patch@linaro.org Received: by 10.140.106.117 with SMTP id d108csp1769899qgf; Sun, 24 Sep 2017 10:47:58 -0700 (PDT) X-Received: by 10.99.38.7 with SMTP id m7mr5210592pgm.53.1506275278065; Sun, 24 Sep 2017 10:47:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1506275278; cv=none; d=google.com; s=arc-20160816; b=veZnKQ1pbY5Cqm+qPDe/XCUGyGUZVtV5H0CiQGo18Rj63r4krfwYz2ZikpPWwUXGmC pq/R5MWdOuSMJ0Pk3xVY+bDxtvaPIKRkAqE9WJWlQ3ZvyAtEd9u4z5xcp1GcArD4iwgN ayhnHu+wYMbce1qVdwGtypHiHVBlRJ+YfzVboZc2CWmyODPCh1dTvM7jFHhbY6kAu/5j GoOm55Q+FEsule6HgioYsN4xY3uo2jVk0WVwXsEZtlQJEYjC0MlCUPv0hDhrOyRqbX12 c0XIJk6oLnkB4KL72qSrMBgGcUtdC7s6oU2CF7pV4P9MvABVHE+Rwwf3+LGFRXTZdiC4 y2fw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:sender:content-transfer-encoding:mime-version:cc :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:message-id:date:subject:to:from:dkim-signature :dkim-signature:arc-authentication-results; bh=sy1gvuvnaGflC46vOh3tzc9uWBn2rUV9C7fdGSm6RaA=; b=GjnewKsBQm3wxBGHxY2FYGcgeCsqGLLUiTzipKgdp3zSSSJqHgM9FnH8/7nLWCms7o wuY1RRWSN4bCKpWm3ZxajOrQBK1s68YQjchn5u7ujaREn+6rhO1jKhUQxE3MoPYByd/7 g4rxvdJnZ+wzrw/X++qbrCQnqHRu6VjRVRhlF/UEmm1wn0z7rlb+4oPUMRWcDOIFsK1J SxUjJglsGS2NYROovJlOn1c2OSnVXavZd//ktxljUfF2yn4rMeh3t3HTBo0ozeUjJX6m JutDOawxdyS9DOmWKINvlyZNH/CyNvDHhx5jHyC2X2ogzasaGr4miRIyQWcuNe6JRgR8 kCsA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.infradead.org header.s=bombadil.20170209 header.b=XYBeDFI9; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=B27d8ob2; spf=pass (google.com: best guess record for domain of linux-mtd-bounces+patch=linaro.org@lists.infradead.org designates 65.50.211.133 as permitted sender) smtp.mailfrom=linux-mtd-bounces+patch=linaro.org@lists.infradead.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from bombadil.infradead.org (bombadil.infradead.org. [65.50.211.133]) by mx.google.com with ESMTPS id t18si2931343plo.738.2017.09.24.10.47.57 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 24 Sep 2017 10:47:58 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-mtd-bounces+patch=linaro.org@lists.infradead.org designates 65.50.211.133 as permitted sender) client-ip=65.50.211.133; Authentication-Results: mx.google.com; dkim=pass header.i=@lists.infradead.org header.s=bombadil.20170209 header.b=XYBeDFI9; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=B27d8ob2; spf=pass (google.com: best guess record for domain of linux-mtd-bounces+patch=linaro.org@lists.infradead.org designates 65.50.211.133 as permitted sender) smtp.mailfrom=linux-mtd-bounces+patch=linaro.org@lists.infradead.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Owner; bh=sy1gvuvnaGflC46vOh3tzc9uWBn2rUV9C7fdGSm6RaA=; b=XYB eDFI9jRHCiFwoNfEJeYxuX+KdWfAyuAiKbBUi65xpJvYiFHr8AZ2SpgNEpx88hW+MW3AQA8bVdmx5 UiNrgmCQAkIBCzgMIsmFmX0We9ZLXWO73qOkij2abuVSFTQiaptdPDJFLU6Oi4//+brrlpeYdQnvE TJwUO+3DQgN871PpV+wUo0h1j/ufJ1PYqGiTgHiLyyITrYj8/tI5cPid5peBOObUoknhUWYaeIZkd 2NdaPC1uQz5Hw7r1aa5qbjOVKvNkTBYmZXr0njUXW+cwQnOtzTb+b5XKuAfkQ6MDwIUnt5Vq5xWru ob7w4fzn+TdpCFVmQhGleiWGifRJo8A==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dwB0W-0002H0-Q4; Sun, 24 Sep 2017 17:47:56 +0000 Received: from mail-pg0-x233.google.com ([2607:f8b0:400e:c05::233]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dwAu4-0005XS-95 for linux-mtd@lists.infradead.org; Sun, 24 Sep 2017 17:41:20 +0000 Received: by mail-pg0-x233.google.com with SMTP id k193so2819122pgc.8 for ; Sun, 24 Sep 2017 10:40:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=rH4h1/AKEIohCgriu5EePnPieiMF6/x58KyPo+hfJuk=; b=B27d8ob2yk5aKudVtAWLihX8tw855MzGbC7i1wcO13idBY9RZeXk5Sgb+XOYnMylrH K7IYPQc0+R7AGspDHm9669XZaM7aW2hKVnth0MOYrw17IYNdLUK+ha0kjk+X5SMqeInU BFlxPAA9nw5rcNaHzvm/Kye4oSmTDwG/JOSts= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=rH4h1/AKEIohCgriu5EePnPieiMF6/x58KyPo+hfJuk=; b=hneV2MjJL5zRIdzuMH260jWwMhkWkH6eYP5cRxKVpcBJ+9JoFwVbCQvSXtWr0uEtff wXRDghe3NnIgx0zOquttGYVoqE+1mKMpRJW9w0t9Hh8XTaEr6P0S7TXWhqpOihfYCZ44 6HiSfXm4jH0p+9hi6brhX6GBd9LRFo6JAtbcV5TPuFtIoL2zu/AZ56diO/a4iyP6iBJB Zkd7EDUXpnr2YwyTdDN2Jc5DllSgcwx+UEJ3ETfT6g+qD/s/Tmo1aUX/QXRxCNXRcz35 JYJFVEtNKRkPGVWFqjAyq6mprGbrbTmEigdIM69c8/9CKdE/eCyRi2u+7XinilpcZ2if Z96Q== X-Gm-Message-State: AHPjjUgNV3TsV/OwNCGG0XdN6ymk3fBpnp/+Ovj3NnBA92i4mRPYo5wt L3KqF7K3R/oIfnY6Z4FpQFcxYA== X-Google-Smtp-Source: AOwi7QB/7EjCzITAonK3UlB4wtEj0QZGQKBrJP0gZItDWlyPtmhjTZ/LSVOIfMzpcDqtb429138xRA== X-Received: by 10.101.73.198 with SMTP id t6mr5279614pgs.382.1506274853528; Sun, 24 Sep 2017 10:40:53 -0700 (PDT) Received: from genomnajs.saswifi.com ([104.153.224.168]) by smtp.gmail.com with ESMTPSA id z26sm9090432pfa.49.2017.09.24.10.40.06 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 24 Sep 2017 10:40:52 -0700 (PDT) From: Linus Walleij To: David Woodhouse , Brian Norris , Boris Brezillon , Marek Vasut , Richard Weinberger , Cyrille Pitchen , linux-mtd@lists.infradead.org Subject: [PATCH] mtd: nand: gpio: Convert to use GPIO descriptors Date: Sun, 24 Sep 2017 19:39:12 +0200 Message-Id: <20170924173912.9199-1-linus.walleij@linaro.org> X-Mailer: git-send-email 2.13.5 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170924_104116_607329_F17393E9 X-CRM114-Status: GOOD ( 25.62 ) X-Spam-Score: -0.5 (/) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-0.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- 1.5 RCVD_IN_SORBS_WEB RBL: SORBS: sender is an abusable web server [104.153.224.168 listed in dnsbl.sorbs.net] -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [2607:f8b0:400e:c05:0:0:0:233 listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mike Rapoport , Jamie Iles , Linus Walleij , arm@kernel.org, Frans Klaver , Gerhard Sittig , linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+patch=linaro.org@lists.infradead.org There is exactly one board in the kernel that defines platform data for the GPIO NAND driver. Use the feature to provide a lookup table for the GPIOs in the board file so we can convert the driver as a whole to just use GPIO descriptors. After this we can cut the use of and use the GPIO descriptor management from alone to grab and use the GPIOs used in the driver. I also created a local struct device *dev in the probe() function because I was getting annoyed with all the &pdev->dev dereferencing. Cc: arm@kernel.org Cc: Mike Rapoport Cc: Frans Klaver Cc: Gerhard Sittig Cc: Jamie Iles Signed-off-by: Linus Walleij --- ARM SoC folks: Please ACK this so it can be merged through the MTD subsystem. Everyone else on CC: can you test and/or ACK this? I don't have this PXA board, and all device tree users seem to be out-of-tree so I rely on third parties to test this. --- arch/arm/mach-pxa/cm-x255.c | 19 ++++--- drivers/mtd/nand/gpio.c | 112 +++++++++++++++++++++--------------------- include/linux/mtd/nand-gpio.h | 5 -- 3 files changed, 70 insertions(+), 66 deletions(-) -- 2.13.5 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ Reviewed-by: Marek Vasut Acked-by: Jamie Iles Acked-by: Olof Johansson diff --git a/arch/arm/mach-pxa/cm-x255.c b/arch/arm/mach-pxa/cm-x255.c index b592f79a1742..f8d67acb7194 100644 --- a/arch/arm/mach-pxa/cm-x255.c +++ b/arch/arm/mach-pxa/cm-x255.c @@ -14,7 +14,7 @@ #include #include #include - +#include #include #include @@ -176,6 +176,17 @@ static inline void cmx255_init_nor(void) {} #endif #if defined(CONFIG_MTD_NAND_GPIO) || defined(CONFIG_MTD_NAND_GPIO_MODULE) + +static struct gpiod_lookup_table cmx255_nand_gpiod_table = { + .dev_id = "cmx255-nand", + .table = { + GPIO_LOOKUP("gpio-pxa", GPIO_NAND_CS, "nce", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("gpio-pxa", GPIO_NAND_CLE, "cle", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("gpio-pxa", GPIO_NAND_ALE, "ale", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("gpio-pxa", GPIO_NAND_RB, "rdy", GPIO_ACTIVE_HIGH), + }, +}; + static struct resource cmx255_nand_resource[] = { [0] = { .start = PXA_CS1_PHYS, @@ -198,11 +209,6 @@ static struct mtd_partition cmx255_nand_parts[] = { }; static struct gpio_nand_platdata cmx255_nand_platdata = { - .gpio_nce = GPIO_NAND_CS, - .gpio_cle = GPIO_NAND_CLE, - .gpio_ale = GPIO_NAND_ALE, - .gpio_rdy = GPIO_NAND_RB, - .gpio_nwp = -1, .parts = cmx255_nand_parts, .num_parts = ARRAY_SIZE(cmx255_nand_parts), .chip_delay = 25, @@ -220,6 +226,7 @@ static struct platform_device cmx255_nand = { static void __init cmx255_init_nand(void) { + gpiod_add_lookup_table(&cmx255_nand_gpiod_table); platform_device_register(&cmx255_nand); } #else diff --git a/drivers/mtd/nand/gpio.c b/drivers/mtd/nand/gpio.c index fd3648952b5a..484f7fbc3f7d 100644 --- a/drivers/mtd/nand/gpio.c +++ b/drivers/mtd/nand/gpio.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include @@ -31,12 +31,16 @@ #include #include #include -#include struct gpiomtd { void __iomem *io_sync; struct nand_chip nand_chip; struct gpio_nand_platdata plat; + struct gpio_desc *nce; /* Optional chip enable */ + struct gpio_desc *cle; + struct gpio_desc *ale; + struct gpio_desc *rdy; + struct gpio_desc *nwp; /* Optional write protection */ }; static inline struct gpiomtd *gpio_nand_getpriv(struct mtd_info *mtd) @@ -78,11 +82,10 @@ static void gpio_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) gpio_nand_dosync(gpiomtd); if (ctrl & NAND_CTRL_CHANGE) { - if (gpio_is_valid(gpiomtd->plat.gpio_nce)) - gpio_set_value(gpiomtd->plat.gpio_nce, - !(ctrl & NAND_NCE)); - gpio_set_value(gpiomtd->plat.gpio_cle, !!(ctrl & NAND_CLE)); - gpio_set_value(gpiomtd->plat.gpio_ale, !!(ctrl & NAND_ALE)); + if (gpiomtd->nce) + gpiod_set_value(gpiomtd->nce, !(ctrl & NAND_NCE)); + gpiod_set_value(gpiomtd->cle, !!(ctrl & NAND_CLE)); + gpiod_set_value(gpiomtd->ale, !!(ctrl & NAND_ALE)); gpio_nand_dosync(gpiomtd); } if (cmd == NAND_CMD_NONE) @@ -96,7 +99,7 @@ static int gpio_nand_devready(struct mtd_info *mtd) { struct gpiomtd *gpiomtd = gpio_nand_getpriv(mtd); - return gpio_get_value(gpiomtd->plat.gpio_rdy); + return gpiod_get_value(gpiomtd->rdy); } #ifdef CONFIG_OF @@ -123,12 +126,6 @@ static int gpio_nand_get_config_of(const struct device *dev, } } - plat->gpio_rdy = of_get_gpio(dev->of_node, 0); - plat->gpio_nce = of_get_gpio(dev->of_node, 1); - plat->gpio_ale = of_get_gpio(dev->of_node, 2); - plat->gpio_cle = of_get_gpio(dev->of_node, 3); - plat->gpio_nwp = of_get_gpio(dev->of_node, 4); - if (!of_property_read_u32(dev->of_node, "chip-delay", &val)) plat->chip_delay = val; @@ -201,10 +198,11 @@ static int gpio_nand_remove(struct platform_device *pdev) nand_release(nand_to_mtd(&gpiomtd->nand_chip)); - if (gpio_is_valid(gpiomtd->plat.gpio_nwp)) - gpio_set_value(gpiomtd->plat.gpio_nwp, 0); - if (gpio_is_valid(gpiomtd->plat.gpio_nce)) - gpio_set_value(gpiomtd->plat.gpio_nce, 1); + /* Enable write protection and disable the chip */ + if (gpiomtd->nwp && !IS_ERR(gpiomtd->nwp)) + gpiod_set_value(gpiomtd->nwp, 0); + if (gpiomtd->nce && !IS_ERR(gpiomtd->nce)) + gpiod_set_value(gpiomtd->nce, 0); return 0; } @@ -215,66 +213,66 @@ static int gpio_nand_probe(struct platform_device *pdev) struct nand_chip *chip; struct mtd_info *mtd; struct resource *res; + struct device *dev = &pdev->dev; int ret = 0; - if (!pdev->dev.of_node && !dev_get_platdata(&pdev->dev)) + if (!dev->of_node && !dev_get_platdata(dev)) return -EINVAL; - gpiomtd = devm_kzalloc(&pdev->dev, sizeof(*gpiomtd), GFP_KERNEL); + gpiomtd = devm_kzalloc(dev, sizeof(*gpiomtd), GFP_KERNEL); if (!gpiomtd) return -ENOMEM; chip = &gpiomtd->nand_chip; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - chip->IO_ADDR_R = devm_ioremap_resource(&pdev->dev, res); + chip->IO_ADDR_R = devm_ioremap_resource(dev, res); if (IS_ERR(chip->IO_ADDR_R)) return PTR_ERR(chip->IO_ADDR_R); res = gpio_nand_get_io_sync(pdev); if (res) { - gpiomtd->io_sync = devm_ioremap_resource(&pdev->dev, res); + gpiomtd->io_sync = devm_ioremap_resource(dev, res); if (IS_ERR(gpiomtd->io_sync)) return PTR_ERR(gpiomtd->io_sync); } - ret = gpio_nand_get_config(&pdev->dev, &gpiomtd->plat); + ret = gpio_nand_get_config(dev, &gpiomtd->plat); if (ret) return ret; - if (gpio_is_valid(gpiomtd->plat.gpio_nce)) { - ret = devm_gpio_request(&pdev->dev, gpiomtd->plat.gpio_nce, - "NAND NCE"); - if (ret) - return ret; - gpio_direction_output(gpiomtd->plat.gpio_nce, 1); + /* Just enable the chip */ + gpiomtd->nce = devm_gpiod_get_optional(dev, "nce", GPIOD_OUT_HIGH); + if (IS_ERR(gpiomtd->nce)) + return PTR_ERR(gpiomtd->nce); + + /* We disable write protection once we know probe() will succeed */ + gpiomtd->nwp = devm_gpiod_get_optional(dev, "nwp", GPIOD_OUT_LOW); + if (IS_ERR(gpiomtd->nwp)) { + ret = PTR_ERR(gpiomtd->nwp); + goto out_ce; } - if (gpio_is_valid(gpiomtd->plat.gpio_nwp)) { - ret = devm_gpio_request(&pdev->dev, gpiomtd->plat.gpio_nwp, - "NAND NWP"); - if (ret) - return ret; + gpiomtd->nwp = devm_gpiod_get(dev, "ale", GPIOD_OUT_LOW); + if (IS_ERR(gpiomtd->nwp)) { + ret = PTR_ERR(gpiomtd->nwp); + goto out_ce; } - ret = devm_gpio_request(&pdev->dev, gpiomtd->plat.gpio_ale, "NAND ALE"); - if (ret) - return ret; - gpio_direction_output(gpiomtd->plat.gpio_ale, 0); + gpiomtd->cle = devm_gpiod_get(dev, "cle", GPIOD_OUT_LOW); + if (IS_ERR(gpiomtd->cle)) { + ret = PTR_ERR(gpiomtd->cle); + goto out_ce; + } - ret = devm_gpio_request(&pdev->dev, gpiomtd->plat.gpio_cle, "NAND CLE"); - if (ret) - return ret; - gpio_direction_output(gpiomtd->plat.gpio_cle, 0); - - if (gpio_is_valid(gpiomtd->plat.gpio_rdy)) { - ret = devm_gpio_request(&pdev->dev, gpiomtd->plat.gpio_rdy, - "NAND RDY"); - if (ret) - return ret; - gpio_direction_input(gpiomtd->plat.gpio_rdy); - chip->dev_ready = gpio_nand_devready; + gpiomtd->rdy = devm_gpiod_get_optional(dev, "rdy", GPIOD_IN); + if (IS_ERR(gpiomtd->rdy)) { + ret = PTR_ERR(gpiomtd->rdy); + goto out_ce; } + /* Using RDY pin */ + if (gpiomtd->rdy) + chip->dev_ready = gpio_nand_devready; nand_set_flash_node(chip, pdev->dev.of_node); chip->IO_ADDR_W = chip->IO_ADDR_R; @@ -285,12 +283,13 @@ static int gpio_nand_probe(struct platform_device *pdev) chip->cmd_ctrl = gpio_nand_cmd_ctrl; mtd = nand_to_mtd(chip); - mtd->dev.parent = &pdev->dev; + mtd->dev.parent = dev; platform_set_drvdata(pdev, gpiomtd); - if (gpio_is_valid(gpiomtd->plat.gpio_nwp)) - gpio_direction_output(gpiomtd->plat.gpio_nwp, 1); + /* Disable write protection, if wired up */ + if (gpiomtd->nwp && !IS_ERR(gpiomtd->nwp)) + gpiod_direction_output(gpiomtd->nwp, 1); ret = nand_scan(mtd, 1); if (ret) @@ -305,8 +304,11 @@ static int gpio_nand_probe(struct platform_device *pdev) return 0; err_wp: - if (gpio_is_valid(gpiomtd->plat.gpio_nwp)) - gpio_set_value(gpiomtd->plat.gpio_nwp, 0); + if (gpiomtd->nwp && !IS_ERR(gpiomtd->nwp)) + gpiod_set_value(gpiomtd->nwp, 0); +out_ce: + if (gpiomtd->nce && !IS_ERR(gpiomtd->nce)) + gpiod_set_value(gpiomtd->nce, 0); return ret; } diff --git a/include/linux/mtd/nand-gpio.h b/include/linux/mtd/nand-gpio.h index be4f45d89be2..98f71908212d 100644 --- a/include/linux/mtd/nand-gpio.h +++ b/include/linux/mtd/nand-gpio.h @@ -4,11 +4,6 @@ #include struct gpio_nand_platdata { - int gpio_nce; - int gpio_nwp; - int gpio_cle; - int gpio_ale; - int gpio_rdy; void (*adjust_parts)(struct gpio_nand_platdata *, size_t); struct mtd_partition *parts; unsigned int num_parts;