diff mbox series

[1/2] pinctrl: meson: convert to livetree

Message ID 20250411-u-boot-meson-livetree-v1-1-ebe31909cba5@linaro.org
State New
Headers show
Series ARM: meson: finally switch to livetree | expand

Commit Message

Neil Armstrong April 11, 2025, 2:55 p.m. UTC
From: Beniamino Galvani <b.galvani@gmail.com>

Update the Meson pinctrl/gpio driver to support a live device tree.

Signed-off-by: Beniamino Galvani <b.galvani@gmail.com>
Link: https://lore.kernel.org/r/20170709223006.3998-5-b.galvani@gmail.com
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
---
 drivers/pinctrl/meson/pinctrl-meson.c | 73 +++++++++++++++++++----------------
 1 file changed, 39 insertions(+), 34 deletions(-)
diff mbox series

Patch

diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c
index babf1bccc9697596522dc93d8906ff0454cfebf5..21409063ee89cd2f8aa3d511f3fed6b64f800e51 100644
--- a/drivers/pinctrl/meson/pinctrl-meson.c
+++ b/drivers/pinctrl/meson/pinctrl-meson.c
@@ -10,6 +10,8 @@ 
 #include <dm/device-internal.h>
 #include <dm/device_compat.h>
 #include <dm/lists.h>
+#include <dm/of_addr.h>
+#include <linux/ioport.h>
 #include <dm/pinctrl.h>
 #include <fdt_support.h>
 #include <linux/bitops.h>
@@ -319,88 +321,91 @@  int meson_gpio_probe(struct udevice *dev)
 	return 0;
 }
 
-static fdt_addr_t parse_address(int offset, const char *name, int na, int ns)
+static phys_addr_t parse_address(struct udevice *dev, ofnode node,
+				 const char *name)
 {
-	int index, len = 0;
-	const fdt32_t *reg;
+	struct resource r;
+	fdt_size_t sz;
+	int na, ns, index;
 
-	index = fdt_stringlist_search(gd->fdt_blob, offset, "reg-names", name);
+	index = ofnode_stringlist_search(node, "reg-names", name);
 	if (index < 0)
 		return FDT_ADDR_T_NONE;
 
-	reg = fdt_getprop(gd->fdt_blob, offset, "reg", &len);
-	if (!reg || (len <= (index * sizeof(fdt32_t) * (na + ns))))
+	if (of_live_active()) {
+		if (of_address_to_resource(ofnode_to_np(node), index, &r))
+			return FDT_ADDR_T_NONE;
+		else
+			return r.start;
+	}
+
+	na = dev_read_addr_cells(dev->parent);
+	if (na < 1) {
+		debug("bad #address-cells\n");
 		return FDT_ADDR_T_NONE;
+	}
 
-	reg += index * (na + ns);
+	ns = dev_read_size_cells(dev->parent);
+	if (ns < 1) {
+		debug("bad #size-cells\n");
+		return FDT_ADDR_T_NONE;
+	}
 
-	return fdt_translate_address((void *)gd->fdt_blob, offset, reg);
+	return fdtdec_get_addr_size_fixed(gd->fdt_blob, ofnode_to_offset(node),
+					  "reg", index, na, ns, &sz, true);
 }
 
 int meson_pinctrl_probe(struct udevice *dev)
 {
 	struct meson_pinctrl *priv = dev_get_priv(dev);
+	ofnode node, gpio = ofnode_null();
 	struct uclass_driver *drv;
 	struct udevice *gpio_dev;
-	fdt_addr_t addr;
-	int node, gpio = -1, len;
-	int na, ns;
+	phys_addr_t addr;
 	char *name;
+	int len;
 
-	/* FIXME: Should use livetree */
-	na = fdt_address_cells(gd->fdt_blob, dev_of_offset(dev->parent));
-	if (na < 1) {
-		debug("bad #address-cells\n");
-		return -EINVAL;
-	}
-
-	ns = fdt_size_cells(gd->fdt_blob, dev_of_offset(dev->parent));
-	if (ns < 1) {
-		debug("bad #size-cells\n");
-		return -EINVAL;
-	}
-
-	fdt_for_each_subnode(node, gd->fdt_blob, dev_of_offset(dev)) {
-		if (fdt_getprop(gd->fdt_blob, node, "gpio-controller", &len)) {
+	dev_for_each_subnode(node, dev) {
+		if (ofnode_read_prop(node, "gpio-controller", &len)) {
 			gpio = node;
 			break;
 		}
 	}
 
-	if (!gpio) {
+	if (!ofnode_valid(gpio)) {
 		debug("gpio node not found\n");
 		return -EINVAL;
 	}
 
-	addr = parse_address(gpio, "mux", na, ns);
+	addr = parse_address(dev, gpio, "mux");
 	if (addr == FDT_ADDR_T_NONE) {
 		debug("mux address not found\n");
 		return -EINVAL;
 	}
 	priv->reg_mux = (void __iomem *)addr;
 
-	addr = parse_address(gpio, "gpio", na, ns);
+	addr = parse_address(dev, gpio, "gpio");
 	if (addr == FDT_ADDR_T_NONE) {
 		debug("gpio address not found\n");
 		return -EINVAL;
 	}
 	priv->reg_gpio = (void __iomem *)addr;
 
-	addr = parse_address(gpio, "pull", na, ns);
+	addr = parse_address(dev, gpio, "pull");
 	/* Use gpio region if pull one is not present */
 	if (addr == FDT_ADDR_T_NONE)
 		priv->reg_pull = priv->reg_gpio;
 	else
 		priv->reg_pull = (void __iomem *)addr;
 
-	addr = parse_address(gpio, "pull-enable", na, ns);
+	addr = parse_address(dev, gpio, "pull-enable");
 	/* Use pull region if pull-enable one is not present */
 	if (addr == FDT_ADDR_T_NONE)
 		priv->reg_pullen = priv->reg_pull;
 	else
 		priv->reg_pullen = (void __iomem *)addr;
 
-	addr = parse_address(gpio, "ds", na, ns);
+	addr = parse_address(dev, gpio, "ds");
 	/* Drive strength region is optional */
 	if (addr == FDT_ADDR_T_NONE)
 		priv->reg_ds = NULL;
@@ -420,8 +425,8 @@  int meson_pinctrl_probe(struct udevice *dev)
 	sprintf(name, "meson-gpio");
 
 	/* Create child device UCLASS_GPIO and bind it */
-	device_bind(dev, priv->data->gpio_driver, name, NULL,
-		    offset_to_ofnode(gpio), &gpio_dev);
+	device_bind_with_driver_data(dev, priv->data->gpio_driver, name, 0,
+				     gpio, &gpio_dev);
 
 	return 0;
 }