Merge branch 'master' of git://git.denx.de/u-boot-sunxi
[oweals/u-boot.git] / drivers / pinctrl / rockchip / pinctrl_rk3288.c
index ae8a4f1fde681b44ff4545805338e683a531245e..cb13d30da8e9e8769a1053a6281f4126ac10af2d 100644 (file)
@@ -479,7 +479,7 @@ static int rk3288_pinctrl_get_periph_id(struct udevice *dev,
        u32 cell[3];
        int ret;
 
-       ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
+       ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph),
                                   "interrupts", cell, ARRAY_SIZE(cell));
        if (ret < 0)
                return -EINVAL;
@@ -588,6 +588,7 @@ static int rk3288_pinctrl_set_pins(struct udevice *dev, int banknum, int index,
        struct rk3288_pinctrl_priv *priv = dev_get_priv(dev);
        uint shift, ind = index;
        uint mask;
+       uint value;
        u32 *addr;
        int ret;
 
@@ -596,7 +597,18 @@ static int rk3288_pinctrl_set_pins(struct udevice *dev, int banknum, int index,
                                          &mask);
        if (ret)
                return ret;
-       rk_clrsetreg(addr, mask << shift, muxval << shift);
+
+       /*
+        * PMU_GPIO0 registers cannot be selectively written so we cannot use
+        * rk_clrsetreg() here.  However, the upper 16 bits are reserved and
+        * are ignored when written, so we can use the same code as for the
+        * other GPIO banks providing that we preserve the value of the other
+        * bits.
+        */
+       value = readl(addr);
+       value &= ~(mask << shift);
+       value |= (mask << (shift + 16)) | (muxval << shift);
+       writel(value, addr);
 
        /* Handle pullup/pulldown */
        if (flags) {
@@ -614,7 +626,12 @@ static int rk3288_pinctrl_set_pins(struct udevice *dev, int banknum, int index,
                        addr = &priv->grf->gpio1_p[banknum - 1][ind];
                debug("%s: addr=%p, val=%x, shift=%x\n", __func__, addr, val,
                      shift);
-               rk_clrsetreg(addr, 3 << shift, val << shift);
+
+               /* As above, rk_clrsetreg() cannot be used here. */
+               value = readl(addr);
+               value &= ~(mask << shift);
+               value |= (3 << (shift + 16)) | (val << shift);
+               writel(value, addr);
        }
 
        return 0;
@@ -627,7 +644,7 @@ static int rk3288_pinctrl_set_state(struct udevice *dev, struct udevice *config)
        u32 cell[60], *ptr;
 
        debug("%s: %s %s\n", __func__, dev->name, config->name);
-       ret = fdtdec_get_int_array_count(blob, config->of_offset,
+       ret = fdtdec_get_int_array_count(blob, dev_of_offset(config),
                                         "rockchip,pins", cell,
                                         ARRAY_SIZE(cell));
        if (ret < 0) {