diff options
Diffstat (limited to 'drivers/sh/intc/core.c')
-rw-r--r-- | drivers/sh/intc/core.c | 95 |
1 files changed, 47 insertions, 48 deletions
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 @@ #include <linux/interrupt.h> #include <linux/sh_intc.h> #include <linux/sysdev.h> +#include <linux/syscore_ops.h> #include <linux/list.h> #include <linux/spinlock.h> #include <linux/radix-tree.h> @@ -376,91 +377,89 @@ err0: return -ENOMEM; } -static ssize_t -show_intc_name(struct sys_device *dev, struct sysdev_attribute *attr, char *buf) +static int intc_suspend(void) { struct intc_desc_int *d; - d = container_of(dev, struct intc_desc_int, sysdev); + list_for_each_entry(d, &intc_list, list) { + int irq; - return sprintf(buf, "%s\n", d->chip.name); -} + /* enable wakeup irqs belonging to this intc controller */ + for_each_active_irq(irq) { + struct irq_data *data; + struct irq_desc *desc; + struct irq_chip *chip; -static SYSDEV_ATTR(name, S_IRUGO, show_intc_name, NULL); + data = irq_get_irq_data(irq); + chip = irq_data_get_irq_chip(data); + if (chip != &d->chip) + continue; + desc = irq_to_desc(irq); + if ((desc->status & IRQ_WAKEUP)) + chip->irq_enable(data); + } + } + + return 0; +} -static int intc_suspend(struct sys_device *dev, pm_message_t state) +static void intc_resume(void) { struct intc_desc_int *d; - struct irq_data *data; - struct irq_desc *desc; - struct irq_chip *chip; - int irq; - - /* get intc controller associated with this sysdev */ - d = container_of(dev, struct intc_desc_int, sysdev); - switch (state.event) { - case PM_EVENT_ON: - if (d->state.event != PM_EVENT_FREEZE) - break; + list_for_each_entry(d, &intc_list, list) { + int irq; for_each_active_irq(irq) { - desc = irq_to_desc(irq); + struct irq_data *data; + struct irq_desc *desc; + struct irq_chip *chip; + data = irq_get_irq_data(irq); chip = irq_data_get_irq_chip(data); - /* * This will catch the redirect and VIRQ cases * due to the dummy_irq_chip being inserted. */ if (chip != &d->chip) continue; + desc = irq_to_desc(irq); if (desc->status & IRQ_DISABLED) chip->irq_disable(data); else chip->irq_enable(data); } - break; - case PM_EVENT_FREEZE: - /* nothing has to be done */ - break; - case PM_EVENT_SUSPEND: - /* enable wakeup irqs belonging to this intc controller */ - for_each_active_irq(irq) { - desc = irq_to_desc(irq); - data = irq_get_irq_data(irq); - chip = irq_data_get_irq_chip(data); - - if (chip != &d->chip) - continue; - if ((desc->status & IRQ_WAKEUP)) - chip->irq_enable(data); - } - break; } - - d->state = state; - - return 0; } -static int intc_resume(struct sys_device *dev) -{ - return intc_suspend(dev, PMSG_ON); -} +struct syscore_ops intc_syscore_ops = { + .suspend = intc_suspend, + .resume = intc_resume, +}; struct sysdev_class intc_sysdev_class = { .name = "intc", - .suspend = intc_suspend, - .resume = intc_resume, }; -/* register this intc as sysdev to allow suspend/resume */ +static ssize_t +show_intc_name(struct sys_device *dev, struct sysdev_attribute *attr, char *buf) +{ + struct intc_desc_int *d; + + d = container_of(dev, struct intc_desc_int, sysdev); + + return sprintf(buf, "%s\n", d->chip.name); +} + +static SYSDEV_ATTR(name, S_IRUGO, show_intc_name, NULL); + static int __init register_intc_sysdevs(void) { struct intc_desc_int *d; int error; + register_syscore_ops(&intc_syscore_ops); + error = sysdev_class_register(&intc_sysdev_class); if (!error) { list_for_each_entry(d, &intc_list, list) { |