[PATCH v3 2/3] gpio: vortex: add new GPIO device driver

Marcos Del Sol Vives posted 3 patches 1 month, 1 week ago
There is a newer version of this series
[PATCH v3 2/3] gpio: vortex: add new GPIO device driver
Posted by Marcos Del Sol Vives 1 month, 1 week ago
Add a new simple GPIO device driver for Vortex86 lines of SoCs,
implemented according to their programming reference manual [1].

This is required for detecting the status of the poweroff button and
performing the poweroff sequence on ICOP eBox computers.

IRQs are not implemented, as they are only available for ports 0 and 1,
none which are accessible on my test machine (an EBOX-3352-GLW).

[1]:
http://www.dmp.com.tw/tech/DMP_Vortex86_Series_Software_Programming_Reference_091216.pdf

Signed-off-by: Marcos Del Sol Vives <marcos@orca.pet>
---
 MAINTAINERS                |   5 ++
 drivers/gpio/Kconfig       |  11 ++++
 drivers/gpio/Makefile      |   1 +
 drivers/gpio/gpio-vortex.c | 110 +++++++++++++++++++++++++++++++++++++
 4 files changed, 127 insertions(+)
 create mode 100644 drivers/gpio/gpio-vortex.c

diff --git a/MAINTAINERS b/MAINTAINERS
index daf520a13bdf..8c3098a39411 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -26953,6 +26953,11 @@ VOLTAGE AND CURRENT REGULATOR IRQ HELPERS
 R:	Matti Vaittinen <mazziesaccount@gmail.com>
 F:	drivers/regulator/irq_helpers.c
 
+VORTEX HARDWARE SUPPORT
+R:	Marcos Del Sol Vives <marcos@orca.pet>
+S:	Maintained
+F:	drivers/gpio/gpio-vortex.c
+
 VRF
 M:	David Ahern <dsahern@kernel.org>
 L:	netdev@vger.kernel.org
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index e43abb322fa6..cd2b1e105908 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1077,6 +1077,17 @@ config GPIO_TS5500
 	  blocks of the TS-5500: DIO1, DIO2 and the LCD port, and the TS-5600
 	  LCD port.
 
+config GPIO_VORTEX
+	tristate "Vortex SoC GPIO support"
+	select REGMAP_MMIO
+	select GPIO_REGMAP
+	help
+	  Driver to access the five 8-bit bidirectional GPIO ports present on
+	  all DM&P Vortex SoCs.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called gpio-vortex.
+
 config GPIO_WINBOND
 	tristate "Winbond Super I/O GPIO support"
 	select ISA_BUS_API
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 379f55e9ed1e..7b8626c9bd75 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -197,6 +197,7 @@ obj-$(CONFIG_GPIO_VIPERBOARD)		+= gpio-viperboard.o
 obj-$(CONFIG_GPIO_VIRTUSER)		+= gpio-virtuser.o
 obj-$(CONFIG_GPIO_VIRTIO)		+= gpio-virtio.o
 obj-$(CONFIG_GPIO_VISCONTI)		+= gpio-visconti.o
+obj-$(CONFIG_GPIO_VORTEX)		+= gpio-vortex.o
 obj-$(CONFIG_GPIO_VX855)		+= gpio-vx855.o
 obj-$(CONFIG_GPIO_WCD934X)		+= gpio-wcd934x.o
 obj-$(CONFIG_GPIO_WHISKEY_COVE)		+= gpio-wcove.o
diff --git a/drivers/gpio/gpio-vortex.c b/drivers/gpio/gpio-vortex.c
new file mode 100644
index 000000000000..6fc184942e7f
--- /dev/null
+++ b/drivers/gpio/gpio-vortex.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  GPIO driver for Vortex86 SoCs
+ *
+ *  Author: Marcos Del Sol Vives <marcos@orca.pet>
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/spinlock.h>
+#include <linux/gpio/driver.h>
+#include <linux/gpio/regmap.h>
+#include <linux/regmap.h>
+#include <linux/ioport.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+
+#define DAT_RANGE 0
+#define DIR_RANGE 1
+
+struct vortex_gpio {
+	struct regmap_range ranges[2];
+	struct regmap_access_table access_table;
+};
+
+static int vortex_gpio_probe(struct platform_device *pdev)
+{
+	struct gpio_regmap_config gpiocfg = {};
+	struct resource *dat_res, *dir_res;
+	struct device *dev = &pdev->dev;
+	struct regmap_config rmcfg = {};
+	unsigned long io_start, io_end;
+	struct vortex_gpio *priv;
+	struct regmap *map;
+	void __iomem *regs;
+
+	dat_res = platform_get_resource_byname(pdev, IORESOURCE_IO, "dat");
+	if (unlikely(!dat_res)) {
+		dev_err(dev, "failed to get data register\n");
+		return -ENODEV;
+	}
+
+	dir_res = platform_get_resource_byname(pdev, IORESOURCE_IO, "dir");
+	if (unlikely(!dir_res)) {
+		dev_err(dev, "failed to get direction register\n");
+		return -ENODEV;
+	}
+
+	if (unlikely(resource_size(dat_res) != resource_size(dir_res))) {
+		dev_err(dev, "data and direction size mismatch\n");
+		return -EINVAL;
+	}
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(struct vortex_gpio),
+			    GFP_KERNEL);
+	if (unlikely(!priv))
+		return -ENOMEM;
+	pdev->dev.driver_data = priv;
+
+	/* Map an I/O window that covers both data and direction */
+	io_start = min(dat_res->start, dir_res->start);
+	io_end = max(dat_res->end, dir_res->end);
+	regs = devm_ioport_map(dev, io_start, io_end - io_start + 1);
+	if (unlikely(!regs))
+		return -ENOMEM;
+
+	/* Dynamically build access table from gpiocfg */
+	priv->ranges[DAT_RANGE].range_min = dat_res->start - io_start;
+	priv->ranges[DAT_RANGE].range_max = dat_res->end - io_start;
+	priv->ranges[DIR_RANGE].range_min = dir_res->start - io_start;
+	priv->ranges[DIR_RANGE].range_max = dir_res->end - io_start;
+	priv->access_table.n_yes_ranges = ARRAY_SIZE(priv->ranges);
+	priv->access_table.yes_ranges = priv->ranges;
+
+	rmcfg.reg_bits = 8;
+	rmcfg.val_bits = 8;
+	rmcfg.io_port = true;
+	rmcfg.wr_table = &priv->access_table;
+	rmcfg.rd_table = &priv->access_table;
+
+	map = devm_regmap_init_mmio(dev, regs, &rmcfg);
+	if (unlikely(IS_ERR(map)))
+		return dev_err_probe(dev, PTR_ERR(map),
+				     "Unable to initialize register map\n");
+
+	gpiocfg.parent = dev;
+	gpiocfg.regmap = map;
+	gpiocfg.ngpio = 8 * resource_size(dat_res);
+	gpiocfg.ngpio_per_reg = 8;
+	gpiocfg.reg_dat_base = GPIO_REGMAP_ADDR(priv->ranges[DAT_RANGE].range_min);
+	gpiocfg.reg_set_base = GPIO_REGMAP_ADDR(priv->ranges[DAT_RANGE].range_min);
+	gpiocfg.reg_dir_out_base = GPIO_REGMAP_ADDR(priv->ranges[DIR_RANGE].range_min);
+	gpiocfg.flags = GPIO_REGMAP_DIR_BEFORE_SET;
+
+	return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(dev, &gpiocfg));
+}
+
+static struct platform_driver vortex_gpio_driver = {
+	.driver.name = "vortex-gpio",
+	.probe = vortex_gpio_probe,
+};
+
+module_platform_driver(vortex_gpio_driver);
+
+MODULE_AUTHOR("Marcos Del Sol Vives <marcos@orca.pet>");
+MODULE_DESCRIPTION("GPIO driver for Vortex86 SoCs");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:vortex-gpio");
-- 
2.34.1
Re: [PATCH v3 2/3] gpio: vortex: add new GPIO device driver
Posted by Marcos Del Sol Vives 1 month, 1 week ago
El 21/08/2025 a las 12:18, Marcos Del Sol Vives escribió:
> +#include <linux/types.h>
> +#include <linux/errno.h>
> +#include <linux/module.h>
> +#include <linux/ioport.h>
> +#include <linux/spinlock.h>
> +#include <linux/gpio/driver.h>
> +#include <linux/gpio/regmap.h>
> +#include <linux/regmap.h>
> +#include <linux/ioport.h>
> +#include <linux/types.h>
> +#include <linux/platform_device.h>

I realized now that, despite checking over and over the patches before
sending to the mailing list, I forgot to clean up leftover includes from
previous versions of the driver.

I am fairly new to this procedure of merging patches. Should I later, after
a send a sensible amount of time has passed to let everyone voice their
opinion, send a new v4 version of the patch to fix these (and also clarify
the commit message on the regmap-gpio, as requested in another email),
or if accepted would maybe the person merging it sort this out?

Sorry for the mess,
Marcos
Re: [PATCH v3 2/3] gpio: vortex: add new GPIO device driver
Posted by Bjorn Helgaas 1 month, 1 week ago
On Thu, Aug 21, 2025 at 07:05:16PM +0200, Marcos Del Sol Vives wrote:
> El 21/08/2025 a las 12:18, Marcos Del Sol Vives escribió:
> > +#include <linux/types.h>
> > +#include <linux/errno.h>
> > +#include <linux/module.h>
> > +#include <linux/ioport.h>
> > +#include <linux/spinlock.h>
> > +#include <linux/gpio/driver.h>
> > +#include <linux/gpio/regmap.h>
> > +#include <linux/regmap.h>
> > +#include <linux/ioport.h>
> > +#include <linux/types.h>
> > +#include <linux/platform_device.h>
> 
> I realized now that, despite checking over and over the patches before
> sending to the mailing list, I forgot to clean up leftover includes from
> previous versions of the driver.
> 
> I am fairly new to this procedure of merging patches. Should I later, after
> a send a sensible amount of time has passed to let everyone voice their
> opinion, send a new v4 version of the patch to fix these (and also clarify
> the commit message on the regmap-gpio, as requested in another email),
> or if accepted would maybe the person merging it sort this out?

I'm not the person to merge this, but my advice is to wait a few days
and post a v4 that cleans up the includes and updates the commit
messages.  It makes the process cleaner if the patch you post is the
same as the one that gets merged.
Re: [PATCH v3 2/3] gpio: vortex: add new GPIO device driver
Posted by Bjorn Helgaas 1 month, 1 week ago
On Fri, Aug 22, 2025 at 10:47:20AM -0500, Bjorn Helgaas wrote:
> On Thu, Aug 21, 2025 at 07:05:16PM +0200, Marcos Del Sol Vives wrote:
> > El 21/08/2025 a las 12:18, Marcos Del Sol Vives escribió:
> > > +#include <linux/types.h>
> > > +#include <linux/errno.h>
> > > +#include <linux/module.h>
> > > +#include <linux/ioport.h>
> > > +#include <linux/spinlock.h>
> > > +#include <linux/gpio/driver.h>
> > > +#include <linux/gpio/regmap.h>
> > > +#include <linux/regmap.h>
> > > +#include <linux/ioport.h>
> > > +#include <linux/types.h>
> > > +#include <linux/platform_device.h>
> > 
> > I realized now that, despite checking over and over the patches before
> > sending to the mailing list, I forgot to clean up leftover includes from
> > previous versions of the driver.
> > 
> > I am fairly new to this procedure of merging patches. Should I later, after
> > a send a sensible amount of time has passed to let everyone voice their
> > opinion, send a new v4 version of the patch to fix these (and also clarify
> > the commit message on the regmap-gpio, as requested in another email),
> > or if accepted would maybe the person merging it sort this out?
> 
> I'm not the person to merge this, but my advice is to wait a few days
> and post a v4 that cleans up the includes and updates the commit
> messages.  It makes the process cleaner if the patch you post is the
> same as the one that gets merged.

Sorry for the noise, should have read farther through my email :)
Re: [PATCH v3 2/3] gpio: vortex: add new GPIO device driver
Posted by Marcos Del Sol Vives 1 month, 1 week ago
El 22/08/2025 a las 17:49, Bjorn Helgaas escribió:
> On Fri, Aug 22, 2025 at 10:47:20AM -0500, Bjorn Helgaas wrote:
>> I'm not the person to merge this, but my advice is to wait a few days
>> and post a v4 that cleans up the includes and updates the commit
>> messages.  It makes the process cleaner if the patch you post is the
>> same as the one that gets merged.
> 
> Sorry for the noise, should have read farther through my email :)

No problem, thanks for clarifying!

I would've waited for a couple days more to give more time for review
before the v4 if it was just minor styling details, but I found a nasty
surprise yesterday in the DX3 programming manual (I was using the SX/MX/DX
manual before): it has two discontinuous ranges for data and two
discontinuous ranges for direction, and the icing on top is that
*all four ranges have different sizes*.

So as it was a pretty big change I wanted to have a new one with support
for that for review asap :)
Re: [PATCH v3 2/3] gpio: vortex: add new GPIO device driver
Posted by Linus Walleij 1 month, 1 week ago
On Thu, Aug 21, 2025 at 12:19 PM Marcos Del Sol Vives <marcos@orca.pet> wrote:

> Add a new simple GPIO device driver for Vortex86 lines of SoCs,
> implemented according to their programming reference manual [1].
>
> This is required for detecting the status of the poweroff button and
> performing the poweroff sequence on ICOP eBox computers.
>
> IRQs are not implemented, as they are only available for ports 0 and 1,
> none which are accessible on my test machine (an EBOX-3352-GLW).
>
> [1]:
> http://www.dmp.com.tw/tech/DMP_Vortex86_Series_Software_Programming_Reference_091216.pdf
>
> Signed-off-by: Marcos Del Sol Vives <marcos@orca.pet>

Wow this driver got really compact with gpio regmap!

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij