struct intc_desc_int {
struct list_head list;
struct sys_device sysdev;
+ pm_message_t state;
unsigned long *reg;
#ifdef CONFIG_SMP
unsigned long *smp;
void __init register_intc_controller(struct intc_desc *desc)
{
- unsigned int i, k, smp;
+ unsigned int i, k, smp, cpu = smp_processor_id();
struct intc_desc_int *d;
d = alloc_bootmem(sizeof(*d));
/* register the vectors one by one */
for (i = 0; i < desc->nr_vectors; i++) {
struct intc_vect *vect = desc->vectors + i;
+ unsigned int irq = evt2irq(vect->vect);
+ struct irq_desc *irq_desc;
if (!vect->enum_id)
continue;
- intc_register_irq(desc, d, vect->enum_id, evt2irq(vect->vect));
+ irq_desc = irq_to_desc_alloc_cpu(irq, cpu);
+ if (unlikely(!irq_desc)) {
+ printk(KERN_INFO "can not get irq_desc for %d\n", irq);
+ continue;
+ }
+
+ intc_register_irq(desc, d, vect->enum_id, irq);
}
}
/* get intc controller associated with this sysdev */
d = container_of(dev, struct intc_desc_int, sysdev);
- /* enable wakeup irqs belonging to this intc controller */
- for_each_irq_desc(irq, desc) {
- if ((desc->status & IRQ_WAKEUP) && (desc->chip == &d->chip))
- intc_enable(irq);
+ switch (state.event) {
+ case PM_EVENT_ON:
+ if (d->state.event != PM_EVENT_FREEZE)
+ break;
+ for_each_irq_desc(irq, desc) {
+ if (desc->chip != &d->chip)
+ continue;
+ if (desc->status & IRQ_DISABLED)
+ intc_disable(irq);
+ else
+ intc_enable(irq);
+ }
+ 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_irq_desc(irq, desc) {
+ if ((desc->status & IRQ_WAKEUP) && (desc->chip == &d->chip))
+ intc_enable(irq);
+ }
+ break;
}
+ d->state = state;
return 0;
}
+static int intc_resume(struct sys_device *dev)
+{
+ return intc_suspend(dev, PMSG_ON);
+}
+
static struct sysdev_class intc_sysdev_class = {
.name = "intc",
.suspend = intc_suspend,
+ .resume = intc_resume,
};
/* register this intc as sysdev to allow suspend/resume */