]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/i386/kernel/apm.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-fixes-2.6
[linux-2.6-omap-h63xx.git] / arch / i386 / kernel / apm.c
index b42f2d914af3bb15eada724c854bc92581f47169..2af65858d3229b29cad60a7d25dc88a5a927bb5c 100644 (file)
@@ -540,11 +540,30 @@ static inline void apm_restore_cpus(cpumask_t mask)
  * Also, we KNOW that for the non error case of apm_bios_call, there
  * is no useful data returned in the low order 8 bits of eax.
  */
-#define APM_DO_CLI     \
-       if (apm_info.allow_ints) \
-               local_irq_enable(); \
-       else \
+
+static inline unsigned long __apm_irq_save(void)
+{
+       unsigned long flags;
+       local_save_flags(flags);
+       if (apm_info.allow_ints) {
+               if (irqs_disabled_flags(flags))
+                       local_irq_enable();
+       } else
+               local_irq_disable();
+
+       return flags;
+}
+
+#define apm_irq_save(flags) \
+       do { flags = __apm_irq_save(); } while (0)
+
+static inline void apm_irq_restore(unsigned long flags)
+{
+       if (irqs_disabled_flags(flags))
                local_irq_disable();
+       else if (irqs_disabled())
+               local_irq_enable();
+}
 
 #ifdef APM_ZERO_SEGS
 #      define APM_DECL_SEGS \
@@ -596,12 +615,11 @@ static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in,
        save_desc_40 = gdt[0x40 / 8];
        gdt[0x40 / 8] = bad_bios_desc;
 
-       local_save_flags(flags);
-       APM_DO_CLI;
+       apm_irq_save(flags);
        APM_DO_SAVE_SEGS;
        apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
        APM_DO_RESTORE_SEGS;
-       local_irq_restore(flags);
+       apm_irq_restore(flags);
        gdt[0x40 / 8] = save_desc_40;
        put_cpu();
        apm_restore_cpus(cpus);
@@ -640,12 +658,11 @@ static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax)
        save_desc_40 = gdt[0x40 / 8];
        gdt[0x40 / 8] = bad_bios_desc;
 
-       local_save_flags(flags);
-       APM_DO_CLI;
+       apm_irq_save(flags);
        APM_DO_SAVE_SEGS;
        error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
        APM_DO_RESTORE_SEGS;
-       local_irq_restore(flags);
+       apm_irq_restore(flags);
        gdt[0x40 / 8] = save_desc_40;
        put_cpu();
        apm_restore_cpus(cpus);