@@ -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;
}
Update the Meson pinctrl/gpio driver to support a live device tree. Signed-off-by: Beniamino Galvani <b.galvani@gmail.com> --- drivers/pinctrl/meson/pinctrl-meson.c | 66 +++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 30 deletions(-)