Commit 52fb97fa authored by Len Brown's avatar Len Brown Committed by Len Brown

[ACPI] save/restore ELCR on suspend/resume (David Shaohua Li)

http://bugzilla.kernel.org/show_bug.cgi?id=2643
parent 0710ad20
...@@ -238,14 +238,39 @@ void mask_and_ack_8259A(unsigned int irq) ...@@ -238,14 +238,39 @@ void mask_and_ack_8259A(unsigned int irq)
} }
} }
static char irq_trigger[2];
/**
* ELCR registers (0x4d0, 0x4d1) control edge/level of IRQ
*/
static void restore_ELCR(char *trigger)
{
outb(trigger[0], 0x4d0);
outb(trigger[1], 0x4d1);
}
static void save_ELCR(char *trigger)
{
/* IRQ 0,1,2,8,13 are marked as reserved */
trigger[0] = inb(0x4d0) & 0xF8;
trigger[1] = inb(0x4d1) & 0xDE;
}
static int i8259A_resume(struct sys_device *dev) static int i8259A_resume(struct sys_device *dev)
{ {
init_8259A(0); init_8259A(0);
restore_ELCR(irq_trigger);
return 0;
}
static int i8259A_suspend(struct sys_device *dev, u32 state)
{
save_ELCR(irq_trigger);
return 0; return 0;
} }
static struct sysdev_class i8259_sysdev_class = { static struct sysdev_class i8259_sysdev_class = {
set_kset_name("i8259"), set_kset_name("i8259"),
.suspend = i8259A_suspend,
.resume = i8259A_resume, .resume = i8259A_resume,
}; };
......
...@@ -318,7 +318,7 @@ void mask_and_ack_8259A(unsigned int irq) ...@@ -318,7 +318,7 @@ void mask_and_ack_8259A(unsigned int irq)
} }
} }
void __init init_8259A(int auto_eoi) void init_8259A(int auto_eoi)
{ {
unsigned long flags; unsigned long flags;
...@@ -361,6 +361,57 @@ void __init init_8259A(int auto_eoi) ...@@ -361,6 +361,57 @@ void __init init_8259A(int auto_eoi)
spin_unlock_irqrestore(&i8259A_lock, flags); spin_unlock_irqrestore(&i8259A_lock, flags);
} }
static char irq_trigger[2];
/**
* ELCR registers (0x4d0, 0x4d1) control edge/level of IRQ
*/
static void restore_ELCR(char *trigger)
{
outb(trigger[0], 0x4d0);
outb(trigger[1], 0x4d1);
}
static void save_ELCR(char *trigger)
{
/* IRQ 0,1,2,8,13 are marked as reserved */
trigger[0] = inb(0x4d0) & 0xF8;
trigger[1] = inb(0x4d1) & 0xDE;
}
static int i8259A_resume(struct sys_device *dev)
{
init_8259A(0);
restore_ELCR(irq_trigger);
return 0;
}
static int i8259A_suspend(struct sys_device *dev, u32 state)
{
save_ELCR(irq_trigger);
return 0;
}
static struct sysdev_class i8259_sysdev_class = {
set_kset_name("i8259"),
.suspend = i8259A_suspend,
.resume = i8259A_resume,
};
static struct sys_device device_i8259A = {
.id = 0,
.cls = &i8259_sysdev_class,
};
static int __init i8259A_init_sysfs(void)
{
int error = sysdev_class_register(&i8259_sysdev_class);
if (!error)
error = sysdev_register(&device_i8259A);
return error;
}
device_initcall(i8259A_init_sysfs);
/* /*
* IRQ2 is cascade interrupt to second interrupt controller * IRQ2 is cascade interrupt to second interrupt controller
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment