[ARM] pxa: add pxa2xx_mfp_set_lpm() to facilitate low power state change

Some boards want to change low power state of pins on-the-fly, this
function helps to facilitate that operation instead of switching
back-n-forth between two configurations with pxa2xx_mfp_config().

Signed-off-by: Eric Miao <eric.miao@marvell.com>
Tested-by: Robert Jarzmik <robert.jarzmik@free.fr>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c
index ed91c04..fd4545e 100644
--- a/arch/arm/mach-pxa/mfp-pxa2xx.c
+++ b/arch/arm/mach-pxa/mfp-pxa2xx.c
@@ -39,6 +39,28 @@
 
 static struct gpio_desc gpio_desc[MFP_PIN_GPIO127 + 1];
 
+static int __mfp_config_lpm(unsigned gpio, unsigned long lpm)
+{
+	unsigned mask = GPIO_bit(gpio);
+
+	/* low power state */
+	switch (lpm) {
+	case MFP_LPM_DRIVE_HIGH:
+		PGSR(gpio) |= mask;
+		break;
+	case MFP_LPM_DRIVE_LOW:
+		PGSR(gpio) &= ~mask;
+		break;
+	case MFP_LPM_INPUT:
+		break;
+	default:
+		pr_warning("%s: invalid low power state for GPIO%d\n",
+				__func__, gpio);
+		return -EINVAL;
+	}
+	return 0;
+}
+
 static int __mfp_config_gpio(unsigned gpio, unsigned long c)
 {
 	unsigned long gafr, mask = GPIO_bit(gpio);
@@ -57,21 +79,8 @@
 	else
 		GPDR(gpio) &= ~mask;
 
-	/* low power state */
-	switch (c & MFP_LPM_STATE_MASK) {
-	case MFP_LPM_DRIVE_HIGH:
-		PGSR(gpio) |= mask;
-		break;
-	case MFP_LPM_DRIVE_LOW:
-		PGSR(gpio) &= ~mask;
-		break;
-	case MFP_LPM_INPUT:
-		break;
-	default:
-		pr_warning("%s: invalid low power state for GPIO%d\n",
-				__func__, gpio);
+	if (__mfp_config_lpm(gpio, c & MFP_LPM_STATE_MASK))
 		return -EINVAL;
-	}
 
 	/* give early warning if MFP_LPM_CAN_WAKEUP is set on the
 	 * configurations of those pins not able to wakeup
@@ -124,6 +133,20 @@
 	}
 }
 
+void pxa2xx_mfp_set_lpm(int mfp, unsigned long lpm)
+{
+	unsigned long flags;
+	int gpio;
+
+	gpio = __mfp_validate(mfp);
+	if (gpio < 0)
+		return;
+
+	local_irq_save(flags);
+	__mfp_config_lpm(gpio, lpm);
+	local_irq_restore(flags);
+}
+
 int gpio_set_wake(unsigned int gpio, unsigned int on)
 {
 	struct gpio_desc *d;