diff options
| -rw-r--r-- | arch/mips/jz4740/gpio.c | 52 |
1 files changed, 22 insertions, 30 deletions
diff --git a/arch/mips/jz4740/gpio.c b/arch/mips/jz4740/gpio.c index 73031f7fc827..4397972949fa 100644 --- a/arch/mips/jz4740/gpio.c +++ b/arch/mips/jz4740/gpio.c | |||
| @@ -18,7 +18,7 @@ | |||
| 18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
| 19 | 19 | ||
| 20 | #include <linux/spinlock.h> | 20 | #include <linux/spinlock.h> |
| 21 | #include <linux/sysdev.h> | 21 | #include <linux/syscore_ops.h> |
| 22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
| 23 | #include <linux/gpio.h> | 23 | #include <linux/gpio.h> |
| 24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
| @@ -86,7 +86,6 @@ struct jz_gpio_chip { | |||
| 86 | spinlock_t lock; | 86 | spinlock_t lock; |
| 87 | 87 | ||
| 88 | struct gpio_chip gpio_chip; | 88 | struct gpio_chip gpio_chip; |
| 89 | struct sys_device sysdev; | ||
| 90 | }; | 89 | }; |
| 91 | 90 | ||
| 92 | static struct jz_gpio_chip jz4740_gpio_chips[]; | 91 | static struct jz_gpio_chip jz4740_gpio_chips[]; |
| @@ -459,49 +458,47 @@ static struct jz_gpio_chip jz4740_gpio_chips[] = { | |||
| 459 | JZ4740_GPIO_CHIP(D), | 458 | JZ4740_GPIO_CHIP(D), |
| 460 | }; | 459 | }; |
| 461 | 460 | ||
| 462 | static inline struct jz_gpio_chip *sysdev_to_chip(struct sys_device *dev) | 461 | static void jz4740_gpio_suspend_chip(struct jz_gpio_chip *chip) |
| 463 | { | 462 | { |
| 464 | return container_of(dev, struct jz_gpio_chip, sysdev); | 463 | chip->suspend_mask = readl(chip->base + JZ_REG_GPIO_MASK); |
| 464 | writel(~(chip->wakeup), chip->base + JZ_REG_GPIO_MASK_SET); | ||
| 465 | writel(chip->wakeup, chip->base + JZ_REG_GPIO_MASK_CLEAR); | ||
| 465 | } | 466 | } |
| 466 | 467 | ||
| 467 | static int jz4740_gpio_suspend(struct sys_device *dev, pm_message_t state) | 468 | static int jz4740_gpio_suspend(void) |
| 468 | { | 469 | { |
| 469 | struct jz_gpio_chip *chip = sysdev_to_chip(dev); | 470 | int i; |
| 470 | 471 | ||
| 471 | chip->suspend_mask = readl(chip->base + JZ_REG_GPIO_MASK); | 472 | for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); i++) |
| 472 | writel(~(chip->wakeup), chip->base + JZ_REG_GPIO_MASK_SET); | 473 | jz4740_gpio_suspend_chip(&jz4740_gpio_chips[i]); |
| 473 | writel(chip->wakeup, chip->base + JZ_REG_GPIO_MASK_CLEAR); | ||
| 474 | 474 | ||
| 475 | return 0; | 475 | return 0; |
| 476 | } | 476 | } |
| 477 | 477 | ||
| 478 | static int jz4740_gpio_resume(struct sys_device *dev) | 478 | static void jz4740_gpio_resume_chip(struct jz_gpio_chip *chip) |
| 479 | { | 479 | { |
| 480 | struct jz_gpio_chip *chip = sysdev_to_chip(dev); | ||
| 481 | uint32_t mask = chip->suspend_mask; | 480 | uint32_t mask = chip->suspend_mask; |
| 482 | 481 | ||
| 483 | writel(~mask, chip->base + JZ_REG_GPIO_MASK_CLEAR); | 482 | writel(~mask, chip->base + JZ_REG_GPIO_MASK_CLEAR); |
| 484 | writel(mask, chip->base + JZ_REG_GPIO_MASK_SET); | 483 | writel(mask, chip->base + JZ_REG_GPIO_MASK_SET); |
| 484 | } | ||
| 485 | 485 | ||
| 486 | return 0; | 486 | static void jz4740_gpio_resume(void) |
| 487 | { | ||
| 488 | int i; | ||
| 489 | |||
| 490 | for (i = ARRAY_SIZE(jz4740_gpio_chips) - 1; i >= 0 ; i--) | ||
| 491 | jz4740_gpio_resume_chip(&jz4740_gpio_chips[i]); | ||
| 487 | } | 492 | } |
| 488 | 493 | ||
| 489 | static struct sysdev_class jz4740_gpio_sysdev_class = { | 494 | static struct syscore_ops jz4740_gpio_syscore_ops = { |
| 490 | .name = "gpio", | ||
| 491 | .suspend = jz4740_gpio_suspend, | 495 | .suspend = jz4740_gpio_suspend, |
| 492 | .resume = jz4740_gpio_resume, | 496 | .resume = jz4740_gpio_resume, |
| 493 | }; | 497 | }; |
| 494 | 498 | ||
| 495 | static int jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id) | 499 | static void jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id) |
| 496 | { | 500 | { |
| 497 | int ret, irq; | 501 | int irq; |
| 498 | |||
| 499 | chip->sysdev.id = id; | ||
| 500 | chip->sysdev.cls = &jz4740_gpio_sysdev_class; | ||
| 501 | ret = sysdev_register(&chip->sysdev); | ||
| 502 | |||
| 503 | if (ret) | ||
| 504 | return ret; | ||
| 505 | 502 | ||
| 506 | spin_lock_init(&chip->lock); | 503 | spin_lock_init(&chip->lock); |
| 507 | 504 | ||
| @@ -519,22 +516,17 @@ static int jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id) | |||
| 519 | irq_set_chip_and_handler(irq, &jz_gpio_irq_chip, | 516 | irq_set_chip_and_handler(irq, &jz_gpio_irq_chip, |
| 520 | handle_level_irq); | 517 | handle_level_irq); |
| 521 | } | 518 | } |
| 522 | |||
| 523 | return 0; | ||
| 524 | } | 519 | } |
| 525 | 520 | ||
| 526 | static int __init jz4740_gpio_init(void) | 521 | static int __init jz4740_gpio_init(void) |
| 527 | { | 522 | { |
| 528 | unsigned int i; | 523 | unsigned int i; |
| 529 | int ret; | ||
| 530 | |||
| 531 | ret = sysdev_class_register(&jz4740_gpio_sysdev_class); | ||
| 532 | if (ret) | ||
| 533 | return ret; | ||
| 534 | 524 | ||
| 535 | for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i) | 525 | for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i) |
| 536 | jz4740_gpio_chip_init(&jz4740_gpio_chips[i], i); | 526 | jz4740_gpio_chip_init(&jz4740_gpio_chips[i], i); |
| 537 | 527 | ||
| 528 | register_syscore_ops(&jz4740_gpio_syscore_ops); | ||
| 529 | |||
| 538 | printk(KERN_INFO "JZ4740 GPIO initialized\n"); | 530 | printk(KERN_INFO "JZ4740 GPIO initialized\n"); |
| 539 | 531 | ||
| 540 | return 0; | 532 | return 0; |
