aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRabin Vincent <rabin.vincent@stericsson.com>2010-06-16 01:09:34 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-06-16 17:29:00 -0400
commit4d4e20f77c6170eaec61976e0a165bdff6b09d79 (patch)
tree37241092f837f9c670ea490eef05b67ff68b5959 /arch
parent33f45ea91706f8fdde04bd6c2245f679403ec63f (diff)
ARM: 6175/1: nomadik-gpio: implement set_wake
So that set_irq_wake() works. Cc: Alessandro Rubini <rubini@unipv.it> Acked-by: Linus Walleij <linus.walleij@stericsson.com> Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/plat-nomadik/gpio.c53
1 files changed, 39 insertions, 14 deletions
diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c
index 14466519fcc3..9cb717417ba0 100644
--- a/arch/arm/plat-nomadik/gpio.c
+++ b/arch/arm/plat-nomadik/gpio.c
@@ -301,32 +301,41 @@ static void nmk_gpio_irq_ack(unsigned int irq)
301 writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC); 301 writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC);
302} 302}
303 303
304enum nmk_gpio_irq_type {
305 NORMAL,
306 WAKE,
307};
308
304static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip, 309static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip,
305 int gpio, bool enable) 310 int gpio, enum nmk_gpio_irq_type which,
311 bool enable)
306{ 312{
313 u32 rimsc = which == WAKE ? NMK_GPIO_RWIMSC : NMK_GPIO_RIMSC;
314 u32 fimsc = which == WAKE ? NMK_GPIO_FWIMSC : NMK_GPIO_FIMSC;
307 u32 bitmask = nmk_gpio_get_bitmask(gpio); 315 u32 bitmask = nmk_gpio_get_bitmask(gpio);
308 u32 reg; 316 u32 reg;
309 317
310 /* we must individually set/clear the two edges */ 318 /* we must individually set/clear the two edges */
311 if (nmk_chip->edge_rising & bitmask) { 319 if (nmk_chip->edge_rising & bitmask) {
312 reg = readl(nmk_chip->addr + NMK_GPIO_RIMSC); 320 reg = readl(nmk_chip->addr + rimsc);
313 if (enable) 321 if (enable)
314 reg |= bitmask; 322 reg |= bitmask;
315 else 323 else
316 reg &= ~bitmask; 324 reg &= ~bitmask;
317 writel(reg, nmk_chip->addr + NMK_GPIO_RIMSC); 325 writel(reg, nmk_chip->addr + rimsc);
318 } 326 }
319 if (nmk_chip->edge_falling & bitmask) { 327 if (nmk_chip->edge_falling & bitmask) {
320 reg = readl(nmk_chip->addr + NMK_GPIO_FIMSC); 328 reg = readl(nmk_chip->addr + fimsc);
321 if (enable) 329 if (enable)
322 reg |= bitmask; 330 reg |= bitmask;
323 else 331 else
324 reg &= ~bitmask; 332 reg &= ~bitmask;
325 writel(reg, nmk_chip->addr + NMK_GPIO_FIMSC); 333 writel(reg, nmk_chip->addr + fimsc);
326 } 334 }
327} 335}
328 336
329static void nmk_gpio_irq_modify(unsigned int irq, bool enable) 337static int nmk_gpio_irq_modify(unsigned int irq, enum nmk_gpio_irq_type which,
338 bool enable)
330{ 339{
331 int gpio; 340 int gpio;
332 struct nmk_gpio_chip *nmk_chip; 341 struct nmk_gpio_chip *nmk_chip;
@@ -337,26 +346,35 @@ static void nmk_gpio_irq_modify(unsigned int irq, bool enable)
337 nmk_chip = get_irq_chip_data(irq); 346 nmk_chip = get_irq_chip_data(irq);
338 bitmask = nmk_gpio_get_bitmask(gpio); 347 bitmask = nmk_gpio_get_bitmask(gpio);
339 if (!nmk_chip) 348 if (!nmk_chip)
340 return; 349 return -EINVAL;
341 350
342 spin_lock_irqsave(&nmk_chip->lock, flags); 351 spin_lock_irqsave(&nmk_chip->lock, flags);
343 __nmk_gpio_irq_modify(nmk_chip, gpio, enable); 352 __nmk_gpio_irq_modify(nmk_chip, gpio, which, enable);
344 spin_unlock_irqrestore(&nmk_chip->lock, flags); 353 spin_unlock_irqrestore(&nmk_chip->lock, flags);
354
355 return 0;
345} 356}
346 357
347static void nmk_gpio_irq_mask(unsigned int irq) 358static void nmk_gpio_irq_mask(unsigned int irq)
348{ 359{
349 nmk_gpio_irq_modify(irq, false); 360 nmk_gpio_irq_modify(irq, NORMAL, false);
350}; 361}
351 362
352static void nmk_gpio_irq_unmask(unsigned int irq) 363static void nmk_gpio_irq_unmask(unsigned int irq)
353{ 364{
354 nmk_gpio_irq_modify(irq, true); 365 nmk_gpio_irq_modify(irq, NORMAL, true);
366}
367
368static int nmk_gpio_irq_set_wake(unsigned int irq, unsigned int on)
369{
370 return nmk_gpio_irq_modify(irq, WAKE, on);
355} 371}
356 372
357static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type) 373static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type)
358{ 374{
359 bool enabled = !(irq_to_desc(irq)->status & IRQ_DISABLED); 375 struct irq_desc *desc = irq_to_desc(irq);
376 bool enabled = !(desc->status & IRQ_DISABLED);
377 bool wake = desc->wake_depth;
360 int gpio; 378 int gpio;
361 struct nmk_gpio_chip *nmk_chip; 379 struct nmk_gpio_chip *nmk_chip;
362 unsigned long flags; 380 unsigned long flags;
@@ -376,7 +394,10 @@ static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type)
376 spin_lock_irqsave(&nmk_chip->lock, flags); 394 spin_lock_irqsave(&nmk_chip->lock, flags);
377 395
378 if (enabled) 396 if (enabled)
379 __nmk_gpio_irq_modify(nmk_chip, gpio, false); 397 __nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, false);
398
399 if (wake)
400 __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, false);
380 401
381 nmk_chip->edge_rising &= ~bitmask; 402 nmk_chip->edge_rising &= ~bitmask;
382 if (type & IRQ_TYPE_EDGE_RISING) 403 if (type & IRQ_TYPE_EDGE_RISING)
@@ -387,7 +408,10 @@ static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type)
387 nmk_chip->edge_falling |= bitmask; 408 nmk_chip->edge_falling |= bitmask;
388 409
389 if (enabled) 410 if (enabled)
390 __nmk_gpio_irq_modify(nmk_chip, gpio, true); 411 __nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, true);
412
413 if (wake)
414 __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, true);
391 415
392 spin_unlock_irqrestore(&nmk_chip->lock, flags); 416 spin_unlock_irqrestore(&nmk_chip->lock, flags);
393 417
@@ -400,6 +424,7 @@ static struct irq_chip nmk_gpio_irq_chip = {
400 .mask = nmk_gpio_irq_mask, 424 .mask = nmk_gpio_irq_mask,
401 .unmask = nmk_gpio_irq_unmask, 425 .unmask = nmk_gpio_irq_unmask,
402 .set_type = nmk_gpio_irq_set_type, 426 .set_type = nmk_gpio_irq_set_type,
427 .set_wake = nmk_gpio_irq_set_wake,
403}; 428};
404 429
405static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) 430static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)