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 | ||
