diff options
Diffstat (limited to 'arch/arm/plat-mxc/gpio.c')
-rw-r--r-- | arch/arm/plat-mxc/gpio.c | 30 |
1 files changed, 11 insertions, 19 deletions
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c index d65ebe303b9f..70b23893f094 100644 --- a/arch/arm/plat-mxc/gpio.c +++ b/arch/arm/plat-mxc/gpio.c | |||
@@ -140,16 +140,13 @@ static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio) | |||
140 | val = __raw_readl(reg); | 140 | val = __raw_readl(reg); |
141 | edge = (val >> (bit << 1)) & 3; | 141 | edge = (val >> (bit << 1)) & 3; |
142 | val &= ~(0x3 << (bit << 1)); | 142 | val &= ~(0x3 << (bit << 1)); |
143 | switch (edge) { | 143 | if (edge == GPIO_INT_HIGH_LEV) { |
144 | case GPIO_INT_HIGH_LEV: | ||
145 | edge = GPIO_INT_LOW_LEV; | 144 | edge = GPIO_INT_LOW_LEV; |
146 | pr_debug("mxc: switch GPIO %d to low trigger\n", gpio); | 145 | pr_debug("mxc: switch GPIO %d to low trigger\n", gpio); |
147 | break; | 146 | } else if (edge == GPIO_INT_LOW_LEV) { |
148 | case GPIO_INT_LOW_LEV: | ||
149 | edge = GPIO_INT_HIGH_LEV; | 147 | edge = GPIO_INT_HIGH_LEV; |
150 | pr_debug("mxc: switch GPIO %d to high trigger\n", gpio); | 148 | pr_debug("mxc: switch GPIO %d to high trigger\n", gpio); |
151 | break; | 149 | } else { |
152 | default: | ||
153 | pr_err("mxc: invalid configuration for GPIO %d: %x\n", | 150 | pr_err("mxc: invalid configuration for GPIO %d: %x\n", |
154 | gpio, edge); | 151 | gpio, edge); |
155 | return; | 152 | return; |
@@ -157,25 +154,20 @@ static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio) | |||
157 | __raw_writel(val | (edge << (bit << 1)), reg); | 154 | __raw_writel(val | (edge << (bit << 1)), reg); |
158 | } | 155 | } |
159 | 156 | ||
160 | /* handle n interrupts in one status register */ | 157 | /* handle 32 interrupts in one status register */ |
161 | static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat) | 158 | static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat) |
162 | { | 159 | { |
163 | u32 gpio_irq_no; | 160 | u32 gpio_irq_no_base = port->virtual_irq_start; |
164 | 161 | ||
165 | gpio_irq_no = port->virtual_irq_start; | 162 | while (irq_stat != 0) { |
166 | for (; irq_stat != 0; irq_stat >>= 1, gpio_irq_no++) { | 163 | int irqoffset = fls(irq_stat) - 1; |
167 | u32 gpio = irq_to_gpio(gpio_irq_no); | ||
168 | |||
169 | if ((irq_stat & 1) == 0) | ||
170 | continue; | ||
171 | 164 | ||
172 | BUG_ON(!(irq_desc[gpio_irq_no].handle_irq)); | 165 | if (port->both_edges & (1 << irqoffset)) |
166 | mxc_flip_edge(port, irqoffset); | ||
173 | 167 | ||
174 | if (port->both_edges & (1 << (gpio & 31))) | 168 | generic_handle_irq(gpio_irq_no_base + irqoffset); |
175 | mxc_flip_edge(port, gpio); | ||
176 | 169 | ||
177 | irq_desc[gpio_irq_no].handle_irq(gpio_irq_no, | 170 | irq_stat &= ~(1 << irqoffset); |
178 | &irq_desc[gpio_irq_no]); | ||
179 | } | 171 | } |
180 | } | 172 | } |
181 | 173 | ||