[ARM] pxa: add gpio_pwdown(_inverted) into pxaficp_ir.c

and convert PXA-based devices to gpio_pwdown where possible.

Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
Signed-off-by: Eric Miao <eric.y.miao@gmail.com>
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index 77d10ed..f5b7d83 100644
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -17,6 +17,7 @@
 #include <linux/etherdevice.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/gpio.h>
 
 #include <net/irda/irda.h>
 #include <net/irda/irmod.h>
@@ -163,6 +164,22 @@
 }
 
 /*
+ * Set the IrDA communications mode.
+ */
+static void pxa_irda_set_mode(struct pxa_irda *si, int mode)
+{
+	if (si->pdata->transceiver_mode)
+		si->pdata->transceiver_mode(si->dev, mode);
+	else {
+		if (gpio_is_valid(si->pdata->gpio_pwdown))
+			gpio_set_value(si->pdata->gpio_pwdown,
+					!(mode & IR_OFF) ^
+					!si->pdata->gpio_pwdown_inverted);
+		pxa2xx_transceiver_mode(si->dev, mode);
+	}
+}
+
+/*
  * Set the IrDA communications speed.
  */
 static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
@@ -188,7 +205,7 @@
 			pxa_irda_disable_clk(si);
 
 			/* set board transceiver to SIR mode */
-			si->pdata->transceiver_mode(si->dev, IR_SIRMODE);
+			pxa_irda_set_mode(si, IR_SIRMODE);
 
 			/* enable the STUART clock */
 			pxa_irda_enable_sirclk(si);
@@ -222,7 +239,7 @@
 		ICCR0 = 0;
 
 		/* set board transceiver to FIR mode */
-		si->pdata->transceiver_mode(si->dev, IR_FIRMODE);
+		pxa_irda_set_mode(si, IR_FIRMODE);
 
 		/* enable the FICP clock */
 		pxa_irda_enable_firclk(si);
@@ -641,7 +658,7 @@
 	local_irq_restore(flags);
 
 	/* power off board transceiver */
-	si->pdata->transceiver_mode(si->dev, IR_OFF);
+	pxa_irda_set_mode(si, IR_OFF);
 
 	printk(KERN_DEBUG "pxa_ir: irda shutdown\n");
 }
@@ -849,10 +866,26 @@
 	if (err)
 		goto err_mem_5;
 
-	if (si->pdata->startup)
+	if (gpio_is_valid(si->pdata->gpio_pwdown)) {
+		err = gpio_request(si->pdata->gpio_pwdown, "IrDA switch");
+		if (err)
+			goto err_startup;
+		err = gpio_direction_output(si->pdata->gpio_pwdown,
+					!si->pdata->gpio_pwdown_inverted);
+		if (err) {
+			gpio_free(si->pdata->gpio_pwdown);
+			goto err_startup;
+		}
+	}
+
+	if (si->pdata->startup) {
 		err = si->pdata->startup(si->dev);
-	if (err)
-		goto err_startup;
+		if (err)
+			goto err_startup;
+	}
+
+	if (gpio_is_valid(si->pdata->gpio_pwdown) && si->pdata->startup)
+		dev_warn(si->dev, "gpio_pwdown and startup() both defined!\n");
 
 	dev->netdev_ops = &pxa_irda_netdev_ops;
 
@@ -903,6 +936,8 @@
 	if (dev) {
 		struct pxa_irda *si = netdev_priv(dev);
 		unregister_netdev(dev);
+		if (gpio_is_valid(si->pdata->gpio_pwdown))
+			gpio_free(si->pdata->gpio_pwdown);
 		if (si->pdata->shutdown)
 			si->pdata->shutdown(si->dev);
 		kfree(si->tx_buff.head);