Browse Source

Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6

* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6:
  leds-hp-disk: fix build warning
  ACPI: Oops in ACPI with git latest
  ACPI suspend: build fix for ACPI_SLEEP=n && XEN_SAVE_RESTORE=y.
  toshiba_acpi: always call input_sync() after input_report_switch()
  ACPI: Always report a sync event after a lid state change
  ACPI: cpufreq, processor: fix compile error in drivers/acpi/processor_perflib.c
  i7300_idle: Fix compile warning CONFIG_I7300_IDLE_IOAT_CHANNEL not defined
  i7300_idle: Cleanup based review comments
  i7300_idle: Disable ioat channel only on platforms where ile driver can load
Linus Torvalds 16 năm trước cách đây
mục cha
commit
7eea5b897e

+ 2 - 1
drivers/acpi/button.c

@@ -262,6 +262,7 @@ static int acpi_lid_send_state(struct acpi_button *button)
 		return -ENODEV;
 		return -ENODEV;
 	/* input layer checks if event is redundant */
 	/* input layer checks if event is redundant */
 	input_report_switch(button->input, SW_LID, !state);
 	input_report_switch(button->input, SW_LID, !state);
+	input_sync(button->input);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -285,8 +286,8 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
 			input_report_key(input, keycode, 1);
 			input_report_key(input, keycode, 1);
 			input_sync(input);
 			input_sync(input);
 			input_report_key(input, keycode, 0);
 			input_report_key(input, keycode, 0);
+			input_sync(input);
 		}
 		}
-		input_sync(input);
 
 
 		acpi_bus_generate_proc_event(button->device, event,
 		acpi_bus_generate_proc_event(button->device, event,
 					++button->pushed);
 					++button->pushed);

+ 5 - 0
drivers/acpi/processor_perflib.c

@@ -38,7 +38,10 @@
 
 
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
 #endif
 #endif
+
+#ifdef CONFIG_X86
 #include <asm/cpufeature.h>
 #include <asm/cpufeature.h>
+#endif
 
 
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/processor.h>
 #include <acpi/processor.h>
@@ -360,11 +363,13 @@ static int acpi_processor_get_performance_info(struct acpi_processor *pr)
 	 * the BIOS is older than the CPU and does not know its frequencies
 	 * the BIOS is older than the CPU and does not know its frequencies
 	 */
 	 */
  update_bios:
  update_bios:
+#ifdef CONFIG_X86
 	if (ACPI_SUCCESS(acpi_get_handle(pr->handle, "_PPC", &handle))){
 	if (ACPI_SUCCESS(acpi_get_handle(pr->handle, "_PPC", &handle))){
 		if(boot_cpu_has(X86_FEATURE_EST))
 		if(boot_cpu_has(X86_FEATURE_EST))
 			printk(KERN_WARNING FW_BUG "BIOS needs update for CPU "
 			printk(KERN_WARNING FW_BUG "BIOS needs update for CPU "
 			       "frequency support\n");
 			       "frequency support\n");
 	}
 	}
+#endif
 	return result;
 	return result;
 }
 }
 
 

+ 2 - 0
drivers/acpi/sleep/main.c

@@ -163,6 +163,8 @@ static void acpi_pm_end(void)
 	acpi_target_sleep_state = ACPI_STATE_S0;
 	acpi_target_sleep_state = ACPI_STATE_S0;
 	acpi_sleep_tts_switch(acpi_target_sleep_state);
 	acpi_sleep_tts_switch(acpi_target_sleep_state);
 }
 }
+#else /* !CONFIG_ACPI_SLEEP */
+#define acpi_target_sleep_state	ACPI_STATE_S0
 #endif /* CONFIG_ACPI_SLEEP */
 #endif /* CONFIG_ACPI_SLEEP */
 
 
 #ifdef CONFIG_SUSPEND
 #ifdef CONFIG_SUSPEND

+ 2 - 0
drivers/acpi/toshiba_acpi.c

@@ -371,6 +371,7 @@ static void bt_poll_rfkill(struct input_polled_dev *poll_dev)
 				   RFKILL_STATE_HARD_BLOCKED);
 				   RFKILL_STATE_HARD_BLOCKED);
 		input_report_switch(poll_dev->input, SW_RFKILL_ALL,
 		input_report_switch(poll_dev->input, SW_RFKILL_ALL,
 				    new_rfk_state);
 				    new_rfk_state);
+		input_sync(poll_dev->input);
 	}
 	}
 }
 }
 
 
@@ -842,6 +843,7 @@ static int __init toshiba_acpi_init(void)
 	set_bit(EV_SW, toshiba_acpi.poll_dev->input->evbit);
 	set_bit(EV_SW, toshiba_acpi.poll_dev->input->evbit);
 	set_bit(SW_RFKILL_ALL, toshiba_acpi.poll_dev->input->swbit);
 	set_bit(SW_RFKILL_ALL, toshiba_acpi.poll_dev->input->swbit);
 	input_report_switch(toshiba_acpi.poll_dev->input, SW_RFKILL_ALL, TRUE);
 	input_report_switch(toshiba_acpi.poll_dev->input, SW_RFKILL_ALL, TRUE);
+	input_sync(toshiba_acpi.poll_dev->input);
 
 
 	ret = input_register_polled_device(toshiba_acpi.poll_dev);
 	ret = input_register_polled_device(toshiba_acpi.poll_dev);
 	if (ret) {
 	if (ret) {

+ 5 - 2
drivers/dma/ioat_dma.c

@@ -33,6 +33,7 @@
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-mapping.h>
 #include <linux/workqueue.h>
 #include <linux/workqueue.h>
+#include <linux/i7300_idle.h>
 #include "ioatdma.h"
 #include "ioatdma.h"
 #include "ioatdma_registers.h"
 #include "ioatdma_registers.h"
 #include "ioatdma_hw.h"
 #include "ioatdma_hw.h"
@@ -171,8 +172,10 @@ static int ioat_dma_enumerate_channels(struct ioatdma_device *device)
 	xfercap_scale = readb(device->reg_base + IOAT_XFERCAP_OFFSET);
 	xfercap_scale = readb(device->reg_base + IOAT_XFERCAP_OFFSET);
 	xfercap = (xfercap_scale == 0 ? -1 : (1UL << xfercap_scale));
 	xfercap = (xfercap_scale == 0 ? -1 : (1UL << xfercap_scale));
 
 
-#if CONFIG_I7300_IDLE_IOAT_CHANNEL
-	device->common.chancnt--;
+#ifdef  CONFIG_I7300_IDLE_IOAT_CHANNEL
+	if (i7300_idle_platform_probe(NULL, NULL) == 0) {
+		device->common.chancnt--;
+	}
 #endif
 #endif
 	for (i = 0; i < device->common.chancnt; i++) {
 	for (i = 0; i < device->common.chancnt; i++) {
 		ioat_chan = kzalloc(sizeof(*ioat_chan), GFP_KERNEL);
 		ioat_chan = kzalloc(sizeof(*ioat_chan), GFP_KERNEL);

+ 6 - 5
drivers/idle/Kconfig

@@ -5,12 +5,13 @@ config I7300_IDLE_IOAT_CHANNEL
 	bool
 	bool
 
 
 config I7300_IDLE
 config I7300_IDLE
-	tristate "Intel chipset idle power saving driver"
+	tristate "Intel chipset idle memory power saving driver"
 	select I7300_IDLE_IOAT_CHANNEL
 	select I7300_IDLE_IOAT_CHANNEL
-	depends on X86_64
+	depends on X86_64 && EXPERIMENTAL
 	help
 	help
-	  Enable idle power savings with certain Intel server chipsets.
-	  The chipset must have I/O AT support, such as the Intel 7300.
-	  The power savings depends on the type and quantity of DRAM devices.
+	  Enable memory power savings when idle with certain Intel server
+	  chipsets. The chipset must have I/O AT support, such as the
+	  Intel 7300. The power savings depends on the type and quantity of
+	  DRAM devices.
 
 
 endmenu
 endmenu

+ 20 - 85
drivers/idle/i7300_idle.c

@@ -25,6 +25,7 @@
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/debugfs.h>
 #include <linux/debugfs.h>
 #include <linux/stop_machine.h>
 #include <linux/stop_machine.h>
+#include <linux/i7300_idle.h>
 
 
 #include <asm/idle.h>
 #include <asm/idle.h>
 
 
@@ -34,6 +35,8 @@
 #define I7300_IDLE_DRIVER_VERSION	"1.55"
 #define I7300_IDLE_DRIVER_VERSION	"1.55"
 #define I7300_PRINT			"i7300_idle:"
 #define I7300_PRINT			"i7300_idle:"
 
 
+#define MAX_STOP_RETRIES	10
+
 static int debug;
 static int debug;
 module_param_named(debug, debug, uint, 0644);
 module_param_named(debug, debug, uint, 0644);
 MODULE_PARM_DESC(debug, "Enable debug printks in this driver");
 MODULE_PARM_DESC(debug, "Enable debug printks in this driver");
@@ -46,12 +49,12 @@ MODULE_PARM_DESC(debug, "Enable debug printks in this driver");
  *  0 = No throttling
  *  0 = No throttling
  *  1 = Throttle when > 4 activations per eval window (Maximum throttling)
  *  1 = Throttle when > 4 activations per eval window (Maximum throttling)
  *  2 = Throttle when > 8 activations
  *  2 = Throttle when > 8 activations
- *  168 = Throttle when > 168 activations (Minimum throttling)
+ *  168 = Throttle when > 672 activations (Minimum throttling)
  */
  */
-#define MAX_THRTLWLIMIT		168
-static uint i7300_idle_thrtlowlm = 1;
-module_param_named(thrtlwlimit, i7300_idle_thrtlowlm, uint, 0644);
-MODULE_PARM_DESC(thrtlwlimit,
+#define MAX_THROTTLE_LOW_LIMIT		168
+static uint throttle_low_limit = 1;
+module_param_named(throttle_low_limit, throttle_low_limit, uint, 0644);
+MODULE_PARM_DESC(throttle_low_limit,
 		"Value for THRTLOWLM activation field "
 		"Value for THRTLOWLM activation field "
 		"(0 = disable throttle, 1 = Max throttle, 168 = Min throttle)");
 		"(0 = disable throttle, 1 = Max throttle, 168 = Min throttle)");
 
 
@@ -110,9 +113,9 @@ static int i7300_idle_ioat_start(void)
 static void i7300_idle_ioat_stop(void)
 static void i7300_idle_ioat_stop(void)
 {
 {
 	int i;
 	int i;
-	u8 sts;
+	u64 sts;
 
 
-	for (i = 0; i < 5; i++) {
+	for (i = 0; i < MAX_STOP_RETRIES; i++) {
 		writeb(IOAT_CHANCMD_RESET,
 		writeb(IOAT_CHANCMD_RESET,
 			ioat_chanbase + IOAT1_CHANCMD_OFFSET);
 			ioat_chanbase + IOAT1_CHANCMD_OFFSET);
 
 
@@ -126,9 +129,10 @@ static void i7300_idle_ioat_stop(void)
 
 
 	}
 	}
 
 
-	if (i == 5)
-		dprintk("failed to suspend+reset I/O AT after 5 retries\n");
-
+	if (i == MAX_STOP_RETRIES) {
+		dprintk("failed to stop I/O AT after %d retries\n",
+			MAX_STOP_RETRIES);
+	}
 }
 }
 
 
 /* Test I/O AT by copying 1024 byte from 2k to 1k */
 /* Test I/O AT by copying 1024 byte from 2k to 1k */
@@ -275,7 +279,7 @@ static void __exit i7300_idle_ioat_exit(void)
 	i7300_idle_ioat_stop();
 	i7300_idle_ioat_stop();
 
 
 	/* Wait for a while for the channel to halt before releasing */
 	/* Wait for a while for the channel to halt before releasing */
-	for (i = 0; i < 10; i++) {
+	for (i = 0; i < MAX_STOP_RETRIES; i++) {
 		writeb(IOAT_CHANCMD_RESET,
 		writeb(IOAT_CHANCMD_RESET,
 		       ioat_chanbase + IOAT1_CHANCMD_OFFSET);
 		       ioat_chanbase + IOAT1_CHANCMD_OFFSET);
 
 
@@ -389,9 +393,9 @@ static void i7300_idle_start(void)
 	new_ctl = i7300_idle_thrtctl_saved & ~DIMM_THRTCTL_THRMHUNT;
 	new_ctl = i7300_idle_thrtctl_saved & ~DIMM_THRTCTL_THRMHUNT;
 	pci_write_config_byte(fbd_dev, DIMM_THRTCTL, new_ctl);
 	pci_write_config_byte(fbd_dev, DIMM_THRTCTL, new_ctl);
 
 
-	limit = i7300_idle_thrtlowlm;
-	if (unlikely(limit > MAX_THRTLWLIMIT))
-		limit = MAX_THRTLWLIMIT;
+	limit = throttle_low_limit;
+	if (unlikely(limit > MAX_THROTTLE_LOW_LIMIT))
+		limit = MAX_THROTTLE_LOW_LIMIT;
 
 
 	pci_write_config_byte(fbd_dev, DIMM_THRTLOW, limit);
 	pci_write_config_byte(fbd_dev, DIMM_THRTLOW, limit);
 
 
@@ -440,7 +444,7 @@ static int i7300_idle_notifier(struct notifier_block *nb, unsigned long val,
 	static ktime_t idle_begin_time;
 	static ktime_t idle_begin_time;
 	static int time_init = 1;
 	static int time_init = 1;
 
 
-	if (!i7300_idle_thrtlowlm)
+	if (!throttle_low_limit)
 		return 0;
 		return 0;
 
 
 	if (unlikely(time_init)) {
 	if (unlikely(time_init)) {
@@ -505,77 +509,8 @@ static struct notifier_block i7300_idle_nb = {
 	.notifier_call = i7300_idle_notifier,
 	.notifier_call = i7300_idle_notifier,
 };
 };
 
 
-/*
- * I/O AT controls (PCI bus 0 device 8 function 0)
- * DIMM controls (PCI bus 0 device 16 function 1)
- */
-#define IOAT_BUS 0
-#define IOAT_DEVFN PCI_DEVFN(8, 0)
-#define MEMCTL_BUS 0
-#define MEMCTL_DEVFN PCI_DEVFN(16, 1)
-
-struct fbd_ioat {
-	unsigned int vendor;
-	unsigned int ioat_dev;
-};
-
-/*
- * The i5000 chip-set has the same hooks as the i7300
- * but support is disabled by default because this driver
- * has not been validated on that platform.
- */
-#define SUPPORT_I5000 0
-
-static const struct fbd_ioat fbd_ioat_list[] = {
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_CNB},
-#if SUPPORT_I5000
-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT},
-#endif
-	{0, 0}
-};
-
-/* table of devices that work with this driver */
-static const struct pci_device_id pci_tbl[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_FBD_CNB) },
-#if SUPPORT_I5000
-	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5000_ERR) },
-#endif
-	{ } /* Terminating entry */
-};
-
 MODULE_DEVICE_TABLE(pci, pci_tbl);
 MODULE_DEVICE_TABLE(pci, pci_tbl);
 
 
-/* Check for known platforms with I/O-AT */
-static int __init i7300_idle_platform_probe(void)
-{
-	int i;
-
-	fbd_dev = pci_get_bus_and_slot(MEMCTL_BUS, MEMCTL_DEVFN);
-	if (!fbd_dev)
-		return -ENODEV;
-
-	for (i = 0; pci_tbl[i].vendor != 0; i++) {
-		if (fbd_dev->vendor == pci_tbl[i].vendor &&
-		    fbd_dev->device == pci_tbl[i].device) {
-			break;
-		}
-	}
-	if (pci_tbl[i].vendor == 0)
-		return -ENODEV;
-
-	ioat_dev = pci_get_bus_and_slot(IOAT_BUS, IOAT_DEVFN);
-	if (!ioat_dev)
-		return -ENODEV;
-
-	for (i = 0; fbd_ioat_list[i].vendor != 0; i++) {
-		if (ioat_dev->vendor == fbd_ioat_list[i].vendor &&
-		    ioat_dev->device == fbd_ioat_list[i].ioat_dev) {
-			return 0;
-		}
-	}
-	return -ENODEV;
-}
-
 int stats_open_generic(struct inode *inode, struct file *fp)
 int stats_open_generic(struct inode *inode, struct file *fp)
 {
 {
 	fp->private_data = inode->i_private;
 	fp->private_data = inode->i_private;
@@ -617,7 +552,7 @@ static int __init i7300_idle_init(void)
 	cpus_clear(idle_cpumask);
 	cpus_clear(idle_cpumask);
 	total_us = 0;
 	total_us = 0;
 
 
-	if (i7300_idle_platform_probe())
+	if (i7300_idle_platform_probe(&fbd_dev, &ioat_dev))
 		return -ENODEV;
 		return -ENODEV;
 
 
 	if (i7300_idle_thrt_save())
 	if (i7300_idle_thrt_save())

+ 1 - 1
drivers/leds/leds-hp-disk.c

@@ -49,7 +49,7 @@ static struct acpi_hpled adev;
 
 
 static acpi_status hpled_acpi_write(acpi_handle handle, int reg)
 static acpi_status hpled_acpi_write(acpi_handle handle, int reg)
 {
 {
-	unsigned long ret; /* Not used when writing */
+	unsigned long long ret; /* Not used when writing */
 	union acpi_object in_obj[1];
 	union acpi_object in_obj[1];
 	struct acpi_object_list args = { 1, in_obj };
 	struct acpi_object_list args = { 1, in_obj };
 
 

+ 3 - 0
drivers/pci/pci-acpi.c

@@ -83,6 +83,9 @@ static acpi_status acpi_run_osc(acpi_handle handle,
 	if (ACPI_FAILURE(status))
 	if (ACPI_FAILURE(status))
 		return status;
 		return status;
 
 
+	if (!output.length)
+		return AE_NULL_OBJECT;
+
 	out_obj = output.pointer;
 	out_obj = output.pointer;
 	if (out_obj->type != ACPI_TYPE_BUFFER) {
 	if (out_obj->type != ACPI_TYPE_BUFFER) {
 		printk(KERN_DEBUG "Evaluate _OSC returns wrong type\n");
 		printk(KERN_DEBUG "Evaluate _OSC returns wrong type\n");

+ 83 - 0
include/linux/i7300_idle.h

@@ -0,0 +1,83 @@
+
+#ifndef I7300_IDLE_H
+#define I7300_IDLE_H
+
+#include <linux/pci.h>
+
+/*
+ * I/O AT controls (PCI bus 0 device 8 function 0)
+ * DIMM controls (PCI bus 0 device 16 function 1)
+ */
+#define IOAT_BUS 0
+#define IOAT_DEVFN PCI_DEVFN(8, 0)
+#define MEMCTL_BUS 0
+#define MEMCTL_DEVFN PCI_DEVFN(16, 1)
+
+struct fbd_ioat {
+	unsigned int vendor;
+	unsigned int ioat_dev;
+};
+
+/*
+ * The i5000 chip-set has the same hooks as the i7300
+ * but support is disabled by default because this driver
+ * has not been validated on that platform.
+ */
+#define SUPPORT_I5000 0
+
+static const struct fbd_ioat fbd_ioat_list[] = {
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_CNB},
+#if SUPPORT_I5000
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT},
+#endif
+	{0, 0}
+};
+
+/* table of devices that work with this driver */
+static const struct pci_device_id pci_tbl[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_FBD_CNB) },
+#if SUPPORT_I5000
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5000_ERR) },
+#endif
+	{ } /* Terminating entry */
+};
+
+/* Check for known platforms with I/O-AT */
+static inline int i7300_idle_platform_probe(struct pci_dev **fbd_dev,
+						struct pci_dev **ioat_dev)
+{
+	int i;
+	struct pci_dev *memdev, *dmadev;
+
+	memdev = pci_get_bus_and_slot(MEMCTL_BUS, MEMCTL_DEVFN);
+	if (!memdev)
+		return -ENODEV;
+
+	for (i = 0; pci_tbl[i].vendor != 0; i++) {
+		if (memdev->vendor == pci_tbl[i].vendor &&
+		    memdev->device == pci_tbl[i].device) {
+			break;
+		}
+	}
+	if (pci_tbl[i].vendor == 0)
+		return -ENODEV;
+
+	dmadev = pci_get_bus_and_slot(IOAT_BUS, IOAT_DEVFN);
+	if (!dmadev)
+		return -ENODEV;
+
+	for (i = 0; fbd_ioat_list[i].vendor != 0; i++) {
+		if (dmadev->vendor == fbd_ioat_list[i].vendor &&
+		    dmadev->device == fbd_ioat_list[i].ioat_dev) {
+			if (fbd_dev)
+				*fbd_dev = memdev;
+			if (ioat_dev)
+				*ioat_dev = dmadev;
+
+			return 0;
+		}
+	}
+	return -ENODEV;
+}
+
+#endif