Merge branches 'at91-fixes' and 'pxa-fixes'
diff --git a/MAINTAINERS b/MAINTAINERS
index cad0882..77c083d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -440,7 +440,7 @@
 
 ARM/ATMEL AT91RM9200 ARM ARCHITECTURE
 P:      Andrew Victor
-M:      andrew@sanpeople.com
+M:      linux@maxim.org.za
 L:      linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
 W:      http://maxim.org.za/at91_26.html
 S:      Maintained
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
index 0417c16..9296833f 100644
--- a/arch/arm/mach-at91/at91rm9200_devices.c
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
@@ -14,6 +14,7 @@
 #include <asm/mach/map.h>
 
 #include <linux/platform_device.h>
+#include <linux/i2c-gpio.h>
 
 #include <asm/arch/board.h>
 #include <asm/arch/gpio.h>
@@ -435,7 +436,40 @@
  *  TWI (i2c)
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+/*
+ * Prefer the GPIO code since the TWI controller isn't robust
+ * (gets overruns and underruns under load) and can only issue
+ * repeated STARTs in one scenario (the driver doesn't yet handle them).
+ */
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+
+static struct i2c_gpio_platform_data pdata = {
+	.sda_pin		= AT91_PIN_PA25,
+	.sda_is_open_drain	= 1,
+	.scl_pin		= AT91_PIN_PA26,
+	.scl_is_open_drain	= 1,
+	.udelay			= 2,		/* ~100 kHz */
+};
+
+static struct platform_device at91rm9200_twi_device = {
+	.name			= "i2c-gpio",
+	.id			= -1,
+	.dev.platform_data	= &pdata,
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+	at91_set_GPIO_periph(AT91_PIN_PA25, 1);		/* TWD (SDA) */
+	at91_set_multi_drive(AT91_PIN_PA25, 1);
+
+	at91_set_GPIO_periph(AT91_PIN_PA26, 1);		/* TWCK (SCL) */
+	at91_set_multi_drive(AT91_PIN_PA26, 1);
+
+	i2c_register_board_info(0, devices, nr_devices);
+	platform_device_register(&at91rm9200_twi_device);
+}
+
+#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
 
 static struct resource twi_resources[] = {
 	[0] = {
@@ -457,7 +491,7 @@
 	.num_resources	= ARRAY_SIZE(twi_resources),
 };
 
-void __init at91_add_device_i2c(void)
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
 {
 	/* pins used for TWI interface */
 	at91_set_A_periph(AT91_PIN_PA25, 0);		/* TWD */
@@ -466,10 +500,11 @@
 	at91_set_A_periph(AT91_PIN_PA26, 0);		/* TWCK */
 	at91_set_multi_drive(AT91_PIN_PA26, 1);
 
+	i2c_register_board_info(0, devices, nr_devices);
 	platform_device_register(&at91rm9200_twi_device);
 }
 #else
-void __init at91_add_device_i2c(void) {}
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
 #endif
 
 
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index ffd3154..3091bf4 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -13,6 +13,7 @@
 #include <asm/mach/map.h>
 
 #include <linux/platform_device.h>
+#include <linux/i2c-gpio.h>
 
 #include <asm/arch/board.h>
 #include <asm/arch/gpio.h>
@@ -352,7 +353,41 @@
  *  TWI (i2c)
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+/*
+ * Prefer the GPIO code since the TWI controller isn't robust
+ * (gets overruns and underruns under load) and can only issue
+ * repeated STARTs in one scenario (the driver doesn't yet handle them).
+ */
+
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+
+static struct i2c_gpio_platform_data pdata = {
+	.sda_pin		= AT91_PIN_PA23,
+	.sda_is_open_drain	= 1,
+	.scl_pin		= AT91_PIN_PA24,
+	.scl_is_open_drain	= 1,
+	.udelay			= 2,		/* ~100 kHz */
+};
+
+static struct platform_device at91sam9260_twi_device = {
+	.name			= "i2c-gpio",
+	.id			= -1,
+	.dev.platform_data	= &pdata,
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+	at91_set_GPIO_periph(AT91_PIN_PA23, 1);		/* TWD (SDA) */
+	at91_set_multi_drive(AT91_PIN_PA23, 1);
+
+	at91_set_GPIO_periph(AT91_PIN_PA24, 1);		/* TWCK (SCL) */
+	at91_set_multi_drive(AT91_PIN_PA24, 1);
+
+	i2c_register_board_info(0, devices, nr_devices);
+	platform_device_register(&at91sam9260_twi_device);
+}
+
+#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
 
 static struct resource twi_resources[] = {
 	[0] = {
@@ -374,7 +409,7 @@
 	.num_resources	= ARRAY_SIZE(twi_resources),
 };
 
-void __init at91_add_device_i2c(void)
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
 {
 	/* pins used for TWI interface */
 	at91_set_A_periph(AT91_PIN_PA23, 0);		/* TWD */
@@ -383,10 +418,11 @@
 	at91_set_A_periph(AT91_PIN_PA24, 0);		/* TWCK */
 	at91_set_multi_drive(AT91_PIN_PA24, 1);
 
+	i2c_register_board_info(0, devices, nr_devices);
 	platform_device_register(&at91sam9260_twi_device);
 }
 #else
-void __init at91_add_device_i2c(void) {}
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
 #endif
 
 
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index 3576595..64979a9 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -14,7 +14,9 @@
 #include <asm/mach/map.h>
 
 #include <linux/platform_device.h>
+#include <linux/i2c-gpio.h>
 
+#include <linux/fb.h>
 #include <video/atmel_lcdc.h>
 
 #include <asm/arch/board.h>
@@ -275,7 +277,40 @@
  *  TWI (i2c)
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+/*
+ * Prefer the GPIO code since the TWI controller isn't robust
+ * (gets overruns and underruns under load) and can only issue
+ * repeated STARTs in one scenario (the driver doesn't yet handle them).
+ */
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+
+static struct i2c_gpio_platform_data pdata = {
+	.sda_pin		= AT91_PIN_PA7,
+	.sda_is_open_drain	= 1,
+	.scl_pin		= AT91_PIN_PA8,
+	.scl_is_open_drain	= 1,
+	.udelay			= 2,		/* ~100 kHz */
+};
+
+static struct platform_device at91sam9261_twi_device = {
+	.name			= "i2c-gpio",
+	.id			= -1,
+	.dev.platform_data	= &pdata,
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+	at91_set_GPIO_periph(AT91_PIN_PA7, 1);		/* TWD (SDA) */
+	at91_set_multi_drive(AT91_PIN_PA7, 1);
+
+	at91_set_GPIO_periph(AT91_PIN_PA8, 1);		/* TWCK (SCL) */
+	at91_set_multi_drive(AT91_PIN_PA8, 1);
+
+	i2c_register_board_info(0, devices, nr_devices);
+	platform_device_register(&at91sam9261_twi_device);
+}
+
+#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
 
 static struct resource twi_resources[] = {
 	[0] = {
@@ -297,7 +332,7 @@
 	.num_resources	= ARRAY_SIZE(twi_resources),
 };
 
-void __init at91_add_device_i2c(void)
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
 {
 	/* pins used for TWI interface */
 	at91_set_A_periph(AT91_PIN_PA7, 0);		/* TWD */
@@ -306,10 +341,11 @@
 	at91_set_A_periph(AT91_PIN_PA8, 0);		/* TWCK */
 	at91_set_multi_drive(AT91_PIN_PA8, 1);
 
+	i2c_register_board_info(0, devices, nr_devices);
 	platform_device_register(&at91sam9261_twi_device);
 }
 #else
-void __init at91_add_device_i2c(void) {}
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
 #endif
 
 
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index f924bd5..ac329a9 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -13,7 +13,9 @@
 #include <asm/mach/map.h>
 
 #include <linux/platform_device.h>
+#include <linux/i2c-gpio.h>
 
+#include <linux/fb.h>
 #include <video/atmel_lcdc.h>
 
 #include <asm/arch/board.h>
@@ -421,7 +423,40 @@
  *  TWI (i2c)
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+/*
+ * Prefer the GPIO code since the TWI controller isn't robust
+ * (gets overruns and underruns under load) and can only issue
+ * repeated STARTs in one scenario (the driver doesn't yet handle them).
+ */
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+
+static struct i2c_gpio_platform_data pdata = {
+	.sda_pin		= AT91_PIN_PB4,
+	.sda_is_open_drain	= 1,
+	.scl_pin		= AT91_PIN_PB5,
+	.scl_is_open_drain	= 1,
+	.udelay			= 2,		/* ~100 kHz */
+};
+
+static struct platform_device at91sam9263_twi_device = {
+	.name			= "i2c-gpio",
+	.id			= -1,
+	.dev.platform_data	= &pdata,
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+	at91_set_GPIO_periph(AT91_PIN_PB4, 1);		/* TWD (SDA) */
+	at91_set_multi_drive(AT91_PIN_PB4, 1);
+
+	at91_set_GPIO_periph(AT91_PIN_PB5, 1);		/* TWCK (SCL) */
+	at91_set_multi_drive(AT91_PIN_PB5, 1);
+
+	i2c_register_board_info(0, devices, nr_devices);
+	platform_device_register(&at91sam9263_twi_device);
+}
+
+#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
 
 static struct resource twi_resources[] = {
 	[0] = {
@@ -443,7 +478,7 @@
 	.num_resources	= ARRAY_SIZE(twi_resources),
 };
 
-void __init at91_add_device_i2c(void)
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
 {
 	/* pins used for TWI interface */
 	at91_set_A_periph(AT91_PIN_PB4, 0);		/* TWD */
@@ -452,10 +487,11 @@
 	at91_set_A_periph(AT91_PIN_PB5, 0);		/* TWCK */
 	at91_set_multi_drive(AT91_PIN_PB5, 1);
 
+	i2c_register_board_info(0, devices, nr_devices);
 	platform_device_register(&at91sam9263_twi_device);
 }
 #else
-void __init at91_add_device_i2c(void) {}
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
 #endif
 
 
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
index cd7532b..2bd60a3 100644
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -10,8 +10,9 @@
 #include <asm/mach/map.h>
 
 #include <linux/platform_device.h>
-#include <linux/fb.h>
+#include <linux/i2c-gpio.h>
 
+#include <linux/fb.h>
 #include <video/atmel_lcdc.h>
 
 #include <asm/arch/board.h>
@@ -169,7 +170,40 @@
  *  TWI (i2c)
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+/*
+ * Prefer the GPIO code since the TWI controller isn't robust
+ * (gets overruns and underruns under load) and can only issue
+ * repeated STARTs in one scenario (the driver doesn't yet handle them).
+ */
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+
+static struct i2c_gpio_platform_data pdata = {
+	.sda_pin		= AT91_PIN_PA23,
+	.sda_is_open_drain	= 1,
+	.scl_pin		= AT91_PIN_PA24,
+	.scl_is_open_drain	= 1,
+	.udelay			= 2,		/* ~100 kHz */
+};
+
+static struct platform_device at91sam9rl_twi_device = {
+	.name			= "i2c-gpio",
+	.id			= -1,
+	.dev.platform_data	= &pdata,
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+	at91_set_GPIO_periph(AT91_PIN_PA23, 1);		/* TWD (SDA) */
+	at91_set_multi_drive(AT91_PIN_PA23, 1);
+
+	at91_set_GPIO_periph(AT91_PIN_PA24, 1);		/* TWCK (SCL) */
+	at91_set_multi_drive(AT91_PIN_PA24, 1);
+
+	i2c_register_board_info(0, devices, nr_devices);
+	platform_device_register(&at91sam9rl_twi_device);
+}
+
+#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
 
 static struct resource twi_resources[] = {
 	[0] = {
@@ -191,7 +225,7 @@
 	.num_resources	= ARRAY_SIZE(twi_resources),
 };
 
-void __init at91_add_device_i2c(void)
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
 {
 	/* pins used for TWI interface */
 	at91_set_A_periph(AT91_PIN_PA23, 0);		/* TWD */
@@ -200,10 +234,11 @@
 	at91_set_A_periph(AT91_PIN_PA24, 0);		/* TWCK */
 	at91_set_multi_drive(AT91_PIN_PA24, 1);
 
+	i2c_register_board_info(0, devices, nr_devices);
 	platform_device_register(&at91sam9rl_twi_device);
 }
 #else
-void __init at91_add_device_i2c(void) {}
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
 #endif
 
 
diff --git a/arch/arm/mach-at91/board-carmeva.c b/arch/arm/mach-at91/board-carmeva.c
index 76ec856..0f087829 100644
--- a/arch/arm/mach-at91/board-carmeva.c
+++ b/arch/arm/mach-at91/board-carmeva.c
@@ -128,7 +128,7 @@
 	/* USB Device */
 	at91_add_device_udc(&carmeva_udc_data);
 	/* I2C */
-	at91_add_device_i2c();
+	at91_add_device_i2c(NULL, 0);
 	/* SPI */
 	at91_add_device_spi(carmeva_spi_devices, ARRAY_SIZE(carmeva_spi_devices));
 	/* Compact Flash */
diff --git a/arch/arm/mach-at91/board-csb337.c b/arch/arm/mach-at91/board-csb337.c
index dde0899..d0aa20c9 100644
--- a/arch/arm/mach-at91/board-csb337.c
+++ b/arch/arm/mach-at91/board-csb337.c
@@ -23,7 +23,6 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/i2c.h>
 #include <linux/spi/spi.h>
 #include <linux/mtd/physmap.h>
 
@@ -85,12 +84,12 @@
 };
 
 static struct i2c_board_info __initdata csb337_i2c_devices[] = {
-	{ I2C_BOARD_INFO("rtc-ds1307", 0x68),
-	  .type = "ds1307",
+	{
+		I2C_BOARD_INFO("rtc-ds1307", 0x68),
+		.type	= "ds1307",
 	},
 };
 
-
 static struct at91_cf_data __initdata csb337_cf_data = {
 	/*
 	 * connector P4 on the CSB 337 mates to
@@ -168,9 +167,7 @@
 	/* USB Device */
 	at91_add_device_udc(&csb337_udc_data);
 	/* I2C */
-	at91_add_device_i2c();
-	i2c_register_board_info(0, csb337_i2c_devices,
-			ARRAY_SIZE(csb337_i2c_devices));
+	at91_add_device_i2c(csb337_i2c_devices, ARRAY_SIZE(csb337_i2c_devices));
 	/* Compact Flash */
 	at91_set_gpio_input(AT91_PIN_PB22, 1);		/* IOIS16 */
 	at91_add_device_cf(&csb337_cf_data);
diff --git a/arch/arm/mach-at91/board-csb637.c b/arch/arm/mach-at91/board-csb637.c
index 77f04b9..c5c721d 100644
--- a/arch/arm/mach-at91/board-csb637.c
+++ b/arch/arm/mach-at91/board-csb637.c
@@ -129,7 +129,7 @@
 	/* USB Device */
 	at91_add_device_udc(&csb637_udc_data);
 	/* I2C */
-	at91_add_device_i2c();
+	at91_add_device_i2c(NULL, 0);
 	/* SPI */
 	at91_add_device_spi(NULL, 0);
 	/* NOR flash */
diff --git a/arch/arm/mach-at91/board-dk.c b/arch/arm/mach-at91/board-dk.c
index af49789..40c9e43 100644
--- a/arch/arm/mach-at91/board-dk.c
+++ b/arch/arm/mach-at91/board-dk.c
@@ -124,6 +124,19 @@
 #endif
 };
 
+static struct i2c_board_info __initdata dk_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("ics1523", 0x26),
+	},
+	{
+		I2C_BOARD_INFO("x9429", 0x28),
+	},
+	{
+		I2C_BOARD_INFO("at24c", 0x50),
+		.type	= "24c1024",
+	}
+};
+
 static struct mtd_partition __initdata dk_nand_partition[] = {
 	{
 		.name	= "NAND Partition 1",
@@ -185,7 +198,7 @@
 	/* Compact Flash */
 	at91_add_device_cf(&dk_cf_data);
 	/* I2C */
-	at91_add_device_i2c();
+	at91_add_device_i2c(dk_i2c_devices, ARRAY_SIZE(dk_i2c_devices));
 	/* SPI */
 	at91_add_device_spi(dk_spi_devices, ARRAY_SIZE(dk_spi_devices));
 #ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
diff --git a/arch/arm/mach-at91/board-eb9200.c b/arch/arm/mach-at91/board-eb9200.c
index 20458b5..b7b79bb 100644
--- a/arch/arm/mach-at91/board-eb9200.c
+++ b/arch/arm/mach-at91/board-eb9200.c
@@ -91,6 +91,14 @@
 	.wire4		= 1,
 };
 
+static struct i2c_board_info __initdata eb9200_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("at24c", 0x50),
+		.type	= "24c512",
+	},
+};
+
+
 static void __init eb9200_board_init(void)
 {
 	/* Serial */
@@ -102,7 +110,7 @@
 	/* USB Device */
 	at91_add_device_udc(&eb9200_udc_data);
 	/* I2C */
-	at91_add_device_i2c();
+	at91_add_device_i2c(eb9200_i2c_devices, ARRAY_SIZE(eb9200_i2c_devices));
 	/* Compact Flash */
 	at91_add_device_cf(&eb9200_cf_data);
 	/* SPI */
diff --git a/arch/arm/mach-at91/board-ek.c b/arch/arm/mach-at91/board-ek.c
index 322fdd7..d05b1b2 100644
--- a/arch/arm/mach-at91/board-ek.c
+++ b/arch/arm/mach-at91/board-ek.c
@@ -145,7 +145,7 @@
 	at91_add_device_udc(&ek_udc_data);
 	at91_set_multi_drive(ek_udc_data.pullup_pin, 1);	/* pullup_pin is connected to reset */
 	/* I2C */
-	at91_add_device_i2c();
+	at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices));
 	/* SPI */
 	at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
 #ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
diff --git a/arch/arm/mach-at91/board-kafa.c b/arch/arm/mach-at91/board-kafa.c
index c77d84c..cf1b7b2 100644
--- a/arch/arm/mach-at91/board-kafa.c
+++ b/arch/arm/mach-at91/board-kafa.c
@@ -92,7 +92,7 @@
 	/* USB Device */
 	at91_add_device_udc(&kafa_udc_data);
 	/* I2C */
-	at91_add_device_i2c();
+	at91_add_device_i2c(NULL, 0);
 	/* SPI */
 	at91_add_device_spi(NULL, 0);
 }
diff --git a/arch/arm/mach-at91/board-kb9202.c b/arch/arm/mach-at91/board-kb9202.c
index 7d9b1a2..4b39b9c 100644
--- a/arch/arm/mach-at91/board-kb9202.c
+++ b/arch/arm/mach-at91/board-kb9202.c
@@ -124,7 +124,7 @@
 	/* MMC */
 	at91_add_device_mmc(0, &kb9202_mmc_data);
 	/* I2C */
-	at91_add_device_i2c();
+	at91_add_device_i2c(NULL, 0);
 	/* SPI */
 	at91_add_device_spi(NULL, 0);
 	/* NAND */
diff --git a/arch/arm/mach-at91/board-picotux200.c b/arch/arm/mach-at91/board-picotux200.c
index 49cfe7a..6acb55c 100644
--- a/arch/arm/mach-at91/board-picotux200.c
+++ b/arch/arm/mach-at91/board-picotux200.c
@@ -139,7 +139,7 @@
 	// at91_add_device_udc(&picotux200_udc_data);
 	// at91_set_multi_drive(picotux200_udc_data.pullup_pin, 1);	/* pullup_pin is connected to reset */
 	/* I2C */
-	at91_add_device_i2c();
+	at91_add_device_i2c(NULL, 0);
 	/* SPI */
 	// at91_add_device_spi(picotux200_spi_devices, ARRAY_SIZE(picotux200_spi_devices));
 #ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c
index 65fa532..b343a6c 100644
--- a/arch/arm/mach-at91/board-sam9260ek.c
+++ b/arch/arm/mach-at91/board-sam9260ek.c
@@ -189,7 +189,7 @@
 	/* MMC */
 	at91_add_device_mmc(0, &ek_mmc_data);
 	/* I2C */
-	at91_add_device_i2c();
+	at91_add_device_i2c(NULL, 0);
 }
 
 MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK")
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c
index 42e172c..550ae59a 100644
--- a/arch/arm/mach-at91/board-sam9261ek.c
+++ b/arch/arm/mach-at91/board-sam9261ek.c
@@ -382,14 +382,14 @@
 
 static void __init ek_add_device_buttons(void)
 {
-	at91_set_gpio_input(AT91_PIN_PB27, 0);	/* btn0 */
-	at91_set_deglitch(AT91_PIN_PB27, 1);
-	at91_set_gpio_input(AT91_PIN_PB26, 0);	/* btn1 */
-	at91_set_deglitch(AT91_PIN_PB26, 1);
-	at91_set_gpio_input(AT91_PIN_PB25, 0);	/* btn2 */
-	at91_set_deglitch(AT91_PIN_PB25, 1);
-	at91_set_gpio_input(AT91_PIN_PB24, 0);	/* btn3 */
-	at91_set_deglitch(AT91_PIN_PB24, 1);
+	at91_set_gpio_input(AT91_PIN_PA27, 0);	/* btn0 */
+	at91_set_deglitch(AT91_PIN_PA27, 1);
+	at91_set_gpio_input(AT91_PIN_PA26, 0);	/* btn1 */
+	at91_set_deglitch(AT91_PIN_PA26, 1);
+	at91_set_gpio_input(AT91_PIN_PA25, 0);	/* btn2 */
+	at91_set_deglitch(AT91_PIN_PA25, 1);
+	at91_set_gpio_input(AT91_PIN_PA24, 0);	/* btn3 */
+	at91_set_deglitch(AT91_PIN_PA24, 1);
 
 	platform_device_register(&ek_button_device);
 }
@@ -406,7 +406,7 @@
 	/* USB Device */
 	at91_add_device_udc(&ek_udc_data);
 	/* I2C */
-	at91_add_device_i2c();
+	at91_add_device_i2c(NULL, 0);
 	/* NAND */
 	at91_add_device_nand(&ek_nand_data);
 	/* DM9000 ethernet */
diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c
index 2a1cc73..ab9dcc0 100644
--- a/arch/arm/mach-at91/board-sam9263ek.c
+++ b/arch/arm/mach-at91/board-sam9263ek.c
@@ -291,7 +291,7 @@
 	/* NAND */
 	at91_add_device_nand(&ek_nand_data);
 	/* I2C */
-	at91_add_device_i2c();
+	at91_add_device_i2c(NULL, 0);
 	/* LCD Controller */
 	at91_add_device_lcdc(&ek_lcdc_data);
 	/* AC97 */
diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c
index 9b61320..bc0546d 100644
--- a/arch/arm/mach-at91/board-sam9rlek.c
+++ b/arch/arm/mach-at91/board-sam9rlek.c
@@ -181,7 +181,7 @@
 	/* Serial */
 	at91_add_device_serial();
 	/* I2C */
-	at91_add_device_i2c();
+	at91_add_device_i2c(NULL, 0);
 	/* NAND */
 	at91_add_device_nand(&ek_nand_data);
 	/* SPI */
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
index 848efb2..57c3b64 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -351,7 +351,7 @@
 	pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
 	parent = at91_css_to_clk(pckr & AT91_PMC_CSS);
 	clk->parent = parent;
-	clk->rate_hz = parent->rate_hz / (1 << ((pckr >> 2) & 3));
+	clk->rate_hz = parent->rate_hz / (1 << ((pckr & AT91_PMC_PRES) >> 2));
 }
 
 #endif	/* CONFIG_AT91_PROGRAMMABLE_CLOCKS */
@@ -587,8 +587,11 @@
 	mckr = at91_sys_read(AT91_PMC_MCKR);
 	mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS);
 	freq = mck.parent->rate_hz;
-	freq /= (1 << ((mckr >> 2) & 3));		/* prescale */
-	mck.rate_hz = freq / (1 + ((mckr >> 8) & 3));	/* mdiv */
+	freq /= (1 << ((mckr & AT91_PMC_PRES) >> 2));				/* prescale */
+	if (cpu_is_at91rm9200())
+		mck.rate_hz = freq / (1 + ((mckr & AT91_PMC_MDIV) >> 8));	/* mdiv */
+	else
+		mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8));	/* mdiv */
 
 	/* Register the PMC's standard clocks */
 	for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++)
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index d0f2b59..8e126e6 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -146,7 +146,7 @@
 	INIT_CKEN("MMCCLK",  MMC,  19500000, 0, &pxa_device_mci.dev),
 	INIT_CKEN("FICPCLK", FICP, 48000000, 0, &pxa_device_ficp.dev),
 
-	INIT_CKEN("USBCLK", USB,    48000000, 0, &pxa27x_device_ohci.dev),
+	INIT_CKEN("USBCLK", USBHOST, 48000000, 0, &pxa27x_device_ohci.dev),
 	INIT_CKEN("I2CCLK", PWRI2C, 13000000, 0, &pxa27x_device_i2c_power.dev),
 	INIT_CKEN("KBDCLK", KEYPAD, 32768, 0, NULL),
 
diff --git a/arch/arm/mach-pxa/pxa320.c b/arch/arm/mach-pxa/pxa320.c
index 1010f77..74128eb 100644
--- a/arch/arm/mach-pxa/pxa320.c
+++ b/arch/arm/mach-pxa/pxa320.c
@@ -23,8 +23,11 @@
 static struct pxa3xx_mfp_addr_map pxa320_mfp_addr_map[] __initdata = {
 
 	MFP_ADDR_X(GPIO0,  GPIO4,   0x0124),
-	MFP_ADDR_X(GPIO5,  GPIO26,  0x028C),
-	MFP_ADDR_X(GPIO27, GPIO62,  0x0400),
+	MFP_ADDR_X(GPIO5,  GPIO9,   0x028C),
+	MFP_ADDR(GPIO10, 0x0458),
+	MFP_ADDR_X(GPIO11, GPIO26,  0x02A0),
+	MFP_ADDR_X(GPIO27, GPIO48,  0x0400),
+	MFP_ADDR_X(GPIO49, GPIO62,  0x045C),
 	MFP_ADDR_X(GPIO63, GPIO73,  0x04B4),
 	MFP_ADDR_X(GPIO74, GPIO98,  0x04F0),
 	MFP_ADDR_X(GPIO99, GPIO127, 0x0600),
diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c
index 71766ac..422afee 100644
--- a/arch/arm/mach-pxa/ssp.c
+++ b/arch/arm/mach-pxa/ssp.c
@@ -309,6 +309,7 @@
 
     	if (dev->port > PXA_SSP_PORTS || dev->port == 0) {
 		printk(KERN_WARNING "SSP: tried to close invalid port\n");
+		mutex_unlock(&mutex);
 		return;
 	}
 
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index af3a011..352fcb8 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -585,11 +585,11 @@
 	return up->name;
 }
 
-#ifdef CONFIG_SERIAL_PXA_CONSOLE
-
 static struct uart_pxa_port *serial_pxa_ports[4];
 static struct uart_driver serial_pxa_reg;
 
+#ifdef CONFIG_SERIAL_PXA_CONSOLE
+
 #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
 
 /*
diff --git a/include/asm-arm/arch-at91/board.h b/include/asm-arm/arch-at91/board.h
index c0d7075..7905496 100644
--- a/include/asm-arm/arch-at91/board.h
+++ b/include/asm-arm/arch-at91/board.h
@@ -33,6 +33,7 @@
 
 #include <linux/mtd/partitions.h>
 #include <linux/device.h>
+#include <linux/i2c.h>
 #include <linux/spi/spi.h>
 
  /* USB Device */
@@ -94,7 +95,7 @@
 extern void __init at91_add_device_nand(struct at91_nand_data *data);
 
  /* I2C*/
-extern void __init at91_add_device_i2c(void);
+extern void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices);
 
  /* SPI */
 extern void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices);
diff --git a/include/asm-arm/arch-pxa/irqs.h b/include/asm-arm/arch-pxa/irqs.h
index 6238dbf..b76ee6d 100644
--- a/include/asm-arm/arch-pxa/irqs.h
+++ b/include/asm-arm/arch-pxa/irqs.h
@@ -13,7 +13,7 @@
 
 #define PXA_IRQ(x)	(x)
 
-#ifdef CONFIG_PXA27x
+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #define IRQ_SSP3	PXA_IRQ(0)	/* SSP3 service request */
 #define IRQ_MSL		PXA_IRQ(1)	/* MSL Interface interrupt */
 #define IRQ_USBH2	PXA_IRQ(2)	/* USB Host interrupt 1 (OHCI) */
@@ -52,11 +52,27 @@
 #define	IRQ_RTC1Hz	PXA_IRQ(30)	/* RTC HZ Clock Tick */
 #define	IRQ_RTCAlrm	PXA_IRQ(31)	/* RTC Alarm */
 
-#ifdef CONFIG_PXA27x
+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
 #define IRQ_TPM		PXA_IRQ(32)	/* TPM interrupt */
 #define IRQ_CAMERA	PXA_IRQ(33)	/* Camera Interface */
 #endif
 
+#ifdef CONFIG_PXA3xx
+#define IRQ_SSP4	PXA_IRQ(13)	/* SSP4 service request */
+#define IRQ_CIR		PXA_IRQ(34)	/* Consumer IR */
+#define IRQ_TSI		PXA_IRQ(36)	/* Touch Screen Interface (PXA320) */
+#define IRQ_USIM2	PXA_IRQ(38)	/* USIM2 Controller */
+#define IRQ_GRPHICS	PXA_IRQ(39)	/* Graphics Controller */
+#define IRQ_MMC2	PXA_IRQ(41)	/* MMC2 Controller */
+#define IRQ_1WIRE	PXA_IRQ(44)	/* 1-Wire Controller */
+#define IRQ_NAND	PXA_IRQ(45)	/* NAND Controller */
+#define IRQ_USB2	PXA_IRQ(46)	/* USB 2.0 Device Controller */
+#define IRQ_WAKEUP0	PXA_IRQ(49)	/* EXT_WAKEUP0 */
+#define IRQ_WAKEUP1	PXA_IRQ(50)	/* EXT_WAKEUP1 */
+#define IRQ_DMEMC	PXA_IRQ(51)	/* Dynamic Memory Controller */
+#define IRQ_MMC3	PXA_IRQ(55)	/* MMC3 Controller (PXA310) */
+#endif
+
 #define PXA_GPIO_IRQ_BASE	(64)
 #define PXA_GPIO_IRQ_NUM	(128)
 
diff --git a/include/asm-arm/arch-pxa/mfp-pxa300.h b/include/asm-arm/arch-pxa/mfp-pxa300.h
index 822a27c..a209966 100644
--- a/include/asm-arm/arch-pxa/mfp-pxa300.h
+++ b/include/asm-arm/arch-pxa/mfp-pxa300.h
@@ -179,7 +179,7 @@
 #define GPIO62_LCD_CS_N		MFP_CFG_DRV(GPIO62, AF2, DS01X)
 #define GPIO72_LCD_FCLK		MFP_CFG_DRV(GPIO72, AF1, DS01X)
 #define GPIO73_LCD_LCLK		MFP_CFG_DRV(GPIO73, AF1, DS01X)
-#define GPIO74_LCD_PCLK		MFP_CFG_DRV(GPIO74, AF1, DS01X)
+#define GPIO74_LCD_PCLK		MFP_CFG_DRV(GPIO74, AF1, DS02X)
 #define GPIO75_LCD_BIAS		MFP_CFG_DRV(GPIO75, AF1, DS01X)
 #define GPIO76_LCD_VSYNC	MFP_CFG_DRV(GPIO76, AF2, DS01X)
 
diff --git a/include/asm-arm/arch-pxa/mfp-pxa320.h b/include/asm-arm/arch-pxa/mfp-pxa320.h
index 488a5bb..52deedc 100644
--- a/include/asm-arm/arch-pxa/mfp-pxa320.h
+++ b/include/asm-arm/arch-pxa/mfp-pxa320.h
@@ -18,7 +18,7 @@
 #include <asm/arch/mfp.h>
 
 /* GPIO */
-#define GPIO46_GPIO		MFP_CFG(GPIO6, AF0)
+#define GPIO46_GPIO		MFP_CFG(GPIO46, AF0)
 #define GPIO49_GPIO		MFP_CFG(GPIO49, AF0)
 #define GPIO50_GPIO		MFP_CFG(GPIO50, AF0)
 #define GPIO51_GPIO		MFP_CFG(GPIO51, AF0)
diff --git a/include/asm-arm/arch-pxa/mfp.h b/include/asm-arm/arch-pxa/mfp.h
index ac4157a..03c508d 100644
--- a/include/asm-arm/arch-pxa/mfp.h
+++ b/include/asm-arm/arch-pxa/mfp.h
@@ -346,23 +346,31 @@
 #define MFP_CFG_PIN(mfp_cfg)	(((mfp_cfg) >> 16) & 0xffff)
 #define MFP_CFG_VAL(mfp_cfg)	((mfp_cfg) & 0xffff)
 
-#define MFPR_DEFAULT	(0x0000)
+/*
+ * MFP register defaults to
+ *   drive strength fast 3mA (010'b)
+ *   edge detection logic disabled
+ *   alternate function 0
+ */
+#define MFPR_DEFAULT	(0x0840)
 
 #define MFP_CFG(pin, af)		\
 	((MFP_PIN_##pin << 16) | MFPR_DEFAULT | (MFP_##af))
 
 #define MFP_CFG_DRV(pin, af, drv)	\
-	((MFP_PIN_##pin << 16) | MFPR_DEFAULT |\
+	((MFP_PIN_##pin << 16) | (MFPR_DEFAULT & ~MFPR_DRV_MASK) |\
 	 ((MFP_##drv) << 10) | (MFP_##af))
 
 #define MFP_CFG_LPM(pin, af, lpm)	\
-	((MFP_PIN_##pin << 16) | MFPR_DEFAULT | (MFP_##af) |\
+	((MFP_PIN_##pin << 16) | (MFPR_DEFAULT & ~MFPR_LPM_MASK) |\
 	 (((MFP_LPM_##lpm) & 0x3) << 7)  |\
 	 (((MFP_LPM_##lpm) & 0x4) << 12) |\
-	 (((MFP_LPM_##lpm) & 0x8) << 10))
+	 (((MFP_LPM_##lpm) & 0x8) << 10) |\
+	 (MFP_##af))
 
 #define MFP_CFG_X(pin, af, drv, lpm)	\
-	((MFP_PIN_##pin << 16) | MFPR_DEFAULT |\
+	((MFP_PIN_##pin << 16) |\
+	 (MFPR_DEFAULT & ~(MFPR_DRV_MASK | MFPR_LPM_MASK)) |\
 	 ((MFP_##drv) << 10) | (MFP_##af) |\
 	 (((MFP_LPM_##lpm) & 0x3) << 7)  |\
 	 (((MFP_LPM_##lpm) & 0x4) << 12) |\
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
index bb68b59..6b33df6 100644
--- a/include/asm-arm/arch-pxa/pxa-regs.h
+++ b/include/asm-arm/arch-pxa/pxa-regs.h
@@ -110,7 +110,10 @@
 #define DALGN		__REG(0x400000a0)  /* DMA Alignment Register */
 #define DINT		__REG(0x400000f0)  /* DMA Interrupt Register */
 
-#define DRCMR(n)	__REG2(0x40000100, (n)<<2)
+#define DRCMR(n)	(*(((n) < 64) ? \
+			&__REG2(0x40000100, ((n) & 0x3f) << 2) : \
+			&__REG2(0x40001100, ((n) & 0x3f) << 2)))
+
 #define DRCMR0		__REG(0x40000100)  /* Request to Channel Map Register for DREQ 0 */
 #define DRCMR1		__REG(0x40000104)  /* Request to Channel Map Register for DREQ 1 */
 #define DRCMR2		__REG(0x40000108)  /* Request to Channel Map Register for I2S receive Request */