[U-Boot] [PATCH v11 1/2] S5P: Exynos: Add GPIO pin numbering and rename definitions

Minkyu Kang mk7.kang at samsung.com
Tue May 6 04:47:32 CEST 2014


Dear Akshay Saraswat,

On 05/05/14 19:39, Akshay Saraswat wrote:
> This patch includes following changes :
> * Adds gpio pin numbering support for EXYNOS SOCs.
>   To have consistent 0..n-1 GPIO numbering the banks are divided
>   into different parts where ever they have holes in them.
> 
> * Rename GPIO definitions from GPIO_... to S5P_GPIO_...
>   These changes were done to enable cmd_gpio for EXYNOS and
>   cmd_gpio has GPIO_INPUT same as s5p_gpio driver and hence
>   getting a error during compilation.
> 
> * Adds support for name to gpio conversion in s5p_gpio to enable
>   gpio command EXYNOS SoCs. Function has been added to asm/gpio.h
>   to decode the input gpio name to gpio number.
>   Example: SMDK5420 # gpio set gpa00
> 
> Signed-off-by: Leela Krishna Amudala <l.krishna at samsung.com>
> Signed-off-by: Rajeshwari Shinde <rajeshwari.s at samsung.com>
> Signed-off-by: Akshay Saraswat <akshay.s at samsung.com>
> ---

please add changes log.

>  arch/arm/cpu/armv7/exynos/pinmux.c         |  549 +++++----
>  arch/arm/dts/exynos4210-origen.dts         |    4 +-
>  arch/arm/dts/exynos4210-trats.dts          |    6 +-
>  arch/arm/dts/exynos4210-universal_c210.dts |    4 +-
>  arch/arm/dts/exynos4412-trats2.dts         |    4 +-
>  arch/arm/include/asm/arch-exynos/cpu.h     |   17 +-
>  arch/arm/include/asm/arch-exynos/gpio.h    | 1761 +++++++++++++++++++++++-----
>  arch/arm/include/asm/arch-s5pc1xx/gpio.h   |  950 ++++++++++++---
>  board/samsung/arndale/arndale.c            |   11 +-
>  board/samsung/goni/goni.c                  |   26 +-
>  board/samsung/smdk5250/exynos5-dt.c        |   20 +-
>  board/samsung/smdk5250/smdk5250.c          |   19 +-
>  board/samsung/smdk5420/smdk5420.c          |   15 +-
>  board/samsung/smdkc100/smdkc100.c          |    5 +-
>  board/samsung/smdkv310/smdkv310.c          |   17 +-
>  board/samsung/trats/trats.c                |   39 +-
>  board/samsung/trats2/trats2.c              |   74 +-
>  board/samsung/universal_c210/universal.c   |   51 +-
>  drivers/gpio/s5p_gpio.c                    |  198 +++-
>  19 files changed, 2883 insertions(+), 887 deletions(-)
> 
> diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c
> index 9edb475..9e26340 100644
> --- a/arch/arm/cpu/armv7/exynos/pinmux.c
> +++ b/arch/arm/cpu/armv7/exynos/pinmux.c
> @@ -197,19 +172,19 @@ static int exynos5420_mmc_config(int peripheral, int flags)
>  		 * this same assumption.
>  		 */
>  		if ((peripheral == PERIPH_ID_SDMMC0) && (i == 2)) {

Should be.. (i == start + 2)??

> -			s5p_gpio_set_value(bank, i, 1);
> -			s5p_gpio_cfg_pin(bank, i, GPIO_OUTPUT);
> +			gpio_set_value(i, 1);
> +			gpio_cfg_pin(i, S5P_GPIO_OUTPUT);
>  		} else {
> -			s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
> +			gpio_cfg_pin(i, S5P_GPIO_FUNC(0x2));
>  		}
> -		s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
> -		s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
> +		gpio_set_pull(i, S5P_GPIO_PULL_NONE);
> +		gpio_set_drv(i, S5P_GPIO_DRV_4X);
>  	}
>  
> -	for (i = 3; i <= 6; i++) {
> -		s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
> -		s5p_gpio_set_pull(bank, i, GPIO_PULL_UP);
> -		s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
> +	for (i = (start + 3); i <= (start + 6); i++) {
> +		gpio_cfg_pin(i, S5P_GPIO_FUNC(0x2));
> +		gpio_set_pull(i, S5P_GPIO_PULL_UP);
> +		gpio_set_drv(i, S5P_GPIO_DRV_4X);
>  	}
>  
>  	return 0;
> diff --git a/arch/arm/include/asm/arch-exynos/gpio.h b/arch/arm/include/asm/arch-exynos/gpio.h
> index d6868fa..c49be8b 100644
> --- a/arch/arm/include/asm/arch-exynos/gpio.h
> +++ b/arch/arm/include/asm/arch-exynos/gpio.h
> -/* functions */
> -void s5p_gpio_cfg_pin(struct s5p_gpio_bank *bank, int gpio, int cfg);
> -void s5p_gpio_direction_output(struct s5p_gpio_bank *bank, int gpio, int en);
> -void s5p_gpio_direction_input(struct s5p_gpio_bank *bank, int gpio);
> -void s5p_gpio_set_value(struct s5p_gpio_bank *bank, int gpio, int en);
> -unsigned int s5p_gpio_get_value(struct s5p_gpio_bank *bank, int gpio);
> -void s5p_gpio_set_pull(struct s5p_gpio_bank *bank, int gpio, int mode);
> -void s5p_gpio_set_drv(struct s5p_gpio_bank *bank, int gpio, int mode);
> -void s5p_gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode);
> +static inline struct gpio_info *get_gpio_data(void)
> +{
> +	if (cpu_is_exynos5()) {
> +		if (proid_is_exynos5420())
> +			return exynos5420_gpio_data;
> +		else
> +			return exynos5_gpio_data;
> +	} else if (cpu_is_exynos4()) {
> +		if (proid_is_exynos4412())
> +			return exynos4x12_gpio_data;
> +		else
> +			return exynos4_gpio_data;
> +	} else {
> +		return NULL;
> +	}

else does not needed.
just return NULL;

> +}
>  
> -/* GPIO pins per bank  */
> -#define GPIO_PER_BANK 8
> -#define S5P_GPIO_PART_SHIFT	(24)
> -#define S5P_GPIO_PART_MASK	(0xff)
> -#define S5P_GPIO_BANK_SHIFT	(8)
> -#define S5P_GPIO_BANK_MASK	(0xffff)
> -#define S5P_GPIO_PIN_MASK	(0xff)
> -
> -#define S5P_GPIO_SET_PART(x) \
> -			(((x) & S5P_GPIO_PART_MASK) << S5P_GPIO_PART_SHIFT)
> -
> -#define S5P_GPIO_GET_PART(x) \
> -			(((x) >> S5P_GPIO_PART_SHIFT) & S5P_GPIO_PART_MASK)
> -
> -#define S5P_GPIO_SET_PIN(x) \
> -			((x) & S5P_GPIO_PIN_MASK)
> -
> -#define EXYNOS4_GPIO_SET_BANK(part, bank) \
> -			((((unsigned)&(((struct exynos4_gpio_part##part *) \
> -			EXYNOS4_GPIO_PART##part##_BASE)->bank) \
> -			- EXYNOS4_GPIO_PART##part##_BASE) \
> -			& S5P_GPIO_BANK_MASK) << S5P_GPIO_BANK_SHIFT)
> -
> -#define EXYNOS4X12_GPIO_SET_BANK(part, bank) \
> -			((((unsigned)&(((struct exynos4x12_gpio_part##part *) \
> -			EXYNOS4X12_GPIO_PART##part##_BASE)->bank) \
> -			- EXYNOS4X12_GPIO_PART##part##_BASE) \
> -			& S5P_GPIO_BANK_MASK) << S5P_GPIO_BANK_SHIFT)
> -
> -#define EXYNOS5_GPIO_SET_BANK(part, bank) \
> -			((((unsigned)&(((struct exynos5420_gpio_part##part *) \
> -			EXYNOS5420_GPIO_PART##part##_BASE)->bank) \
> -			- EXYNOS5_GPIO_PART##part##_BASE) \
> -			& S5P_GPIO_BANK_MASK) << S5P_GPIO_BANK_SHIFT)
> -
> -#define EXYNOS5420_GPIO_SET_BANK(part, bank) \
> -			((((unsigned)&(((struct exynos5420_gpio_part##part *) \
> -			EXYNOS5420_GPIO_PART##part##_BASE)->bank) \
> -			- EXYNOS5420_GPIO_PART##part##_BASE) \
> -			& S5P_GPIO_BANK_MASK) << S5P_GPIO_BANK_SHIFT)
> -
> -#define exynos4_gpio_get(part, bank, pin) \
> -			(S5P_GPIO_SET_PART(part) | \
> -			EXYNOS4_GPIO_SET_BANK(part, bank) | \
> -			S5P_GPIO_SET_PIN(pin))
> -
> -#define exynos4x12_gpio_get(part, bank, pin) \
> -			(S5P_GPIO_SET_PART(part) | \
> -			EXYNOS4X12_GPIO_SET_BANK(part, bank) | \
> -			S5P_GPIO_SET_PIN(pin))
> -
> -#define exynos5420_gpio_get(part, bank, pin) \
> -			(S5P_GPIO_SET_PART(part) | \
> -			EXYNOS5420_GPIO_SET_BANK(part, bank) | \
> -			S5P_GPIO_SET_PIN(pin))
> -
> -#define exynos5_gpio_get(part, bank, pin) \
> -			(S5P_GPIO_SET_PART(part) | \
> -			EXYNOS5_GPIO_SET_BANK(part, bank) | \
> -			S5P_GPIO_SET_PIN(pin))
> -
> -static inline unsigned int s5p_gpio_base(int gpio)
> +static inline unsigned int get_bank_num(void)
>  {
> -	unsigned gpio_part = S5P_GPIO_GET_PART(gpio);
> -
> -	switch (gpio_part) {
> -	case 1:
> -		return samsung_get_base_gpio_part1();
> -	case 2:
> -		return samsung_get_base_gpio_part2();
> -	case 3:
> -		return samsung_get_base_gpio_part3();
> -	case 4:
> -		return samsung_get_base_gpio_part4();
> -	default:
> +	if (cpu_is_exynos5()) {
> +		if (proid_is_exynos5420())
> +			return EXYNOS5420_GPIO_NUM_PARTS;
> +		else
> +			return EXYNOS5_GPIO_NUM_PARTS;
> +	} else if (cpu_is_exynos4()) {
> +		if (proid_is_exynos4412())
> +			return EXYNOS4X12_GPIO_NUM_PARTS;
> +		else
> +			return EXYNOS4_GPIO_NUM_PARTS;
> +	} else {
>  		return 0;
>  	}

ditto.
return 0;

>  }
> diff --git a/arch/arm/include/asm/arch-s5pc1xx/gpio.h b/arch/arm/include/asm/arch-s5pc1xx/gpio.h
> index da8df74..74e9b5a 100644
> --- a/arch/arm/include/asm/arch-s5pc1xx/gpio.h
> +++ b/arch/arm/include/asm/arch-s5pc1xx/gpio.h
> -#define S5P_GPIO_SET_PIN(x) \
> -			((x) & S5P_GPIO_PIN_MASK)
> +static inline struct gpio_info *get_gpio_data(void)
> +{
> +	if (cpu_is_s5pc100())
> +		return s5pc100_gpio_data;
> +	else if (cpu_is_s5pc110())
> +		return s5pc110_gpio_data;
> +	else
> +		return NULL;

ditto.

> +}
>  
> -#define S5PC100_SET_BANK(bank) \
> -			(((unsigned)&(((struct s5pc100_gpio *) \
> -			S5PC100_GPIO_BASE)->bank) - S5PC100_GPIO_BASE) \
> -			& S5P_GPIO_BANK_MASK) << S5P_GPIO_BANK_SHIFT)
> +static inline unsigned int get_bank_num(void)
> +{
> +	if (cpu_is_s5pc100())
> +		return S5PC100_GPIO_NUM_PARTS;
> +	else if (cpu_is_s5pc110())
> +		return S5PC110_GPIO_NUM_PARTS;
> +	else
> +		return 0;

ditto.

> +}
>  
> -#define S5PC110_SET_BANK(bank) \
> -			((((unsigned)&(((struct s5pc110_gpio *) \
> -			S5PC110_GPIO_BASE)->bank) - S5PC110_GPIO_BASE) \
> -			& S5P_GPIO_BANK_MASK) << S5P_GPIO_BANK_SHIFT)
> diff --git a/board/samsung/goni/goni.c b/board/samsung/goni/goni.c
> index 61b9ece..60bb998 100644
> --- a/board/samsung/goni/goni.c
> +++ b/board/samsung/goni/goni.c
> @@ -17,8 +17,6 @@
>  
>  DECLARE_GLOBAL_DATA_PTR;
>  
> -static struct s5pc110_gpio *s5pc110_gpio;
> -
>  u32 get_board_rev(void)
>  {
>  	return 0;
> @@ -27,8 +25,6 @@ u32 get_board_rev(void)
>  int board_init(void)
>  {
>  	/* Set Initial global variables */
> -	s5pc110_gpio = (struct s5pc110_gpio *)S5PC110_GPIO_BASE;
> -
>  	gd->bd->bi_arch_number = MACH_TYPE_GONI;
>  	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
>  
> @@ -82,7 +78,7 @@ int board_mmc_init(bd_t *bis)
>  	int i, ret, ret_sd = 0;
>  
>  	/* MASSMEMORY_EN: XMSMDATA7: GPJ2[7] output high */
> -	s5p_gpio_direction_output(&s5pc110_gpio->j2, 7, 1);
> +	gpio_direction_output(S5PC110_GPIO_J27, 1);
>  
>  	/*
>  	 * MMC0 GPIO
> @@ -91,15 +87,15 @@ int board_mmc_init(bd_t *bis)
>  	 * GPG0[2]	SD_0_CDn	-> Not used
>  	 * GPG0[3:6]	SD_0_DATA[0:3]
>  	 */
> -	for (i = 0; i < 7; i++) {
> +	for (i = S5PC110_GPIO_G00; i < S5PC110_GPIO_G07; i++) {
>  		if (i == 2)

if (i == S5PC110_GPIO_G02)

>  			continue;
>  		/* GPG0[0:6] special function 2 */
> -		s5p_gpio_cfg_pin(&s5pc110_gpio->g0, i, 0x2);
> +		gpio_cfg_pin(i, 0x2);
>  		/* GPG0[0:6] pull disable */
> -		s5p_gpio_set_pull(&s5pc110_gpio->g0, i, GPIO_PULL_NONE);
> +		gpio_set_pull(i, S5P_GPIO_PULL_NONE);
>  		/* GPG0[0:6] drv 4x */
> -		s5p_gpio_set_drv(&s5pc110_gpio->g0, i, GPIO_DRV_4X);
> +		gpio_set_drv(i, S5P_GPIO_DRV_4X);
>  	}
>  
>  	ret = s5p_mmc_init(0, 4);
> @@ -110,20 +106,20 @@ int board_mmc_init(bd_t *bis)
>  	 * SD card (T_FLASH) detect and init
>  	 * T_FLASH_DETECT: EINT28: GPH3[4] input mode
>  	 */
> -	s5p_gpio_cfg_pin(&s5pc110_gpio->h3, 4, GPIO_INPUT);
> -	s5p_gpio_set_pull(&s5pc110_gpio->h3, 4, GPIO_PULL_UP);
> +	gpio_cfg_pin(S5PC110_GPIO_H34, S5P_GPIO_INPUT);
> +	gpio_set_pull(S5PC110_GPIO_H34, S5P_GPIO_PULL_UP);
>  
> -	if (!s5p_gpio_get_value(&s5pc110_gpio->h3, 4)) {
> +	if (!gpio_get_value(S5PC110_GPIO_H34)) {
>  		for (i = 0; i < 7; i++) {

for (i = S5PC110_GPIO_G20; i < S5PC110_GPIO_G27; i++)

>  			if (i == 2)

i == S5PC110_GPIO_G22

>  				continue;
>  
>  			/* GPG2[0:6] special function 2 */
> -			s5p_gpio_cfg_pin(&s5pc110_gpio->g2, i, 0x2);
> +			gpio_cfg_pin(S5PC110_GPIO_G20 + i, 0x2);
>  			/* GPG2[0:6] pull disable */
> -			s5p_gpio_set_pull(&s5pc110_gpio->g2, i, GPIO_PULL_NONE);
> +			gpio_set_pull(S5PC110_GPIO_G20 + i, S5P_GPIO_PULL_NONE);
>  			/* GPG2[0:6] drv 4x */
> -			s5p_gpio_set_drv(&s5pc110_gpio->g2, i, GPIO_DRV_4X);
> +			gpio_set_drv(S5PC110_GPIO_G20 + i, S5P_GPIO_DRV_4X);
>  		}
>  
>  		ret_sd = s5p_mmc_init(2, 4);
> diff --git a/board/samsung/smdkv310/smdkv310.c b/board/samsung/smdkv310/smdkv310.c
> index 81a3060..416d0ea 100644
> --- a/board/samsung/smdkv310/smdkv310.c
> +++ b/board/samsung/smdkv310/smdkv310.c
> @@ -15,15 +15,13 @@
>  #include <asm/arch/sromc.h>
>  
>  DECLARE_GLOBAL_DATA_PTR;
> -struct exynos4_gpio_part1 *gpio1;
> -struct exynos4_gpio_part2 *gpio2;
>  
>  static void smc9115_pre_init(void)
>  {
>  	u32 smc_bw_conf, smc_bc_conf;
>  
>  	/* gpio configuration GPK0CON */
> -	s5p_gpio_cfg_pin(&gpio2->y0, CONFIG_ENV_SROM_BANK, GPIO_FUNC(2));
> +	gpio_cfg_pin(EXYNOS4_GPIO_Y00 + CONFIG_ENV_SROM_BANK, S5P_GPIO_FUNC(2));
>  
>  	/* Ethernet needs bus width of 16 bits */
>  	smc_bw_conf = SROMC_DATA16_WIDTH(CONFIG_ENV_SROM_BANK);
> @@ -38,9 +36,6 @@ static void smc9115_pre_init(void)
>  
>  int board_init(void)
>  {
> -	gpio1 = (struct exynos4_gpio_part1 *) EXYNOS4_GPIO_PART1_BASE;
> -	gpio2 = (struct exynos4_gpio_part2 *) EXYNOS4_GPIO_PART2_BASE;
> -
>  	smc9115_pre_init();
>  
>  	gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL);
> @@ -103,21 +98,21 @@ int board_mmc_init(bd_t *bis)
>  	 * GPK2[2]	SD_2_CDn
>  	 * GPK2[3:6]	SD_2_DATA[0:3](2)
>  	 */
> -	for (i = 0; i < 7; i++) {
> +	for (i = EXYNOS4_GPIO_K20; i < EXYNOS4_GPIO_K27; i++) {
>  		/* GPK2[0:6] special function 2 */
> -		s5p_gpio_cfg_pin(&gpio2->k2, i, GPIO_FUNC(0x2));
> +		gpio_cfg_pin(i, S5P_GPIO_FUNC(0x2));
>  
>  		/* GPK2[0:6] drv 4x */
> -		s5p_gpio_set_drv(&gpio2->k2, i, GPIO_DRV_4X);
> +		gpio_set_drv(i, S5P_GPIO_DRV_4X);
>  
>  		/* GPK2[0:1] pull disable */
>  		if (i == 0 || i == 1) {

(i == EXYNOS4_GPIO_K20 || i == EXYNOS4_GPIO_K21)

> -			s5p_gpio_set_pull(&gpio2->k2, i, GPIO_PULL_NONE);
> +			gpio_set_pull(i, S5P_GPIO_PULL_NONE);
>  			continue;
>  		}
>  
>  		/* GPK2[2:6] pull up */
> -		s5p_gpio_set_pull(&gpio2->k2, i, GPIO_PULL_UP);
> +		gpio_set_pull(i, S5P_GPIO_PULL_UP);
>  	}
>  	err = s5p_mmc_init(2, 4);
>  	return err;
> diff --git a/board/samsung/universal_c210/universal.c b/board/samsung/universal_c210/universal.c
> index f9d71b6..9a2bd45 100644
> --- a/board/samsung/universal_c210/universal.c
> +++ b/board/samsung/universal_c210/universal.c
> @@ -27,8 +27,6 @@
>  
>  DECLARE_GLOBAL_DATA_PTR;
>  
> -struct exynos4_gpio_part1 *gpio1;
> -struct exynos4_gpio_part2 *gpio2;
>  unsigned int board_rev;
>  
>  u32 get_board_rev(void)
> @@ -312,35 +310,35 @@ void exynos_cfg_lcd_gpio(void)
>  
>  	for (i = 0; i < 8; i++) {
>  		/* set GPF0,1,2[0:7] for RGB Interface and Data lines (32bit) */
> -		s5p_gpio_cfg_pin(&gpio1->f0, i, GPIO_FUNC(2));
> -		s5p_gpio_cfg_pin(&gpio1->f1, i, GPIO_FUNC(2));
> -		s5p_gpio_cfg_pin(&gpio1->f2, i, GPIO_FUNC(2));
> +		gpio_cfg_pin(EXYNOS4_GPIO_F00 + i, S5P_GPIO_FUNC(2));
> +		gpio_cfg_pin(EXYNOS4_GPIO_F10 + i, S5P_GPIO_FUNC(2));
> +		gpio_cfg_pin(EXYNOS4_GPIO_F20 + i, S5P_GPIO_FUNC(2));
>  		/* pull-up/down disable */
> -		s5p_gpio_set_pull(&gpio1->f0, i, GPIO_PULL_NONE);
> -		s5p_gpio_set_pull(&gpio1->f1, i, GPIO_PULL_NONE);
> -		s5p_gpio_set_pull(&gpio1->f2, i, GPIO_PULL_NONE);
> +		gpio_set_pull(EXYNOS4_GPIO_F00 + i, S5P_GPIO_PULL_NONE);
> +		gpio_set_pull(EXYNOS4_GPIO_F10 + i, S5P_GPIO_PULL_NONE);
> +		gpio_set_pull(EXYNOS4_GPIO_F20 + i, S5P_GPIO_PULL_NONE);
>  
>  		/* drive strength to max (24bit) */
> -		s5p_gpio_set_drv(&gpio1->f0, i, GPIO_DRV_4X);
> -		s5p_gpio_set_rate(&gpio1->f0, i, GPIO_DRV_SLOW);
> -		s5p_gpio_set_drv(&gpio1->f1, i, GPIO_DRV_4X);
> -		s5p_gpio_set_rate(&gpio1->f1, i, GPIO_DRV_SLOW);
> -		s5p_gpio_set_drv(&gpio1->f2, i, GPIO_DRV_4X);
> -		s5p_gpio_set_rate(&gpio1->f0, i, GPIO_DRV_SLOW);
> +		gpio_set_drv(EXYNOS4_GPIO_F00 + i, S5P_GPIO_DRV_4X);
> +		gpio_set_rate(EXYNOS4_GPIO_F00 + i, S5P_GPIO_DRV_SLOW);
> +		gpio_set_drv(EXYNOS4_GPIO_F10 + i, S5P_GPIO_DRV_4X);
> +		gpio_set_rate(EXYNOS4_GPIO_F10 + i, S5P_GPIO_DRV_SLOW);
> +		gpio_set_drv(EXYNOS4_GPIO_F20 + i, S5P_GPIO_DRV_4X);
> +		gpio_set_rate(EXYNOS4_GPIO_F00 + i, S5P_GPIO_DRV_SLOW);
>  	}
>  
> -	for (i = 0; i < f3_end; i++) {
> +	for (i = EXYNOS4_GPIO_F30; i < (EXYNOS4_GPIO_F30 + f3_end); i++) {
>  		/* set GPF3[0:3] for RGB Interface and Data lines (32bit) */
> -		s5p_gpio_cfg_pin(&gpio1->f3, i, GPIO_FUNC(2));
> +		gpio_cfg_pin(i, S5P_GPIO_FUNC(2));
>  		/* pull-up/down disable */
> -		s5p_gpio_set_pull(&gpio1->f3, i, GPIO_PULL_NONE);
> +		gpio_set_pull(i, S5P_GPIO_PULL_NONE);
>  		/* drive strength to max (24bit) */
> -		s5p_gpio_set_drv(&gpio1->f3, i, GPIO_DRV_4X);
> -		s5p_gpio_set_rate(&gpio1->f3, i, GPIO_DRV_SLOW);
> +

missing set the drv?

> +		gpio_set_rate(i, S5P_GPIO_DRV_SLOW);
>  	}
>  
>  	/* gpio pad configuration for LCD reset. */
> -	s5p_gpio_cfg_pin(&gpio2->y4, 5, GPIO_OUTPUT);
> +	gpio_cfg_pin(EXYNOS4_GPIO_Y45, S5P_GPIO_OUTPUT);
>  
>  	spi_init();
>  } 
> diff --git a/drivers/gpio/s5p_gpio.c b/drivers/gpio/s5p_gpio.c
> index 11a0472..49e99cb 100644
> --- a/drivers/gpio/s5p_gpio.c
> +++ b/drivers/gpio/s5p_gpio.c
> @@ -8,11 +8,9 @@
>  #include <common.h>
>  #include <asm/io.h>
>  #include <asm/gpio.h>
> +#include <asm/arch/gpio.h>
>  
> -#define S5P_GPIO_GET_BANK(x)	((x >> S5P_GPIO_BANK_SHIFT) \
> -				& S5P_GPIO_BANK_MASK)
> -
> -#define S5P_GPIO_GET_PIN(x)	(x & S5P_GPIO_PIN_MASK)
> +#define S5P_GPIO_GET_PIN(x)	(x % GPIO_PER_BANK)
>  
>  #define CON_MASK(x)		(0xf << ((x) << 2))
>  #define CON_SFR(x, v)		((v) << ((x) << 2))
> @@ -28,7 +26,100 @@
>  #define RATE_MASK(x)		(0x1 << (x + 16))
>  #define RATE_SET(x)		(0x1 << (x + 16))
>  
> -void s5p_gpio_cfg_pin(struct s5p_gpio_bank *bank, int gpio, int cfg)
> +#define name_to_gpio(n) s5p_name_to_gpio(n)
> +static inline int s5p_name_to_gpio(const char *name)
> +{
> +	unsigned num, irregular_set_number, irregular_bank_base;
> +	const struct gpio_name_num_table *tabp;
> +	char this_bank, bank_name, irregular_bank_name;
> +	char *endp;
> +
> +	/*
> +	 * The gpio name starts with either 'g' ot 'gp' followed by the bank
> +	 * name character. Skip one or two characters depending on the prefix.
> +	 */

so, why don't you check name[0]?

> +	if (name[1] == 'p')
> +		name += 2;
> +	else
> +		name++;
> +	bank_name = *name++;

I think you should check the address (the name) before you access.

> +	if (!*name)
> +		return -1; /* At least one digit is required/expected. */
> +
> +	/*
> +	 * On both exynos5 and exynos5420 architectures there is a bank of
> +	 * GPIOs which does not fall into the regular address pattern. Those
> +	 * banks are c4 on Exynos5 and y7 on Exynos5420. The rest of the below
> +	 * assignments help to handle these irregularities.
> +	 */
> +#if defined(CONFIG_EXYNOS4) || defined(CONFIG_EXYNOS5)
> +	if (cpu_is_exynos5()) {
> +		if (proid_is_exynos5420()) {
> +			tabp = exynos5420_gpio_table;
> +			irregular_bank_name = 'y';
> +			irregular_set_number = '7';
> +			irregular_bank_base = EXYNOS5420_GPIO_Y70;
> +		} else {
> +			tabp = exynos5_gpio_table;
> +			irregular_bank_name = 'c';
> +			irregular_set_number = '4';
> +			irregular_bank_base = EXYNOS5_GPIO_C40;
> +		}
> +	} else {
> +		if (proid_is_exynos4412())
> +			tabp = exynos4x12_gpio_table;
> +		else
> +			tabp = exynos4_gpio_table;
> +		irregular_bank_name = 0;
> +		irregular_set_number = 0;
> +		irregular_bank_base = 0;
> +	}
> +#else
> +	if (cpu_is_s5pc110())
> +		tabp = s5pc110_gpio_table;
> +	else
> +		tabp = s5pc100_gpio_table;
> +	irregular_bank_name = 0;
> +	irregular_set_number = 0;
> +	irregular_bank_base = 0;
> +#endif
> +
> +	this_bank = tabp->bank;
> +	do {
> +		if (bank_name == this_bank) {
> +			unsigned pin_index; /* pin number within the bank */
> +			if ((bank_name == irregular_bank_name) &&
> +			    (name[0] == irregular_set_number)) {
> +				pin_index = name[1] - '0';
> +				/* Irregular sets have 8 pins. */
> +				if (pin_index >= GPIO_PER_BANK)
> +					return -1;
> +				num = irregular_bank_base + pin_index;
> +			} else {
> +				pin_index = simple_strtoul(name, &endp, 8);
> +				pin_index -= tabp->bank_offset;
> +				/*
> +				 * Sanity check: bunk 'z' has no set number,
> +				 * for all other banks there must be exactly
> +				 * two octal digits, and the resulting number
> +				 * should not exceed the number of pins in the
> +				 * bank.
> +				 */
> +				if (((bank_name != 'z') && !name[1]) ||
> +				    *endp ||
> +				    (pin_index >= tabp->bank_size))
> +					return -1;
> +				num = tabp->base + pin_index;
> +			}
> +			return num;
> +		}
> +		this_bank = (++tabp)->bank;
> +	} while (this_bank);
> +
> +	return -1;
> +}
> +
> +static void s5p_gpio_cfg_pin(struct s5p_gpio_bank *bank, int gpio, int cfg)
>  {
>  	unsigned int value;
>  
> @@ -38,18 +129,7 @@ void s5p_gpio_cfg_pin(struct s5p_gpio_bank *bank, int gpio, int cfg)
>  	writel(value, &bank->con);
>  }
>  
> -void s5p_gpio_direction_output(struct s5p_gpio_bank *bank, int gpio, int en)
> -{
> -	s5p_gpio_cfg_pin(bank, gpio, GPIO_OUTPUT);
> -	s5p_gpio_set_value(bank, gpio, en);
> -}
> -
> -void s5p_gpio_direction_input(struct s5p_gpio_bank *bank, int gpio)
> -{
> -	s5p_gpio_cfg_pin(bank, gpio, GPIO_INPUT);
> -}
> -
> -void s5p_gpio_set_value(struct s5p_gpio_bank *bank, int gpio, int en)
> +static void s5p_gpio_set_value(struct s5p_gpio_bank *bank, int gpio, int en)
>  {
>  	unsigned int value;
>  
> @@ -60,7 +140,19 @@ void s5p_gpio_set_value(struct s5p_gpio_bank *bank, int gpio, int en)
>  	writel(value, &bank->dat);
>  }
>  
> -unsigned int s5p_gpio_get_value(struct s5p_gpio_bank *bank, int gpio)
> +static void s5p_gpio_direction_output(struct s5p_gpio_bank *bank,
> +				      int gpio, int en)
> +{
> +	s5p_gpio_cfg_pin(bank, gpio, S5P_GPIO_OUTPUT);
> +	s5p_gpio_set_value(bank, gpio, en);
> +}
> +
> +static void s5p_gpio_direction_input(struct s5p_gpio_bank *bank, int gpio)
> +{
> +	s5p_gpio_cfg_pin(bank, gpio, S5P_GPIO_INPUT);
> +}
> +
> +static unsigned int s5p_gpio_get_value(struct s5p_gpio_bank *bank, int gpio)
>  {
>  	unsigned int value;
>  
> @@ -68,7 +160,7 @@ unsigned int s5p_gpio_get_value(struct s5p_gpio_bank *bank, int gpio)
>  	return !!(value & DAT_MASK(gpio));
>  }
>  
> -void s5p_gpio_set_pull(struct s5p_gpio_bank *bank, int gpio, int mode)
> +static void s5p_gpio_set_pull(struct s5p_gpio_bank *bank, int gpio, int mode)
>  {
>  	unsigned int value;
>  
> @@ -76,8 +168,8 @@ void s5p_gpio_set_pull(struct s5p_gpio_bank *bank, int gpio, int mode)
>  	value &= ~PULL_MASK(gpio);
>  
>  	switch (mode) {
> -	case GPIO_PULL_DOWN:
> -	case GPIO_PULL_UP:
> +	case S5P_GPIO_PULL_DOWN:
> +	case S5P_GPIO_PULL_UP:
>  		value |= PULL_MODE(gpio, mode);
>  		break;
>  	default:
> @@ -87,7 +179,7 @@ void s5p_gpio_set_pull(struct s5p_gpio_bank *bank, int gpio, int mode)
>  	writel(value, &bank->pull);
>  }
>  
> -void s5p_gpio_set_drv(struct s5p_gpio_bank *bank, int gpio, int mode)
> +static void s5p_gpio_set_drv(struct s5p_gpio_bank *bank, int gpio, int mode)
>  {
>  	unsigned int value;
>  
> @@ -95,10 +187,10 @@ void s5p_gpio_set_drv(struct s5p_gpio_bank *bank, int gpio, int mode)
>  	value &= ~DRV_MASK(gpio);
>  
>  	switch (mode) {
> -	case GPIO_DRV_1X:
> -	case GPIO_DRV_2X:
> -	case GPIO_DRV_3X:
> -	case GPIO_DRV_4X:
> +	case S5P_GPIO_DRV_1X:
> +	case S5P_GPIO_DRV_2X:
> +	case S5P_GPIO_DRV_3X:
> +	case S5P_GPIO_DRV_4X:
>  		value |= DRV_SET(gpio, mode);
>  		break;
>  	default:
> @@ -108,7 +200,7 @@ void s5p_gpio_set_drv(struct s5p_gpio_bank *bank, int gpio, int mode)
>  	writel(value, &bank->drv);
>  }
>  
> -void s5p_gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode)
> +static void s5p_gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode)
>  {
>  	unsigned int value;
>  
> @@ -116,8 +208,8 @@ void s5p_gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode)
>  	value &= ~RATE_MASK(gpio);
>  
>  	switch (mode) {
> -	case GPIO_DRV_FAST:
> -	case GPIO_DRV_SLOW:
> +	case S5P_GPIO_DRV_FAST:
> +	case S5P_GPIO_DRV_SLOW:
>  		value |= RATE_SET(gpio);
>  		break;
>  	default:
> @@ -127,12 +219,26 @@ void s5p_gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode)
>  	writel(value, &bank->drv);
>  }
>  
> -struct s5p_gpio_bank *s5p_gpio_get_bank(unsigned gpio)
> +struct s5p_gpio_bank *s5p_gpio_get_bank(unsigned int gpio)
>  {
> -	unsigned bank = S5P_GPIO_GET_BANK(gpio);
> -	unsigned base = s5p_gpio_base(gpio);
> -
> -	return (struct s5p_gpio_bank *)(base + bank);
> +	const struct gpio_info *data;
> +	unsigned int upto;
> +	int i, count;
> +
> +	data = get_gpio_data();
> +	count = get_bank_num();
> +	for (i = upto = 0; i < count;
> +			i++, upto = data->max_gpio, data++) {

Could you please move upto = 0,  upto = data->max_gpio, data++ to somewhere for code readability?
please make simple for statement.
for (i = upto; i <count; i++)

> +		debug("i=%d, upto=%d\n", i, upto);
> +		if (gpio < data->max_gpio) {
> +			struct s5p_gpio_bank *bank;
> +			bank = (struct s5p_gpio_bank *)data->reg_addr;
> +			bank += (gpio - upto) / GPIO_PER_BANK;
> +			debug("gpio=%d, bank=%p\n", gpio, bank);
> +			return bank;
> +		}
> +	}
> +	return NULL;
>  }
>  
>  int s5p_gpio_get_pin(unsigned gpio)
> @@ -179,3 +285,27 @@ int gpio_set_value(unsigned gpio, int value)
>  
>  	return 0;
>  }
> +
> +void gpio_set_pull(int gpio, int mode)
> +{
> +	s5p_gpio_set_pull(s5p_gpio_get_bank(gpio),
> +			  s5p_gpio_get_pin(gpio), mode);
> +}
> +
> +void gpio_set_drv(int gpio, int mode)
> +{
> +	s5p_gpio_set_drv(s5p_gpio_get_bank(gpio),
> +			 s5p_gpio_get_pin(gpio), mode);
> +}
> +
> +void gpio_cfg_pin(int gpio, int cfg)
> +{
> +	s5p_gpio_cfg_pin(s5p_gpio_get_bank(gpio),
> +			 s5p_gpio_get_pin(gpio), cfg);
> +}
> +
> +void gpio_set_rate(int gpio, int mode)
> +{
> +	s5p_gpio_set_rate(s5p_gpio_get_bank(gpio),
> +			  s5p_gpio_get_pin(gpio), mode);
> +}
> 

Thanks,
Minkyu Kang.


More information about the U-Boot mailing list