aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/apm.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel/apm.c')
-rw-r--r--arch/i386/kernel/apm.c42
1 files changed, 30 insertions, 12 deletions
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index b42f2d914af3..a97847da9ed5 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -198,7 +198,7 @@
198 * (APM) BIOS Interface Specification, Revision 1.2, February 1996. 198 * (APM) BIOS Interface Specification, Revision 1.2, February 1996.
199 * 199 *
200 * [This document is available from Microsoft at: 200 * [This document is available from Microsoft at:
201 * http://www.microsoft.com/hwdev/busbios/amp_12.htm] 201 * http://www.microsoft.com/whdc/archive/amp_12.mspx]
202 */ 202 */
203 203
204#include <linux/module.h> 204#include <linux/module.h>
@@ -231,6 +231,7 @@
231#include <asm/uaccess.h> 231#include <asm/uaccess.h>
232#include <asm/desc.h> 232#include <asm/desc.h>
233#include <asm/i8253.h> 233#include <asm/i8253.h>
234#include <asm/paravirt.h>
234 235
235#include "io_ports.h" 236#include "io_ports.h"
236 237
@@ -540,11 +541,30 @@ static inline void apm_restore_cpus(cpumask_t mask)
540 * Also, we KNOW that for the non error case of apm_bios_call, there 541 * Also, we KNOW that for the non error case of apm_bios_call, there
541 * is no useful data returned in the low order 8 bits of eax. 542 * is no useful data returned in the low order 8 bits of eax.
542 */ 543 */
543#define APM_DO_CLI \ 544
544 if (apm_info.allow_ints) \ 545static inline unsigned long __apm_irq_save(void)
545 local_irq_enable(); \ 546{
546 else \ 547 unsigned long flags;
548 local_save_flags(flags);
549 if (apm_info.allow_ints) {
550 if (irqs_disabled_flags(flags))
551 local_irq_enable();
552 } else
553 local_irq_disable();
554
555 return flags;
556}
557
558#define apm_irq_save(flags) \
559 do { flags = __apm_irq_save(); } while (0)
560
561static inline void apm_irq_restore(unsigned long flags)
562{
563 if (irqs_disabled_flags(flags))
547 local_irq_disable(); 564 local_irq_disable();
565 else if (irqs_disabled())
566 local_irq_enable();
567}
548 568
549#ifdef APM_ZERO_SEGS 569#ifdef APM_ZERO_SEGS
550# define APM_DECL_SEGS \ 570# define APM_DECL_SEGS \
@@ -596,12 +616,11 @@ static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in,
596 save_desc_40 = gdt[0x40 / 8]; 616 save_desc_40 = gdt[0x40 / 8];
597 gdt[0x40 / 8] = bad_bios_desc; 617 gdt[0x40 / 8] = bad_bios_desc;
598 618
599 local_save_flags(flags); 619 apm_irq_save(flags);
600 APM_DO_CLI;
601 APM_DO_SAVE_SEGS; 620 APM_DO_SAVE_SEGS;
602 apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi); 621 apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
603 APM_DO_RESTORE_SEGS; 622 APM_DO_RESTORE_SEGS;
604 local_irq_restore(flags); 623 apm_irq_restore(flags);
605 gdt[0x40 / 8] = save_desc_40; 624 gdt[0x40 / 8] = save_desc_40;
606 put_cpu(); 625 put_cpu();
607 apm_restore_cpus(cpus); 626 apm_restore_cpus(cpus);
@@ -640,12 +659,11 @@ static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax)
640 save_desc_40 = gdt[0x40 / 8]; 659 save_desc_40 = gdt[0x40 / 8];
641 gdt[0x40 / 8] = bad_bios_desc; 660 gdt[0x40 / 8] = bad_bios_desc;
642 661
643 local_save_flags(flags); 662 apm_irq_save(flags);
644 APM_DO_CLI;
645 APM_DO_SAVE_SEGS; 663 APM_DO_SAVE_SEGS;
646 error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax); 664 error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
647 APM_DO_RESTORE_SEGS; 665 APM_DO_RESTORE_SEGS;
648 local_irq_restore(flags); 666 apm_irq_restore(flags);
649 gdt[0x40 / 8] = save_desc_40; 667 gdt[0x40 / 8] = save_desc_40;
650 put_cpu(); 668 put_cpu();
651 apm_restore_cpus(cpus); 669 apm_restore_cpus(cpus);
@@ -2218,7 +2236,7 @@ static int __init apm_init(void)
2218 2236
2219 dmi_check_system(apm_dmi_table); 2237 dmi_check_system(apm_dmi_table);
2220 2238
2221 if (apm_info.bios.version == 0) { 2239 if (apm_info.bios.version == 0 || paravirt_enabled()) {
2222 printk(KERN_INFO "apm: BIOS not found.\n"); 2240 printk(KERN_INFO "apm: BIOS not found.\n");
2223 return -ENODEV; 2241 return -ENODEV;
2224 } 2242 }