diff options
Diffstat (limited to 'arch/x86/kernel/acpi')
21 files changed, 180 insertions, 704 deletions
diff --git a/arch/x86/kernel/acpi/Makefile b/arch/x86/kernel/acpi/Makefile index 6f35260bb3e..163b2258147 100644 --- a/arch/x86/kernel/acpi/Makefile +++ b/arch/x86/kernel/acpi/Makefile @@ -1,14 +1,7 @@ -subdir-				:= realmode -  obj-$(CONFIG_ACPI)		+= boot.o -obj-$(CONFIG_ACPI_SLEEP)	+= sleep.o wakeup_rm.o wakeup_$(BITS).o +obj-$(CONFIG_ACPI_SLEEP)	+= sleep.o wakeup_$(BITS).o  ifneq ($(CONFIG_ACPI_PROCESSOR),)  obj-y				+= cstate.o  endif -$(obj)/wakeup_rm.o:    $(obj)/realmode/wakeup.bin - -$(obj)/realmode/wakeup.bin: FORCE -	$(Q)$(MAKE) $(build)=$(obj)/realmode - diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 71232b941b6..86281ffb96d 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -44,20 +44,15 @@  #include <asm/mpspec.h>  #include <asm/smp.h> +#include "sleep.h" /* To include x86_acpi_suspend_lowlevel */  static int __initdata acpi_force = 0; -u32 acpi_rsdt_forced;  int acpi_disabled;  EXPORT_SYMBOL(acpi_disabled);  #ifdef	CONFIG_X86_64  # include <asm/proto.h> -# include <asm/numa_64.h>  #endif				/* X86 */ -#define BAD_MADT_ENTRY(entry, end) (					    \ -		(!entry) || (unsigned long)entry + sizeof(*entry) > end ||  \ -		((struct acpi_subtable_header *)entry)->length < sizeof(*entry)) -  #define PREFIX			"ACPI: "  int acpi_noirq;				/* skip ACPI IRQ initialization */ @@ -67,11 +62,13 @@ EXPORT_SYMBOL(acpi_pci_disabled);  int acpi_lapic;  int acpi_ioapic;  int acpi_strict; +int acpi_disable_cmcff;  u8 acpi_sci_flags __initdata;  int acpi_sci_override_gsi __initdata;  int acpi_skip_timer_override __initdata;  int acpi_use_timer_override __initdata; +int acpi_fix_pin2_polarity __initdata;  #ifdef CONFIG_X86_LOCAL_APIC  static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; @@ -140,16 +137,8 @@ static u32 irq_to_gsi(int irq)  }  /* - * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END, - * to map the target physical address. The problem is that set_fixmap() - * provides a single page, and it is possible that the page is not - * sufficient. - * By using this area, we can map up to MAX_IO_APICS pages temporarily, - * i.e. until the next __va_range() call. - * - * Important Safety Note:  The fixed I/O APIC page numbers are *subtracted* - * from the fixed base.  That's why we start at FIX_IO_APIC_BASE_END and - * count idx down while incrementing the phys address. + * This is just a simple wrapper around early_ioremap(), + * with sanity checks for phys == 0 and size == 0.   */  char *__init __acpi_map_table(unsigned long phys, unsigned long size)  { @@ -159,6 +148,7 @@ char *__init __acpi_map_table(unsigned long phys, unsigned long size)  	return early_ioremap(phys, size);  } +  void __init __acpi_unmap_table(char *map, unsigned long size)  {  	if (!map || !size) @@ -194,25 +184,39 @@ static int __init acpi_parse_madt(struct acpi_table_header *table)  	return 0;  } -static void __cpuinit acpi_register_lapic(int id, u8 enabled) +/** + * acpi_register_lapic - register a local apic and generates a logic cpu number + * @id: local apic id to register + * @enabled: this cpu is enabled or not + * + * Returns the logic cpu number which maps to the local apic + */ +static int acpi_register_lapic(int id, u8 enabled)  {  	unsigned int ver = 0; +	if (id >= MAX_LOCAL_APIC) { +		printk(KERN_INFO PREFIX "skipped apicid that is too big\n"); +		return -EINVAL; +	} +  	if (!enabled) {  		++disabled_cpus; -		return; +		return -EINVAL;  	}  	if (boot_cpu_physical_apicid != -1U)  		ver = apic_version[boot_cpu_physical_apicid]; -	generic_processor_info(id, ver); +	return generic_processor_info(id, ver);  }  static int __init  acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)  {  	struct acpi_madt_local_x2apic *processor = NULL; +	int apic_id; +	u8 enabled;  	processor = (struct acpi_madt_local_x2apic *)header; @@ -221,6 +225,8 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)  	acpi_table_print_madt_entry(header); +	apic_id = processor->local_apic_id; +	enabled = processor->lapic_flags & ACPI_MADT_ENABLED;  #ifdef CONFIG_X86_X2APIC  	/*  	 * We need to register disabled CPU as well to permit @@ -229,8 +235,10 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)  	 * to not preallocating memory for all NR_CPUS  	 * when we use CPU hotplug.  	 */ -	acpi_register_lapic(processor->local_apic_id,	/* APIC ID */ -			    processor->lapic_flags & ACPI_MADT_ENABLED); +	if (!apic->apic_id_valid(apic_id) && enabled) +		printk(KERN_WARNING PREFIX "x2apic entry ignored\n"); +	else +		acpi_register_lapic(apic_id, enabled);  #else  	printk(KERN_WARNING PREFIX "x2apic entry ignored\n");  #endif @@ -410,10 +418,17 @@ acpi_parse_int_src_ovr(struct acpi_subtable_header * header,  		return 0;  	} -	if (acpi_skip_timer_override && -	    intsrc->source_irq == 0 && intsrc->global_irq == 2) { -		printk(PREFIX "BIOS IRQ0 pin2 override ignored.\n"); -		return 0; +	if (intsrc->source_irq == 0) { +		if (acpi_skip_timer_override) { +			printk(PREFIX "BIOS IRQ0 override ignored.\n"); +			return 0; +		} + +		if ((intsrc->global_irq == 2) && acpi_fix_pin2_polarity +			&& (intsrc->inti_flags & ACPI_MADT_POLARITY_MASK)) { +			intsrc->inti_flags &= ~ACPI_MADT_POLARITY_MASK; +			printk(PREFIX "BIOS IRQ0 pin2 override: forcing polarity to high active.\n"); +		}  	}  	mp_override_legacy_irq(intsrc->source_irq, @@ -504,6 +519,7 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)  	return 0;  } +EXPORT_SYMBOL_GPL(acpi_gsi_to_irq);  int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)  { @@ -540,6 +556,12 @@ static int acpi_register_gsi_ioapic(struct device *dev, u32 gsi,  int (*__acpi_register_gsi)(struct device *dev, u32 gsi,  			   int trigger, int polarity) = acpi_register_gsi_pic; +#ifdef CONFIG_ACPI_SLEEP +int (*acpi_suspend_lowlevel)(void) = x86_acpi_suspend_lowlevel; +#else +int (*acpi_suspend_lowlevel)(void); +#endif +  /*   * success: return IRQ number (>=0)   * failure: return < 0 @@ -554,6 +576,12 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)  	return irq;  } +EXPORT_SYMBOL_GPL(acpi_register_gsi); + +void acpi_unregister_gsi(u32 gsi) +{ +} +EXPORT_SYMBOL_GPL(acpi_unregister_gsi);  void __init acpi_set_irq_model_pic(void)  { @@ -581,101 +609,43 @@ static void acpi_map_cpu2node(acpi_handle handle, int cpu, int physid)  	int nid;  	nid = acpi_get_node(handle); -	if (nid == -1 || !node_online(nid)) -		return; -#ifdef CONFIG_X86_64 -	apicid_to_node[physid] = nid; -	numa_set_node(cpu, nid); -#else /* CONFIG_X86_32 */ -	apicid_2_node[physid] = nid; -	cpu_to_node_map[cpu] = nid; -#endif - +	if (nid != -1) { +		set_apicid_to_node(physid, nid); +		numa_set_node(cpu, nid); +	}  #endif  } -static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu) +static int _acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu)  { -	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; -	union acpi_object *obj; -	struct acpi_madt_local_apic *lapic; -	cpumask_var_t tmp_map, new_map; -	u8 physid;  	int cpu; -	int retval = -ENOMEM; - -	if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) -		return -EINVAL; - -	if (!buffer.length || !buffer.pointer) -		return -EINVAL; - -	obj = buffer.pointer; -	if (obj->type != ACPI_TYPE_BUFFER || -	    obj->buffer.length < sizeof(*lapic)) { -		kfree(buffer.pointer); -		return -EINVAL; -	} - -	lapic = (struct acpi_madt_local_apic *)obj->buffer.pointer; -	if (lapic->header.type != ACPI_MADT_TYPE_LOCAL_APIC || -	    !(lapic->lapic_flags & ACPI_MADT_ENABLED)) { -		kfree(buffer.pointer); -		return -EINVAL; -	} - -	physid = lapic->id; - -	kfree(buffer.pointer); -	buffer.length = ACPI_ALLOCATE_BUFFER; -	buffer.pointer = NULL; - -	if (!alloc_cpumask_var(&tmp_map, GFP_KERNEL)) -		goto out; - -	if (!alloc_cpumask_var(&new_map, GFP_KERNEL)) -		goto free_tmp_map; - -	cpumask_copy(tmp_map, cpu_present_mask); -	acpi_register_lapic(physid, lapic->lapic_flags & ACPI_MADT_ENABLED); - -	/* -	 * If mp_register_lapic successfully generates a new logical cpu -	 * number, then the following will get us exactly what was mapped -	 */ -	cpumask_andnot(new_map, cpu_present_mask, tmp_map); -	if (cpumask_empty(new_map)) { -		printk ("Unable to map lapic to logical cpu number\n"); -		retval = -EINVAL; -		goto free_new_map; +	cpu = acpi_register_lapic(physid, ACPI_MADT_ENABLED); +	if (cpu < 0) { +		pr_info(PREFIX "Unable to map lapic to logical cpu number\n"); +		return cpu;  	}  	acpi_processor_set_pdc(handle); - -	cpu = cpumask_first(new_map);  	acpi_map_cpu2node(handle, cpu, physid);  	*pcpu = cpu; -	retval = 0; - -free_new_map: -	free_cpumask_var(new_map); -free_tmp_map: -	free_cpumask_var(tmp_map); -out: -	return retval; +	return 0;  }  /* wrapper to silence section mismatch warning */ -int __ref acpi_map_lsapic(acpi_handle handle, int *pcpu) +int __ref acpi_map_lsapic(acpi_handle handle, int physid, int *pcpu)  { -	return _acpi_map_lsapic(handle, pcpu); +	return _acpi_map_lsapic(handle, physid, pcpu);  }  EXPORT_SYMBOL(acpi_map_lsapic);  int acpi_unmap_lsapic(int cpu)  { +#ifdef CONFIG_ACPI_NUMA +	set_apicid_to_node(per_cpu(x86_cpu_to_apicid, cpu), NUMA_NO_NODE); +#endif +  	per_cpu(x86_cpu_to_apicid, cpu) = -1;  	set_cpu_present(cpu, false);  	num_processors--; @@ -720,7 +690,7 @@ static int __init acpi_parse_sbf(struct acpi_table_header *table)  #ifdef CONFIG_HPET_TIMER  #include <asm/hpet.h> -static struct __initdata resource *hpet_res; +static struct resource *hpet_res __initdata;  static int __init acpi_parse_hpet(struct acpi_table_header *table)  { @@ -847,18 +817,6 @@ static int __init acpi_parse_fadt(struct acpi_table_header *table)   * returns 0 on success, < 0 on error   */ -static void __init acpi_register_lapic_address(unsigned long address) -{ -	mp_lapic_addr = address; - -	set_fixmap_nocache(FIX_APIC_BASE, address); -	if (boot_cpu_physical_apicid == -1U) { -		boot_cpu_physical_apicid  = read_apic_id(); -		apic_version[boot_cpu_physical_apicid] = -			 GET_APIC_VERSION(apic_read(APIC_LVR)); -	} -} -  static int __init early_acpi_parse_madt_lapic_addr_ovr(void)  {  	int count; @@ -880,7 +838,7 @@ static int __init early_acpi_parse_madt_lapic_addr_ovr(void)  		return count;  	} -	acpi_register_lapic_address(acpi_lapic_addr); +	register_lapic_address(acpi_lapic_addr);  	return count;  } @@ -907,16 +865,16 @@ static int __init acpi_parse_madt_lapic_entries(void)  		return count;  	} -	acpi_register_lapic_address(acpi_lapic_addr); +	register_lapic_address(acpi_lapic_addr);  	count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC, -				      acpi_parse_sapic, MAX_APICS); +				      acpi_parse_sapic, MAX_LOCAL_APIC);  	if (!count) {  		x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC, -						acpi_parse_x2apic, MAX_APICS); +					acpi_parse_x2apic, MAX_LOCAL_APIC);  		count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC, -					      acpi_parse_lapic, MAX_APICS); +					acpi_parse_lapic, MAX_LOCAL_APIC);  	}  	if (!count && !x2count) {  		printk(KERN_ERR PREFIX "No LAPIC entries present\n"); @@ -945,36 +903,6 @@ static int __init acpi_parse_madt_lapic_entries(void)  #ifdef	CONFIG_X86_IO_APIC  #define MP_ISA_BUS		0 -#ifdef CONFIG_X86_ES7000 -extern int es7000_plat; -#endif - -static void assign_to_mp_irq(struct mpc_intsrc *m, -				    struct mpc_intsrc *mp_irq) -{ -	memcpy(mp_irq, m, sizeof(struct mpc_intsrc)); -} - -static int mp_irq_cmp(struct mpc_intsrc *mp_irq, -				struct mpc_intsrc *m) -{ -	return memcmp(mp_irq, m, sizeof(struct mpc_intsrc)); -} - -static void save_mp_irq(struct mpc_intsrc *m) -{ -	int i; - -	for (i = 0; i < mp_irq_entries; i++) { -		if (!mp_irq_cmp(&mp_irqs[i], m)) -			return; -	} - -	assign_to_mp_irq(m, &mp_irqs[mp_irq_entries]); -	if (++mp_irq_entries == MAX_IRQ_SOURCES) -		panic("Max # of irq sources exceeded!!\n"); -} -  void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)  {  	int ioapic; @@ -1002,10 +930,10 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)  	mp_irq.irqflag = (trigger << 2) | polarity;  	mp_irq.srcbus = MP_ISA_BUS;  	mp_irq.srcbusirq = bus_irq;	/* IRQ */ -	mp_irq.dstapic = mp_ioapics[ioapic].apicid; /* APIC ID */ +	mp_irq.dstapic = mpc_ioapic_id(ioapic); /* APIC ID */  	mp_irq.dstirq = pin;	/* INTIN# */ -	save_mp_irq(&mp_irq); +	mp_save_irq(&mp_irq);  	isa_irq_to_gsi[bus_irq] = gsi;  } @@ -1015,7 +943,7 @@ void __init mp_config_acpi_legacy_irqs(void)  	int i;  	struct mpc_intsrc mp_irq; -#if defined (CONFIG_MCA) || defined (CONFIG_EISA) +#ifdef CONFIG_EISA  	/*  	 * Fabricate the legacy ISA bus (bus #31).  	 */ @@ -1024,14 +952,6 @@ void __init mp_config_acpi_legacy_irqs(void)  	set_bit(MP_ISA_BUS, mp_bus_not_pci);  	pr_debug("Bus #%d is ISA\n", MP_ISA_BUS); -#ifdef CONFIG_X86_ES7000 -	/* -	 * Older generations of ES7000 have no legacy identity mappings -	 */ -	if (es7000_plat == 1) -		return; -#endif -  	/*  	 * Use the default configuration for the IRQs 0-15.  Unless  	 * overridden by (MADT) interrupt source override entries. @@ -1053,7 +973,7 @@ void __init mp_config_acpi_legacy_irqs(void)  		if (ioapic < 0)  			continue;  		pin = mp_find_ioapic_pin(ioapic, gsi); -		dstapic = mp_ioapics[ioapic].apicid; +		dstapic = mpc_ioapic_id(ioapic);  		for (idx = 0; idx < mp_irq_entries; idx++) {  			struct mpc_intsrc *irq = mp_irqs + idx; @@ -1080,7 +1000,7 @@ void __init mp_config_acpi_legacy_irqs(void)  		mp_irq.srcbusirq = i; /* Identity mapped */  		mp_irq.dstirq = pin; -		save_mp_irq(&mp_irq); +		mp_save_irq(&mp_irq);  	}  } @@ -1097,9 +1017,7 @@ static int mp_config_acpi_gsi(struct device *dev, u32 gsi, int trigger,  	if (!acpi_ioapic)  		return 0; -	if (!dev) -		return 0; -	if (dev->bus != &pci_bus_type) +	if (!dev || !dev_is_pci(dev))  		return 0;  	pdev = to_pci_dev(dev); @@ -1114,10 +1032,10 @@ static int mp_config_acpi_gsi(struct device *dev, u32 gsi, int trigger,  	mp_irq.srcbus = number;  	mp_irq.srcbusirq = (((devfn >> 3) & 0x1f) << 2) | ((pin - 1) & 3);  	ioapic = mp_find_ioapic(gsi); -	mp_irq.dstapic = mp_ioapics[ioapic].apicid; +	mp_irq.dstapic = mpc_ioapic_id(ioapic);  	mp_irq.dstirq = mp_find_ioapic_pin(ioapic, gsi); -	save_mp_irq(&mp_irq); +	mp_save_irq(&mp_irq);  #endif  	return 0;  } @@ -1127,6 +1045,7 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)  	int ioapic;  	int ioapic_pin;  	struct io_apic_irq_attr irq_attr; +	int ret;  	if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)  		return gsi; @@ -1145,7 +1064,7 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)  	if (ioapic_pin > MP_MAX_IOAPIC_PIN) {  		printk(KERN_ERR "Invalid reference to IOAPIC pin " -		       "%d-%d\n", mp_ioapics[ioapic].apicid, +		       "%d-%d\n", mpc_ioapic_id(ioapic),  		       ioapic_pin);  		return gsi;  	} @@ -1156,7 +1075,9 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)  	set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin,  			     trigger == ACPI_EDGE_SENSITIVE ? 0 : 1,  			     polarity == ACPI_ACTIVE_HIGH ? 0 : 1); -	io_apic_set_pci_routing(dev, gsi_to_irq(gsi), &irq_attr); +	ret = io_apic_set_pci_routing(dev, gsi_to_irq(gsi), &irq_attr); +	if (ret < 0) +		gsi = INT_MIN;  	return gsi;  } @@ -1359,17 +1280,12 @@ static int __init dmi_disable_acpi(const struct dmi_system_id *d)  }  /* - * Force ignoring BIOS IRQ0 pin2 override + * Force ignoring BIOS IRQ0 override   */  static int __init dmi_ignore_irq0_timer_override(const struct dmi_system_id *d)  { -	/* -	 * The ati_ixp4x0_rev() early PCI quirk should have set -	 * the acpi_skip_timer_override flag already: -	 */  	if (!acpi_skip_timer_override) { -		WARN(1, KERN_ERR "ati_ixp4x0 quirk not complete.\n"); -		pr_notice("%s detected: Ignoring BIOS IRQ0 pin2 override\n", +		pr_notice("%s detected: Ignoring BIOS IRQ0 override\n",  			d->ident);  		acpi_skip_timer_override = 1;  	} @@ -1463,7 +1379,7 @@ static struct dmi_system_id __initdata acpi_dmi_table_late[] = {  	 * is enabled.  This input is incorrectly designated the  	 * ISA IRQ 0 via an interrupt source override even though  	 * it is wired to the output of the master 8259A and INTIN0 -	 * is not connected at all.  Force ignoring BIOS IRQ0 pin2 +	 * is not connected at all.  Force ignoring BIOS IRQ0  	 * override in that cases.  	 */  	{ @@ -1498,6 +1414,14 @@ static struct dmi_system_id __initdata acpi_dmi_table_late[] = {  		     DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6715b"),  		     },  	 }, +	{ +	 .callback = dmi_ignore_irq0_timer_override, +	 .ident = "FUJITSU SIEMENS", +	 .matches = { +		     DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), +		     DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"), +		     }, +	 },  	{}  }; @@ -1621,7 +1545,7 @@ static int __init parse_acpi(char *arg)  	}  	/* acpi=rsdt use RSDT instead of XSDT */  	else if (strcmp(arg, "rsdt") == 0) { -		acpi_rsdt_forced = 1; +		acpi_gbl_do_not_use_xsdt = TRUE;  	}  	/* "acpi=noirq" disables ACPI interrupt routing */  	else if (strcmp(arg, "noirq") == 0) { @@ -1630,6 +1554,10 @@ static int __init parse_acpi(char *arg)  	/* "acpi=copy_dsdt" copys DSDT */  	else if (strcmp(arg, "copy_dsdt") == 0) {  		acpi_gbl_copy_dsdt_locally = 1; +	} +	/* "acpi=nocmcff" disables FF mode for corrected errors */ +	else if (strcmp(arg, "nocmcff") == 0) { +		acpi_disable_cmcff = 1;  	} else {  		/* Core will printk when we return error. */  		return -EINVAL; @@ -1720,3 +1648,9 @@ int __acpi_release_global_lock(unsigned int *lock)  	} while (unlikely (val != old));  	return old & 0x1;  } + +void __init arch_reserve_mem_area(acpi_physical_address addr, size_t size) +{ +	e820_add_region(addr, size, E820_ACPI); +	update_e820(); +} diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c index 5812404a0d4..4b28159e042 100644 --- a/arch/x86/kernel/acpi/cstate.c +++ b/arch/x86/kernel/acpi/cstate.c @@ -14,6 +14,7 @@  #include <acpi/processor.h>  #include <asm/acpi.h>  #include <asm/mwait.h> +#include <asm/special_insns.h>  /*   * Initialize bm_flags based on the CPU cache properties @@ -86,7 +87,9 @@ static long acpi_processor_ffh_cstate_probe_cpu(void *_cx)  	num_cstate_subtype = edx_part & MWAIT_SUBSTATE_MASK;  	retval = 0; -	if (num_cstate_subtype < (cx->address & MWAIT_SUBSTATE_MASK)) { +	/* If the HW does not support any sub-states in this C-state */ +	if (num_cstate_subtype == 0) { +		pr_warn(FW_BUG "ACPI MWAIT C-state 0x%x not supported by HW (0x%x)\n", cx->address, edx_part);  		retval = -1;  		goto out;  	} diff --git a/arch/x86/kernel/acpi/realmode/.gitignore b/arch/x86/kernel/acpi/realmode/.gitignore deleted file mode 100644 index 58f1f48a58f..00000000000 --- a/arch/x86/kernel/acpi/realmode/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -wakeup.bin -wakeup.elf -wakeup.lds diff --git a/arch/x86/kernel/acpi/realmode/Makefile b/arch/x86/kernel/acpi/realmode/Makefile deleted file mode 100644 index 6a564ac67ef..00000000000 --- a/arch/x86/kernel/acpi/realmode/Makefile +++ /dev/null @@ -1,59 +0,0 @@ -# -# arch/x86/kernel/acpi/realmode/Makefile -# -# This file is subject to the terms and conditions of the GNU General Public -# License.  See the file "COPYING" in the main directory of this archive -# for more details. -# - -always		:= wakeup.bin -targets		:= wakeup.elf wakeup.lds - -wakeup-y	+= wakeup.o wakemain.o video-mode.o copy.o bioscall.o regs.o - -# The link order of the video-*.o modules can matter.  In particular, -# video-vga.o *must* be listed first, followed by video-vesa.o. -# Hardware-specific drivers should follow in the order they should be -# probed, and video-bios.o should typically be last. -wakeup-y	+= video-vga.o -wakeup-y	+= video-vesa.o -wakeup-y	+= video-bios.o - -targets		+= $(wakeup-y) - -bootsrc		:= $(src)/../../../boot - -# --------------------------------------------------------------------------- - -# How to compile the 16-bit code.  Note we always compile for -march=i386, -# that way we can complain to the user if the CPU is insufficient. -# Compile with _SETUP since this is similar to the boot-time setup code. -KBUILD_CFLAGS	:= $(LINUXINCLUDE) -g -Os -D_SETUP -D_WAKEUP -D__KERNEL__ \ -		   -I$(srctree)/$(bootsrc) \ -		   $(cflags-y) \ -		   -Wall -Wstrict-prototypes \ -		   -march=i386 -mregparm=3 \ -		   -include $(srctree)/$(bootsrc)/code16gcc.h \ -		   -fno-strict-aliasing -fomit-frame-pointer \ -		   $(call cc-option, -ffreestanding) \ -		   $(call cc-option, -fno-toplevel-reorder,\ -			$(call cc-option, -fno-unit-at-a-time)) \ -		   $(call cc-option, -fno-stack-protector) \ -		   $(call cc-option, -mpreferred-stack-boundary=2) -KBUILD_CFLAGS	+= $(call cc-option, -m32) -KBUILD_AFLAGS	:= $(KBUILD_CFLAGS) -D__ASSEMBLY__ -GCOV_PROFILE := n - -WAKEUP_OBJS = $(addprefix $(obj)/,$(wakeup-y)) - -LDFLAGS_wakeup.elf	:= -T - -CPPFLAGS_wakeup.lds += -P -C - -$(obj)/wakeup.elf: $(obj)/wakeup.lds $(WAKEUP_OBJS) FORCE -	$(call if_changed,ld) - -OBJCOPYFLAGS_wakeup.bin	:= -O binary - -$(obj)/wakeup.bin: $(obj)/wakeup.elf FORCE -	$(call if_changed,objcopy) diff --git a/arch/x86/kernel/acpi/realmode/bioscall.S b/arch/x86/kernel/acpi/realmode/bioscall.S deleted file mode 100644 index f51eb0bb56c..00000000000 --- a/arch/x86/kernel/acpi/realmode/bioscall.S +++ /dev/null @@ -1 +0,0 @@ -#include "../../../boot/bioscall.S" diff --git a/arch/x86/kernel/acpi/realmode/copy.S b/arch/x86/kernel/acpi/realmode/copy.S deleted file mode 100644 index dc59ebee69d..00000000000 --- a/arch/x86/kernel/acpi/realmode/copy.S +++ /dev/null @@ -1 +0,0 @@ -#include "../../../boot/copy.S" diff --git a/arch/x86/kernel/acpi/realmode/regs.c b/arch/x86/kernel/acpi/realmode/regs.c deleted file mode 100644 index 6206033ba20..00000000000 --- a/arch/x86/kernel/acpi/realmode/regs.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../../boot/regs.c" diff --git a/arch/x86/kernel/acpi/realmode/video-bios.c b/arch/x86/kernel/acpi/realmode/video-bios.c deleted file mode 100644 index 7deabc144a2..00000000000 --- a/arch/x86/kernel/acpi/realmode/video-bios.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../../boot/video-bios.c" diff --git a/arch/x86/kernel/acpi/realmode/video-mode.c b/arch/x86/kernel/acpi/realmode/video-mode.c deleted file mode 100644 index 328ad209f11..00000000000 --- a/arch/x86/kernel/acpi/realmode/video-mode.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../../boot/video-mode.c" diff --git a/arch/x86/kernel/acpi/realmode/video-vesa.c b/arch/x86/kernel/acpi/realmode/video-vesa.c deleted file mode 100644 index 9dbb9672226..00000000000 --- a/arch/x86/kernel/acpi/realmode/video-vesa.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../../boot/video-vesa.c" diff --git a/arch/x86/kernel/acpi/realmode/video-vga.c b/arch/x86/kernel/acpi/realmode/video-vga.c deleted file mode 100644 index bcc81255f37..00000000000 --- a/arch/x86/kernel/acpi/realmode/video-vga.c +++ /dev/null @@ -1 +0,0 @@ -#include "../../../boot/video-vga.c" diff --git a/arch/x86/kernel/acpi/realmode/wakemain.c b/arch/x86/kernel/acpi/realmode/wakemain.c deleted file mode 100644 index 883962d9eef..00000000000 --- a/arch/x86/kernel/acpi/realmode/wakemain.c +++ /dev/null @@ -1,81 +0,0 @@ -#include "wakeup.h" -#include "boot.h" - -static void udelay(int loops) -{ -	while (loops--) -		io_delay();	/* Approximately 1 us */ -} - -static void beep(unsigned int hz) -{ -	u8 enable; - -	if (!hz) { -		enable = 0x00;		/* Turn off speaker */ -	} else { -		u16 div = 1193181/hz; - -		outb(0xb6, 0x43);	/* Ctr 2, squarewave, load, binary */ -		io_delay(); -		outb(div, 0x42);	/* LSB of counter */ -		io_delay(); -		outb(div >> 8, 0x42);	/* MSB of counter */ -		io_delay(); - -		enable = 0x03;		/* Turn on speaker */ -	} -	inb(0x61);		/* Dummy read of System Control Port B */ -	io_delay(); -	outb(enable, 0x61);	/* Enable timer 2 output to speaker */ -	io_delay(); -} - -#define DOT_HZ		880 -#define DASH_HZ		587 -#define US_PER_DOT	125000 - -/* Okay, this is totally silly, but it's kind of fun. */ -static void send_morse(const char *pattern) -{ -	char s; - -	while ((s = *pattern++)) { -		switch (s) { -		case '.': -			beep(DOT_HZ); -			udelay(US_PER_DOT); -			beep(0); -			udelay(US_PER_DOT); -			break; -		case '-': -			beep(DASH_HZ); -			udelay(US_PER_DOT * 3); -			beep(0); -			udelay(US_PER_DOT); -			break; -		default:	/* Assume it's a space */ -			udelay(US_PER_DOT * 3); -			break; -		} -	} -} - -void main(void) -{ -	/* Kill machine if structures are wrong */ -	if (wakeup_header.real_magic != 0x12345678) -		while (1); - -	if (wakeup_header.realmode_flags & 4) -		send_morse("...-"); - -	if (wakeup_header.realmode_flags & 1) -		asm volatile("lcallw   $0xc000,$3"); - -	if (wakeup_header.realmode_flags & 2) { -		/* Need to call BIOS */ -		probe_cards(0); -		set_mode(wakeup_header.video_mode); -	} -} diff --git a/arch/x86/kernel/acpi/realmode/wakeup.S b/arch/x86/kernel/acpi/realmode/wakeup.S deleted file mode 100644 index 28595d6df47..00000000000 --- a/arch/x86/kernel/acpi/realmode/wakeup.S +++ /dev/null @@ -1,149 +0,0 @@ -/* - * ACPI wakeup real mode startup stub - */ -#include <asm/segment.h> -#include <asm/msr-index.h> -#include <asm/page_types.h> -#include <asm/pgtable_types.h> -#include <asm/processor-flags.h> - -	.code16 -	.section ".header", "a" - -/* This should match the structure in wakeup.h */ -		.globl	wakeup_header -wakeup_header: -video_mode:	.short	0	/* Video mode number */ -pmode_return:	.byte	0x66, 0xea	/* ljmpl */ -		.long	0	/* offset goes here */ -		.short	__KERNEL_CS -pmode_cr0:	.long	0	/* Saved %cr0 */ -pmode_cr3:	.long	0	/* Saved %cr3 */ -pmode_cr4:	.long	0	/* Saved %cr4 */ -pmode_efer:	.quad	0	/* Saved EFER */ -pmode_gdt:	.quad	0 -realmode_flags:	.long	0 -real_magic:	.long	0 -trampoline_segment:	.word 0 -_pad1:		.byte	0 -wakeup_jmp:	.byte	0xea	/* ljmpw */ -wakeup_jmp_off:	.word	3f -wakeup_jmp_seg:	.word	0 -wakeup_gdt:	.quad	0, 0, 0 -signature:	.long	0x51ee1111 - -	.text -	.globl	_start -	.code16 -wakeup_code: -_start: -	cli -	cld - -	/* Apparently some dimwit BIOS programmers don't know how to -	   program a PM to RM transition, and we might end up here with -	   junk in the data segment descriptor registers.  The only way -	   to repair that is to go into PM and fix it ourselves... */ -	movw	$16, %cx -	lgdtl	%cs:wakeup_gdt -	movl	%cr0, %eax -	orb	$X86_CR0_PE, %al -	movl	%eax, %cr0 -	jmp	1f -1:	ljmpw	$8, $2f -2: -	movw	%cx, %ds -	movw	%cx, %es -	movw	%cx, %ss -	movw	%cx, %fs -	movw	%cx, %gs - -	andb	$~X86_CR0_PE, %al -	movl	%eax, %cr0 -	jmp	wakeup_jmp -3: -	/* Set up segments */ -	movw	%cs, %ax -	movw	%ax, %ds -	movw	%ax, %es -	movw	%ax, %ss -	lidtl	wakeup_idt - -	movl	$wakeup_stack_end, %esp - -	/* Clear the EFLAGS */ -	pushl	$0 -	popfl - -	/* Check header signature... */ -	movl	signature, %eax -	cmpl	$0x51ee1111, %eax -	jne	bogus_real_magic - -	/* Check we really have everything... */ -	movl	end_signature, %eax -	cmpl	$0x65a22c82, %eax -	jne	bogus_real_magic - -	/* Call the C code */ -	calll	main - -	/* Do any other stuff... */ - -#ifndef CONFIG_64BIT -	/* This could also be done in C code... */ -	movl	pmode_cr3, %eax -	movl	%eax, %cr3 - -	movl	pmode_cr4, %ecx -	jecxz	1f -	movl	%ecx, %cr4 -1: -	movl	pmode_efer, %eax -	movl	pmode_efer + 4, %edx -	movl	%eax, %ecx -	orl	%edx, %ecx -	jz	1f -	movl	$MSR_EFER, %ecx -	wrmsr -1: - -	lgdtl	pmode_gdt - -	/* This really couldn't... */ -	movl	pmode_cr0, %eax -	movl	%eax, %cr0 -	jmp	pmode_return -#else -	pushw	$0 -	pushw	trampoline_segment -	pushw	$0 -	lret -#endif - -bogus_real_magic: -1: -	hlt -	jmp	1b - -	.data -	.balign	8 - -	/* This is the standard real-mode IDT */ -wakeup_idt: -	.word	0xffff		/* limit */ -	.long	0		/* address */ -	.word	0 - -	.globl	HEAP, heap_end -HEAP: -	.long	wakeup_heap -heap_end: -	.long	wakeup_stack - -	.bss -wakeup_heap: -	.space	2048 -wakeup_stack: -	.space	2048 -wakeup_stack_end: diff --git a/arch/x86/kernel/acpi/realmode/wakeup.h b/arch/x86/kernel/acpi/realmode/wakeup.h deleted file mode 100644 index 69d38d0b2b6..00000000000 --- a/arch/x86/kernel/acpi/realmode/wakeup.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Definitions for the wakeup data structure at the head of the - * wakeup code. - */ - -#ifndef ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H -#define ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H - -#ifndef __ASSEMBLY__ -#include <linux/types.h> - -/* This must match data at wakeup.S */ -struct wakeup_header { -	u16 video_mode;		/* Video mode number */ -	u16 _jmp1;		/* ljmpl opcode, 32-bit only */ -	u32 pmode_entry;	/* Protected mode resume point, 32-bit only */ -	u16 _jmp2;		/* CS value, 32-bit only */ -	u32 pmode_cr0;		/* Protected mode cr0 */ -	u32 pmode_cr3;		/* Protected mode cr3 */ -	u32 pmode_cr4;		/* Protected mode cr4 */ -	u32 pmode_efer_low;	/* Protected mode EFER */ -	u32 pmode_efer_high; -	u64 pmode_gdt; -	u32 realmode_flags; -	u32 real_magic; -	u16 trampoline_segment;	/* segment with trampoline code, 64-bit only */ -	u8  _pad1; -	u8  wakeup_jmp; -	u16 wakeup_jmp_off; -	u16 wakeup_jmp_seg; -	u64 wakeup_gdt[3]; -	u32 signature;		/* To check we have correct structure */ -} __attribute__((__packed__)); - -extern struct wakeup_header wakeup_header; -#endif - -#define HEADER_OFFSET 0x3f00 -#define WAKEUP_SIZE   0x4000 - -#endif /* ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H */ diff --git a/arch/x86/kernel/acpi/realmode/wakeup.lds.S b/arch/x86/kernel/acpi/realmode/wakeup.lds.S deleted file mode 100644 index 060fff8f5c5..00000000000 --- a/arch/x86/kernel/acpi/realmode/wakeup.lds.S +++ /dev/null @@ -1,64 +0,0 @@ -/* - * wakeup.ld - * - * Linker script for the real-mode wakeup code - */ -#undef i386 -#include "wakeup.h" - -OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") -OUTPUT_ARCH(i386) -ENTRY(_start) - -SECTIONS -{ -	. = 0; -	.text : { -		 *(.text*) -	} - -	. = ALIGN(16); -	.rodata : { -		*(.rodata*) -	} - -	.videocards : { -		video_cards = .; -		*(.videocards) -		video_cards_end = .; -	} - -	. = ALIGN(16); -	.data : { -		 *(.data*) -	} - -	.signature : { -		end_signature = .; -		LONG(0x65a22c82) -	} - -	. = ALIGN(16); -	.bss :	{ -		__bss_start = .; -		*(.bss) -		__bss_end = .; -	} - -	. = HEADER_OFFSET; -	.header : { -		*(.header) -	} - -	. = ALIGN(16); -	_end = .; - -	/DISCARD/ : { -		*(.note*) -	} - -	/* -	 * The ASSERT() sink to . is intentional, for binutils 2.14 compatibility: -	 */ -	. = ASSERT(_end <= WAKEUP_SIZE, "Wakeup too big!"); -} diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index 69fd72aa559..31368207837 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c @@ -12,95 +12,93 @@  #include <linux/cpumask.h>  #include <asm/segment.h>  #include <asm/desc.h> - -#ifdef CONFIG_X86_32  #include <asm/pgtable.h> -#endif +#include <asm/cacheflush.h> +#include <asm/realmode.h> -#include "realmode/wakeup.h" +#include "../../realmode/rm/wakeup.h"  #include "sleep.h" -unsigned long acpi_wakeup_address;  unsigned long acpi_realmode_flags; -/* address in low memory of the wakeup routine. */ -static unsigned long acpi_realmode; -  #if defined(CONFIG_SMP) && defined(CONFIG_64BIT)  static char temp_stack[4096];  #endif  /** - * acpi_save_state_mem - save kernel state + * x86_acpi_enter_sleep_state - enter sleep state + * @state: Sleep state to enter. + * + * Wrapper around acpi_enter_sleep_state() to be called by assmebly. + */ +acpi_status asmlinkage __visible x86_acpi_enter_sleep_state(u8 state) +{ +	return acpi_enter_sleep_state(state); +} + +/** + * x86_acpi_suspend_lowlevel - save kernel state   *   * Create an identity mapped page table and copy the wakeup routine to   * low memory. - * - * Note that this is too late to change acpi_wakeup_address.   */ -int acpi_save_state_mem(void) +int x86_acpi_suspend_lowlevel(void)  { -	struct wakeup_header *header; +	struct wakeup_header *header = +		(struct wakeup_header *) __va(real_mode_header->wakeup_header); -	if (!acpi_realmode) { -		printk(KERN_ERR "Could not allocate memory during boot, " -		       "S3 disabled\n"); -		return -ENOMEM; -	} -	memcpy((void *)acpi_realmode, &wakeup_code_start, WAKEUP_SIZE); - -	header = (struct wakeup_header *)(acpi_realmode + HEADER_OFFSET); -	if (header->signature != 0x51ee1111) { +	if (header->signature != WAKEUP_HEADER_SIGNATURE) {  		printk(KERN_ERR "wakeup header does not match\n");  		return -EINVAL;  	}  	header->video_mode = saved_video_mode; -	header->wakeup_jmp_seg = acpi_wakeup_address >> 4; - -	/* -	 * Set up the wakeup GDT.  We set these up as Big Real Mode, -	 * that is, with limits set to 4 GB.  At least the Lenovo -	 * Thinkpad X61 is known to need this for the video BIOS -	 * initialization quirk to work; this is likely to also -	 * be the case for other laptops or integrated video devices. -	 */ - -	/* GDT[0]: GDT self-pointer */ -	header->wakeup_gdt[0] = -		(u64)(sizeof(header->wakeup_gdt) - 1) + -		((u64)(acpi_wakeup_address + -			((char *)&header->wakeup_gdt - (char *)acpi_realmode)) -				<< 16); -	/* GDT[1]: big real mode-like code segment */ -	header->wakeup_gdt[1] = -		GDT_ENTRY(0x809b, acpi_wakeup_address, 0xfffff); -	/* GDT[2]: big real mode-like data segment */ -	header->wakeup_gdt[2] = -		GDT_ENTRY(0x8093, acpi_wakeup_address, 0xfffff); +	header->pmode_behavior = 0;  #ifndef CONFIG_64BIT -	store_gdt((struct desc_ptr *)&header->pmode_gdt); +	native_store_gdt((struct desc_ptr *)&header->pmode_gdt); -	if (rdmsr_safe(MSR_EFER, &header->pmode_efer_low, -		       &header->pmode_efer_high)) -		header->pmode_efer_low = header->pmode_efer_high = 0; +	/* +	 * We have to check that we can write back the value, and not +	 * just read it.  At least on 90 nm Pentium M (Family 6, Model +	 * 13), reading an invalid MSR is not guaranteed to trap, see +	 * Erratum X4 in "Intel Pentium M Processor on 90 nm Process +	 * with 2-MB L2 Cache and IntelĀ® Processor A100 and A110 on 90 +	 * nm process with 512-KB L2 Cache Specification Update". +	 */ +	if (!rdmsr_safe(MSR_EFER, +			&header->pmode_efer_low, +			&header->pmode_efer_high) && +	    !wrmsr_safe(MSR_EFER, +			header->pmode_efer_low, +			header->pmode_efer_high)) +		header->pmode_behavior |= (1 << WAKEUP_BEHAVIOR_RESTORE_EFER);  #endif /* !CONFIG_64BIT */  	header->pmode_cr0 = read_cr0(); -	header->pmode_cr4 = read_cr4_safe(); +	if (__this_cpu_read(cpu_info.cpuid_level) >= 0) { +		header->pmode_cr4 = read_cr4(); +		header->pmode_behavior |= (1 << WAKEUP_BEHAVIOR_RESTORE_CR4); +	} +	if (!rdmsr_safe(MSR_IA32_MISC_ENABLE, +			&header->pmode_misc_en_low, +			&header->pmode_misc_en_high) && +	    !wrmsr_safe(MSR_IA32_MISC_ENABLE, +			header->pmode_misc_en_low, +			header->pmode_misc_en_high)) +		header->pmode_behavior |= +			(1 << WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE);  	header->realmode_flags = acpi_realmode_flags;  	header->real_magic = 0x12345678;  #ifndef CONFIG_64BIT  	header->pmode_entry = (u32)&wakeup_pmode_return; -	header->pmode_cr3 = (u32)__pa(&initial_page_table); +	header->pmode_cr3 = (u32)__pa_symbol(initial_page_table);  	saved_magic = 0x12345678;  #else /* CONFIG_64BIT */ -	header->trampoline_segment = setup_trampoline() >> 4;  #ifdef CONFIG_SMP -	stack_start.sp = temp_stack + sizeof(temp_stack); +	stack_start = (unsigned long)temp_stack + sizeof(temp_stack);  	early_gdt_descr.address =  			(unsigned long)get_cpu_gdt_table(smp_processor_id());  	initial_gs = per_cpu_offset(smp_processor_id()); @@ -109,47 +107,10 @@ int acpi_save_state_mem(void)         saved_magic = 0x123456789abcdef0L;  #endif /* CONFIG_64BIT */ +	do_suspend_lowlevel();  	return 0;  } -/* - * acpi_restore_state - undo effects of acpi_save_state_mem - */ -void acpi_restore_state_mem(void) -{ -} - - -/** - * acpi_reserve_wakeup_memory - do _very_ early ACPI initialisation - * - * We allocate a page from the first 1MB of memory for the wakeup - * routine for when we come back from a sleep state. The - * runtime allocator allows specification of <16MB pages, but not - * <1MB pages. - */ -void __init acpi_reserve_wakeup_memory(void) -{ -	phys_addr_t mem; - -	if ((&wakeup_code_end - &wakeup_code_start) > WAKEUP_SIZE) { -		printk(KERN_ERR -		       "ACPI: Wakeup code way too big, S3 disabled.\n"); -		return; -	} - -	mem = memblock_find_in_range(0, 1<<20, WAKEUP_SIZE, PAGE_SIZE); - -	if (mem == MEMBLOCK_ERROR) { -		printk(KERN_ERR "ACPI: Cannot allocate lowmem, S3 disabled.\n"); -		return; -	} -	acpi_realmode = (unsigned long) phys_to_virt(mem); -	acpi_wakeup_address = mem; -	memblock_x86_reserve_range(mem, mem + WAKEUP_SIZE, "ACPI WAKEUP"); -} - -  static int __init acpi_sleep_setup(char *str)  {  	while ((str != NULL) && (*str != '\0')) { @@ -162,14 +123,11 @@ static int __init acpi_sleep_setup(char *str)  #ifdef CONFIG_HIBERNATION  		if (strncmp(str, "s4_nohwsig", 10) == 0)  			acpi_no_s4_hw_signature(); -		if (strncmp(str, "s4_nonvs", 8) == 0) { -			pr_warning("ACPI: acpi_sleep=s4_nonvs is deprecated, " -					"please use acpi_sleep=nonvs instead"); -			acpi_nvs_nosave(); -		}  #endif  		if (strncmp(str, "nonvs", 5) == 0)  			acpi_nvs_nosave(); +		if (strncmp(str, "nonvs_s3", 8) == 0) +			acpi_nvs_nosave_s3();  		if (strncmp(str, "old_ordering", 12) == 0)  			acpi_old_suspend_ordering();  		str = strchr(str, ','); diff --git a/arch/x86/kernel/acpi/sleep.h b/arch/x86/kernel/acpi/sleep.h index adbcbaa6f1d..65c7b606b60 100644 --- a/arch/x86/kernel/acpi/sleep.h +++ b/arch/x86/kernel/acpi/sleep.h @@ -2,15 +2,20 @@   *	Variables and functions used by the code in sleep.c   */ -#include <asm/trampoline.h> - -extern char wakeup_code_start, wakeup_code_end; +#include <asm/realmode.h>  extern unsigned long saved_video_mode;  extern long saved_magic;  extern int wakeup_pmode_return; -extern char swsusp_pg_dir[PAGE_SIZE]; + +extern u8 wake_sleep_flags;  extern unsigned long acpi_copy_wakeup_routine(unsigned long);  extern void wakeup_long64(void); + +extern void do_suspend_lowlevel(void); + +extern int x86_acpi_suspend_lowlevel(void); + +acpi_status asmlinkage x86_acpi_enter_sleep_state(u8 state); diff --git a/arch/x86/kernel/acpi/wakeup_32.S b/arch/x86/kernel/acpi/wakeup_32.S index 13ab720573e..665c6b7d2ea 100644 --- a/arch/x86/kernel/acpi/wakeup_32.S +++ b/arch/x86/kernel/acpi/wakeup_32.S @@ -1,4 +1,4 @@ -	.section .text..page_aligned +	.text  #include <linux/linkage.h>  #include <asm/segment.h>  #include <asm/page_types.h> @@ -18,7 +18,6 @@ wakeup_pmode_return:  	movw	%ax, %gs  	# reload the gdt, as we need the full 32 bit address -	lgdt	saved_gdt  	lidt	saved_idt  	lldt	saved_ldt  	ljmp	$(__KERNEL_CS), $1f @@ -44,7 +43,6 @@ bogus_magic:  save_registers: -	sgdt	saved_gdt  	sidt	saved_idt  	sldt	saved_ldt  	str	saved_tss @@ -75,7 +73,7 @@ ENTRY(do_suspend_lowlevel)  	call	save_processor_state  	call	save_registers  	pushl	$3 -	call	acpi_enter_sleep_state +	call	x86_acpi_enter_sleep_state  	addl	$4, %esp  #	In case of S3 failure, we'll emerge here.  Jump @@ -93,7 +91,6 @@ ENTRY(saved_magic)	.long	0  ENTRY(saved_eip)	.long	0  # saved registers -saved_gdt:	.long	0,0  saved_idt:	.long	0,0  saved_ldt:	.long	0  saved_tss:	.long	0 diff --git a/arch/x86/kernel/acpi/wakeup_64.S b/arch/x86/kernel/acpi/wakeup_64.S index 8ea5164cbd0..ae693b51ed8 100644 --- a/arch/x86/kernel/acpi/wakeup_64.S +++ b/arch/x86/kernel/acpi/wakeup_64.S @@ -73,7 +73,7 @@ ENTRY(do_suspend_lowlevel)  	addq	$8, %rsp  	movl	$3, %edi  	xorl	%eax, %eax -	call	acpi_enter_sleep_state +	call	x86_acpi_enter_sleep_state  	/* in case something went wrong, restore the machine status and go on */  	jmp	resume_point diff --git a/arch/x86/kernel/acpi/wakeup_rm.S b/arch/x86/kernel/acpi/wakeup_rm.S deleted file mode 100644 index 6ff3b573057..00000000000 --- a/arch/x86/kernel/acpi/wakeup_rm.S +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Wrapper script for the realmode binary as a transport object - * before copying to low memory. - */ -	.section ".rodata","a" -	.globl	wakeup_code_start, wakeup_code_end -wakeup_code_start: -	.incbin	"arch/x86/kernel/acpi/realmode/wakeup.bin" -wakeup_code_end: -	.size	wakeup_code_start, .-wakeup_code_start  | 
