]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/x86/kernel/apic/apic.c
Merge branches 'x86-apic-for-linus', 'x86-asm-for-linus' and 'x86-cleanups-for-linus...
[karo-tx-linux.git] / arch / x86 / kernel / apic / apic.c
index 966673f44141ef1db7d5f8e1ab198fc28b53f6df..ae147126b7b702c740ec674455495037cce1cc94 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/ftrace.h>
 #include <linux/ioport.h>
 #include <linux/module.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/delay.h>
 #include <linux/timex.h>
 #include <linux/dmar.h>
@@ -1812,30 +1812,41 @@ void smp_spurious_interrupt(struct pt_regs *regs)
  */
 void smp_error_interrupt(struct pt_regs *regs)
 {
-       u32 v, v1;
+       u32 v0, v1;
+       u32 i = 0;
+       static const char * const error_interrupt_reason[] = {
+               "Send CS error",                /* APIC Error Bit 0 */
+               "Receive CS error",             /* APIC Error Bit 1 */
+               "Send accept error",            /* APIC Error Bit 2 */
+               "Receive accept error",         /* APIC Error Bit 3 */
+               "Redirectable IPI",             /* APIC Error Bit 4 */
+               "Send illegal vector",          /* APIC Error Bit 5 */
+               "Received illegal vector",      /* APIC Error Bit 6 */
+               "Illegal register address",     /* APIC Error Bit 7 */
+       };
 
        exit_idle();
        irq_enter();
        /* First tickle the hardware, only then report what went on. -- REW */
-       v = apic_read(APIC_ESR);
+       v0 = apic_read(APIC_ESR);
        apic_write(APIC_ESR, 0);
        v1 = apic_read(APIC_ESR);
        ack_APIC_irq();
        atomic_inc(&irq_err_count);
 
-       /*
-        * Here is what the APIC error bits mean:
-        * 0: Send CS error
-        * 1: Receive CS error
-        * 2: Send accept error
-        * 3: Receive accept error
-        * 4: Reserved
-        * 5: Send illegal vector
-        * 6: Received illegal vector
-        * 7: Illegal register address
-        */
-       pr_debug("APIC error on CPU%d: %02x(%02x)\n",
-               smp_processor_id(), v , v1);
+       apic_printk(APIC_DEBUG, KERN_DEBUG "APIC error on CPU%d: %02x(%02x)",
+                   smp_processor_id(), v0 , v1);
+
+       v1 = v1 & 0xff;
+       while (v1) {
+               if (v1 & 0x1)
+                       apic_printk(APIC_DEBUG, KERN_CONT " : %s", error_interrupt_reason[i]);
+               i++;
+               v1 >>= 1;
+       };
+
+       apic_printk(APIC_DEBUG, KERN_CONT "\n");
+
        irq_exit();
 }
 
@@ -2046,7 +2057,7 @@ static struct {
        unsigned int apic_thmr;
 } apic_pm_state;
 
-static int lapic_suspend(struct sys_device *dev, pm_message_t state)
+static int lapic_suspend(void)
 {
        unsigned long flags;
        int maxlvt;
@@ -2084,23 +2095,21 @@ static int lapic_suspend(struct sys_device *dev, pm_message_t state)
        return 0;
 }
 
-static int lapic_resume(struct sys_device *dev)
+static void lapic_resume(void)
 {
        unsigned int l, h;
        unsigned long flags;
-       int maxlvt;
-       int ret = 0;
+       int maxlvt, ret;
        struct IO_APIC_route_entry **ioapic_entries = NULL;
 
        if (!apic_pm_state.active)
-               return 0;
+               return;
 
        local_irq_save(flags);
        if (intr_remapping_enabled) {
                ioapic_entries = alloc_ioapic_entries();
                if (!ioapic_entries) {
                        WARN(1, "Alloc ioapic_entries in lapic resume failed.");
-                       ret = -ENOMEM;
                        goto restore;
                }
 
@@ -2162,8 +2171,6 @@ static int lapic_resume(struct sys_device *dev)
        }
 restore:
        local_irq_restore(flags);
-
-       return ret;
 }
 
 /*
@@ -2171,17 +2178,11 @@ restore:
  * are needed on every CPU up until machine_halt/restart/poweroff.
  */
 
-static struct sysdev_class lapic_sysclass = {
-       .name           = "lapic",
+static struct syscore_ops lapic_syscore_ops = {
        .resume         = lapic_resume,
        .suspend        = lapic_suspend,
 };
 
-static struct sys_device device_lapic = {
-       .id     = 0,
-       .cls    = &lapic_sysclass,
-};
-
 static void __cpuinit apic_pm_activate(void)
 {
        apic_pm_state.active = 1;
@@ -2189,16 +2190,11 @@ static void __cpuinit apic_pm_activate(void)
 
 static int __init init_lapic_sysfs(void)
 {
-       int error;
-
-       if (!cpu_has_apic)
-               return 0;
        /* XXX: remove suspend/resume procs if !apic_pm_state.active? */
+       if (cpu_has_apic)
+               register_syscore_ops(&lapic_syscore_ops);
 
-       error = sysdev_class_register(&lapic_sysclass);
-       if (!error)
-               error = sysdev_register(&device_lapic);
-       return error;
+       return 0;
 }
 
 /* local apic needs to resume before other devices access its registers. */