[U-Boot] [PATCH v3] Exynos5: Pinmux: Add fdt for pinmux
Simon Glass
sjg at chromium.org
Mon Feb 25 05:31:02 CET 2013
Hi Akshay,
On Thu, Feb 21, 2013 at 11:05 AM, Akshay Saraswat <akshay.s at 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 at samsung.com>
> ---
> Changes since v2:
> - Rebased as per new version of GPIO numbering patch-set.
This looks pretty reasonable to me. Please find some comment below.
As a general comment, it seems to read from the FDT each time anything
is changed. I suppose that is efficient on space, and allows it to
work prior to malloc() being available, but isn't it slow? Perhaps the
data should be cached?
>
> arch/arm/cpu/armv7/exynos/pinmux.c | 379 +++++++++++----
> arch/arm/dts/exynos5250-pinctrl.dtsi | 675 ++++++++++++++++++++++++++
> arch/arm/dts/exynos5250.dtsi | 1 +
> doc/device-tree-bindings/samsung-pinctrl.txt | 253 ++++++++++
> include/fdtdec.h | 1 +
> lib/fdtdec.c | 1 +
> 6 files changed, 1204 insertions(+), 106 deletions(-)
> create mode 100644 arch/arm/dts/exynos5250-pinctrl.dtsi
> create mode 100644 doc/device-tree-bindings/samsung-pinctrl.txt
>
> diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c
> index a01ce0c..f4dccad 100644
> --- a/arch/arm/cpu/armv7/exynos/pinmux.c
> +++ b/arch/arm/cpu/armv7/exynos/pinmux.c
> @@ -27,6 +27,18 @@
> #include <asm/arch/pinmux.h>
> #include <asm/arch/sromc.h>
>
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +/* Struct for storing pin function and gpio related info */
> +struct pin_group {
> + void *dev_name;
What is this for?
> + int npins;
> + int function;
> + int pull_mode;
> + int drive_strength;
Should add comments about the S5P_GPIO... defines to use in each case.
> + enum exynos5_gpio_pin gpio[];
This array has no members?
> +};
> +
> struct gpio_name_num_table exynos5_gpio_table[] = {
> { 'a', GPIO_A00 },
> { 'b', GPIO_B00 },
> @@ -42,87 +54,202 @@ struct gpio_name_num_table exynos5_gpio_table[] = {
> { 'z', GPIO_Z0 },
> };
>
> -static void exynos5_uart_config(int peripheral)
> +static void get_pins(const struct fdt_property *fprop, struct pin_group *pingrp)
> {
> - int i, start, count;
> + int i;
> + char gpio[5];
> +
> + pingrp->npins = 0;
> +
> + for (i = 0; !(fprop->data[i] == (int)NULL &&
> + fprop->data[i-1] == (int)NULL); i += 7) {
This is a bit obtuse - please add a comment
> + int pin_num = -1;
> +
> + 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];
What is this doing? Please add a comment.
> +
> + pin_num = name_to_gpio(gpio);
> +
> + if (pin_num >= 0) {
> + pingrp->gpio[pingrp->npins] = pin_num;
This seems to be assigning to something with no members.
> + pingrp->npins++;
> + }
> + }
> +}
> +
> +static int get_fdt_values(struct pin_group *pingrp)
Please add a function comment.
> +{
> + int i;
> + int node, subnode;
> + const struct fdt_property *fprop;
> +
> + for (i = 0; i < 4; i++) {
Why 4? I think you should just continue until node returns -ve.
> + /* Get the node from FDT for pinctrl */
> + node = fdtdec_next_compatible(gd->fdt_blob, 0,
> + COMPAT_SAMSUNG_PINCTRL);
> + if (node < 0) {
> + printf("PINCTRL: No node for pinctrl in device tree\n");
debug()
Only give this error if you don't find any match
> + return -1;
> + }
> +
> + subnode = fdt_subnode_offset(gd->fdt_blob,
> + node, pingrp->dev_name);
> + if (subnode < 0)
> + continue;
> +
> + fprop = fdt_get_property(gd->fdt_blob,
> + subnode, "samsung,pins", NULL);
Suggest you use fdt_getprop() here.
> + pingrp->function = fdtdec_get_int(gd->fdt_blob,
> + subnode, "samsung,pin-function", -1);
> + pingrp->pull_mode = fdtdec_get_int(gd->fdt_blob,
> + subnode, "samsung,pin-pud", -1);
> + pingrp->drive_strength = fdtdec_get_int(gd->fdt_blob,
> + subnode, "samsung,pin-drv", -1);
Error checking on these? Is -1 a valid value?
> + get_pins(fprop, pingrp);
> +
> + return 0;
> + }
> +
> + debug("PINCTRL: No subnode for %s\n", (char *)pingrp->dev_name);
Can dev_name be const char *?
> +
> + return -1;
> +}
> +
> +static void pin_config_group_set(struct pin_group *pingrp)
> +{
> + int i;
> +
> + for (i = 0; i < pingrp->npins; i++) {
> + gpio_cfg_pin(pingrp->gpio[i], S5P_GPIO_FUNC(pingrp->function));
> + gpio_set_pull(pingrp->gpio[i], pingrp->pull_mode);
> + gpio_set_drv(pingrp->gpio[i], pingrp->drive_strength);
> + }
> +}
> +
> +static int exynos5_uart_config(int peripheral)
> +{
> + char *data, *fctl = NULL;
> + struct pin_group pingrp;
>
> switch (peripheral) {
> case PERIPH_ID_UART0:
> - start = GPIO_A00;
> - count = 4;
> + data = "uart0-data";
> + fctl = "uart0-fctl";
> break;
> case PERIPH_ID_UART1:
> - start = GPIO_D00;
> - count = 4;
> + data = "uart1-data";
> + fctl = "uart1-fctl";
> break;
> case PERIPH_ID_UART2:
> - start = GPIO_A10;
> - count = 4;
> + data = "uart2-data";
> + fctl = "uart2-fctl";
> break;
> case PERIPH_ID_UART3:
> - start = GPIO_A14;
> - count = 2;
> + data = "uart3-data";
> break;
> }
> - for (i = start; i < start + count; i++) {
> - gpio_set_pull(i, S5P_GPIO_PULL_NONE);
> - gpio_cfg_pin(i, S5P_GPIO_FUNC(0x2));
> +
> + pingrp.dev_name = data;
> +
> + /*
> + * Retrieve and apply pin config details
> + * from fdt for this UART's data line.
> + */
> + if (get_fdt_values(&pingrp))
> + return -1;
> +
> + pin_config_group_set(&pingrp);
Suggest you add a function which does both of thees things - i.e.
get_fdt_values() and pin_config_group_set().
Also probably should have a pinmux_ prefix on the latter, given the
name of this file.
> +
> + if (peripheral != PERIPH_ID_UART3) {
> + pingrp.dev_name = fctl;
> +
> + /*
> + * Retrieve and apply pin config details
> + * from fdt for this UART's fctl.
> + */
> + if (get_fdt_values(&pingrp))
> + return -1;
> +
> + pin_config_group_set(&pingrp);
> }
> +
> + return 0;
> }
>
> static int exynos5_mmc_config(int peripheral, int flags)
> {
> - int i, start, start_ext, gpio_func = 0;
> + char *periph_name = NULL;
> + struct pin_group pingrp;
>
> switch (peripheral) {
> case PERIPH_ID_SDMMC0:
> - start = GPIO_C00;
> - start_ext = GPIO_C10;
> - gpio_func = S5P_GPIO_FUNC(0x2);
> + periph_name = "sd0";
> break;
> case PERIPH_ID_SDMMC1:
> - start = GPIO_C20;
> - start_ext = 0;
> + periph_name = "sd1";
> break;
> case PERIPH_ID_SDMMC2:
> - start = GPIO_C30;
> - start_ext = GPIO_C43;
> - gpio_func = S5P_GPIO_FUNC(0x3);
> + periph_name = "sd2";
> break;
> case PERIPH_ID_SDMMC3:
> - start = GPIO_C40;
> - start_ext = 0;
> + periph_name = "sd3";
> 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);
> + pingrp.dev_name = strcat(periph_name, "-bus-width8");
> + /*
> + * Retrieve and apply pin config details from fdt
> + * for remaining 4 bits if this sd has 8-bit bus.
> + */
> + if (get_fdt_values(&pingrp))
> + return -1;
> +
> + pin_config_group_set(&pingrp);
> }
>
> + pingrp.dev_name = strcat(periph_name, "-clk");
> +
> + /*
> + * Retrieve and apply pin config details
> + * from fdt for this sd's clk.
> + */
> + if (get_fdt_values(&pingrp))
> + return -1;
> +
> + pin_config_group_set(&pingrp);
> +
> + pingrp.dev_name = strcat(periph_name, "-cmd");
> +
> + /*
> + * Retrieve and apply pin config details
> + * from fdt for this sd's cmd.
> + */
> + if (get_fdt_values(&pingrp))
> + return -1;
> +
> + pin_config_group_set(&pingrp);
> +
> + pingrp.dev_name = strcat(periph_name, "-bus-width4");
> +
> + /*
> + * Retrieve and apply pin config details
> + * from fdt for this sd's 4-bit bus.
> + */
> + if (get_fdt_values(&pingrp))
> + return -1;
> +
> + pin_config_group_set(&pingrp);
> +
> return 0;
> }
>
> -static void exynos5_sromc_config(int flags)
> +static int exynos5_sromc_config(int flags)
> {
> - int i;
> + static struct pin_group pingrp;
>
> /*
> * SROM:CS1 and EBI
> @@ -139,13 +266,28 @@ static void exynos5_sromc_config(int flags)
> * 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));
> + pingrp.dev_name = "srom-cs1";
All these names that you are hard-coding...is it not possible to list
them in the device node in the FDT? Perhaps the caller should pass a
node offset?
>
> - for (i = 0; i < 4; i++)
> - gpio_cfg_pin(GPIO_Y10 + i, S5P_GPIO_FUNC(2));
> + /*
> + * Retrieve and apply pin config details
> + * from fdt to enable SROM CS1.
> + */
> + if (get_fdt_values(&pingrp))
> + return -1;
> +
> + pingrp.gpio[0] += (flags & PINMUX_FLAG_BANK);
> + pin_config_group_set(&pingrp);
> +
> + pingrp.dev_name = "srom-ebi-enable";
> +
> + /*
> + * Retrieve and apply pin config details
> + * from fdt to enable SROM EBI.
> + */
> + if (get_fdt_values(&pingrp))
> + return -1;
> +
> + pin_config_group_set(&pingrp);
>
> /*
> * EBI: 8 Addrss Lines
> @@ -179,97 +321,124 @@ static void exynos5_sromc_config(int flags)
> * 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);
> + pingrp.dev_name = "srom-ebi-addr-lines";
> +
> + /*
> + * Retrieve and apply pin config details
> + * from fdt for EBI address lines.
> + */
> + if (get_fdt_values(&pingrp))
> + return -1;
>
> - gpio_cfg_pin(GPIO_Y50 + i, S5P_GPIO_FUNC(2));
> - gpio_set_pull(GPIO_Y50 + i, S5P_GPIO_PULL_UP);
> + pin_config_group_set(&pingrp);
>
> - gpio_cfg_pin(GPIO_Y60 + i, S5P_GPIO_FUNC(2));
> - gpio_set_pull(GPIO_Y60 + i, S5P_GPIO_PULL_UP);
> - }
> + pingrp.dev_name = "srom-ebi-data-lines";
> +
> + /*
> + * Retrieve and apply pin config details
> + * from fdt for EBI data lines.
> + */
> + if (get_fdt_values(&pingrp))
> + return -1;
> +
> + pin_config_group_set(&pingrp);
> +
> + return 0;
> }
>
> -static void exynos5_i2c_config(int peripheral, int flags)
> +static int exynos5_i2c_config(int peripheral, int flags)
> {
> + 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));
> + pingrp.dev_name = "i2c0-bus";
> break;
> case PERIPH_ID_I2C1:
> - gpio_cfg_pin(GPIO_B32, S5P_GPIO_FUNC(0x2));
> - gpio_cfg_pin(GPIO_B33, S5P_GPIO_FUNC(0x2));
> + pingrp.dev_name = "i2c1-bus";
> break;
> case PERIPH_ID_I2C2:
> - gpio_cfg_pin(GPIO_A06, S5P_GPIO_FUNC(0x3));
> - gpio_cfg_pin(GPIO_A07, S5P_GPIO_FUNC(0x3));
> + pingrp.dev_name = "i2c2-bus";
> break;
> case PERIPH_ID_I2C3:
> - gpio_cfg_pin(GPIO_A12, S5P_GPIO_FUNC(0x3));
> - gpio_cfg_pin(GPIO_A13, S5P_GPIO_FUNC(0x3));
> + pingrp.dev_name = "i2c3-bus";
> break;
> case PERIPH_ID_I2C4:
> - gpio_cfg_pin(GPIO_A20, S5P_GPIO_FUNC(0x3));
> - gpio_cfg_pin(GPIO_A21, S5P_GPIO_FUNC(0x3));
> + pingrp.dev_name = "i2c4-bus";
> break;
> case PERIPH_ID_I2C5:
> - gpio_cfg_pin(GPIO_A22, S5P_GPIO_FUNC(0x3));
> - gpio_cfg_pin(GPIO_A23, S5P_GPIO_FUNC(0x3));
> + pingrp.dev_name = "i2c5-bus";
> break;
> case PERIPH_ID_I2C6:
> - gpio_cfg_pin(GPIO_B13, S5P_GPIO_FUNC(0x4));
> - gpio_cfg_pin(GPIO_B14, S5P_GPIO_FUNC(0x4));
> + pingrp.dev_name = "i2c6-bus";
> break;
> case PERIPH_ID_I2C7:
> - gpio_cfg_pin(GPIO_B22, S5P_GPIO_FUNC(0x3));
> - gpio_cfg_pin(GPIO_B23, S5P_GPIO_FUNC(0x3));
> + pingrp.dev_name = "i2c7-bus";
> break;
> }
> +
> + /*
> + * Retrieve and apply pin config details
> + * from fdt for this i2c bus.
> + */
> + if (get_fdt_values(&pingrp))
> + return -1;
> +
> + pin_config_group_set(&pingrp);
> +
> + return 0;
> }
>
> -static void exynos5_i2s_config(int peripheral)
> +static int exynos5_i2s_config(int peripheral)
> {
> - int i;
> + struct pin_group pingrp;
> +
> + pingrp.dev_name = "i2s";
> +
> + /*
> + * Retrieve and apply pin config details
> + * from fdt for i2s.
> + */
> + if (get_fdt_values(&pingrp))
> + return -1;
> +
> + pin_config_group_set(&pingrp);
>
> - for (i = 0; i < 5; i++)
> - gpio_cfg_pin(GPIO_B00+i, S5P_GPIO_FUNC(0x02));
> + return 0;
> }
>
> -void exynos5_spi_config(int peripheral)
> +int exynos5_spi_config(int peripheral)
> {
> - int cfg = 0, pin = 0, i;
> + static struct pin_group pingrp;
>
> switch (peripheral) {
> case PERIPH_ID_SPI0:
> - cfg = S5P_GPIO_FUNC(0x2);
> - pin = GPIO_A20;
> + pingrp.dev_name = "spi0-bus";
> break;
> case PERIPH_ID_SPI1:
> - cfg = S5P_GPIO_FUNC(0x2);
> - pin = GPIO_A24;
> + pingrp.dev_name = "spi1-bus";
> break;
> case PERIPH_ID_SPI2:
> - cfg = S5P_GPIO_FUNC(0x5);
> - pin = GPIO_B11;
> + pingrp.dev_name = "spi2-bus";
> break;
> case PERIPH_ID_SPI3:
> - cfg = S5P_GPIO_FUNC(0x2);
> - pin = GPIO_F10;
> + pingrp.dev_name = "spi3-bus";
> 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));
> - }
> + pingrp.dev_name = "spi4-bus";
> break;
> }
> - if (peripheral != PERIPH_ID_SPI4) {
> - for (i = pin; i < pin + 4; i++)
> - gpio_cfg_pin(i, cfg);
> - }
> +
> + /*
> + * Retrieve and apply pin config details
> + * from fdt for this spi.
> + */
> + if (get_fdt_values(&pingrp))
> + return -1;
> +
> + pin_config_group_set(&pingrp);
> +
> + return 0;
> }
>
> static int exynos5_pinmux_config(int peripheral, int flags)
> @@ -279,7 +448,7 @@ static int exynos5_pinmux_config(int peripheral, int flags)
> 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:
> @@ -287,7 +456,7 @@ static int exynos5_pinmux_config(int peripheral, int flags)
> case PERIPH_ID_SDMMC3:
> return exynos5_mmc_config(peripheral, flags);
> case PERIPH_ID_SROMC:
> - exynos5_sromc_config(flags);
> + return exynos5_sromc_config(flags);
> break;
> case PERIPH_ID_I2C0:
> case PERIPH_ID_I2C1:
> @@ -297,24 +466,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, flags);
> 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)
> diff --git a/arch/arm/dts/exynos5250-pinctrl.dtsi b/arch/arm/dts/exynos5250-pinctrl.dtsi
> new file mode 100644
> index 0000000..efbe1be
> --- /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 at 11400000 {
> + compatible = "samsung,pinctrl";
> + 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-0", "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 at 13400000 {
> + compatible = "samsung,pinctrl";
> + 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 at 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 at 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..8fcf432 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";
> diff --git a/doc/device-tree-bindings/samsung-pinctrl.txt b/doc/device-tree-bindings/samsung-pinctrl.txt
> new file mode 100644
> index 0000000..708ca45
> --- /dev/null
> +++ b/doc/device-tree-bindings/samsung-pinctrl.txt
> @@ -0,0 +1,253 @@
> +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 at 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 at 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 at 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.
> +
> + uart at 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..9c1bd82 100644
> --- a/include/fdtdec.h
> +++ b/include/fdtdec.h
> @@ -81,6 +81,7 @@ 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_PINCTRL, /* PINCTRL */
>
> COMPAT_COUNT,
> };
> diff --git a/lib/fdtdec.c b/lib/fdtdec.c
> index 3ae348d..16dbdcd 100644
> --- a/lib/fdtdec.c
> +++ b/lib/fdtdec.c
> @@ -56,6 +56,7 @@ 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_PINCTRL, "samsung,pinctrl"),
> };
>
> const char *fdtdec_get_compatible(enum fdt_compat_id id)
> --
> 1.7.9.5
>
More information about the U-Boot
mailing list