diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 0ff5ed80936fab62899cda1e96baab5175e4f2be..b536b5a5a10d4d8f4420c37d06d54dce780814d4 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -447,34 +447,9 @@ static struct pxamci_platform_data corgi_mci_platform_data = {
 /*
  * Irda
  */
-static void corgi_irda_transceiver_mode(struct device *dev, int mode)
-{
-	gpio_set_value(CORGI_GPIO_IR_ON, mode & IR_OFF);
-	pxa2xx_transceiver_mode(dev, mode);
-}
-
-static int corgi_irda_startup(struct device *dev)
-{
-	int err;
-
-	err = gpio_request(CORGI_GPIO_IR_ON, "IR_ON");
-	if (err)
-		return err;
-
-	gpio_direction_output(CORGI_GPIO_IR_ON, 1);
-	return 0;
-}
-
-static void corgi_irda_shutdown(struct device *dev)
-{
-	gpio_free(CORGI_GPIO_IR_ON);
-}
-
 static struct pxaficp_platform_data corgi_ficp_platform_data = {
+	.gpio_pwdown		= CORGI_GPIO_IR_ON,
 	.transceiver_cap	= IR_SIRMODE | IR_OFF,
-	.transceiver_mode	= corgi_irda_transceiver_mode,
-	.startup		= corgi_irda_startup,
-	.shutdown		= corgi_irda_shutdown,
 };
 
 
diff --git a/arch/arm/mach-pxa/e740.c b/arch/arm/mach-pxa/e740.c
index a36fc17f671d937f73e8e0fe8626a2e271afa1e2..49acdfa6650d3e7827807156fc071c1da0d49db1 100644
--- a/arch/arm/mach-pxa/e740.c
+++ b/arch/arm/mach-pxa/e740.c
@@ -199,7 +199,6 @@ static void __init e740_init(void)
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 	pxa_set_udc_info(&e7xx_udc_mach_info);
 	pxa_set_ac97_info(NULL);
-	e7xx_irda_init();
 	pxa_set_ficp_info(&e7xx_ficp_platform_data);
 }
 
diff --git a/arch/arm/mach-pxa/e750.c b/arch/arm/mach-pxa/e750.c
index 1d00110590e5c7dee25cca9918e1c6591a798526..4052ece3ef4981e03f488be70542577670b05085 100644
--- a/arch/arm/mach-pxa/e750.c
+++ b/arch/arm/mach-pxa/e750.c
@@ -200,7 +200,6 @@ static void __init e750_init(void)
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 	pxa_set_udc_info(&e7xx_udc_mach_info);
 	pxa_set_ac97_info(NULL);
-	e7xx_irda_init();
 	pxa_set_ficp_info(&e7xx_ficp_platform_data);
 }
 
diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c
index c60dadf847a624da6cc34da40bb61c61654e947e..91417f035069a0ce40efd7cc9c60d2542962bdd9 100644
--- a/arch/arm/mach-pxa/eseries.c
+++ b/arch/arm/mach-pxa/eseries.c
@@ -47,44 +47,9 @@ struct pxa2xx_udc_mach_info e7xx_udc_mach_info = {
 	.gpio_pullup_inverted = 1
 };
 
-static void e7xx_irda_transceiver_mode(struct device *dev, int mode)
-{
-	if (mode & IR_OFF) {
-		gpio_set_value(GPIO_E7XX_IR_OFF, 1);
-		pxa2xx_transceiver_mode(dev, mode);
-	} else {
-		pxa2xx_transceiver_mode(dev, mode);
-		gpio_set_value(GPIO_E7XX_IR_OFF, 0);
-	}
-}
-
-int e7xx_irda_init(void)
-{
-	int ret;
-
-	ret = gpio_request(GPIO_E7XX_IR_OFF, "IrDA power");
-	if (ret)
-		goto out;
-
-	ret = gpio_direction_output(GPIO_E7XX_IR_OFF, 0);
-	if (ret)
-		goto out;
-
-	e7xx_irda_transceiver_mode(NULL, IR_SIRMODE | IR_OFF);
-out:
-	return ret;
-}
-
-static void e7xx_irda_shutdown(struct device *dev)
-{
-	e7xx_irda_transceiver_mode(dev, IR_SIRMODE | IR_OFF);
-	gpio_free(GPIO_E7XX_IR_OFF);
-}
-
 struct pxaficp_platform_data e7xx_ficp_platform_data = {
-	.transceiver_cap  = IR_SIRMODE | IR_OFF,
-	.transceiver_mode = e7xx_irda_transceiver_mode,
-	.shutdown = e7xx_irda_shutdown,
+	.gpio_pwdown		= GPIO_E7XX_IR_OFF,
+	.transceiver_cap	= IR_SIRMODE | IR_OFF,
 };
 
 int eseries_tmio_enable(struct platform_device *dev)
diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c
index f2058721254b29902cc4b4774c3e704bb8a5580a..abff9e1327492b42254a455c1f57dcbb0604df57 100644
--- a/arch/arm/mach-pxa/hx4700.c
+++ b/arch/arm/mach-pxa/hx4700.c
@@ -175,14 +175,9 @@ static int hx4700_gpio_request(struct gpio_ress *gpios, int size)
  * IRDA
  */
 
-static void irda_transceiver_mode(struct device *dev, int mode)
-{
-	gpio_set_value(GPIO105_HX4700_nIR_ON, mode & IR_OFF);
-}
-
 static struct pxaficp_platform_data ficp_info = {
-	.transceiver_cap  = IR_SIRMODE | IR_OFF,
-	.transceiver_mode = irda_transceiver_mode,
+	.gpio_pwdown		= GPIO105_HX4700_nIR_ON,
+	.transceiver_cap	= IR_SIRMODE | IR_OFF,
 };
 
 /*
diff --git a/arch/arm/mach-pxa/include/mach/irda.h b/arch/arm/mach-pxa/include/mach/irda.h
index 0a50c3c763dfd80af811bc5675c3b23fdb1da258..3cd41f77dda44128a5afd052c563d6a8cea5edc2 100644
--- a/arch/arm/mach-pxa/include/mach/irda.h
+++ b/arch/arm/mach-pxa/include/mach/irda.h
@@ -12,6 +12,8 @@ struct pxaficp_platform_data {
 	void (*transceiver_mode)(struct device *dev, int mode);
 	int (*startup)(struct device *dev);
 	void (*shutdown)(struct device *dev);
+	int gpio_pwdown;		/* powerdown GPIO for the IrDA chip */
+	bool gpio_pwdown_inverted;	/* gpio_pwdown is inverted */
 };
 
 extern void pxa_set_ficp_info(struct pxaficp_platform_data *info);
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 1785cc9494d9b27a962e64b5541625cbba1bf776..c6a94d3fdd61c0c3a13484372434e5f0cacf8954 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -507,8 +507,9 @@ static void lubbock_irda_transceiver_mode(struct device *dev, int mode)
 }
 
 static struct pxaficp_platform_data lubbock_ficp_platform_data = {
-	.transceiver_cap  = IR_SIRMODE | IR_FIRMODE,
-	.transceiver_mode = lubbock_irda_transceiver_mode,
+	.gpio_pwdown		= -1,
+	.transceiver_cap	= IR_SIRMODE | IR_FIRMODE,
+	.transceiver_mode	= lubbock_irda_transceiver_mode,
 };
 
 static void __init lubbock_init(void)
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index 0daba43d7ca15cbf20fcf41265fda3e4be59ec88..5360c07f5138fb0af5692f1dcb04f4e76b8cf110 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -140,15 +140,9 @@ static unsigned long magician_pin_config[] __initdata = {
  * IRDA
  */
 
-static void magician_irda_transceiver_mode(struct device *dev, int mode)
-{
-	gpio_set_value(GPIO83_MAGICIAN_nIR_EN, mode & IR_OFF);
-	pxa2xx_transceiver_mode(dev, mode);
-}
-
 static struct pxaficp_platform_data magician_ficp_info = {
-	.transceiver_cap  = IR_SIRMODE | IR_OFF,
-	.transceiver_mode = magician_irda_transceiver_mode,
+	.gpio_pwdown		= GPIO83_MAGICIAN_nIR_EN,
+	.transceiver_cap	= IR_SIRMODE | IR_OFF,
 };
 
 /*
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index f7dc23078ce3c92aa4f2a637f8c61182ca1344ef..a4eeae345e643f92f2c8c77d08fc46deb586db47 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -479,8 +479,9 @@ static void mainstone_irda_transceiver_mode(struct device *dev, int mode)
 }
 
 static struct pxaficp_platform_data mainstone_ficp_platform_data = {
-	.transceiver_cap  = IR_SIRMODE | IR_FIRMODE | IR_OFF,
-	.transceiver_mode = mainstone_irda_transceiver_mode,
+	.gpio_pwdown		= -1,
+	.transceiver_cap	= IR_SIRMODE | IR_FIRMODE | IR_OFF,
+	.transceiver_mode	= mainstone_irda_transceiver_mode,
 };
 
 static struct gpio_keys_button gpio_keys_button[] = {
diff --git a/arch/arm/mach-pxa/palmld.c b/arch/arm/mach-pxa/palmld.c
index b3ae8b958ad6b661a46ae018603097b670df2558..1ad029dd44382f63ea04e6b27e3db5ad34165ab8 100644
--- a/arch/arm/mach-pxa/palmld.c
+++ b/arch/arm/mach-pxa/palmld.c
@@ -304,35 +304,9 @@ static struct platform_device palmld_backlight = {
 /******************************************************************************
  * IrDA
  ******************************************************************************/
-static int palmld_irda_startup(struct device *dev)
-{
-	int err;
-	err = gpio_request(GPIO_NR_PALMLD_IR_DISABLE, "IR DISABLE");
-	if (err)
-		goto err;
-	err = gpio_direction_output(GPIO_NR_PALMLD_IR_DISABLE, 1);
-	if (err)
-		gpio_free(GPIO_NR_PALMLD_IR_DISABLE);
-err:
-	return err;
-}
-
-static void palmld_irda_shutdown(struct device *dev)
-{
-	gpio_free(GPIO_NR_PALMLD_IR_DISABLE);
-}
-
-static void palmld_irda_transceiver_mode(struct device *dev, int mode)
-{
-	gpio_set_value(GPIO_NR_PALMLD_IR_DISABLE, mode & IR_OFF);
-	pxa2xx_transceiver_mode(dev, mode);
-}
-
 static struct pxaficp_platform_data palmld_ficp_platform_data = {
-	.startup		= palmld_irda_startup,
-	.shutdown		= palmld_irda_shutdown,
-	.transceiver_cap	= IR_SIRMODE | IR_FIRMODE | IR_OFF,
-	.transceiver_mode	= palmld_irda_transceiver_mode,
+	.gpio_pwdown		= GPIO_NR_PALMLD_IR_DISABLE,
+	.transceiver_cap	= IR_SIRMODE | IR_OFF,
 };
 
 /******************************************************************************
diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c
index 88dcaac358a234cc83f95abbcc350d51d771e60c..2dd7ce28556b4962a241fbb5ea085a0cb5b0f297 100644
--- a/arch/arm/mach-pxa/palmt5.c
+++ b/arch/arm/mach-pxa/palmt5.c
@@ -243,35 +243,9 @@ static struct platform_device palmt5_backlight = {
 /******************************************************************************
  * IrDA
  ******************************************************************************/
-static int palmt5_irda_startup(struct device *dev)
-{
-	int err;
-	err = gpio_request(GPIO_NR_PALMT5_IR_DISABLE, "IR DISABLE");
-	if (err)
-		goto err;
-	err = gpio_direction_output(GPIO_NR_PALMT5_IR_DISABLE, 1);
-	if (err)
-		gpio_free(GPIO_NR_PALMT5_IR_DISABLE);
-err:
-	return err;
-}
-
-static void palmt5_irda_shutdown(struct device *dev)
-{
-	gpio_free(GPIO_NR_PALMT5_IR_DISABLE);
-}
-
-static void palmt5_irda_transceiver_mode(struct device *dev, int mode)
-{
-	gpio_set_value(GPIO_NR_PALMT5_IR_DISABLE, mode & IR_OFF);
-	pxa2xx_transceiver_mode(dev, mode);
-}
-
 static struct pxaficp_platform_data palmt5_ficp_platform_data = {
-	.startup		= palmt5_irda_startup,
-	.shutdown		= palmt5_irda_shutdown,
-	.transceiver_cap	= IR_SIRMODE | IR_FIRMODE | IR_OFF,
-	.transceiver_mode	= palmt5_irda_transceiver_mode,
+	.gpio_pwdown		= GPIO_NR_PALMT5_IR_DISABLE,
+	.transceiver_cap	= IR_SIRMODE | IR_OFF,
 };
 
 /******************************************************************************
diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c
index f70f1f820eeda60534669e2d3746a0d2b0d48165..bb2cc0dd44ec5c84a47dd3d2754726ed140f3ef7 100644
--- a/arch/arm/mach-pxa/palmtc.c
+++ b/arch/arm/mach-pxa/palmtc.c
@@ -218,35 +218,9 @@ static struct platform_device palmtc_backlight = {
 /******************************************************************************
  * IrDA
  ******************************************************************************/
-static int palmtc_irda_startup(struct device *dev)
-{
-	int err;
-	err = gpio_request(GPIO_NR_PALMTC_IR_DISABLE, "IR DISABLE");
-	if (err)
-		goto err;
-	err = gpio_direction_output(GPIO_NR_PALMTC_IR_DISABLE, 1);
-	if (err)
-		gpio_free(GPIO_NR_PALMTC_IR_DISABLE);
-err:
-	return err;
-}
-
-static void palmtc_irda_shutdown(struct device *dev)
-{
-	gpio_free(GPIO_NR_PALMTC_IR_DISABLE);
-}
-
-static void palmtc_irda_transceiver_mode(struct device *dev, int mode)
-{
-	gpio_set_value(GPIO_NR_PALMTC_IR_DISABLE, mode & IR_OFF);
-	pxa2xx_transceiver_mode(dev, mode);
-}
-
 static struct pxaficp_platform_data palmtc_ficp_platform_data = {
-	.startup		= palmtc_irda_startup,
-	.shutdown		= palmtc_irda_shutdown,
-	.transceiver_cap	= IR_SIRMODE | IR_FIRMODE | IR_OFF,
-	.transceiver_mode	= palmtc_irda_transceiver_mode,
+	.gpio_pwdown		= GPIO_NR_PALMTC_IR_DISABLE,
+	.transceiver_cap	= IR_SIRMODE | IR_OFF,
 };
 
 /******************************************************************************
diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c
index d9ef76c9278f18927986c13ebb7924e7d1ce50c4..277c4062e3c6b8cf399f6afb892398d13d3076d8 100644
--- a/arch/arm/mach-pxa/palmte2.c
+++ b/arch/arm/mach-pxa/palmte2.c
@@ -215,35 +215,9 @@ static struct platform_device palmte2_backlight = {
 /******************************************************************************
  * IrDA
  ******************************************************************************/
-static int palmte2_irda_startup(struct device *dev)
-{
-	int err;
-	err = gpio_request(GPIO_NR_PALMTE2_IR_DISABLE, "IR DISABLE");
-	if (err)
-		goto err;
-	err = gpio_direction_output(GPIO_NR_PALMTE2_IR_DISABLE, 1);
-	if (err)
-		gpio_free(GPIO_NR_PALMTE2_IR_DISABLE);
-err:
-	return err;
-}
-
-static void palmte2_irda_shutdown(struct device *dev)
-{
-	gpio_free(GPIO_NR_PALMTE2_IR_DISABLE);
-}
-
-static void palmte2_irda_transceiver_mode(struct device *dev, int mode)
-{
-	gpio_set_value(GPIO_NR_PALMTE2_IR_DISABLE, mode & IR_OFF);
-	pxa2xx_transceiver_mode(dev, mode);
-}
-
 static struct pxaficp_platform_data palmte2_ficp_platform_data = {
-	.startup		= palmte2_irda_startup,
-	.shutdown		= palmte2_irda_shutdown,
-	.transceiver_cap	= IR_SIRMODE | IR_FIRMODE | IR_OFF,
-	.transceiver_mode	= palmte2_irda_transceiver_mode,
+	.gpio_pwdown		= GPIO_NR_PALMTE2_IR_DISABLE,
+	.transceiver_cap	= IR_SIRMODE | IR_OFF,
 };
 
 /******************************************************************************
diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c
index c0aca18b71bb633e099904d6b2e96715b83184b9..76a2b37eaf30baa57fd14b1c9a82a80af26c9469 100644
--- a/arch/arm/mach-pxa/palmtx.c
+++ b/arch/arm/mach-pxa/palmtx.c
@@ -303,35 +303,9 @@ static struct platform_device palmtx_backlight = {
 /******************************************************************************
  * IrDA
  ******************************************************************************/
-static int palmtx_irda_startup(struct device *dev)
-{
-	int err;
-	err = gpio_request(GPIO_NR_PALMTX_IR_DISABLE, "IR DISABLE");
-	if (err)
-		goto err;
-	err = gpio_direction_output(GPIO_NR_PALMTX_IR_DISABLE, 1);
-	if (err)
-		gpio_free(GPIO_NR_PALMTX_IR_DISABLE);
-err:
-	return err;
-}
-
-static void palmtx_irda_shutdown(struct device *dev)
-{
-	gpio_free(GPIO_NR_PALMTX_IR_DISABLE);
-}
-
-static void palmtx_irda_transceiver_mode(struct device *dev, int mode)
-{
-	gpio_set_value(GPIO_NR_PALMTX_IR_DISABLE, mode & IR_OFF);
-	pxa2xx_transceiver_mode(dev, mode);
-}
-
 static struct pxaficp_platform_data palmtx_ficp_platform_data = {
-	.startup		= palmtx_irda_startup,
-	.shutdown		= palmtx_irda_shutdown,
-	.transceiver_cap	= IR_SIRMODE | IR_FIRMODE | IR_OFF,
-	.transceiver_mode	= palmtx_irda_transceiver_mode,
+	.gpio_pwdown		= GPIO_NR_PALMTX_IR_DISABLE,
+	.transceiver_cap	= IR_SIRMODE | IR_OFF,
 };
 
 /******************************************************************************
diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c
index d8fa53c19178147ff229adf79a1324c19460887e..c2bf493c5f53fe7d91cc4a65742b0fb109ceaaa8 100644
--- a/arch/arm/mach-pxa/palmz72.c
+++ b/arch/arm/mach-pxa/palmz72.c
@@ -230,35 +230,9 @@ static struct platform_device palmz72_backlight = {
 /******************************************************************************
  * IrDA
  ******************************************************************************/
-static int palmz72_irda_startup(struct device *dev)
-{
-	int err;
-	err = gpio_request(GPIO_NR_PALMZ72_IR_DISABLE, "IR DISABLE");
-	if (err)
-		goto err;
-	err = gpio_direction_output(GPIO_NR_PALMZ72_IR_DISABLE, 1);
-	if (err)
-		gpio_free(GPIO_NR_PALMZ72_IR_DISABLE);
-err:
-	return err;
-}
-
-static void palmz72_irda_shutdown(struct device *dev)
-{
-	gpio_free(GPIO_NR_PALMZ72_IR_DISABLE);
-}
-
-static void palmz72_irda_transceiver_mode(struct device *dev, int mode)
-{
-	gpio_set_value(GPIO_NR_PALMZ72_IR_DISABLE, mode & IR_OFF);
-	pxa2xx_transceiver_mode(dev, mode);
-}
-
 static struct pxaficp_platform_data palmz72_ficp_platform_data = {
-	.startup		= palmz72_irda_startup,
-	.shutdown		= palmz72_irda_shutdown,
+	.gpio_pwdown		= GPIO_NR_PALMZ72_IR_DISABLE,
 	.transceiver_cap	= IR_SIRMODE | IR_OFF,
-	.transceiver_mode	= palmz72_irda_transceiver_mode,
 };
 
 /******************************************************************************
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 333b1dc2dd3e933160d1ba4bdfe4426298de0d43..a186994f77fbf852af09ba646e8215ff8c2c70d0 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -302,34 +302,9 @@ static struct pxamci_platform_data poodle_mci_platform_data = {
 /*
  * Irda
  */
-static void poodle_irda_transceiver_mode(struct device *dev, int mode)
-{
-	gpio_set_value(POODLE_GPIO_IR_ON, mode & IR_OFF);
-	pxa2xx_transceiver_mode(dev, mode);
-}
-
-static int poodle_irda_startup(struct device *dev)
-{
-	int err;
-
-	err = gpio_request(POODLE_GPIO_IR_ON, "IR_ON");
-	if (err)
-		return err;
-
-	gpio_direction_output(POODLE_GPIO_IR_ON, 1);
-	return 0;
-}
-
-static void poodle_irda_shutdown(struct device *dev)
-{
-	gpio_free(POODLE_GPIO_IR_ON);
-}
-
 static struct pxaficp_platform_data poodle_ficp_platform_data = {
+	.gpio_pwdown		= POODLE_GPIO_IR_ON,
 	.transceiver_cap	= IR_SIRMODE | IR_OFF,
-	.transceiver_mode	= poodle_irda_transceiver_mode,
-	.startup		= poodle_irda_startup,
-	.shutdown		= poodle_irda_shutdown,
 };
 
 
diff --git a/arch/arm/mach-pxa/pxa2xx.c b/arch/arm/mach-pxa/pxa2xx.c
index 2f3394f859173aec39eac5da5fb1eb1afaa09299..868270421b8c1bdcaa5000b5cb012c32063999f3 100644
--- a/arch/arm/mach-pxa/pxa2xx.c
+++ b/arch/arm/mach-pxa/pxa2xx.c
@@ -52,3 +52,4 @@ void pxa2xx_transceiver_mode(struct device *dev, int mode)
 	} else
 		BUG();
 }
+EXPORT_SYMBOL_GPL(pxa2xx_transceiver_mode);
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index c4b8305b66a4434957cbd6d529f6b019dddde55c..f9dc59c054b33ce0a09c47e5807b2e57e94f181d 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -560,50 +560,10 @@ static struct pxaohci_platform_data spitz_ohci_platform_data = {
 /*
  * Irda
  */
-static int spitz_irda_startup(struct device *dev)
-{
-	int rc;
-
-	rc = gpio_request(SPITZ_GPIO_IR_ON, "IrDA on");
-	if (rc)
-		goto err;
-
-	rc = gpio_direction_output(SPITZ_GPIO_IR_ON, 1);
-	if (rc)
-		goto err_dir;
-
-	return 0;
-
-err_dir:
-	gpio_free(SPITZ_GPIO_IR_ON);
-err:
-	return rc;
-}
-
-static void spitz_irda_shutdown(struct device *dev)
-{
-	gpio_free(SPITZ_GPIO_IR_ON);
-}
-
-static void spitz_irda_transceiver_mode(struct device *dev, int mode)
-{
-	gpio_set_value(SPITZ_GPIO_IR_ON, mode & IR_OFF);
-	pxa2xx_transceiver_mode(dev, mode);
-}
-
-#ifdef CONFIG_MACH_AKITA
-static void akita_irda_transceiver_mode(struct device *dev, int mode)
-{
-	gpio_set_value(AKITA_GPIO_IR_ON, mode & IR_OFF);
-	pxa2xx_transceiver_mode(dev, mode);
-}
-#endif
 
 static struct pxaficp_platform_data spitz_ficp_platform_data = {
+/* .gpio_pwdown is set in spitz_init() and akita_init() accordingly */
 	.transceiver_cap	= IR_SIRMODE | IR_OFF,
-	.transceiver_mode	= spitz_irda_transceiver_mode,
-	.startup		= spitz_irda_startup,
-	.shutdown		= spitz_irda_shutdown,
 };
 
 
@@ -782,6 +742,8 @@ static void __init common_init(void)
 #if defined(CONFIG_MACH_SPITZ) || defined(CONFIG_MACH_BORZOI)
 static void __init spitz_init(void)
 {
+	spitz_ficp_platform_data.gpio_pwdown = SPITZ_GPIO_IR_ON;
+
 	platform_scoop_config = &spitz_pcmcia_config;
 
 	common_init();
@@ -824,7 +786,7 @@ static struct nand_ecclayout akita_oobinfo = {
 
 static void __init akita_init(void)
 {
-	spitz_ficp_platform_data.transceiver_mode = akita_irda_transceiver_mode;
+	spitz_ficp_platform_data.gpio_pwdown = AKITA_GPIO_IR_ON;
 
 	sharpsl_nand_platform_data.badblock_pattern = &sharpsl_akita_bbt;
 	sharpsl_nand_platform_data.ecc_layout = &akita_oobinfo;
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index b56cc5667bb4931266a7cd47610552d1acff808e..e81a52673d49ad0dfb396511ebf2e131f01ec8c0 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -337,10 +337,11 @@ static void tosa_irda_shutdown(struct device *dev)
 }
 
 static struct pxaficp_platform_data tosa_ficp_platform_data = {
-	.transceiver_cap  = IR_SIRMODE | IR_OFF,
-	.transceiver_mode = tosa_irda_transceiver_mode,
-	.startup = tosa_irda_startup,
-	.shutdown = tosa_irda_shutdown,
+	.gpio_pwdown		= -1,
+	.transceiver_cap	= IR_SIRMODE | IR_OFF,
+	.transceiver_mode	= tosa_irda_transceiver_mode,
+	.startup		= tosa_irda_startup,
+	.shutdown		= tosa_irda_shutdown,
 };
 
 /*
diff --git a/arch/arm/mach-pxa/treo680.c b/arch/arm/mach-pxa/treo680.c
index 9a2df64c6599a18e9cce4effcc9b77b33e6eb3ac..fe085076fbf2d6ce3dd8f5c81d85b322fab16b19 100644
--- a/arch/arm/mach-pxa/treo680.c
+++ b/arch/arm/mach-pxa/treo680.c
@@ -295,44 +295,9 @@ static struct platform_device treo680_backlight = {
 /******************************************************************************
  * IrDA
  ******************************************************************************/
-static void treo680_transceiver_mode(struct device *dev, int mode)
-{
-	gpio_set_value(GPIO_NR_TREO680_IR_EN, mode & IR_OFF);
-	pxa2xx_transceiver_mode(dev, mode);
-}
-
-static int treo680_irda_startup(struct device *dev)
-{
-	int err;
-
-	err = gpio_request(GPIO_NR_TREO680_IR_EN, "Ir port disable");
-	if (err)
-		goto err1;
-
-	err = gpio_direction_output(GPIO_NR_TREO680_IR_EN, 1);
-	if (err)
-		goto err2;
-
-	return 0;
-
-err2:
-	dev_err(dev, "treo680_irda: cannot change IR gpio direction\n");
-	gpio_free(GPIO_NR_TREO680_IR_EN);
-err1:
-	dev_err(dev, "treo680_irda: cannot allocate IR gpio\n");
-	return err;
-}
-
-static void treo680_irda_shutdown(struct device *dev)
-{
-	gpio_free(GPIO_NR_TREO680_IR_EN);
-}
-
 static struct pxaficp_platform_data treo680_ficp_info = {
-	.transceiver_cap  = IR_FIRMODE | IR_SIRMODE | IR_OFF,
-	.startup          = treo680_irda_startup,
-	.shutdown         = treo680_irda_shutdown,
-	.transceiver_mode = treo680_transceiver_mode,
+	.gpio_pwdown		= GPIO_NR_TREO680_IR_EN,
+	.transceiver_cap	= IR_SIRMODE | IR_OFF,
 };
 
 /******************************************************************************
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c
index 32299869b352826deeed9dc1de4325d200c51eb5..3981e0356d12d21b1d75cf236bd3dd33a233284c 100644
--- a/arch/arm/mach-pxa/trizeps4.c
+++ b/arch/arm/mach-pxa/trizeps4.c
@@ -415,6 +415,7 @@ static void trizeps4_irda_transceiver_mode(struct device *dev, int mode)
 }
 
 static struct pxaficp_platform_data trizeps4_ficp_platform_data = {
+	.gpio_pwdown		= -1,
 	.transceiver_cap	= IR_SIRMODE | IR_FIRMODE | IR_OFF,
 	.transceiver_mode	= trizeps4_irda_transceiver_mode,
 	.startup		= trizeps4_irda_startup,
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index 77d10edefd2579cd06c7e53f065bdf3dda7a96e7..f5b7d8320787324772254c304286bd4f8c895c6d 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>
@@ -162,6 +163,22 @@ inline static void pxa_irda_fir_dma_tx_start(struct pxa_irda *si)
 	DCSR(si->txdma) |= DCSR_RUN;
 }
 
+/*
+ * 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.
  */
@@ -188,7 +205,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
 			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 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed)
 		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 @@ static void pxa_irda_shutdown(struct pxa_irda *si)
 	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 @@ static int pxa_irda_probe(struct platform_device *pdev)
 	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 @@ static int pxa_irda_remove(struct platform_device *_dev)
 	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);