diff options
Diffstat (limited to 'arch/arm/mach-davinci/gpio.c')
| -rw-r--r-- | arch/arm/mach-davinci/gpio.c | 63 |
1 files changed, 31 insertions, 32 deletions
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c index 1aba41c6351e..1b6532159c58 100644 --- a/arch/arm/mach-davinci/gpio.c +++ b/arch/arm/mach-davinci/gpio.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <mach/cputype.h> | 23 | #include <mach/cputype.h> |
| 24 | #include <mach/irqs.h> | 24 | #include <mach/irqs.h> |
| 25 | #include <mach/hardware.h> | 25 | #include <mach/hardware.h> |
| 26 | #include <mach/common.h> | ||
| 26 | #include <mach/gpio.h> | 27 | #include <mach/gpio.h> |
| 27 | 28 | ||
| 28 | #include <asm/mach/irq.h> | 29 | #include <asm/mach/irq.h> |
| @@ -37,14 +38,13 @@ struct davinci_gpio { | |||
| 37 | 38 | ||
| 38 | static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)]; | 39 | static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)]; |
| 39 | 40 | ||
| 40 | static unsigned __initdata ngpio; | ||
| 41 | |||
| 42 | /* create a non-inlined version */ | 41 | /* create a non-inlined version */ |
| 43 | static struct gpio_controller __iomem * __init gpio2controller(unsigned gpio) | 42 | static struct gpio_controller __iomem * __init gpio2controller(unsigned gpio) |
| 44 | { | 43 | { |
| 45 | return __gpio_to_controller(gpio); | 44 | return __gpio_to_controller(gpio); |
| 46 | } | 45 | } |
| 47 | 46 | ||
| 47 | static int __init davinci_gpio_irq_setup(void); | ||
| 48 | 48 | ||
| 49 | /*--------------------------------------------------------------------------*/ | 49 | /*--------------------------------------------------------------------------*/ |
| 50 | 50 | ||
| @@ -115,23 +115,16 @@ davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | |||
| 115 | static int __init davinci_gpio_setup(void) | 115 | static int __init davinci_gpio_setup(void) |
| 116 | { | 116 | { |
| 117 | int i, base; | 117 | int i, base; |
| 118 | unsigned ngpio; | ||
| 119 | struct davinci_soc_info *soc_info = &davinci_soc_info; | ||
| 118 | 120 | ||
| 119 | /* The gpio banks conceptually expose a segmented bitmap, | 121 | /* |
| 122 | * The gpio banks conceptually expose a segmented bitmap, | ||
| 120 | * and "ngpio" is one more than the largest zero-based | 123 | * and "ngpio" is one more than the largest zero-based |
| 121 | * bit index that's valid. | 124 | * bit index that's valid. |
| 122 | */ | 125 | */ |
| 123 | if (cpu_is_davinci_dm355()) { /* or dm335() */ | 126 | ngpio = soc_info->gpio_num; |
| 124 | ngpio = 104; | 127 | if (ngpio == 0) { |
| 125 | } else if (cpu_is_davinci_dm644x()) { /* or dm337() */ | ||
| 126 | ngpio = 71; | ||
| 127 | } else if (cpu_is_davinci_dm646x()) { | ||
| 128 | /* NOTE: each bank has several "reserved" bits, | ||
| 129 | * unusable as GPIOs. Only 33 of the GPIO numbers | ||
| 130 | * are usable, and we're not rejecting the others. | ||
| 131 | */ | ||
| 132 | ngpio = 43; | ||
| 133 | } else { | ||
| 134 | /* if cpu_is_davinci_dm643x() ngpio = 111 */ | ||
| 135 | pr_err("GPIO setup: how many GPIOs?\n"); | 128 | pr_err("GPIO setup: how many GPIOs?\n"); |
| 136 | return -EINVAL; | 129 | return -EINVAL; |
| 137 | } | 130 | } |
| @@ -157,6 +150,7 @@ static int __init davinci_gpio_setup(void) | |||
| 157 | gpiochip_add(&chips[i].chip); | 150 | gpiochip_add(&chips[i].chip); |
| 158 | } | 151 | } |
| 159 | 152 | ||
| 153 | davinci_gpio_irq_setup(); | ||
| 160 | return 0; | 154 | return 0; |
| 161 | } | 155 | } |
| 162 | pure_initcall(davinci_gpio_setup); | 156 | pure_initcall(davinci_gpio_setup); |
| @@ -187,10 +181,15 @@ static void gpio_irq_enable(unsigned irq) | |||
| 187 | { | 181 | { |
| 188 | struct gpio_controller *__iomem g = get_irq_chip_data(irq); | 182 | struct gpio_controller *__iomem g = get_irq_chip_data(irq); |
| 189 | u32 mask = __gpio_mask(irq_to_gpio(irq)); | 183 | u32 mask = __gpio_mask(irq_to_gpio(irq)); |
| 184 | unsigned status = irq_desc[irq].status; | ||
| 185 | |||
| 186 | status &= IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING; | ||
| 187 | if (!status) | ||
| 188 | status = IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING; | ||
| 190 | 189 | ||
| 191 | if (irq_desc[irq].status & IRQ_TYPE_EDGE_FALLING) | 190 | if (status & IRQ_TYPE_EDGE_FALLING) |
| 192 | __raw_writel(mask, &g->set_falling); | 191 | __raw_writel(mask, &g->set_falling); |
| 193 | if (irq_desc[irq].status & IRQ_TYPE_EDGE_RISING) | 192 | if (status & IRQ_TYPE_EDGE_RISING) |
| 194 | __raw_writel(mask, &g->set_rising); | 193 | __raw_writel(mask, &g->set_rising); |
| 195 | } | 194 | } |
| 196 | 195 | ||
| @@ -205,10 +204,13 @@ static int gpio_irq_type(unsigned irq, unsigned trigger) | |||
| 205 | irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK; | 204 | irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK; |
| 206 | irq_desc[irq].status |= trigger; | 205 | irq_desc[irq].status |= trigger; |
| 207 | 206 | ||
| 208 | __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING) | 207 | /* don't enable the IRQ if it's currently disabled */ |
| 209 | ? &g->set_falling : &g->clr_falling); | 208 | if (irq_desc[irq].depth == 0) { |
| 210 | __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING) | 209 | __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING) |
| 211 | ? &g->set_rising : &g->clr_rising); | 210 | ? &g->set_falling : &g->clr_falling); |
| 211 | __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING) | ||
| 212 | ? &g->set_rising : &g->clr_rising); | ||
| 213 | } | ||
| 212 | return 0; | 214 | return 0; |
| 213 | } | 215 | } |
| 214 | 216 | ||
| @@ -230,6 +232,7 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc) | |||
| 230 | mask <<= 16; | 232 | mask <<= 16; |
| 231 | 233 | ||
| 232 | /* temporarily mask (level sensitive) parent IRQ */ | 234 | /* temporarily mask (level sensitive) parent IRQ */ |
| 235 | desc->chip->mask(irq); | ||
| 233 | desc->chip->ack(irq); | 236 | desc->chip->ack(irq); |
| 234 | while (1) { | 237 | while (1) { |
| 235 | u32 status; | 238 | u32 status; |
| @@ -268,17 +271,15 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc) | |||
| 268 | static int __init davinci_gpio_irq_setup(void) | 271 | static int __init davinci_gpio_irq_setup(void) |
| 269 | { | 272 | { |
| 270 | unsigned gpio, irq, bank; | 273 | unsigned gpio, irq, bank; |
| 271 | unsigned bank_irq; | ||
| 272 | struct clk *clk; | 274 | struct clk *clk; |
| 273 | u32 binten = 0; | 275 | u32 binten = 0; |
| 276 | unsigned ngpio, bank_irq; | ||
| 277 | struct davinci_soc_info *soc_info = &davinci_soc_info; | ||
| 278 | |||
| 279 | ngpio = soc_info->gpio_num; | ||
| 274 | 280 | ||
| 275 | if (cpu_is_davinci_dm355()) { /* or dm335() */ | 281 | bank_irq = soc_info->gpio_irq; |
| 276 | bank_irq = IRQ_DM355_GPIOBNK0; | 282 | if (bank_irq == 0) { |
| 277 | } else if (cpu_is_davinci_dm644x()) { | ||
| 278 | bank_irq = IRQ_GPIOBNK0; | ||
| 279 | } else if (cpu_is_davinci_dm646x()) { | ||
| 280 | bank_irq = IRQ_DM646X_GPIOBNK0; | ||
| 281 | } else { | ||
| 282 | printk(KERN_ERR "Don't know first GPIO bank IRQ.\n"); | 283 | printk(KERN_ERR "Don't know first GPIO bank IRQ.\n"); |
| 283 | return -EINVAL; | 284 | return -EINVAL; |
| 284 | } | 285 | } |
| @@ -318,11 +319,9 @@ static int __init davinci_gpio_irq_setup(void) | |||
| 318 | /* BINTEN -- per-bank interrupt enable. genirq would also let these | 319 | /* BINTEN -- per-bank interrupt enable. genirq would also let these |
| 319 | * bits be set/cleared dynamically. | 320 | * bits be set/cleared dynamically. |
| 320 | */ | 321 | */ |
| 321 | __raw_writel(binten, (void *__iomem) | 322 | __raw_writel(binten, soc_info->gpio_base + 0x08); |
| 322 | IO_ADDRESS(DAVINCI_GPIO_BASE + 0x08)); | ||
| 323 | 323 | ||
| 324 | printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0)); | 324 | printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0)); |
| 325 | 325 | ||
| 326 | return 0; | 326 | return 0; |
| 327 | } | 327 | } |
| 328 | arch_initcall(davinci_gpio_irq_setup); | ||
