diff options
Diffstat (limited to 'drivers/sh')
-rw-r--r-- | drivers/sh/clk/core.c | 68 | ||||
-rw-r--r-- | drivers/sh/intc/core.c | 95 | ||||
-rw-r--r-- | drivers/sh/intc/internals.h | 1 |
3 files changed, 65 insertions, 99 deletions
diff --git a/drivers/sh/clk/core.c b/drivers/sh/clk/core.c index 5f63c3b83828..4f64183b27fa 100644 --- a/drivers/sh/clk/core.c +++ b/drivers/sh/clk/core.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/mutex.h> | 22 | #include <linux/mutex.h> |
23 | #include <linux/list.h> | 23 | #include <linux/list.h> |
24 | #include <linux/sysdev.h> | 24 | #include <linux/syscore_ops.h> |
25 | #include <linux/seq_file.h> | 25 | #include <linux/seq_file.h> |
26 | #include <linux/err.h> | 26 | #include <linux/err.h> |
27 | #include <linux/io.h> | 27 | #include <linux/io.h> |
@@ -630,68 +630,36 @@ long clk_round_parent(struct clk *clk, unsigned long target, | |||
630 | EXPORT_SYMBOL_GPL(clk_round_parent); | 630 | EXPORT_SYMBOL_GPL(clk_round_parent); |
631 | 631 | ||
632 | #ifdef CONFIG_PM | 632 | #ifdef CONFIG_PM |
633 | static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state) | 633 | static void clks_core_resume(void) |
634 | { | 634 | { |
635 | static pm_message_t prev_state; | ||
636 | struct clk *clkp; | 635 | struct clk *clkp; |
637 | 636 | ||
638 | switch (state.event) { | 637 | list_for_each_entry(clkp, &clock_list, node) { |
639 | case PM_EVENT_ON: | 638 | if (likely(clkp->ops)) { |
640 | /* Resumeing from hibernation */ | 639 | unsigned long rate = clkp->rate; |
641 | if (prev_state.event != PM_EVENT_FREEZE) | 640 | |
642 | break; | 641 | if (likely(clkp->ops->set_parent)) |
643 | 642 | clkp->ops->set_parent(clkp, | |
644 | list_for_each_entry(clkp, &clock_list, node) { | 643 | clkp->parent); |
645 | if (likely(clkp->ops)) { | 644 | if (likely(clkp->ops->set_rate)) |
646 | unsigned long rate = clkp->rate; | 645 | clkp->ops->set_rate(clkp, rate); |
647 | 646 | else if (likely(clkp->ops->recalc)) | |
648 | if (likely(clkp->ops->set_parent)) | 647 | clkp->rate = clkp->ops->recalc(clkp); |
649 | clkp->ops->set_parent(clkp, | ||
650 | clkp->parent); | ||
651 | if (likely(clkp->ops->set_rate)) | ||
652 | clkp->ops->set_rate(clkp, rate); | ||
653 | else if (likely(clkp->ops->recalc)) | ||
654 | clkp->rate = clkp->ops->recalc(clkp); | ||
655 | } | ||
656 | } | 648 | } |
657 | break; | ||
658 | case PM_EVENT_FREEZE: | ||
659 | break; | ||
660 | case PM_EVENT_SUSPEND: | ||
661 | break; | ||
662 | } | 649 | } |
663 | |||
664 | prev_state = state; | ||
665 | return 0; | ||
666 | } | ||
667 | |||
668 | static int clks_sysdev_resume(struct sys_device *dev) | ||
669 | { | ||
670 | return clks_sysdev_suspend(dev, PMSG_ON); | ||
671 | } | 650 | } |
672 | 651 | ||
673 | static struct sysdev_class clks_sysdev_class = { | 652 | static struct syscore_ops clks_syscore_ops = { |
674 | .name = "clks", | 653 | .resume = clks_core_resume, |
675 | }; | ||
676 | |||
677 | static struct sysdev_driver clks_sysdev_driver = { | ||
678 | .suspend = clks_sysdev_suspend, | ||
679 | .resume = clks_sysdev_resume, | ||
680 | }; | ||
681 | |||
682 | static struct sys_device clks_sysdev_dev = { | ||
683 | .cls = &clks_sysdev_class, | ||
684 | }; | 654 | }; |
685 | 655 | ||
686 | static int __init clk_sysdev_init(void) | 656 | static int __init clk_syscore_init(void) |
687 | { | 657 | { |
688 | sysdev_class_register(&clks_sysdev_class); | 658 | register_syscore_ops(&clks_syscore_ops); |
689 | sysdev_driver_register(&clks_sysdev_class, &clks_sysdev_driver); | ||
690 | sysdev_register(&clks_sysdev_dev); | ||
691 | 659 | ||
692 | return 0; | 660 | return 0; |
693 | } | 661 | } |
694 | subsys_initcall(clk_sysdev_init); | 662 | subsys_initcall(clk_syscore_init); |
695 | #endif | 663 | #endif |
696 | 664 | ||
697 | /* | 665 | /* |
diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c index 9739431092d1..5833afbf08d7 100644 --- a/drivers/sh/intc/core.c +++ b/drivers/sh/intc/core.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
26 | #include <linux/sh_intc.h> | 26 | #include <linux/sh_intc.h> |
27 | #include <linux/sysdev.h> | 27 | #include <linux/sysdev.h> |
28 | #include <linux/syscore_ops.h> | ||
28 | #include <linux/list.h> | 29 | #include <linux/list.h> |
29 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
30 | #include <linux/radix-tree.h> | 31 | #include <linux/radix-tree.h> |
@@ -376,91 +377,89 @@ err0: | |||
376 | return -ENOMEM; | 377 | return -ENOMEM; |
377 | } | 378 | } |
378 | 379 | ||
379 | static ssize_t | 380 | static int intc_suspend(void) |
380 | show_intc_name(struct sys_device *dev, struct sysdev_attribute *attr, char *buf) | ||
381 | { | 381 | { |
382 | struct intc_desc_int *d; | 382 | struct intc_desc_int *d; |
383 | 383 | ||
384 | d = container_of(dev, struct intc_desc_int, sysdev); | 384 | list_for_each_entry(d, &intc_list, list) { |
385 | int irq; | ||
385 | 386 | ||
386 | return sprintf(buf, "%s\n", d->chip.name); | 387 | /* enable wakeup irqs belonging to this intc controller */ |
387 | } | 388 | for_each_active_irq(irq) { |
389 | struct irq_data *data; | ||
390 | struct irq_desc *desc; | ||
391 | struct irq_chip *chip; | ||
388 | 392 | ||
389 | static SYSDEV_ATTR(name, S_IRUGO, show_intc_name, NULL); | 393 | data = irq_get_irq_data(irq); |
394 | chip = irq_data_get_irq_chip(data); | ||
395 | if (chip != &d->chip) | ||
396 | continue; | ||
397 | desc = irq_to_desc(irq); | ||
398 | if ((desc->status & IRQ_WAKEUP)) | ||
399 | chip->irq_enable(data); | ||
400 | } | ||
401 | } | ||
402 | |||
403 | return 0; | ||
404 | } | ||
390 | 405 | ||
391 | static int intc_suspend(struct sys_device *dev, pm_message_t state) | 406 | static void intc_resume(void) |
392 | { | 407 | { |
393 | struct intc_desc_int *d; | 408 | struct intc_desc_int *d; |
394 | struct irq_data *data; | ||
395 | struct irq_desc *desc; | ||
396 | struct irq_chip *chip; | ||
397 | int irq; | ||
398 | |||
399 | /* get intc controller associated with this sysdev */ | ||
400 | d = container_of(dev, struct intc_desc_int, sysdev); | ||
401 | 409 | ||
402 | switch (state.event) { | 410 | list_for_each_entry(d, &intc_list, list) { |
403 | case PM_EVENT_ON: | 411 | int irq; |
404 | if (d->state.event != PM_EVENT_FREEZE) | ||
405 | break; | ||
406 | 412 | ||
407 | for_each_active_irq(irq) { | 413 | for_each_active_irq(irq) { |
408 | desc = irq_to_desc(irq); | 414 | struct irq_data *data; |
415 | struct irq_desc *desc; | ||
416 | struct irq_chip *chip; | ||
417 | |||
409 | data = irq_get_irq_data(irq); | 418 | data = irq_get_irq_data(irq); |
410 | chip = irq_data_get_irq_chip(data); | 419 | chip = irq_data_get_irq_chip(data); |
411 | |||
412 | /* | 420 | /* |
413 | * This will catch the redirect and VIRQ cases | 421 | * This will catch the redirect and VIRQ cases |
414 | * due to the dummy_irq_chip being inserted. | 422 | * due to the dummy_irq_chip being inserted. |
415 | */ | 423 | */ |
416 | if (chip != &d->chip) | 424 | if (chip != &d->chip) |
417 | continue; | 425 | continue; |
426 | desc = irq_to_desc(irq); | ||
418 | if (desc->status & IRQ_DISABLED) | 427 | if (desc->status & IRQ_DISABLED) |
419 | chip->irq_disable(data); | 428 | chip->irq_disable(data); |
420 | else | 429 | else |
421 | chip->irq_enable(data); | 430 | chip->irq_enable(data); |
422 | } | 431 | } |
423 | break; | ||
424 | case PM_EVENT_FREEZE: | ||
425 | /* nothing has to be done */ | ||
426 | break; | ||
427 | case PM_EVENT_SUSPEND: | ||
428 | /* enable wakeup irqs belonging to this intc controller */ | ||
429 | for_each_active_irq(irq) { | ||
430 | desc = irq_to_desc(irq); | ||
431 | data = irq_get_irq_data(irq); | ||
432 | chip = irq_data_get_irq_chip(data); | ||
433 | |||
434 | if (chip != &d->chip) | ||
435 | continue; | ||
436 | if ((desc->status & IRQ_WAKEUP)) | ||
437 | chip->irq_enable(data); | ||
438 | } | ||
439 | break; | ||
440 | } | 432 | } |
441 | |||
442 | d->state = state; | ||
443 | |||
444 | return 0; | ||
445 | } | 433 | } |
446 | 434 | ||
447 | static int intc_resume(struct sys_device *dev) | 435 | struct syscore_ops intc_syscore_ops = { |
448 | { | 436 | .suspend = intc_suspend, |
449 | return intc_suspend(dev, PMSG_ON); | 437 | .resume = intc_resume, |
450 | } | 438 | }; |
451 | 439 | ||
452 | struct sysdev_class intc_sysdev_class = { | 440 | struct sysdev_class intc_sysdev_class = { |
453 | .name = "intc", | 441 | .name = "intc", |
454 | .suspend = intc_suspend, | ||
455 | .resume = intc_resume, | ||
456 | }; | 442 | }; |
457 | 443 | ||
458 | /* register this intc as sysdev to allow suspend/resume */ | 444 | static ssize_t |
445 | show_intc_name(struct sys_device *dev, struct sysdev_attribute *attr, char *buf) | ||
446 | { | ||
447 | struct intc_desc_int *d; | ||
448 | |||
449 | d = container_of(dev, struct intc_desc_int, sysdev); | ||
450 | |||
451 | return sprintf(buf, "%s\n", d->chip.name); | ||
452 | } | ||
453 | |||
454 | static SYSDEV_ATTR(name, S_IRUGO, show_intc_name, NULL); | ||
455 | |||
459 | static int __init register_intc_sysdevs(void) | 456 | static int __init register_intc_sysdevs(void) |
460 | { | 457 | { |
461 | struct intc_desc_int *d; | 458 | struct intc_desc_int *d; |
462 | int error; | 459 | int error; |
463 | 460 | ||
461 | register_syscore_ops(&intc_syscore_ops); | ||
462 | |||
464 | error = sysdev_class_register(&intc_sysdev_class); | 463 | error = sysdev_class_register(&intc_sysdev_class); |
465 | if (!error) { | 464 | if (!error) { |
466 | list_for_each_entry(d, &intc_list, list) { | 465 | list_for_each_entry(d, &intc_list, list) { |
diff --git a/drivers/sh/intc/internals.h b/drivers/sh/intc/internals.h index 0cf8260971d4..df36a421e675 100644 --- a/drivers/sh/intc/internals.h +++ b/drivers/sh/intc/internals.h | |||
@@ -53,7 +53,6 @@ struct intc_desc_int { | |||
53 | struct list_head list; | 53 | struct list_head list; |
54 | struct sys_device sysdev; | 54 | struct sys_device sysdev; |
55 | struct radix_tree_root tree; | 55 | struct radix_tree_root tree; |
56 | pm_message_t state; | ||
57 | raw_spinlock_t lock; | 56 | raw_spinlock_t lock; |
58 | unsigned int index; | 57 | unsigned int index; |
59 | unsigned long *reg; | 58 | unsigned long *reg; |