Patchwork [U-Boot,v6] Exynos5: Pinmux: Add fdt for pinmux

login
register
mail settings
Submitter Akshay Saraswat
Date March 11, 2013, 6:53 a.m.
Message ID <1362984816-2108-1-git-send-email-akshay.s@samsung.com>
Download mbox | patch
Permalink /patch/226484/
State Not Applicable
Delegated to: Minkyu Kang
Headers show

Comments

Akshay Saraswat - March 11, 2013, 6:53 a.m.
This patch adds fdt nodes for peripherals which require
pin muxing and configuration. Device tree bindings for pinctrl
are kept same as required for Linux. Existing pinmux code
modified to retrieve gpio range and function related info from fdt.

Depends-on: [U-Boot] [PATCH 0/4 V3] EXYNOS5: Add GPIO numbering feature
URL: http://lists.denx.de/pipermail/u-boot/2013-February/146151.html

Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>
---
Changes since v1:
	- Device tree bindings changed to linux style.
	- Added documentation for samsung pinctrl.

Changes since v2:
        - Rebased as per new version of GPIO numbering patch-set.

Changes since v3:
        - Added comments to reduce ambiguity and increase readability.
	- Fixed few other nits.

Changes since v4:
        - Added support for reading peripheral pinctrl subnode names from
	  preipheral's node instead of hard coding.

Changes since v5:
	- Changed compatible strings for uart, mshc, i2s and pinctrl to make
	  them similar to kernel in lib/fdtdec.c.
	- Changed "samsung,pinctrl-names" to "pinctrl-names" in exynos5250.dtsi
	  to make it same as kernel.
	- Added explanation for "pinctrl-names" in bindings documentation
	  samsung-pinctrl.txt.

 arch/arm/cpu/armv7/exynos/pinmux.c           | 357 +++++++-------
 arch/arm/dts/exynos5250-pinctrl.dtsi         | 675 +++++++++++++++++++++++++++
 arch/arm/dts/exynos5250.dtsi                 |  88 ++++
 board/samsung/dts/exynos5250-smdk5250.dts    |  11 +
 doc/device-tree-bindings/samsung-pinctrl.txt | 258 ++++++++++
 include/fdtdec.h                             |   4 +
 lib/fdtdec.c                                 |   4 +
 7 files changed, 1232 insertions(+), 165 deletions(-)
 create mode 100644 arch/arm/dts/exynos5250-pinctrl.dtsi
 create mode 100644 doc/device-tree-bindings/samsung-pinctrl.txt
Simon Glass - March 12, 2013, 10:46 p.m.
On Sun, Mar 10, 2013 at 11:53 PM, Akshay Saraswat <akshay.s@samsung.com> wrote:
> This patch adds fdt nodes for peripherals which require
> pin muxing and configuration. Device tree bindings for pinctrl
> are kept same as required for Linux. Existing pinmux code
> modified to retrieve gpio range and function related info from fdt.
>
> Depends-on: [U-Boot] [PATCH 0/4 V3] EXYNOS5: Add GPIO numbering feature
> URL: http://lists.denx.de/pipermail/u-boot/2013-February/146151.html
>
> Signed-off-by: Akshay Saraswat <akshay.s@samsung.com>

Acked-by: Simon Glass <sjg@chromium.org>

> ---
> Changes since v1:
>         - Device tree bindings changed to linux style.
>         - Added documentation for samsung pinctrl.
>
> Changes since v2:
>         - Rebased as per new version of GPIO numbering patch-set.
>
> Changes since v3:
>         - Added comments to reduce ambiguity and increase readability.
>         - Fixed few other nits.
>
> Changes since v4:
>         - Added support for reading peripheral pinctrl subnode names from
>           preipheral's node instead of hard coding.
>
> Changes since v5:
>         - Changed compatible strings for uart, mshc, i2s and pinctrl to make
>           them similar to kernel in lib/fdtdec.c.
>         - Changed "samsung,pinctrl-names" to "pinctrl-names" in exynos5250.dtsi
>           to make it same as kernel.
>         - Added explanation for "pinctrl-names" in bindings documentation
>           samsung-pinctrl.txt.
>
>  arch/arm/cpu/armv7/exynos/pinmux.c           | 357 +++++++-------
>  arch/arm/dts/exynos5250-pinctrl.dtsi         | 675 +++++++++++++++++++++++++++
>  arch/arm/dts/exynos5250.dtsi                 |  88 ++++
>  board/samsung/dts/exynos5250-smdk5250.dts    |  11 +
>  doc/device-tree-bindings/samsung-pinctrl.txt | 258 ++++++++++
>  include/fdtdec.h                             |   4 +
>  lib/fdtdec.c                                 |   4 +
>  7 files changed, 1232 insertions(+), 165 deletions(-)
>  create mode 100644 arch/arm/dts/exynos5250-pinctrl.dtsi
>  create mode 100644 doc/device-tree-bindings/samsung-pinctrl.txt

Patch

diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c
index a01ce0c..d590fc9 100644
--- a/arch/arm/cpu/armv7/exynos/pinmux.c
+++ b/arch/arm/cpu/armv7/exynos/pinmux.c
@@ -23,10 +23,20 @@ 
 
 #include <common.h>
 #include <fdtdec.h>
+#include <linux/ctype.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/pinmux.h>
 #include <asm/arch/sromc.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Struct for temporarily storing pin related info */
+struct pin_group {
+	uint8_t function;		/* Pin function */
+	uint8_t pull_mode;		/* Pin pull mode */
+	uint8_t drive_strength;		/* Pin drive strength */
+};
+
 struct gpio_name_num_table exynos5_gpio_table[] = {
 	{ 'a', GPIO_A00 },
 	{ 'b', GPIO_B00 },
@@ -42,252 +52,271 @@  struct gpio_name_num_table exynos5_gpio_table[] = {
 	{ 'z', GPIO_Z0 },
 };
 
-static void exynos5_uart_config(int peripheral)
+/* Extract and set pins in a particular pinctrl node */
+static void pinmux_set_pins(const char *fprop_data,
+						struct pin_group *pingrp)
 {
-	int i, start, count;
+	int i;
+	char gpio[5];
+
+	/*
+	 * Get all the pin names from fdt and fill the gpio array
+	 * with corresponding enum values(Pin numbers).
+	 */
+	for (i = 0; !(fprop_data[i] == (int)NULL &&
+				fprop_data[i+1] == (int)NULL); i += 7) {
+		int pin_num = -1;
+
+		/*
+		 * Modify pin name retrieved from fdt,
+		 * so that name_to_gpio may understand.
+		 */
+		gpio[0] = fprop_data[i];
+		gpio[1] = fprop_data[i + 1];
+		gpio[2] = fprop_data[i + 2];
+		gpio[3] = fprop_data[i + 3];
+		gpio[4] = fprop_data[i + 5];
+
+		pin_num = name_to_gpio(gpio);
+
+		/*
+		 * If pin number is valid, add it to the pin array
+		 * and increment pin count.
+		 */
+		if (pin_num >= 0) {
+			gpio_cfg_pin(pin_num,
+					S5P_GPIO_FUNC(pingrp->function));
+			gpio_set_pull(pin_num, pingrp->pull_mode);
+			gpio_set_drv(pin_num, pingrp->drive_strength);
+		}
+	}
+}
+
+/* Extract all the config info from pinctrl periph subnodei */
+static int pinmux_do_config(struct pin_group *pingrp, const char * dev_name)
+{
+	int node, subnode;
+	const char *fprop_data;
+
+	/* Loop for all pinctrl nodes in fdt */
+	for (node = fdtdec_next_compatible(gd->fdt_blob, 0,
+			COMPAT_SAMSUNG_PINCTRL); node >= 0;
+			node = fdtdec_next_compatible(gd->fdt_blob, node,
+						COMPAT_SAMSUNG_PINCTRL)) {
+		/* Get the subnode from FDT for this peripheral*/
+		subnode = fdt_subnode_offset(gd->fdt_blob,
+						node, dev_name);
+		if (subnode < 0)
+			continue;
+
+		/* Get names of pins to be configured from fdt */
+		fprop_data = fdt_getprop(gd->fdt_blob,
+					subnode, "samsung,pins", NULL);
+
+		/* Get the pin function from fdt */
+		pingrp->function = fdtdec_get_int(gd->fdt_blob,
+					subnode, "samsung,pin-function", 0);
+
+		/* Get the pull mode for pins from fdt */
+		pingrp->pull_mode = fdtdec_get_int(gd->fdt_blob,
+					subnode, "samsung,pin-pud", 0);
+
+		/* Get the drive strength for pins from fdt */
+		pingrp->drive_strength = fdtdec_get_int(gd->fdt_blob,
+					subnode, "samsung,pin-drv", 0);
+
+		/* Convert pin names to pin numbers */
+		pinmux_set_pins(fprop_data, pingrp);
+
+		return 0;
+	}
+
+	return -1;
+}
+
+/* Set configuration for all pins as per fdt for a peripheral */
+static int pinmux_group_set(struct pin_group *pingrp, int pnode)
+{
+	int err, i = 0;
+	const char *fprop_data;
+	const char *dev_name;
+
+	fprop_data = fdt_getprop(gd->fdt_blob, pnode,
+				"pinctrl-names", NULL);
+
+	do {
+		dev_name = (fprop_data + i);
+		err = pinmux_do_config(pingrp, dev_name);
+		if (err)
+			break;
+		while (fprop_data[i] != (int)NULL)
+			i++;
+	} while (isalnum(fprop_data[++i]));
+
+	return err;
+}
+
+static int exynos5_uart_config(int peripheral)
+{
+	int suffix, pnode;
+	struct pin_group pingrp;
 
 	switch (peripheral) {
 	case PERIPH_ID_UART0:
-		start = GPIO_A00;
-		count = 4;
+		suffix = 0;
 		break;
 	case PERIPH_ID_UART1:
-		start = GPIO_D00;
-		count = 4;
+		suffix = 1;
 		break;
 	case PERIPH_ID_UART2:
-		start = GPIO_A10;
-		count = 4;
+		suffix = 2;
 		break;
 	case PERIPH_ID_UART3:
-		start = GPIO_A14;
-		count = 2;
+		suffix = 3;
 		break;
 	}
-	for (i = start; i < start + count; i++) {
-		gpio_set_pull(i, S5P_GPIO_PULL_NONE);
-		gpio_cfg_pin(i, S5P_GPIO_FUNC(0x2));
-	}
+
+	pnode = fdtdec_next_alias(gd->fdt_blob, "uart",
+				COMPAT_SAMSUNG_EXYNOS_UART, &suffix);
+
+	return pinmux_group_set(&pingrp, pnode);
 }
 
-static int exynos5_mmc_config(int peripheral, int flags)
+static int exynos5_mmc_config(int peripheral)
 {
-	int i, start, start_ext, gpio_func = 0;
+	int suffix, pnode;
+	struct pin_group pingrp;
 
 	switch (peripheral) {
 	case PERIPH_ID_SDMMC0:
-		start = GPIO_C00;
-		start_ext = GPIO_C10;
-		gpio_func = S5P_GPIO_FUNC(0x2);
+		suffix = 0;
 		break;
 	case PERIPH_ID_SDMMC1:
-		start = GPIO_C20;
-		start_ext = 0;
+		suffix = 1;
 		break;
 	case PERIPH_ID_SDMMC2:
-		start = GPIO_C30;
-		start_ext = GPIO_C43;
-		gpio_func = S5P_GPIO_FUNC(0x3);
+		suffix = 2;
 		break;
 	case PERIPH_ID_SDMMC3:
-		start = GPIO_C40;
-		start_ext = 0;
+		suffix = 3;
 		break;
 	}
-	if ((flags & PINMUX_FLAG_8BIT_MODE) && !start_ext) {
-		debug("SDMMC device %d does not support 8bit mode",
-				peripheral);
-		return -1;
-	}
-	if (flags & PINMUX_FLAG_8BIT_MODE) {
-		for (i = start_ext; i <= (start_ext + 3); i++) {
-			gpio_cfg_pin(i, gpio_func);
-			gpio_set_pull(i, S5P_GPIO_PULL_UP);
-			gpio_set_drv(i, S5P_GPIO_DRV_4X);
-		}
-	}
-	for (i = 0; i < 2; i++) {
-		gpio_cfg_pin(start + i, S5P_GPIO_FUNC(0x2));
-		gpio_set_pull(start + i, S5P_GPIO_PULL_NONE);
-		gpio_set_drv(start + i, S5P_GPIO_DRV_4X);
-	}
-	for (i = 3; i <= 6; i++) {
-		gpio_cfg_pin(start + i, S5P_GPIO_FUNC(0x2));
-		gpio_set_pull(start + i, S5P_GPIO_PULL_UP);
-		gpio_set_drv(start + i, S5P_GPIO_DRV_4X);
-	}
 
-	return 0;
+	pnode = fdtdec_next_alias(gd->fdt_blob, "mshc",
+				COMPAT_SAMSUNG_EXYNOS_MSHC, &suffix);
+
+	return pinmux_group_set(&pingrp, pnode);
 }
 
-static void exynos5_sromc_config(int flags)
+static int exynos5_sromc_config(void)
 {
-	int i;
-
-	/*
-	 * SROM:CS1 and EBI
-	 *
-	 * GPY0[0]	SROM_CSn[0]
-	 * GPY0[1]	SROM_CSn[1](2)
-	 * GPY0[2]	SROM_CSn[2]
-	 * GPY0[3]	SROM_CSn[3]
-	 * GPY0[4]	EBI_OEn(2)
-	 * GPY0[5]	EBI_EEn(2)
-	 *
-	 * GPY1[0]	EBI_BEn[0](2)
-	 * GPY1[1]	EBI_BEn[1](2)
-	 * GPY1[2]	SROM_WAIT(2)
-	 * GPY1[3]	EBI_DATA_RDn(2)
-	 */
-	gpio_cfg_pin(GPIO_Y00 + (flags & PINMUX_FLAG_BANK),
-				S5P_GPIO_FUNC(2));
-	gpio_cfg_pin(GPIO_Y04, S5P_GPIO_FUNC(2));
-	gpio_cfg_pin(GPIO_Y05, S5P_GPIO_FUNC(2));
-
-	for (i = 0; i < 4; i++)
-		gpio_cfg_pin(GPIO_Y10 + i, S5P_GPIO_FUNC(2));
-
-	/*
-	 * EBI: 8 Addrss Lines
-	 *
-	 * GPY3[0]	EBI_ADDR[0](2)
-	 * GPY3[1]	EBI_ADDR[1](2)
-	 * GPY3[2]	EBI_ADDR[2](2)
-	 * GPY3[3]	EBI_ADDR[3](2)
-	 * GPY3[4]	EBI_ADDR[4](2)
-	 * GPY3[5]	EBI_ADDR[5](2)
-	 * GPY3[6]	EBI_ADDR[6](2)
-	 * GPY3[7]	EBI_ADDR[7](2)
-	 *
-	 * EBI: 16 Data Lines
-	 *
-	 * GPY5[0]	EBI_DATA[0](2)
-	 * GPY5[1]	EBI_DATA[1](2)
-	 * GPY5[2]	EBI_DATA[2](2)
-	 * GPY5[3]	EBI_DATA[3](2)
-	 * GPY5[4]	EBI_DATA[4](2)
-	 * GPY5[5]	EBI_DATA[5](2)
-	 * GPY5[6]	EBI_DATA[6](2)
-	 * GPY5[7]	EBI_DATA[7](2)
-	 *
-	 * GPY6[0]	EBI_DATA[8](2)
-	 * GPY6[1]	EBI_DATA[9](2)
-	 * GPY6[2]	EBI_DATA[10](2)
-	 * GPY6[3]	EBI_DATA[11](2)
-	 * GPY6[4]	EBI_DATA[12](2)
-	 * GPY6[5]	EBI_DATA[13](2)
-	 * GPY6[6]	EBI_DATA[14](2)
-	 * GPY6[7]	EBI_DATA[15](2)
-	 */
-	for (i = 0; i < 8; i++) {
-		gpio_cfg_pin(GPIO_Y30 + i, S5P_GPIO_FUNC(2));
-		gpio_set_pull(GPIO_Y30 + i, S5P_GPIO_PULL_UP);
+	int pnode;
+	static struct pin_group pingrp;
 
-		gpio_cfg_pin(GPIO_Y50 + i, S5P_GPIO_FUNC(2));
-		gpio_set_pull(GPIO_Y50 + i, S5P_GPIO_PULL_UP);
+	pnode = fdtdec_next_compatible(gd->fdt_blob, 0,
+					COMPAT_SAMSUNG_EXYNOS5_SROMC);
 
-		gpio_cfg_pin(GPIO_Y60 + i, S5P_GPIO_FUNC(2));
-		gpio_set_pull(GPIO_Y60 + i, S5P_GPIO_PULL_UP);
-	}
+	return pinmux_group_set(&pingrp, pnode);
 }
 
-static void exynos5_i2c_config(int peripheral, int flags)
+static int exynos5_i2c_config(int peripheral)
 {
+	int suffix, pnode;
+	struct pin_group pingrp;
 
 	switch (peripheral) {
 	case PERIPH_ID_I2C0:
-		gpio_cfg_pin(GPIO_B30, S5P_GPIO_FUNC(0x2));
-		gpio_cfg_pin(GPIO_B31, S5P_GPIO_FUNC(0x2));
+		suffix = 0;
 		break;
 	case PERIPH_ID_I2C1:
-		gpio_cfg_pin(GPIO_B32, S5P_GPIO_FUNC(0x2));
-		gpio_cfg_pin(GPIO_B33, S5P_GPIO_FUNC(0x2));
+		suffix = 1;
 		break;
 	case PERIPH_ID_I2C2:
-		gpio_cfg_pin(GPIO_A06, S5P_GPIO_FUNC(0x3));
-		gpio_cfg_pin(GPIO_A07, S5P_GPIO_FUNC(0x3));
+		suffix = 2;
 		break;
 	case PERIPH_ID_I2C3:
-		gpio_cfg_pin(GPIO_A12, S5P_GPIO_FUNC(0x3));
-		gpio_cfg_pin(GPIO_A13, S5P_GPIO_FUNC(0x3));
+		suffix = 3;
 		break;
 	case PERIPH_ID_I2C4:
-		gpio_cfg_pin(GPIO_A20, S5P_GPIO_FUNC(0x3));
-		gpio_cfg_pin(GPIO_A21, S5P_GPIO_FUNC(0x3));
+		suffix = 4;
 		break;
 	case PERIPH_ID_I2C5:
-		gpio_cfg_pin(GPIO_A22, S5P_GPIO_FUNC(0x3));
-		gpio_cfg_pin(GPIO_A23, S5P_GPIO_FUNC(0x3));
+		suffix = 5;
 		break;
 	case PERIPH_ID_I2C6:
-		gpio_cfg_pin(GPIO_B13, S5P_GPIO_FUNC(0x4));
-		gpio_cfg_pin(GPIO_B14, S5P_GPIO_FUNC(0x4));
+		suffix = 6;
 		break;
 	case PERIPH_ID_I2C7:
-		gpio_cfg_pin(GPIO_B22, S5P_GPIO_FUNC(0x3));
-		gpio_cfg_pin(GPIO_B23, S5P_GPIO_FUNC(0x3));
+		suffix = 7;
 		break;
 	}
+
+	pnode = fdtdec_next_alias(gd->fdt_blob, "i2c",
+				COMPAT_SAMSUNG_S3C2440_I2C, &suffix);
+
+	return pinmux_group_set(&pingrp, pnode);
 }
 
-static void exynos5_i2s_config(int peripheral)
+static int exynos5_i2s_config(int peripheral)
 {
-	int i;
+	int suffix, pnode;
+	struct pin_group pingrp;
+
+	if (peripheral == PERIPH_ID_I2S1) {
+		suffix = 1;
+		pnode = fdtdec_next_alias(gd->fdt_blob, "i2s",
+					COMPAT_SAMSUNG_EXYNOS_I2S, &suffix);
+	}
 
-	for (i = 0; i < 5; i++)
-		gpio_cfg_pin(GPIO_B00+i, S5P_GPIO_FUNC(0x02));
+	return pinmux_group_set(&pingrp, pnode);
 }
 
-void exynos5_spi_config(int peripheral)
+int exynos5_spi_config(int peripheral)
 {
-	int cfg = 0, pin = 0, i;
+	int suffix, pnode;
+	static struct pin_group pingrp;
 
 	switch (peripheral) {
 	case PERIPH_ID_SPI0:
-		cfg = S5P_GPIO_FUNC(0x2);
-		pin = GPIO_A20;
+		suffix = 0;
 		break;
 	case PERIPH_ID_SPI1:
-		cfg = S5P_GPIO_FUNC(0x2);
-		pin = GPIO_A24;
+		suffix = 1;
 		break;
 	case PERIPH_ID_SPI2:
-		cfg = S5P_GPIO_FUNC(0x5);
-		pin = GPIO_B11;
+		suffix = 2;
 		break;
 	case PERIPH_ID_SPI3:
-		cfg = S5P_GPIO_FUNC(0x2);
-		pin = GPIO_F10;
+		suffix = 3;
 		break;
 	case PERIPH_ID_SPI4:
-		for (i = 0; i < 2; i++) {
-			gpio_cfg_pin(GPIO_F02 + i, S5P_GPIO_FUNC(0x4));
-			gpio_cfg_pin(GPIO_E04 + i, S5P_GPIO_FUNC(0x4));
-		}
+		suffix = 4;
 		break;
 	}
-	if (peripheral != PERIPH_ID_SPI4) {
-		for (i = pin; i < pin + 4; i++)
-			gpio_cfg_pin(i, cfg);
-	}
+
+	pnode = fdtdec_next_alias(gd->fdt_blob, "spi",
+			COMPAT_SAMSUNG_EXYNOS_SPI, &suffix);
+
+	return pinmux_group_set(&pingrp, pnode);
 }
 
-static int exynos5_pinmux_config(int peripheral, int flags)
+static int exynos5_pinmux_config(int peripheral)
 {
 	switch (peripheral) {
 	case PERIPH_ID_UART0:
 	case PERIPH_ID_UART1:
 	case PERIPH_ID_UART2:
 	case PERIPH_ID_UART3:
-		exynos5_uart_config(peripheral);
+		return exynos5_uart_config(peripheral);
 		break;
 	case PERIPH_ID_SDMMC0:
 	case PERIPH_ID_SDMMC1:
 	case PERIPH_ID_SDMMC2:
 	case PERIPH_ID_SDMMC3:
-		return exynos5_mmc_config(peripheral, flags);
+		return exynos5_mmc_config(peripheral);
+		break;
 	case PERIPH_ID_SROMC:
-		exynos5_sromc_config(flags);
+		return exynos5_sromc_config();
 		break;
 	case PERIPH_ID_I2C0:
 	case PERIPH_ID_I2C1:
@@ -297,24 +326,22 @@  static int exynos5_pinmux_config(int peripheral, int flags)
 	case PERIPH_ID_I2C5:
 	case PERIPH_ID_I2C6:
 	case PERIPH_ID_I2C7:
-		exynos5_i2c_config(peripheral, flags);
+		return exynos5_i2c_config(peripheral);
 		break;
 	case PERIPH_ID_I2S1:
-		exynos5_i2s_config(peripheral);
+		return exynos5_i2s_config(peripheral);
 		break;
 	case PERIPH_ID_SPI0:
 	case PERIPH_ID_SPI1:
 	case PERIPH_ID_SPI2:
 	case PERIPH_ID_SPI3:
 	case PERIPH_ID_SPI4:
-		exynos5_spi_config(peripheral);
+		return exynos5_spi_config(peripheral);
 		break;
 	default:
 		debug("%s: invalid peripheral %d", __func__, peripheral);
 		return -1;
 	}
-
-	return 0;
 }
 
 static void exynos4_i2c_config(int peripheral, int flags)
@@ -427,7 +454,7 @@  static int exynos4_pinmux_config(int peripheral, int flags)
 int exynos_pinmux_config(int peripheral, int flags)
 {
 	if (cpu_is_exynos5())
-		return exynos5_pinmux_config(peripheral, flags);
+		return exynos5_pinmux_config(peripheral);
 	else if (cpu_is_exynos4())
 		return exynos4_pinmux_config(peripheral, flags);
 	else {
@@ -495,6 +522,6 @@  int name_to_gpio(const char *name)
 
 	if (i == ARRAY_SIZE(exynos5_gpio_table))
 		return -1;
-	
+
 	return num;
 }
diff --git a/arch/arm/dts/exynos5250-pinctrl.dtsi b/arch/arm/dts/exynos5250-pinctrl.dtsi
new file mode 100644
index 0000000..657fdb0
--- /dev/null
+++ b/arch/arm/dts/exynos5250-pinctrl.dtsi
@@ -0,0 +1,675 @@ 
+/*
+ * Samsung's Exynos5250 SoC pin-mux and pin-config device tree source
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * Samsung's Exynos5250 SoC pin-mux and pin-config options are listed as device
+ * tree nodes in this file.
+ *
+ * Note: This file does not include pin-ctrl subnodes for all the controllers in
+ * Exynos5250 SoC. It can be updated as per need in future.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/ {
+	pinctrl_0: pinctrl@11400000 {
+		compatible = "samsung,pinctrl-exynos5250";
+		reg = <0x11400000 0x1000>;
+		interrupts = <0 46 0>;
+
+		gpa0: gpa0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpa1: gpa1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpa2: gpa2 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpb0: gpb0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpb1: gpb1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpb2: gpb2 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpb3: gpb3 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpc0: gpc0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpc1: gpc1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpc2: gpc2 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpc3: gpc3 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpd0: gpd0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpd1: gpd1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpy0: gpy0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpy1: gpy1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpy2: gpy2 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpy3: gpy3 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpy4: gpy4 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpy5: gpy5 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpy6: gpy6 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpc4: gpc4 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpx0: gpx0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpx1: gpx1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpx2: gpx2 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpx3: gpx3 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		uart0_data: uart0-data {
+			samsung,pins = "gpa0-0", "gpa0-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		uart0_fctl: uart0-fctl {
+			samsung,pins = "gpa0-2", "gpa0-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samaung,pin-drv = <0>;
+		};
+
+		uart1_data: uart1-data {
+			samsung,pins = "gpd0-0", "gpd0-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		uart1_fctl: uart1-fctl {
+			samsung,pins = "gpd0-2", "gpd0-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samaung,pin-drv = <0>;
+		};
+
+		uart2_data: uart2-data {
+			samsung,pins = "gpa1-0", "gpa1-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		uart2_fctl: uart2-fctl {
+			samsung,pins = "gpa1-2", "gpa1-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samaung,pin-drv = <0>;
+		};
+
+		uart3_data: uart3-data {
+			samsung,pins = "gpa1-4", "gpa1-5";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		sd0_clk: sd0-clk {
+			samsung,pins = "gpc0-0";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd0_cmd: sd0-cmd {
+			samsung,pins = "gpc0-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd0_cd: sd0-cd {
+			samsung,pins = "gpc0-2";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd0_bus1: sd0-bus-width1 {
+			samsung,pins = "gpc0-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd0_bus4: sd0-bus-width4 {
+			samsung,pins = "gpc0-3", "gpc0-4", "gpc0-5", "gpc0-6";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd0_bus8: sd0-bus-width8 {
+			samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd1_clk: sd1-clk {
+			samsung,pins = "gpc2-0";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd1_cmd: sd1-cmd {
+			samsung,pins = "gpc2-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd1_cd: sd1-cd {
+			samsung,pins = "gpc2-2";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd1_bus1: sd1-bus-width1 {
+			samsung,pins = "gpc2-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd1_bus4: sd1-bus-width4 {
+			samsung,pins = "gpc2-3", "gpc2-4", "gpc2-5", "gpc2-6";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd2_clk: sd2-clk {
+			samsung,pins = "gpc3-0";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd2_cmd: sd2-cmd {
+			samsung,pins = "gpc3-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd2_cd: sd2-cd {
+			samsung,pins = "gpc3-2";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd2_bus1: sd2-bus-width1 {
+			samsung,pins = "gpc3-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd2_bus4: sd2-bus-width4 {
+			samsung,pins = "gpc3-3", "gpc3-4", "gpc3-5", "gpc3-6";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd2_bus8: sd2-bus-width8 {
+			samsung,pins = "gpc4-3", "gpc4-4", "gpc4-5", "gpc4-6";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd3_clk: sd3-clk {
+			samsung,pins = "gpc4-0";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd3_cmd: sd3-cmd {
+			samsung,pins = "gpc4-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd3_cd: sd3-cd {
+			samsung,pins = "gpc4-2";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd3_bus1: sd3-bus-width1 {
+			samsung,pins = "gpc4-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		sd3_bus4: sd3-bus-width4 {
+			samsung,pins = "gpc4-3", "gpc4-4", "gpc4-5", "gpc4-6";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <3>;
+		};
+
+		srom_cs1: srom-cs1 {
+			samsung,pins = "gpy0-1", "gpy0-4", "gpy0-5";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		srom_ebi: srom-ebi-enable {
+			samsung,pins = "gpy1-0", "gpy1-1", "gpy1-2", "gpy1-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		srom_ebi_a: srom-ebi-addr-lines {
+			samsung,pins = "gpy3-0", "gpy3-1", "gpy3-2", "gpy3-3",
+					"gpy3-4", "gpy3-5", "gpy3-6", "gpy3-7";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		srom_ebi_d: srom-ebi-data-lines {
+			samsung,pins = "gpy5-0", "gpy5-1", "gpy5-2", "gpy5-3",
+					"gpy5-4", "gpy5-5", "gpy5-6", "gpy5-7",
+					"gpy6-0", "gpy6-1", "gpy6-2", "gpy6-3",
+					"gpy6-4", "gpy6-5", "gpy6-6", "gpy6-7";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2s: i2s {
+			samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
+					"gpb0-4";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		spi0_bus: spi0-bus {
+			samsung,pins = "gpa2-0", "gpa2-1", "gpa2-2", "gpa2-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		spi1_bus: spi1-bus {
+			samsung,pins = "gpa2-4", "gpa2-5", "gpa2-6", "gpa2-7";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		spi2_bus: spi2-bus {
+			samsung,pins = "gpb1-1", "gpb1-2", "gpb1-3", "gpb1-4";
+			samsung,pin-function = <5>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2c0_bus: i2c0-bus {
+			samsung,pins = "gpb3-0", "gpb3-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2c1_bus: i2c1-bus {
+			samsung,pins = "gpb3-2", "gpb3-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2c2_bus: i2c2-bus {
+			samsung,pins = "gpa0-6", "gpa0-7";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <3>;
+			samaung,pin-drv = <0>;
+		};
+
+		i2c3_bus: i2c3-bus {
+			samsung,pins = "gpa1-2", "gpa1-3";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <3>;
+			samaung,pin-drv = <0>;
+		};
+
+		i2c4_bus: i2c4-bus {
+			samsung,pins = "gpa2-0", "gpa2-1";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <3>;
+			samaung,pin-drv = <0>;
+		};
+
+		i2c5_bus: i2c5-bus {
+			samsung,pins = "gpa2-2", "gpa2-3";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <3>;
+			samaung,pin-drv = <0>;
+		};
+
+		i2c6_bus: i2c6-bus {
+			samsung,pins = "gpb1-3", "gpb1-4";
+			samsung,pin-function = <4>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2c7_bus: i2c7-bus {
+			samsung,pins = "gpb2-2", "gpb2-3";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+	};
+
+	pinctrl_1: pinctrl@13400000 {
+		compatible = "samsung,pinctrl-exynos5250";
+		reg = <0x13400000 0x1000>;
+		interrupts = <0 45 0>;
+
+		gpe0: gpe0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpe1: gpe1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpf0: gpf0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpf1: gpf1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpg0: gpg0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpg1: gpg1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpg2: gpg2 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gph0: gph0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gph1: gph1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		spi3_bus: spi3-bus {
+			samsung,pins = "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+
+		spi4_bus: spi4-bus {
+			samsung,pins = "gpf0-2", "gpf0-3", "gpe0-4", "gpe0-5";
+			samsung,pin-function = <4>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+	};
+
+	pinctrl_2: pinctrl@10d10000 {
+		compatible = "samsung,pinctrl-exynos5250";
+		reg = <0x10d10000 0x1000>;
+		interrupts = <0 45 0>;
+
+		gpv0: gpv0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpv1: gpv1 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpv2: gpv2 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpv3: gpv3 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpv4: gpv4 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+
+	pinctrl_3: pinctrl@03680000 {
+		compatible = "samsung,pinctrl-exynos5250";
+		reg = <0x03680000 0x1000>;
+		interrupts = <0 45 0>;
+
+		gpz: gpz {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+};
diff --git a/arch/arm/dts/exynos5250.dtsi b/arch/arm/dts/exynos5250.dtsi
index ed8c8dd..bbf56c6 100644
--- a/arch/arm/dts/exynos5250.dtsi
+++ b/arch/arm/dts/exynos5250.dtsi
@@ -18,6 +18,7 @@ 
 */
 
 /include/ "skeleton.dtsi"
+/include/ "exynos5250-pinctrl.dtsi"
 
 / {
 	compatible = "samsung,exynos5250";
@@ -27,6 +28,9 @@ 
 		reg = <0x12250000 0x20>;
 		#address-cells = <1>;
 		#size-cells = <0>;
+		pinctrl-names = "srom-cs1", "srom-ebi-enable",
+				"srom-ebi-addr-lines",
+				"srom-ebi-data-lines";
 	};
 
 	i2c@12c60000 {
@@ -35,6 +39,7 @@ 
 		compatible = "samsung,s3c2440-i2c";
 		reg = <0x12C60000 0x100>;
 		interrupts = <0 56 0>;
+		pinctrl-names = "i2c0-bus";
 	};
 
 	i2c@12c70000 {
@@ -43,6 +48,7 @@ 
 		compatible = "samsung,s3c2440-i2c";
 		reg = <0x12C70000 0x100>;
 		interrupts = <0 57 0>;
+		pinctrl-names = "i2c1-bus";
 	};
 
 	i2c@12c80000 {
@@ -51,6 +57,7 @@ 
 		compatible = "samsung,s3c2440-i2c";
 		reg = <0x12C80000 0x100>;
 		interrupts = <0 58 0>;
+		pinctrl-names = "i2c2-bus";
 	};
 
 	i2c@12c90000 {
@@ -59,6 +66,7 @@ 
 		compatible = "samsung,s3c2440-i2c";
 		reg = <0x12C90000 0x100>;
 		interrupts = <0 59 0>;
+		pinctrl-names = "i2c3-bus";
 	};
 
 	i2c@12ca0000 {
@@ -67,6 +75,7 @@ 
 		compatible = "samsung,s3c2440-i2c";
 		reg = <0x12CA0000 0x100>;
 		interrupts = <0 60 0>;
+		pinctrl-names = "i2c4-bus";
 	};
 
 	i2c@12cb0000 {
@@ -75,6 +84,7 @@ 
 		compatible = "samsung,s3c2440-i2c";
 		reg = <0x12CB0000 0x100>;
 		interrupts = <0 61 0>;
+		pinctrl-names = "i2c5-bus";
 	};
 
 	i2c@12cc0000 {
@@ -83,6 +93,7 @@ 
 		compatible = "samsung,s3c2440-i2c";
 		reg = <0x12CC0000 0x100>;
 		interrupts = <0 62 0>;
+		pinctrl-names = "i2c6-bus";
 	};
 
 	i2c@12cd0000 {
@@ -91,6 +102,7 @@ 
 		compatible = "samsung,s3c2440-i2c";
 		reg = <0x12CD0000 0x100>;
 		interrupts = <0 63 0>;
+		pinctrl-names = "i2c7-bus";
 	};
 
 	sound@12d60000 {
@@ -104,6 +116,7 @@ 
 		compatible = "samsung,exynos-spi";
 		reg = <0x12d20000 0x30>;
 		interrupts = <0 68 0>;
+		pinctrl-names = "spi0-bus";
 	};
 
 	spi@12d30000 {
@@ -112,6 +125,7 @@ 
 		compatible = "samsung,exynos-spi";
 		reg = <0x12d30000 0x30>;
 		interrupts = <0 69 0>;
+		pinctrl-names = "spi1-bus";
 	};
 
 	spi@12d40000 {
@@ -121,6 +135,7 @@ 
 		reg = <0x12d40000 0x30>;
 		clock-frequency = <50000000>;
 		interrupts = <0 70 0>;
+		pinctrl-names = "spi2-bus";
         };
 
 	spi@131a0000 {
@@ -129,6 +144,7 @@ 
 		compatible = "samsung,exynos-spi";
 		reg = <0x131a0000 0x30>;
 		interrupts = <0 129 0>;
+		pinctrl-names = "spi3-bus";
 	};
 
 	spi@131b0000 {
@@ -137,6 +153,7 @@ 
 		compatible = "samsung,exynos-spi";
 		reg = <0x131b0000 0x30>;
 		interrupts = <0 130 0>;
+		pinctrl-names = "spi4-bus";
 	};
 
 	ehci@12110000 {
@@ -151,4 +168,75 @@ 
 		};
 	};
 
+	serial@12C00000 {
+		compatible = "samsung,exynos4210-uart";
+		reg = <0x12C00000 0x100>;
+		pinctrl-names = "uart0-data", "uart0-fctl";
+	};
+
+	serial@12C10000 {
+		compatible = "samsung,exynos4210-uart";
+		reg = <0x12C10000 0x100>;
+		pinctrl-names = "uart1-data", "uart1-fctl";
+	};
+
+	serial@12C20000 {
+		compatible = "samsung,exynos4210-uart";
+		reg = <0x12C20000 0x100>;
+		pinctrl-names = "uart2-data", "uart2-fctl";
+	};
+
+	serial@12C30000 {
+		compatible = "samsung,exynos4210-uart";
+		reg = <0x12C30000 0x100>;
+		pinctrl-names = "uart3-data";
+	};
+
+	dwmmc@12200000 {
+		compatible = "samsung,exynos5250-dw-mshc";
+		reg = <0x12200000 0x1000>;
+		pinctrl-names = "sd0-clk", "sd0-cmd",
+				"sd0-bus-width4",
+				"sd0-bus-width8";
+	};
+
+	dwmmc@12210000 {
+		compatible = "samsung,exynos5250-dw-mshc";
+		reg = <0x12210000 0x1000>;
+		pinctrl-names = "sd1-clk", "sd1-cmd",
+				"sd1-bus-width4";
+	};
+
+	dwmmc@12220000 {
+		compatible = "samsung,exynos5250-dw-mshc";
+		reg = <0x12220000 0x1000>;
+		pinctrl-names = "sd2-clk", "sd2-cmd",
+				"sd2-bus-width4",
+				"sd2-bus-width8";
+	};
+
+	dwmmc@12230000 {
+		compatible = "samsung,exynos5250-dw-mshc";
+		reg = <0x12230000 0x1000>;
+		pinctrl-names = "sd3-clk", "sd3-cmd",
+				"sd3-bus-width4";
+	};
+
+	i2s@03830000 {
+		compatible = "samsung,exynos5250-i2s";
+		reg = <0x03830000 0x100>;
+		pinctrl-names = "i2s0";
+	};
+
+	i2s@12d60000 {
+		compatible = "samsung,exynos5250-i2s";
+		reg = <0x12d60000 0x100>;
+		pinctrl-names = "i2s1";
+	};
+
+	i2s@12D70000 {
+		compatible = "samsung,exynos5250-i2s";
+		reg = <0x12D70000 0x100>;
+		pinctrl-names = "i2s2";
+	};
 };
diff --git a/board/samsung/dts/exynos5250-smdk5250.dts b/board/samsung/dts/exynos5250-smdk5250.dts
index cbfab6f..30ba5aa 100644
--- a/board/samsung/dts/exynos5250-smdk5250.dts
+++ b/board/samsung/dts/exynos5250-smdk5250.dts
@@ -30,6 +30,17 @@ 
 		spi2 = "/spi@12d40000";
 		spi3 = "/spi@131a0000";
 		spi4 = "/spi@131b0000";
+		mshc0 = "/dwmmc@12200000";
+		mshc1 = "/dwmmc@12210000";
+		mshc2 = "/dwmmc@12220000";
+		mshc3 = "/dwmmc@12230000";
+		uart0 = "/serial@12C00000";
+		uart1 = "/serial@12C10000";
+		uart2 = "/serial@12C20000";
+		uart3 = "/serial@12C30000";
+		i2s0 = "/i2s@03830000";
+		i2s1 = "/sound@12d60000";
+		i2s2 = "/i2s@12D70000";
 	};
 
 	sromc@12250000 {
diff --git a/doc/device-tree-bindings/samsung-pinctrl.txt b/doc/device-tree-bindings/samsung-pinctrl.txt
new file mode 100644
index 0000000..f2364a1
--- /dev/null
+++ b/doc/device-tree-bindings/samsung-pinctrl.txt
@@ -0,0 +1,258 @@ 
+Samsung GPIO and Pin Mux/Config controller
+
+Samsung's ARM based SoC's integrates a GPIO and Pin mux/config hardware
+controller. It controls the input/output settings on the available pads/pins
+and also provides ability to multiplex and configure the output of various
+on-chip controllers onto these pads.
+
+Required Properties:
+- compatible: should be one of the following.
+  - "samsung,pinctrl": for Exynos compatible pin-controller.
+
+- reg: Base address of the pin controller hardware module and length of
+  the address space it occupies.
+
+- Pin banks as child nodes: Pin banks of the controller are represented by child
+  nodes of the controller node. Bank name is taken from name of the node. Each
+  bank node must contain following properties:
+
+  - gpio-controller: identifies the node as a gpio controller and pin bank.
+  - #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO
+    binding is used, the amount of cells must be specified as 2. See generic
+    GPIO binding documentation for description of particular cells.
+
+- Pin mux/config groups as child nodes: The pin mux (selecting pin function
+  mode) and pin config (pull up/down, driver strength) settings are represented
+  as child nodes of the pin-controller node. There should be atleast one
+  child node and there is no limit on the count of these child nodes.
+
+  The child node should contain a list of pin(s) on which a particular pin
+  function selection or pin configuration (or both) have to applied. This
+  list of pins is specified using the property name "samsung,pins". There
+  should be atleast one pin specfied for this property and there is no upper
+  limit on the count of pins that can be specified. The pins are specified
+  using pin names which are derived from the hardware manual of the SoC. As
+  an example, the pins in GPA0 bank of the pin controller can be represented
+  as "gpa0-0", "gpa0-1", "gpa0-2" and so on. The names should be in lower case.
+  The format of the pin names should be (as per the hardware manual)
+  "[pin bank name]-[pin number within the bank]".
+
+  The pin function selection that should be applied on the pins listed in the
+  child node is specified using the "samsung,pin-function" property. The value
+  of this property that should be applied to each of the pins listed in the
+  "samsung,pins" property should be picked from the hardware manual of the SoC
+  for the specified pin group. This property is optional in the child node if
+  no specific function selection is desired for the pins listed in the child
+  node. The value of this property is used as-is to program the pin-controller
+  function selector register of the pin-bank.
+
+  The child node can also optionally specify one or more of the pin
+  configuration that should be applied on all the pins listed in the
+  "samsung,pins" property of the child node. The following pin configuration
+  properties are supported.
+
+  - samsung,pin-pud: Pull up/down configuration.
+  - samsung,pin-drv: Drive strength configuration.
+  - samsung,pin-pud-pdn: Pull up/down configuration in power down mode.
+  - samsung,pin-drv-pdn: Drive strength configuration in power down mode.
+
+  The values specified by these config properties should be derived from the
+  hardware manual and these values are programmed as-is into the pin
+  pull up/down and driver strength register of the pin-controller.
+
+  Note: A child should include atleast a pin function selection property or
+  pin configuration property (one or more) or both.
+
+  The client nodes that require a particular pin function selection and/or
+  pin configuration should use the bindings listed in the "pinctrl-bindings.txt"
+  file.
+
+External GPIO and Wakeup Interrupts:
+
+The controller supports two types of external interrupts over gpio. The first
+is the external gpio interrupt and second is the external wakeup interrupts.
+The difference between the two is that the external wakeup interrupts can be
+used as system wakeup events.
+
+A. External GPIO Interrupts: For supporting external gpio interrupts, the
+   following properties should be specified in the pin-controller device node.
+
+   - interrupt-parent: phandle of the interrupt parent to which the external
+     GPIO interrupts are forwarded to.
+   - interrupts: interrupt specifier for the controller. The format and value of
+     the interrupt specifier depends on the interrupt parent for the controller.
+
+   In addition, following properties must be present in node of every bank
+   of pins supporting GPIO interrupts:
+
+   - interrupt-controller: identifies the controller node as interrupt-parent.
+   - #interrupt-cells: the value of this property should be 2.
+     - First Cell: represents the external gpio interrupt number local to the
+       external gpio interrupt space of the controller.
+     - Second Cell: flags to identify the type of the interrupt
+       - 1 = rising edge triggered
+       - 2 = falling edge triggered
+       - 3 = rising and falling edge triggered
+       - 4 = high level triggered
+       - 8 = low level triggered
+
+B. External Wakeup Interrupts: For supporting external wakeup interrupts, a
+   child node representing the external wakeup interrupt controller should be
+   included in the pin-controller device node. This child node should include
+   the following properties.
+
+   - compatible: identifies the type of the external wakeup interrupt controller
+     The possible values are:
+     - samsung,wakeup-eint: represents wakeup interrupt controller
+       found on Samsung Exynos SoC.
+   - interrupt-parent: phandle of the interrupt parent to which the external
+     wakeup interrupts are forwarded to.
+   - interrupts: interrupt used by multiplexed wakeup interrupts.
+
+   In addition, following properties must be present in node of every bank
+   of pins supporting wake-up interrupts:
+
+   - interrupt-controller: identifies the node as interrupt-parent.
+   - #interrupt-cells: the value of this property should be 2
+     - First Cell: represents the external wakeup interrupt number local to
+       the external wakeup interrupt space of the controller.
+     - Second Cell: flags to identify the type of the interrupt
+       - 1 = rising edge triggered
+       - 2 = falling edge triggered
+       - 3 = rising and falling edge triggered
+       - 4 = high level triggered
+       - 8 = low level triggered
+
+   Node of every bank of pins supporting direct wake-up interrupts (without
+   multiplexing) must contain following properties:
+
+   - interrupt-parent: phandle of the interrupt parent to which the external
+     wakeup interrupts are forwarded to.
+   - interrupts: interrupts of the interrupt parent which are used for external
+     wakeup interrupts from pins of the bank, must contain interrupts for all
+     pins of the bank.
+
+Aliases:
+
+All the pin controller nodes should be represented in the aliases node using
+the following format 'pinctrl{n}' where n is a unique number for the alias.
+
+Example: A pin-controller node with pin banks:
+
+	pinctrl_0: pinctrl@11400000 {
+		compatible = "samsung,pinctrl;
+		reg = <0x11400000 0x1000>;
+		interrupts = <0 47 0>;
+
+		/* ... */
+
+		/* Pin bank without external interrupts */
+		gpy0: gpy0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		/* ... */
+
+		/* Pin bank with external GPIO or muxed wake-up interrupts */
+		gpj0: gpj0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		/* ... */
+
+		/* Pin bank with external direct wake-up interrupts */
+		gpx0: gpx0 {
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			interrupt-parent = <&gic>;
+			interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
+				     <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>;
+			#interrupt-cells = <2>;
+		};
+
+		/* ... */
+	};
+
+Example 1: A pin-controller node with pin groups.
+
+	pinctrl_0: pinctrl@11400000 {
+		compatible = "samsung,pinctrl";
+		reg = <0x11400000 0x1000>;
+		interrupts = <0 47 0>;
+
+		/* ... */
+
+		uart0_data: uart0-data {
+			samsung,pins = "gpa0-0", "gpa0-1";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		uart0_fctl: uart0-fctl {
+			samsung,pins = "gpa0-2", "gpa0-3";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		uart1_data: uart1-data {
+			samsung,pins = "gpa0-4", "gpa0-5";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		uart1_fctl: uart1-fctl {
+			samsung,pins = "gpa0-6", "gpa0-7";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <0>;
+			samsung,pin-drv = <0>;
+		};
+
+		i2c2_bus: i2c2-bus {
+			samsung,pins = "gpa0-6", "gpa0-7";
+			samsung,pin-function = <3>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+		};
+	};
+
+Example 2: A pin-controller node with external wakeup interrupt controller node.
+
+	pinctrl_1: pinctrl@11000000 {
+		compatible = "samsung,pinctrl";
+		reg = <0x11000000 0x1000>;
+		interrupts = <0 46 0>
+
+		/* ... */
+
+		wakeup-interrupt-controller {
+			compatible = "samsung,wakeup-eint";
+			interrupt-parent = <&gic>;
+			interrupts = <0 32 0>;
+		};
+	};
+
+Example 3: A uart client node that supports 'default' and 'flow-control' states.
+	Pinctrl Properties:
+	-	pinctrl-names: names of all the pin-controller peripheral
+		sub-nodes which provide pinmux and pinconfig info.
+	-	pinctrl{n}: This shows parent pin-controller nodes consisting
+		peripheral pin-controller subnodes.
+
+	uart@13800000 {
+		compatible = "samsung,uart";
+		reg = <0x13800000 0x100>;
+		interrupts = <0 52 0>;
+		pinctrl-names = "default", "flow-control;
+		pinctrl-0 = <&uart0_data>;
+		pinctrl-1 = <&uart0_data &uart0_fctl>;
+	};
diff --git a/include/fdtdec.h b/include/fdtdec.h
index 77f244f..3e5cb8a 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -81,6 +81,10 @@  enum fdt_compat_id {
 	COMPAT_SAMSUNG_EXYNOS_EHCI,	/* Exynos EHCI controller */
 	COMPAT_SAMSUNG_EXYNOS_USB_PHY,	/* Exynos phy controller for usb2.0 */
 	COMPAT_MAXIM_MAX77686_PMIC,	/* MAX77686 PMIC */
+	COMPAT_SAMSUNG_EXYNOS_UART,	/* Exynos serial */
+	COMPAT_SAMSUNG_EXYNOS_MSHC,	/* Exynos MMC controller */
+	COMPAT_SAMSUNG_EXYNOS_I2S,	/* Exynos I2S controller */
+	COMPAT_SAMSUNG_PINCTRL,		/* Exynos PINCTRL */
 
 	COMPAT_COUNT,
 };
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 3ae348d..5486996 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -56,6 +56,10 @@  static const char * const compat_names[COMPAT_COUNT] = {
 	COMPAT(SAMSUNG_EXYNOS_EHCI, "samsung,exynos-ehci"),
 	COMPAT(SAMSUNG_EXYNOS_USB_PHY, "samsung,exynos-usb-phy"),
 	COMPAT(MAXIM_MAX77686_PMIC, "maxim,max77686_pmic"),
+	COMPAT(SAMSUNG_EXYNOS_UART, "samsung,exynos4210-uart"),
+	COMPAT(SAMSUNG_EXYNOS_MSHC, "samsung,exynos5250-dw-mshc"),
+	COMPAT(SAMSUNG_EXYNOS_I2S, "samsung,exynos5250-i2s"),
+	COMPAT(SAMSUNG_PINCTRL, "samsung,pinctrl-exynos5250"),
 };
 
 const char *fdtdec_get_compatible(enum fdt_compat_id id)