Merge remote-tracking branch 'asoc/fix/core' into asoc-linus
[linux-2.6-microblaze.git] / arch / x86 / kernel / i8259.c
index 2e977b5..8af8171 100644 (file)
@@ -299,13 +299,31 @@ static void unmask_8259A(void)
 static void init_8259A(int auto_eoi)
 {
        unsigned long flags;
+       unsigned char probe_val = ~(1 << PIC_CASCADE_IR);
+       unsigned char new_val;
 
        i8259A_auto_eoi = auto_eoi;
 
        raw_spin_lock_irqsave(&i8259A_lock, flags);
 
-       outb(0xff, PIC_MASTER_IMR);     /* mask all of 8259A-1 */
+       /*
+        * Check to see if we have a PIC.
+        * Mask all except the cascade and read
+        * back the value we just wrote. If we don't
+        * have a PIC, we will read 0xff as opposed to the
+        * value we wrote.
+        */
        outb(0xff, PIC_SLAVE_IMR);      /* mask all of 8259A-2 */
+       outb(probe_val, PIC_MASTER_IMR);
+       new_val = inb(PIC_MASTER_IMR);
+       if (new_val != probe_val) {
+               printk(KERN_INFO "Using NULL legacy PIC\n");
+               legacy_pic = &null_legacy_pic;
+               raw_spin_unlock_irqrestore(&i8259A_lock, flags);
+               return;
+       }
+
+       outb(0xff, PIC_MASTER_IMR);     /* mask all of 8259A-1 */
 
        /*
         * outb_pic - this has to work on a wide range of PC hardware.