diff mbox

[U-Boot,v4,3/4] ARMV7: Exynos4: Fix toolchain optimization problem for using volatile

Message ID 1326699725-22049-4-git-send-email-riverful.kim@samsung.com
State Rejected
Delegated to: Minkyu Kang
Headers show

Commit Message

HeungJun, Kim Jan. 16, 2012, 7:42 a.m. UTC
Because of wrong disassembled codes from C by the optimization of toolchain,
it occurs a problem that wrong register is read if the functions were called
in the asm code.

This patch uses keyword "volatile" for fixing it for sure. And, it is inserted
only when the function is extern in the driver/gpio/s5p_gpio.c

It was founded while testing TRATS board & completed tests on the TRATS board.

Signed-off-by: HeungJun, Kim <riverful.kim@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
Changes for v4:
   - Created

 arch/arm/include/asm/arch-exynos/gpio.h |   22 ++++++++++------
 drivers/gpio/s5p_gpio.c                 |   42 +++++++++++++++++-------------
 2 files changed, 38 insertions(+), 26 deletions(-)
diff mbox

Patch

diff --git a/arch/arm/include/asm/arch-exynos/gpio.h b/arch/arm/include/asm/arch-exynos/gpio.h
index 9863a12..2fb2a0b 100644
--- a/arch/arm/include/asm/arch-exynos/gpio.h
+++ b/arch/arm/include/asm/arch-exynos/gpio.h
@@ -80,14 +80,20 @@  struct exynos4_gpio_part3 {
 };
 
 /* 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);
+void s5p_gpio_cfg_pin(struct s5p_gpio_bank *bank,
+			volatile int gpio, volatile int cfg);
+void s5p_gpio_direction_output(struct s5p_gpio_bank *bank,
+			volatile int gpio, volatile int en);
+void s5p_gpio_direction_input(struct s5p_gpio_bank *bank, volatile int gpio);
+void s5p_gpio_set_value(struct s5p_gpio_bank *bank,
+			volatile int gpio, volatile int en);
+unsigned int s5p_gpio_get_value(struct s5p_gpio_bank *bank, volatile int gpio);
+void s5p_gpio_set_pull(struct s5p_gpio_bank *bank,
+			volatile int gpio, volatile int mode);
+void s5p_gpio_set_drv(struct s5p_gpio_bank *bank,
+			volatile int gpio, volatile int mode);
+void s5p_gpio_set_rate(struct s5p_gpio_bank *bank,
+			volatile int gpio, volatile int mode);
 
 /* GPIO pins per bank  */
 #define GPIO_PER_BANK 8
diff --git a/drivers/gpio/s5p_gpio.c b/drivers/gpio/s5p_gpio.c
index 1edf9a2..edc3511 100644
--- a/drivers/gpio/s5p_gpio.c
+++ b/drivers/gpio/s5p_gpio.c
@@ -36,9 +36,10 @@ 
 #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)
+void s5p_gpio_cfg_pin(struct s5p_gpio_bank *bank,
+		      volatile int gpio, volatile int cfg)
 {
-	unsigned int value;
+	volatile unsigned int value;
 
 	value = readl(&bank->con);
 	value &= ~CON_MASK(gpio);
@@ -46,9 +47,10 @@  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)
+void s5p_gpio_direction_output(struct s5p_gpio_bank *bank,
+			       volatile int gpio, volatile int en)
 {
-	unsigned int value;
+	volatile unsigned int value;
 
 	s5p_gpio_cfg_pin(bank, gpio, GPIO_OUTPUT);
 
@@ -59,14 +61,15 @@  void s5p_gpio_direction_output(struct s5p_gpio_bank *bank, int gpio, int en)
 	writel(value, &bank->dat);
 }
 
-void s5p_gpio_direction_input(struct s5p_gpio_bank *bank, int gpio)
+void s5p_gpio_direction_input(struct s5p_gpio_bank *bank, volatile int gpio)
 {
 	s5p_gpio_cfg_pin(bank, gpio, GPIO_INPUT);
 }
 
-void s5p_gpio_set_value(struct s5p_gpio_bank *bank, int gpio, int en)
+void s5p_gpio_set_value(struct s5p_gpio_bank *bank,
+			volatile int gpio, volatile int en)
 {
-	unsigned int value;
+	volatile unsigned int value;
 
 	value = readl(&bank->dat);
 	value &= ~DAT_MASK(gpio);
@@ -75,17 +78,18 @@  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)
+unsigned int s5p_gpio_get_value(struct s5p_gpio_bank *bank, volatile int gpio)
 {
-	unsigned int value;
+	volatile unsigned int value;
 
 	value = readl(&bank->dat);
 	return !!(value & DAT_MASK(gpio));
 }
 
-void s5p_gpio_set_pull(struct s5p_gpio_bank *bank, int gpio, int mode)
+void s5p_gpio_set_pull(struct s5p_gpio_bank *bank,
+		       volatile int gpio, volatile int mode)
 {
-	unsigned int value;
+	volatile unsigned int value;
 
 	value = readl(&bank->pull);
 	value &= ~PULL_MASK(gpio);
@@ -102,9 +106,10 @@  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)
+void s5p_gpio_set_drv(struct s5p_gpio_bank *bank,
+		      volatile int gpio, volatile int mode)
 {
-	unsigned int value;
+	volatile unsigned int value;
 
 	value = readl(&bank->drv);
 	value &= ~DRV_MASK(gpio);
@@ -123,9 +128,10 @@  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)
+void s5p_gpio_set_rate(struct s5p_gpio_bank *bank,
+		       volatile int gpio, volatile int mode)
 {
-	unsigned int value;
+	volatile unsigned int value;
 
 	value = readl(&bank->drv);
 	value &= ~RATE_MASK(gpio);
@@ -142,15 +148,15 @@  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(int nr)
+struct s5p_gpio_bank *s5p_gpio_get_bank(volatile int nr)
 {
-	int bank = nr / GPIO_PER_BANK;
+	volatile int bank = nr / GPIO_PER_BANK;
 	bank *= sizeof(struct s5p_gpio_bank);
 
 	return (struct s5p_gpio_bank *) (s5p_gpio_base(nr) + bank);
 }
 
-int s5p_gpio_get_pin(int nr)
+int s5p_gpio_get_pin(volatile int nr)
 {
 	return nr % GPIO_PER_BANK;
 }