diff options
| author | Ben Dooks <ben-linux@fluff.org> | 2010-05-19 03:31:49 -0400 |
|---|---|---|
| committer | Ben Dooks <ben-linux@fluff.org> | 2010-05-20 08:05:40 -0400 |
| commit | 6a399547242df3b12f13d637a95f63eaa82f9385 (patch) | |
| tree | af4ea12f9734f6020d0fd1219d2077ed80cbb20d /arch | |
| parent | 1ae35de1c1ac81f8f31879316656b0a66616a4b0 (diff) | |
ARM: S5P6440: Add locking to GPIO calls
Add the new locking calls to ensure that these are always exclusively
accessing the GPIO registers.
Fixes a possible race between two threads modifying the same GPIO bank,
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/arm/mach-s5p6440/gpio.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/arch/arm/mach-s5p6440/gpio.c b/arch/arm/mach-s5p6440/gpio.c index 262dc75d5bea..92efc05b1ba2 100644 --- a/arch/arm/mach-s5p6440/gpio.c +++ b/arch/arm/mach-s5p6440/gpio.c | |||
| @@ -46,6 +46,7 @@ static int s5p6440_gpiolib_rbank_4bit2_input(struct gpio_chip *chip, | |||
| 46 | void __iomem *base = ourchip->base; | 46 | void __iomem *base = ourchip->base; |
| 47 | void __iomem *regcon = base; | 47 | void __iomem *regcon = base; |
| 48 | unsigned long con; | 48 | unsigned long con; |
| 49 | unsigned long flags; | ||
| 49 | 50 | ||
| 50 | switch (offset) { | 51 | switch (offset) { |
| 51 | case 6: | 52 | case 6: |
| @@ -63,10 +64,14 @@ static int s5p6440_gpiolib_rbank_4bit2_input(struct gpio_chip *chip, | |||
| 63 | break; | 64 | break; |
| 64 | } | 65 | } |
| 65 | 66 | ||
| 67 | s3c_gpio_lock(ourchip, flags); | ||
| 68 | |||
| 66 | con = __raw_readl(regcon); | 69 | con = __raw_readl(regcon); |
| 67 | con &= ~(0xf << con_4bit_shift(offset)); | 70 | con &= ~(0xf << con_4bit_shift(offset)); |
| 68 | __raw_writel(con, regcon); | 71 | __raw_writel(con, regcon); |
| 69 | 72 | ||
| 73 | s3c_gpio_unlock(ourchip, flags); | ||
| 74 | |||
| 70 | return 0; | 75 | return 0; |
| 71 | } | 76 | } |
| 72 | 77 | ||
| @@ -78,6 +83,7 @@ static int s5p6440_gpiolib_rbank_4bit2_output(struct gpio_chip *chip, | |||
| 78 | void __iomem *regcon = base; | 83 | void __iomem *regcon = base; |
| 79 | unsigned long con; | 84 | unsigned long con; |
| 80 | unsigned long dat; | 85 | unsigned long dat; |
| 86 | unsigned long flags; | ||
| 81 | unsigned con_offset = offset; | 87 | unsigned con_offset = offset; |
| 82 | 88 | ||
| 83 | switch (con_offset) { | 89 | switch (con_offset) { |
| @@ -96,6 +102,8 @@ static int s5p6440_gpiolib_rbank_4bit2_output(struct gpio_chip *chip, | |||
| 96 | break; | 102 | break; |
| 97 | } | 103 | } |
| 98 | 104 | ||
| 105 | s3c_gpio_lock(ourchip, flags); | ||
| 106 | |||
| 99 | con = __raw_readl(regcon); | 107 | con = __raw_readl(regcon); |
| 100 | con &= ~(0xf << con_4bit_shift(con_offset)); | 108 | con &= ~(0xf << con_4bit_shift(con_offset)); |
| 101 | con |= 0x1 << con_4bit_shift(con_offset); | 109 | con |= 0x1 << con_4bit_shift(con_offset); |
| @@ -109,6 +117,8 @@ static int s5p6440_gpiolib_rbank_4bit2_output(struct gpio_chip *chip, | |||
| 109 | __raw_writel(con, regcon); | 117 | __raw_writel(con, regcon); |
| 110 | __raw_writel(dat, base + GPIODAT_OFF); | 118 | __raw_writel(dat, base + GPIODAT_OFF); |
| 111 | 119 | ||
| 120 | s3c_gpio_unlock(ourchip, flags); | ||
| 121 | |||
| 112 | return 0; | 122 | return 0; |
| 113 | } | 123 | } |
| 114 | 124 | ||
| @@ -117,6 +127,7 @@ int s5p6440_gpio_setcfg_4bit_rbank(struct s3c_gpio_chip *chip, | |||
| 117 | { | 127 | { |
| 118 | void __iomem *reg = chip->base; | 128 | void __iomem *reg = chip->base; |
| 119 | unsigned int shift; | 129 | unsigned int shift; |
| 130 | unsigned long flags; | ||
| 120 | u32 con; | 131 | u32 con; |
| 121 | 132 | ||
| 122 | switch (off) { | 133 | switch (off) { |
| @@ -142,11 +153,15 @@ int s5p6440_gpio_setcfg_4bit_rbank(struct s3c_gpio_chip *chip, | |||
| 142 | cfg <<= shift; | 153 | cfg <<= shift; |
| 143 | } | 154 | } |
| 144 | 155 | ||
| 156 | s3c_gpio_lock(chip, flags); | ||
| 157 | |||
| 145 | con = __raw_readl(reg); | 158 | con = __raw_readl(reg); |
| 146 | con &= ~(0xf << shift); | 159 | con &= ~(0xf << shift); |
| 147 | con |= cfg; | 160 | con |= cfg; |
| 148 | __raw_writel(con, reg); | 161 | __raw_writel(con, reg); |
| 149 | 162 | ||
| 163 | s3c_gpio_unlock(chip, flags); | ||
| 164 | |||
| 150 | return 0; | 165 | return 0; |
| 151 | } | 166 | } |
| 152 | 167 | ||
