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

Signed-off-by: Beniamino Galvani <b.galv...@gmail.com>
---
 drivers/pinctrl/meson/pinctrl-meson.c | 66 +++++++++++++++++++----------------
 1 file changed, 36 insertions(+), 30 deletions(-)

diff --git a/drivers/pinctrl/meson/pinctrl-meson.c 
b/drivers/pinctrl/meson/pinctrl-meson.c
index a860200..c8cae51 100644
--- a/drivers/pinctrl/meson/pinctrl-meson.c
+++ b/drivers/pinctrl/meson/pinctrl-meson.c
@@ -8,6 +8,8 @@
 #include <dm.h>
 #include <dm/device-internal.h>
 #include <dm/lists.h>
+#include <dm/of_addr.h>
+#include <linux/ioport.h>
 #include <dm/pinctrl.h>
 #include <fdt_support.h>
 #include <linux/err.h>
@@ -257,66 +259,70 @@ static struct driver meson_gpio_driver = {
        .ops    = &meson_gpio_ops,
 };
 
-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;
 
-       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;
@@ -335,8 +341,8 @@ int meson_pinctrl_probe(struct udevice *dev)
        sprintf(name, "meson-gpio");
 
        /* Create child device UCLASS_GPIO and bind it */
-       device_bind(dev, &meson_gpio_driver, name, NULL, gpio, &gpio_dev);
-       dev_set_of_offset(gpio_dev, gpio);
+       device_bind_with_driver_data(dev, &meson_gpio_driver, name, 0,
+                                    gpio, &gpio_dev);
 
        return 0;
 }
-- 
2.9.3

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to