new file mode 100644
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Driver of GPIO controller on a 8-bit NAND latch (LVC573) on MikroTik RB91x.
+ *
+ * Copyright (C) 2021 Denis Kalashnikov <denis281089@gmail.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+
+#include <mfd/rb91x-ngl.h>
+
+#define DRIVER_NAME "rb91x-gpio-latch"
+
+static int get(struct gpio_chip *gc, unsigned offset)
+{
+ return -ENOSYS;
+}
+
+static void set(struct gpio_chip *gc, unsigned offset, int value)
+{
+ struct rb91x_ngl *ngl = gpiochip_get_data(gc);
+
+ ngl->latch_gpio_set_value(ngl, offset, value);
+}
+
+static int direction_input(struct gpio_chip *gc, unsigned offset)
+{
+ return -ENOSYS;
+}
+
+static int direction_output(struct gpio_chip *gc, unsigned offset, int value)
+{
+ struct rb91x_ngl *ngl = gpiochip_get_data(gc);
+
+ ngl->latch_gpio_set_value(ngl, offset, value);
+
+ return 0;
+}
+
+static int probe(struct platform_device *pdev)
+{
+ struct gpio_chip *gc;
+ struct device_node *of_node = pdev->dev.of_node;
+ struct device *dev = &pdev->dev, *parent = pdev->dev.parent;
+ struct rb91x_ngl *ngl;
+ int ret;
+ u32 val;
+
+ pr_info(DRIVER_NAME " driver probe\n");
+
+ if (!parent)
+ return -ENODEV;
+
+ gc = devm_kzalloc(&pdev->dev, sizeof(*gc), GFP_KERNEL);
+ if (!gc)
+ return -ENOMEM;
+
+ /*
+ ret = of_property_read_u32(of_node, "base", &val);
+ if (ret < 0) {
+ dev_err(dev, "Could not read required 'base' property\n");
+ return -EINVAL;
+ }
+ pr_info(DRIVER_NAME ": base = %d\n", val);
+ gc->base = val;
+ */
+ gc->base = -1; /* Request dynamic allocation */
+
+ ngl = dev_get_drvdata(parent);
+ if (!ngl) {
+ pr_err(DRIVER_NAME " ngl is null\n");
+ return -EINVAL;
+ }
+
+ gc->label = DRIVER_NAME;
+ gc->parent = dev;
+ gc->can_sleep = true;
+ gc->ngpio = ngl->latch_gpios_count(ngl);
+ gc->get = get;
+ gc->set = set;
+ gc->direction_input = direction_input,
+ gc->direction_output = direction_output;
+ gc->of_node = of_node;
+
+ platform_set_drvdata(pdev, gc);
+
+ ret = gpiochip_add_data(gc, ngl);
+ if (ret) {
+ pr_err(DRIVER_NAME ": failed to add gpio chip: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int remove(struct platform_device *pdev)
+{
+ gpiochip_remove(platform_get_drvdata(pdev));
+ return 0;
+}
+
+static const struct of_device_id match[] = {
+ { .compatible = "mikrotik," DRIVER_NAME },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, match);
+
+static struct platform_driver rb91x_gpio_latch_driver = {
+ .probe = probe,
+ .remove = remove,
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = match,
+ },
+};
+
+module_platform_driver(rb91x_gpio_latch_driver);
+
+MODULE_DESCRIPTION("Driver for GPIO on MikroTik RB91x NAND latch");
+MODULE_AUTHOR("Denis Kalashnikov <denis281089@gmail.com>");
+MODULE_LICENSE("GPL v2");
@@ -1,6 +1,7 @@
CONFIG_CRC16=y
CONFIG_CRYPTO_DEFLATE=y
CONFIG_GPIO_LATCH=y
+CONFIG_GPIO_LATCH_RB91X=y
CONFIG_GPIO_RB4XX=y
CONFIG_GPIO_WATCHDOG=y
CONFIG_GPIO_WATCHDOG_ARCH_INITCALL=y
@@ -19,3 +19,26 @@
obj-$(CONFIG_MFD_RB4XX_CPLD) += rb4xx-cpld.o
+
+obj-$(CONFIG_MFD_RB91X_NGL) += rb91x-ngl.o
+--- a/drivers/gpio/Kconfig
++++ b/drivers/gpio/Kconfig
+@@ -130,6 +130,10 @@ config GPIO_ATH79
+ Select this option to enable GPIO driver for
+ Atheros AR71XX/AR724X/AR913X SoC devices.
+
++config GPIO_LATCH_RB91X
++ tristate "Mikrotik RB91X GPIO latch driver"
++ depends on MFD_RB91X_NGL
++
+ config GPIO_RASPBERRYPI_EXP
+ tristate "Raspberry Pi 3 GPIO Expander"
+ default RASPBERRYPI_FIRMWARE
+--- a/drivers/gpio/Makefile
++++ b/drivers/gpio/Makefile
+@@ -67,6 +67,7 @@ obj-$(CONFIG_GPIO_IT87) += gpio-it87.o
+ obj-$(CONFIG_GPIO_IXP4XX) += gpio-ixp4xx.o
+ obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o
+ obj-$(CONFIG_GPIO_KEMPLD) += gpio-kempld.o
++obj-$(CONFIG_GPIO_LATCH_RB91X) += gpio-latch-rb91x.o
+ obj-$(CONFIG_GPIO_LOONGSON1) += gpio-loongson1.o
+ obj-$(CONFIG_GPIO_LOONGSON) += gpio-loongson.o
+ obj-$(CONFIG_GPIO_LP3943) += gpio-lp3943.o
This driver exports GPIO lines on the latch that are not used for NAND control lines (but used for data lines). It doesn't request byself SoC gpio lines and set them through API provided by rb91x-ngl. Exported lines are used for power LED, user LED and nCS of the Shift Register. Signed-off-by: Denis Kalashnikov <denis281089@gmail.com> --- .../files/drivers/gpio/gpio-latch-rb91x.c | 127 ++++++++++++++++++ target/linux/ath79/mikrotik/config-default | 1 + .../patches-5.4/939-mikrotik-rb91x.patch | 23 ++++ 3 files changed, 151 insertions(+) create mode 100644 target/linux/ath79/files/drivers/gpio/gpio-latch-rb91x.c