Commit 7eea5b89 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 0173a326 9fb3c5ca
...@@ -262,6 +262,7 @@ static int acpi_lid_send_state(struct acpi_button *button) ...@@ -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) ...@@ -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);
......
...@@ -38,7 +38,10 @@ ...@@ -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) ...@@ -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;
} }
......
...@@ -163,6 +163,8 @@ static void acpi_pm_end(void) ...@@ -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
......
...@@ -371,6 +371,7 @@ static void bt_poll_rfkill(struct input_polled_dev *poll_dev) ...@@ -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) ...@@ -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) {
......
...@@ -33,6 +33,7 @@ ...@@ -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) ...@@ -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 #ifdef CONFIG_I7300_IDLE_IOAT_CHANNEL
if (i7300_idle_platform_probe(NULL, NULL) == 0) {
device->common.chancnt--; 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);
......
...@@ -5,12 +5,13 @@ config I7300_IDLE_IOAT_CHANNEL ...@@ -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. Enable memory power savings when idle with certain Intel server
The chipset must have I/O AT support, such as the Intel 7300. chipsets. The chipset must have I/O AT support, such as the
The power savings depends on the type and quantity of DRAM devices. Intel 7300. The power savings depends on the type and quantity of
DRAM devices.
endmenu endmenu
...@@ -25,6 +25,7 @@ ...@@ -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 @@ ...@@ -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"); ...@@ -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 #define MAX_THROTTLE_LOW_LIMIT 168
static uint i7300_idle_thrtlowlm = 1; static uint throttle_low_limit = 1;
module_param_named(thrtlwlimit, i7300_idle_thrtlowlm, uint, 0644); module_param_named(throttle_low_limit, throttle_low_limit, uint, 0644);
MODULE_PARM_DESC(thrtlwlimit, 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) ...@@ -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) ...@@ -126,9 +129,10 @@ static void i7300_idle_ioat_stop(void)
} }
if (i == 5) if (i == MAX_STOP_RETRIES) {
dprintk("failed to suspend+reset I/O AT after 5 retries\n"); 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) ...@@ -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) ...@@ -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; limit = throttle_low_limit;
if (unlikely(limit > MAX_THRTLWLIMIT)) if (unlikely(limit > MAX_THROTTLE_LOW_LIMIT))
limit = MAX_THRTLWLIMIT; 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, ...@@ -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 = { ...@@ -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) ...@@ -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())
......
...@@ -49,7 +49,7 @@ static struct acpi_hpled adev; ...@@ -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 };
......
...@@ -83,6 +83,9 @@ static acpi_status acpi_run_osc(acpi_handle handle, ...@@ -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");
......
#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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment