diff options
| author | Linus Walleij <linusw@kernel.org> | 2026-03-28 16:55:48 +0100 |
|---|---|---|
| committer | Thomas Bogendoerfer <tsbogend@alpha.franken.de> | 2026-04-13 15:41:56 +0200 |
| commit | 15513eefac7ca68602e9de9853f5e671bf7b4eef (patch) | |
| tree | 4e0eaaff715c039e7bce0b6f6f3fb7b1f483dc23 | |
| parent | 42671e9c1e40032f982d2163ba4867dc85e23832 (diff) | |
MIPS/mtd: Handle READY GPIO in generic NAND platform data
The callbacks into the MIPS RB532 platform to read the GPIO pin
indicating that the NAND chip is ready are oldschool and does
not assign GPIOs as properties to the NAND device.
Add a capability to the generic platform NAND chip driver to use
a GPIO line to detect if a NAND chip is ready and override the
platform-local drv_ready() callback with this check if the GPIO
is present.
This makes it possible to drop the legacy include header
<linux/gpio.h> from the RB532 devices.
Signed-off-by: Linus Walleij <linusw@kernel.org>
Acked-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
| -rw-r--r-- | arch/mips/rb532/devices.c | 36 | ||||
| -rw-r--r-- | drivers/mtd/nand/raw/plat_nand.c | 24 |
2 files changed, 44 insertions, 16 deletions
diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c index 3f56d9feb73a..c3d8d96d0ef5 100644 --- a/arch/mips/rb532/devices.c +++ b/arch/mips/rb532/devices.c @@ -14,7 +14,6 @@ #include <linux/platform_device.h> #include <linux/mtd/platnand.h> #include <linux/mtd/mtd.h> -#include <linux/gpio.h> #include <linux/gpio/machine.h> #include <linux/gpio/property.h> #include <linux/gpio_keys.h> @@ -135,12 +134,6 @@ static struct platform_device cf_slot0 = { .num_resources = ARRAY_SIZE(cf_slot0_res), }; -/* Resources and device for NAND */ -static int rb532_dev_ready(struct nand_chip *chip) -{ - return gpio_get_value(GPIO_RDY); -} - static void rb532_cmd_ctrl(struct nand_chip *chip, int cmd, unsigned int ctrl) { unsigned char orbits, nandbits; @@ -166,16 +159,23 @@ static struct resource nand_slot0_res[] = { }; static struct platform_nand_data rb532_nand_data = { - .ctrl.dev_ready = rb532_dev_ready, .ctrl.cmd_ctrl = rb532_cmd_ctrl, }; -static struct platform_device nand_slot0 = { - .name = "gen_nand", - .id = -1, - .resource = nand_slot0_res, - .num_resources = ARRAY_SIZE(nand_slot0_res), - .dev.platform_data = &rb532_nand_data, +static const struct property_entry nand0_properties[] = { + PROPERTY_ENTRY_GPIO("ready-gpios", &rb532_gpio0_node, + GPIO_RDY, GPIO_ACTIVE_HIGH), + { } +}; + +static const struct platform_device_info nand0_info __initconst = { + .name = "gen_nand", + .id = PLATFORM_DEVID_NONE, + .res = nand_slot0_res, + .num_res = ARRAY_SIZE(nand_slot0_res), + .data = &rb532_nand_data, + .size_data = sizeof(struct platform_nand_data), + .properties = nand0_properties, }; static struct mtd_partition rb532_partition_info[] = { @@ -234,7 +234,6 @@ static struct platform_device rb532_uart = { static struct platform_device *rb532_devs[] = { &korina_dev0, - &nand_slot0, &cf_slot0, &rb532_led, &rb532_uart, @@ -321,6 +320,13 @@ static int __init plat_setup_devices(void) */ software_node_register(&rb532_gpio0_node); + pd = platform_device_register_full(&nand0_info); + ret = PTR_ERR_OR_ZERO(pd); + if (ret) { + pr_err("failed to create NAND slot0 device: %d\n", ret); + return ret; + } + pd = platform_device_register_full(&rb532_button_info); ret = PTR_ERR_OR_ZERO(pd); if (ret) { diff --git a/drivers/mtd/nand/raw/plat_nand.c b/drivers/mtd/nand/raw/plat_nand.c index 0bcd455328ef..fe31551bcf5f 100644 --- a/drivers/mtd/nand/raw/plat_nand.c +++ b/drivers/mtd/nand/raw/plat_nand.c @@ -6,6 +6,7 @@ */ #include <linux/err.h> +#include <linux/gpio/consumer.h> #include <linux/io.h> #include <linux/module.h> #include <linux/platform_device.h> @@ -17,6 +18,7 @@ struct plat_nand_data { struct nand_controller controller; struct nand_chip chip; void __iomem *io_base; + struct gpio_desc *ready_gpio; }; static int plat_nand_attach_chip(struct nand_chip *chip) @@ -32,6 +34,14 @@ static const struct nand_controller_ops plat_nand_ops = { .attach_chip = plat_nand_attach_chip, }; +/* Resources and device for NAND */ +static int plat_nand_gpio_dev_ready(struct nand_chip *chip) +{ + struct plat_nand_data *data = nand_get_controller_data(chip); + + return gpiod_get_value(data->ready_gpio); +} + /* * Probe for the NAND device. */ @@ -41,6 +51,7 @@ static int plat_nand_probe(struct platform_device *pdev) struct plat_nand_data *data; struct mtd_info *mtd; const char **part_types; + struct nand_chip *chip; int err = 0; if (!pdata) { @@ -59,9 +70,17 @@ static int plat_nand_probe(struct platform_device *pdev) if (!data) return -ENOMEM; + data->ready_gpio = devm_gpiod_get_optional(&pdev->dev, "ready", + GPIOD_IN); + if (IS_ERR(data->ready_gpio)) + return dev_err_probe(&pdev->dev, PTR_ERR(data->ready_gpio), + "could not get READY GPIO\n"); + data->controller.ops = &plat_nand_ops; nand_controller_init(&data->controller); data->chip.controller = &data->controller; + chip = &data->chip; + nand_set_controller_data(chip, data); data->io_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(data->io_base)) @@ -74,7 +93,10 @@ static int plat_nand_probe(struct platform_device *pdev) data->chip.legacy.IO_ADDR_R = data->io_base; data->chip.legacy.IO_ADDR_W = data->io_base; data->chip.legacy.cmd_ctrl = pdata->ctrl.cmd_ctrl; - data->chip.legacy.dev_ready = pdata->ctrl.dev_ready; + if (data->ready_gpio) + data->chip.legacy.dev_ready = plat_nand_gpio_dev_ready; + else + data->chip.legacy.dev_ready = pdata->ctrl.dev_ready; data->chip.legacy.select_chip = pdata->ctrl.select_chip; data->chip.legacy.write_buf = pdata->ctrl.write_buf; data->chip.legacy.read_buf = pdata->ctrl.read_buf; |
