@@ -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;
}