diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
index d3042e0c9712..6a86b7989b25 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
@@ -997,18 +997,27 @@ static int sunxi_pinctrl_gpio_get(struct gpio_chip *chip, unsigned offset)
 	struct sunxi_pinctrl *pctl = gpiochip_get_data(chip);
 	bool set_mux = pctl->desc->irq_read_needs_mux &&
 		gpiochip_line_is_irq(chip, offset);
-	u32 pin = offset + chip->base;
+	u32 mreg, mshift, mmask, mval;
 	u32 reg, shift, mask, val;
+	unsigned long flags;
 
 	sunxi_data_reg(pctl, offset, &reg, &shift, &mask);
+	if (!set_mux)
+		return (readl(pctl->membase + reg) & mask) >> shift;
 
-	if (set_mux)
-		sunxi_pmx_set(pctl->pctl_dev, pin, SUN4I_FUNC_INPUT);
-
+	/*
+	 * Some SoCs don't read the GPIO value registers correctly
+	 * when the pinmux is not set to GPIO_INPUT. Temporarily switch
+	 * to that mux, to read the correct value.
+	 */
+	sunxi_mux_reg(pctl, offset, &mreg, &mshift, &mmask);
+	raw_spin_lock_irqsave(&pctl->lock, flags);
+	mval = readl(pctl->membase + mreg);
+	writel((mval & ~mmask) | SUN4I_FUNC_INPUT << mshift,
+	       pctl->membase + mreg);
 	val = (readl(pctl->membase + reg) & mask) >> shift;
-
-	if (set_mux)
-		sunxi_pmx_set(pctl->pctl_dev, pin, SUN4I_FUNC_IRQ);
+	writel(mval, pctl->membase + mreg);
+	raw_spin_unlock_irqrestore(&pctl->lock, flags);
 
 	return val;
 }
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.h b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
index 0daf7600e2fb..ec7c977655b5 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
@@ -85,7 +85,6 @@
 #define IO_BIAS_MASK		GENMASK(3, 0)
 
 #define SUN4I_FUNC_INPUT	0
-#define SUN4I_FUNC_IRQ		6
 #define SUN4I_FUNC_DISABLED_OLD 7
 #define SUN4I_FUNC_DISABLED_NEW 15
 
