Merge branches 'acpi_pad-bugzilla-42981', 'apei-bugzilla-43282', 'video-bugzilla...
authorLen Brown <len.brown@intel.com>
Sat, 30 Jun 2012 04:53:50 +0000 (00:53 -0400)
committerLen Brown <len.brown@intel.com>
Sat, 30 Jun 2012 04:53:50 +0000 (00:53 -0400)
bug fixes

1  2  3  4  5 
arch/x86/kernel/reboot.c
drivers/acpi/video.c

diff --combined arch/x86/kernel/reboot.c
     #ifdef CONFIG_X86_32
     # include <linux/ctype.h>
     # include <linux/mc146818rtc.h>
+ +  # include <asm/realmode.h>
     #else
     # include <asm/x86_init.h>
     #endif
@@@@@@ -39,7 -40,8 -39,7 -40,8 -40,8 +40,8 @@@@@@ static int reboot_mode
     enum reboot_type reboot_type = BOOT_ACPI;
     int reboot_force;
     
- -  /* This variable is used privately to keep track of whether or not
+ +  /*
+ +   * This variable is used privately to keep track of whether or not
      * reboot_type is still set to its default value (i.e., reboot= hasn't
      * been set on the command line).  This is needed so that we can
      * suppress DMI scanning for reboot quirks.  Without it, it's
@@@@@@ -51,7 -53,8 -51,7 -53,8 -53,8 +53,8 @@@@@@ static int reboot_default = 1
     static int reboot_cpu = -1;
     #endif
     
- -  /* This is set if we need to go through the 'emergency' path.
+ +  /*
+ +   * This is set if we need to go through the 'emergency' path.
      * When machine_emergency_restart() is called, we may be on
      * an inconsistent state and won't be able to do a clean cleanup
      */
@@@@@@ -60,22 -63,24 -60,22 -63,24 -63,24 +63,24 @@@@@@ static int reboot_emergency
     /* This is set by the PCI code if either type 1 or type 2 PCI is detected */
     bool port_cf9_safe = false;
     
- -  /* reboot=b[ios] | s[mp] | t[riple] | k[bd] | e[fi] [, [w]arm | [c]old] | p[ci]
- -     warm   Don't set the cold reboot flag
- -     cold   Set the cold reboot flag
- -     bios   Reboot by jumping through the BIOS (only for X86_32)
- -     smp    Reboot by executing reset on BSP or other CPU (only for X86_32)
- -     triple Force a triple fault (init)
- -     kbd    Use the keyboard controller. cold reset (default)
- -     acpi   Use the RESET_REG in the FADT
- -     efi    Use efi reset_system runtime service
- -     pci    Use the so-called "PCI reset register", CF9
- -     force  Avoid anything that could hang.
+ +  /*
+ +   * reboot=b[ios] | s[mp] | t[riple] | k[bd] | e[fi] [, [w]arm | [c]old] | p[ci]
+ +   * warm   Don't set the cold reboot flag
+ +   * cold   Set the cold reboot flag
+ +   * bios   Reboot by jumping through the BIOS (only for X86_32)
+ +   * smp    Reboot by executing reset on BSP or other CPU (only for X86_32)
+ +   * triple Force a triple fault (init)
+ +   * kbd    Use the keyboard controller. cold reset (default)
+ +   * acpi   Use the RESET_REG in the FADT
+ +   * efi    Use efi reset_system runtime service
+ +   * pci    Use the so-called "PCI reset register", CF9
+ +   * force  Avoid anything that could hang.
      */
     static int __init reboot_setup(char *str)
     {
        for (;;) {
- -             /* Having anything passed on the command line via
+ +             /*
+ +              * Having anything passed on the command line via
                 * reboot= will cause us to disable DMI checking
                 * below.
                 */
                                if (isdigit(*(str+2)))
                                        reboot_cpu = reboot_cpu*10 + (int)(*(str+2) - '0');
                        }
- -                             /* we will leave sorting out the final value
- -                                when we are ready to reboot, since we might not
- -                                have detected BSP APIC ID or smp_num_cpu */
+ +                     /*
+ +                      * We will leave sorting out the final value
+ +                      * when we are ready to reboot, since we might not
+ +                      * have detected BSP APIC ID or smp_num_cpu
+ +                      */
                        break;
     #endif /* CONFIG_SMP */
     
@@@@@@ -150,6 -157,62 -150,6 -157,62 -157,62 +157,62 @@@@@@ static int __init set_bios_reboot(cons
        return 0;
     }
     
+ +  void machine_real_restart(unsigned int type)
+ +  {
+ +     void (*restart_lowmem)(unsigned int) = (void (*)(unsigned int))
+ +             real_mode_header->machine_real_restart_asm;
+ +  
+ +     local_irq_disable();
+ +  
+ +     /*
+ +      * Write zero to CMOS register number 0x0f, which the BIOS POST
+ +      * routine will recognize as telling it to do a proper reboot.  (Well
+ +      * that's what this book in front of me says -- it may only apply to
+ +      * the Phoenix BIOS though, it's not clear).  At the same time,
+ +      * disable NMIs by setting the top bit in the CMOS address register,
+ +      * as we're about to do peculiar things to the CPU.  I'm not sure if
+ +      * `outb_p' is needed instead of just `outb'.  Use it to be on the
+ +      * safe side.  (Yes, CMOS_WRITE does outb_p's. -  Paul G.)
+ +      */
+ +     spin_lock(&rtc_lock);
+ +     CMOS_WRITE(0x00, 0x8f);
+ +     spin_unlock(&rtc_lock);
+ +  
+ +     /*
+ +      * Switch back to the initial page table.
+ +      */
+ +     load_cr3(initial_page_table);
+ +  
+ +     /*
+ +      * Write 0x1234 to absolute memory location 0x472.  The BIOS reads
+ +      * this on booting to tell it to "Bypass memory test (also warm
+ +      * boot)".  This seems like a fairly standard thing that gets set by
+ +      * REBOOT.COM programs, and the previous reset routine did this
+ +      * too. */
+ +     *((unsigned short *)0x472) = reboot_mode;
+ +  
+ +     /* Jump to the identity-mapped low memory code */
+ +     restart_lowmem(type);
+ +  }
+ +  #ifdef CONFIG_APM_MODULE
+ +  EXPORT_SYMBOL(machine_real_restart);
+ +  #endif
+ +  
+ +  #endif /* CONFIG_X86_32 */
+ +  
+ +  /*
+ +   * Some Apple MacBook and MacBookPro's needs reboot=p to be able to reboot
+ +   */
+ +  static int __init set_pci_reboot(const struct dmi_system_id *d)
+ +  {
+ +     if (reboot_type != BOOT_CF9) {
+ +             reboot_type = BOOT_CF9;
+ +             printk(KERN_INFO "%s series board detected. "
+ +                    "Selecting PCI-method for reboots.\n", d->ident);
+ +     }
+ +     return 0;
+ +  }
+ +  
     static int __init set_kbd_reboot(const struct dmi_system_id *d)
     {
        if (reboot_type != BOOT_KBD) {
        return 0;
     }
     
+ +  /*
+ +   * This is a single dmi_table handling all reboot quirks.  Note that
+ +   * REBOOT_BIOS is only available for 32bit
+ +   */
     static struct dmi_system_id __initdata reboot_dmi_table[] = {
+ +  #ifdef CONFIG_X86_32
        {       /* Handle problems with rebooting on Dell E520's */
                .callback = set_bios_reboot,
                .ident = "Dell E520",
                        DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 300/"),
                },
        },
- -     {       /* Handle problems with rebooting on Dell Optiplex 745's SFF*/
+ +     {       /* Handle problems with rebooting on Dell Optiplex 745's SFF */
                .callback = set_bios_reboot,
                .ident = "Dell OptiPlex 745",
                .matches = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 745"),
                },
        },
- -     {       /* Handle problems with rebooting on Dell Optiplex 745's DFF*/
+ +     {       /* Handle problems with rebooting on Dell Optiplex 745's DFF */
                .callback = set_bios_reboot,
                .ident = "Dell OptiPlex 745",
                .matches = {
                        DMI_MATCH(DMI_BOARD_NAME, "0MM599"),
                },
        },
- -     {       /* Handle problems with rebooting on Dell Optiplex 745 with 0KW626 */
+ +     {       /* Handle problems with rebooting on Dell Optiplex 745 with 0KW626 */
                .callback = set_bios_reboot,
                .ident = "Dell OptiPlex 745",
                .matches = {
                        DMI_MATCH(DMI_BOARD_NAME, "0KW626"),
                },
        },
- -     {   /* Handle problems with rebooting on Dell Optiplex 330 with 0KP561 */
+ +     {       /* Handle problems with rebooting on Dell Optiplex 330 with 0KP561 */
                .callback = set_bios_reboot,
                .ident = "Dell OptiPlex 330",
                .matches = {
                        DMI_MATCH(DMI_BOARD_NAME, "0KP561"),
                },
        },
- -     {   /* Handle problems with rebooting on Dell Optiplex 360 with 0T656F */
+ +     {       /* Handle problems with rebooting on Dell Optiplex 360 with 0T656F */
                .callback = set_bios_reboot,
                .ident = "Dell OptiPlex 360",
                .matches = {
                        DMI_MATCH(DMI_BOARD_NAME, "0T656F"),
                },
        },
- -     {       /* Handle problems with rebooting on Dell OptiPlex 760 with 0G919G*/
+ +     {       /* Handle problems with rebooting on Dell OptiPlex 760 with 0G919G */
                .callback = set_bios_reboot,
                .ident = "Dell OptiPlex 760",
                .matches = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "SBC-FITPC2"),
                },
        },
- -     {       /* Handle problems with rebooting on ASUS P4S800 */
+ +     {       /* Handle problems with rebooting on ASUS P4S800 */
                .callback = set_bios_reboot,
                .ident = "ASUS P4S800",
                .matches = {
                        DMI_MATCH(DMI_BOARD_NAME, "P4S800"),
                },
        },
- -     { /* Handle reboot issue on Acer Aspire one */
+ +  #endif /* CONFIG_X86_32 */
+ +  
+ +     {       /* Handle reboot issue on Acer Aspire one */
                .callback = set_kbd_reboot,
                .ident = "Acer Aspire One A110",
                .matches = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"),
                },
        },
- -     { }
- -  };
- -  
- -  static int __init reboot_init(void)
- -  {
- -     /* Only do the DMI check if reboot_type hasn't been overridden
- -      * on the command line
- -      */
- -     if (reboot_default) {
- -             dmi_check_system(reboot_dmi_table);
- -     }
- -     return 0;
- -  }
- -  core_initcall(reboot_init);
- -  
- -  extern const unsigned char machine_real_restart_asm[];
- -  extern const u64 machine_real_restart_gdt[3];
- -  
- -  void machine_real_restart(unsigned int type)
- -  {
- -     void *restart_va;
- -     unsigned long restart_pa;
- -     void (*restart_lowmem)(unsigned int);
- -     u64 *lowmem_gdt;
- -  
- -     local_irq_disable();
- -  
- -     /* Write zero to CMOS register number 0x0f, which the BIOS POST
- -        routine will recognize as telling it to do a proper reboot.  (Well
- -        that's what this book in front of me says -- it may only apply to
- -        the Phoenix BIOS though, it's not clear).  At the same time,
- -        disable NMIs by setting the top bit in the CMOS address register,
- -        as we're about to do peculiar things to the CPU.  I'm not sure if
- -        `outb_p' is needed instead of just `outb'.  Use it to be on the
- -        safe side.  (Yes, CMOS_WRITE does outb_p's. -  Paul G.)
- -      */
- -     spin_lock(&rtc_lock);
- -     CMOS_WRITE(0x00, 0x8f);
- -     spin_unlock(&rtc_lock);
- -  
- -     /*
- -      * Switch back to the initial page table.
- -      */
- -     load_cr3(initial_page_table);
- -  
- -     /* Write 0x1234 to absolute memory location 0x472.  The BIOS reads
- -        this on booting to tell it to "Bypass memory test (also warm
- -        boot)".  This seems like a fairly standard thing that gets set by
- -        REBOOT.COM programs, and the previous reset routine did this
- -        too. */
- -     *((unsigned short *)0x472) = reboot_mode;
- -  
- -     /* Patch the GDT in the low memory trampoline */
- -     lowmem_gdt = TRAMPOLINE_SYM(machine_real_restart_gdt);
- -  
- -     restart_va = TRAMPOLINE_SYM(machine_real_restart_asm);
- -     restart_pa = virt_to_phys(restart_va);
- -     restart_lowmem = (void (*)(unsigned int))restart_pa;
- -  
- -     /* GDT[0]: GDT self-pointer */
- -     lowmem_gdt[0] =
- -             (u64)(sizeof(machine_real_restart_gdt) - 1) +
- -             ((u64)virt_to_phys(lowmem_gdt) << 16);
- -     /* GDT[1]: 64K real mode code segment */
- -     lowmem_gdt[1] =
- -             GDT_ENTRY(0x009b, restart_pa, 0xffff);
- -  
- -     /* Jump to the identity-mapped low memory code */
- -     restart_lowmem(type);
- -  }
- -  #ifdef CONFIG_APM_MODULE
- -  EXPORT_SYMBOL(machine_real_restart);
- -  #endif
- -  
- -  #endif /* CONFIG_X86_32 */
- -  
- -  /*
- -   * Some Apple MacBook and MacBookPro's needs reboot=p to be able to reboot
- -   */
- -  static int __init set_pci_reboot(const struct dmi_system_id *d)
- -  {
- -     if (reboot_type != BOOT_CF9) {
- -             reboot_type = BOOT_CF9;
- -             printk(KERN_INFO "%s series board detected. "
- -                    "Selecting PCI-method for reboots.\n", d->ident);
- -     }
- -     return 0;
- -  }
- -  
- -  static struct dmi_system_id __initdata pci_reboot_dmi_table[] = {
        {       /* Handle problems with rebooting on Apple MacBook5 */
                .callback = set_pci_reboot,
                .ident = "Apple MacBook5",
                        DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 990"),
                },
        },
++++    {       /* Handle problems with rebooting on the Precision M6600. */
++++            .callback = set_pci_reboot,
++++            .ident = "Dell OptiPlex 990",
++++            .matches = {
++++                    DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++++                    DMI_MATCH(DMI_PRODUCT_NAME, "Precision M6600"),
++++            },
++++    },
        { }
     };
     
- -  static int __init pci_reboot_init(void)
+ +  static int __init reboot_init(void)
     {
- -     /* Only do the DMI check if reboot_type hasn't been overridden
+ +     /*
+ +      * Only do the DMI check if reboot_type hasn't been overridden
         * on the command line
         */
- -     if (reboot_default) {
- -             dmi_check_system(pci_reboot_dmi_table);
- -     }
+ +     if (reboot_default)
+ +             dmi_check_system(reboot_dmi_table);
        return 0;
     }
- -  core_initcall(pci_reboot_init);
+ +  core_initcall(reboot_init);
     
     static inline void kb_wait(void)
     {
@@@@@@ -502,14 -482,14 -502,14 -482,14 -490,14 +490,14 @@@@@@ static void vmxoff_nmi(int cpu, struct 
        cpu_emergency_vmxoff();
     }
     
- -  /* Use NMIs as IPIs to tell all CPUs to disable virtualization
- -   */
+ +  /* Use NMIs as IPIs to tell all CPUs to disable virtualization */
     static void emergency_vmx_disable_all(void)
     {
        /* Just make sure we won't change CPUs while doing this */
        local_irq_disable();
     
- -     /* We need to disable VMX on all CPUs before rebooting, otherwise
+ +     /*
+ +      * We need to disable VMX on all CPUs before rebooting, otherwise
         * we risk hanging up the machine, because the CPU ignore INIT
         * signals when VMX is enabled.
         *
         * is still enabling VMX.
         */
        if (cpu_has_vmx() && cpu_vmx_enabled()) {
- -             /* Disable VMX on this CPU.
- -              */
+ +             /* Disable VMX on this CPU. */
                cpu_vmxoff();
     
                /* Halt and disable VMX on the other CPUs */
@@@@@@ -574,12 -553,12 -574,12 -553,12 -561,12 +561,12 @@@@@@ static void native_machine_emergency_re
                /* Could also try the reset bit in the Hammer NB */
                switch (reboot_type) {
                case BOOT_KBD:
- -                     mach_reboot_fixups(); /* for board specific fixups */
+ +                     mach_reboot_fixups(); /* For board specific fixups */
     
                        for (i = 0; i < 10; i++) {
                                kb_wait();
                                udelay(50);
- -                             outb(0xfe, 0x64); /* pulse reset low */
+ +                             outb(0xfe, 0x64); /* Pulse reset low */
                                udelay(50);
                        }
                        if (attempt == 0 && orig_reboot_type == BOOT_ACPI) {
     
                case BOOT_CF9:
                        port_cf9_safe = true;
- -                     /* fall through */
+ +                     /* Fall through */
     
                case BOOT_CF9_COND:
                        if (port_cf9_safe) {
@@@@@@ -659,9 -638,12 -659,9 -638,12 -646,10 +646,12 @@@@@@ void native_machine_shutdown(void
        /* Make certain I only run on the appropriate processor */
        set_cpus_allowed_ptr(current, cpumask_of(reboot_cpu_id));
     
- -     /* O.K Now that I'm on the appropriate processor,
- -      * stop all of the others.
+ +     /*
    -    * O.K Now that I'm on the appropriate processor,
    -    * stop all of the others.
+ + +    * O.K Now that I'm on the appropriate processor, stop all of the
+ + +    * others. Also disable the local irq to not receive the per-cpu
+ + +    * timer interrupt which may trigger scheduler's load balance.
         */
+ + +   local_irq_disable();
        stop_other_cpus();
     #endif
     
@@@@@@ -697,12 -679,11 -697,12 -679,11 -685,11 +687,11 @@@@@@ static void native_machine_restart(cha
     
     static void native_machine_halt(void)
     {
- -     /* stop other cpus and apics */
+ +     /* Stop other cpus and apics */
        machine_shutdown();
     
        tboot_shutdown(TB_SHUTDOWN_HALT);
     
- -     /* stop this cpu */
        stop_this_cpu(NULL);
     }
     
@@@@@@ -713,7 -694,7 -713,7 -694,7 -700,7 +702,7 @@@@@@ static void native_machine_power_off(vo
                        machine_shutdown();
                pm_power_off();
        }
- -     /* a fallback in case there is no PM info available */
+ +     /* A fallback in case there is no PM info available */
        tboot_shutdown(TB_SHUTDOWN_HALT);
     }
     
@@@@@@ -775,7 -756,8 -775,7 -756,8 -762,8 +764,8 @@@@@@ static int crash_nmi_callback(unsigned 
     
        cpu = raw_smp_processor_id();
     
- -     /* Don't do anything if this handler is invoked on crashing cpu.
+ +     /*
+ +      * Don't do anything if this handler is invoked on crashing cpu.
         * Otherwise, system will completely hang. Crashing cpu can get
         * an NMI if system was initially booted with nmi_watchdog parameter.
         */
@@@@@@ -799,7 -781,8 -799,7 -781,8 -787,8 +789,8 @@@@@@ static void smp_send_nmi_allbutself(voi
        apic->send_IPI_allbutself(NMI_VECTOR);
     }
     
- -  /* Halt all other CPUs, calling the specified function on each of them
+ +  /*
+ +   * Halt all other CPUs, calling the specified function on each of them
      *
      * This function can be used to halt all other CPUs on crash
      * or emergency reboot time. The function passed as parameter
@@@@@@ -810,7 -793,7 -810,7 -793,7 -799,7 +801,7 @@@@@@ void nmi_shootdown_cpus(nmi_shootdown_c
        unsigned long msecs;
        local_irq_disable();
     
- -     /* Make a note of crashing cpu. Will be used in NMI callback.*/
+ +     /* Make a note of crashing cpu. Will be used in NMI callback. */
        crashing_cpu = safe_smp_processor_id();
     
        shootdown_callback = callback;
        /* Would it be better to replace the trap vector here? */
        if (register_nmi_handler(NMI_LOCAL, crash_nmi_callback,
                                 NMI_FLAG_FIRST, "crash"))
- -             return;         /* return what? */
- -     /* Ensure the new callback function is set before sending
+ +             return;         /* Return what? */
+ +     /*
+ +      * Ensure the new callback function is set before sending
         * out the NMI
         */
        wmb();
diff --combined drivers/acpi/video.c
@@@@@@ -558,6 -558,6 -558,8 -558,6 -558,6 +558,8 @@@@@@ acpi_video_bus_DOS(struct acpi_video_bu
        union acpi_object arg0 = { ACPI_TYPE_INTEGER };
        struct acpi_object_list args = { 1, &arg0 };
     
++ ++   if (!video->cap._DOS)
++ ++           return 0;
     
        if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1)
                return -EINVAL;
@@@@@@ -1687,10 -1687,6 -1689,10 -1687,6 -1687,10 +1689,6 @@@@@@ static int acpi_video_bus_add(struct ac
        set_bit(KEY_BRIGHTNESS_ZERO, input->keybit);
        set_bit(KEY_DISPLAY_OFF, input->keybit);
     
- - -   error = input_register_device(input);
- - -   if (error)
- - -           goto err_stop_video;
- - -
        printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s  rom: %s  post: %s)\n",
               ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device),
               video->flags.multihead ? "yes" : "no",
        video->pm_nb.priority = 0;
        error = register_pm_notifier(&video->pm_nb);
        if (error)
- - -           goto err_unregister_input_dev;
+ + +           goto err_stop_video;
+ + +
+ + +   error = input_register_device(input);
+ + +   if (error)
+ + +           goto err_unregister_pm_notifier;
     
        return 0;
     
- - - err_unregister_input_dev:
- - -   input_unregister_device(input);
+ + + err_unregister_pm_notifier:
+ + +   unregister_pm_notifier(&video->pm_nb);
      err_stop_video:
        acpi_video_bus_stop_devices(video);
      err_free_input_dev:
@@@@@@ -1743,9 -1743,18 -1745,9 -1743,18 -1743,9 +1745,18 @@@@@@ static int acpi_video_bus_remove(struc
        return 0;
     }
     
+ + +static int __init is_i740(struct pci_dev *dev)
+ + +{
+ + +   if (dev->device == 0x00D1)
+ + +           return 1;
+ + +   if (dev->device == 0x7000)
+ + +           return 1;
+ + +   return 0;
+ + +}
+ + +
     static int __init intel_opregion_present(void)
     {
- - -#if defined(CONFIG_DRM_I915) || defined(CONFIG_DRM_I915_MODULE)
+ + +   int opregion = 0;
        struct pci_dev *dev = NULL;
        u32 address;
     
                        continue;
                if (dev->vendor != PCI_VENDOR_ID_INTEL)
                        continue;
+ + +           /* We don't want to poke around undefined i740 registers */
+ + +           if (is_i740(dev))
+ + +                   continue;
                pci_read_config_dword(dev, 0xfc, &address);
                if (!address)
                        continue;
- - -           return 1;
+ + +           opregion = 1;
        }
- - -#endif
- - -   return 0;
+ + +   return opregion;
     }
     
     int acpi_video_register(void)