ACPI and driver patches for 2.6.30-rc1
Subsystems (8)
Len Brown
reviewerPlease speak up if you see a problem with any of these.
thanks,
Len Brown, Intel Open Source Technology Center
Len Brown
reviewerPATCH 2/17 ACPI: Adjust Kelvin offset to match local implementation
From: Jean Delvare <[email protected]>
The exact offset between Kelvin and degree Celsius is 273.15. However ACPI handles temperature values with a single decimal place. As a consequence, some implementations use an offset of 273.1 and others use an offset of 273.2. Try to find out which one is being used, to present the most accurate and visually appealing number.
Tested on a Sony Vaio PGC-GR214EP (which uses 273.1) and a Lenovo Thinkpad T60p (which uses 273.2).
--- drivers/acpi/thermal.c | 41 ++++++++++++++++++++++++++++++++++------- 1 files changed, 34 insertions(+), 7 deletions(-)
drivers/acpi/thermal.c +34 -7
@@ -192,6 +192,7 @@ struct acpi_thermal {struct acpi_handle_list devices;struct thermal_zone_device *thermal_zone;int tz_enabled; +int kelvin_offset;struct mutex lock; };
@@ -581,7 +582,7 @@ static void acpi_thermal_check(void *data) }/* sys I/F for generic thermal sysfs support */ -#define KELVIN_TO_MILLICELSIUS (t) (t * 100 - 273200) +#define KELVIN_TO_MILLICELSIUS (t, off) (((t) - (off)) * 100)static int thermal_get_temp (struct thermal_zone_device *thermal,unsigned long *temp)
@@ -596,7 +597,7 @@ static int thermal_get_temp(struct thermal_zone_device *thermal,if (result)return result; - *temp =KELVIN_TO_MILLICELSIUS (tz->temperature); + *temp =KELVIN_TO_MILLICELSIUS (tz->temperature, tz->kelvin_offset);return 0 ; }
@@ -702,7 +703,8 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,if (tz->trips.critical.flags.valid) {if (!trip) { *temp =KELVIN_TO_MILLICELSIUS ( - tz->trips.critical.temperature); + tz->trips.critical.temperature, + tz->kelvin_offset);return 0 ; } trip--;
@@ -711,7 +713,8 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,if (tz->trips.hot.flags.valid) {if (!trip) { *temp =KELVIN_TO_MILLICELSIUS ( - tz->trips.hot.temperature); + tz->trips.hot.temperature, + tz->kelvin_offset);return 0 ; } trip--;
@@ -720,7 +723,8 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,if (tz->trips.passive.flags.valid) {if (!trip) { *temp =KELVIN_TO_MILLICELSIUS ( - tz->trips.passive.temperature); + tz->trips.passive.temperature, + tz->kelvin_offset);return 0 ; } trip--;
@@ -730,7 +734,8 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal, tz->trips.active[i].flags.valid; i++) {if (!trip) { *temp =KELVIN_TO_MILLICELSIUS ( - tz->trips.active[i].temperature); + tz->trips.active[i].temperature, + tz->kelvin_offset);return 0 ; } trip--;
@@ -745,7 +750,8 @@ static int thermal_get_crit_temp(struct thermal_zone_device *thermal,if (tz->trips.critical.flags.valid) { *temperature =KELVIN_TO_MILLICELSIUS ( - tz->trips.critical.temperature); + tz->trips.critical.temperature, + tz->kelvin_offset);return 0 ; }else return -EINVAL ;
@@ -1334,6 +1340,25 @@ static int acpi_thermal_get_info(struct acpi_thermal *tz)return 0 ; } +/* +* The exact offset between Kelvin and degree Celsius is 273.15. However ACPI +* handles temperature values with a single decimal place. As a consequence, +* some implementations use an offset of 273.1 and others use an offset of +* 273.2. Try to find out which one is being used, to present the most +* accurate and visually appealing number. +* +* The heuristic below should work for all ACPI thermal zones which have a +* critical trip point with a value being a multiple of 0.5 degree Celsius. +*/ +static void acpi_thermal_guess_offset (struct acpi_thermal *tz) +{ +if (tz->trips.critical.flags.valid && + (tz->trips.critical.temperature %5 ) ==1 ) + tz->kelvin_offset =2731 ; +else + tz->kelvin_offset =2732 ; +} +static int acpi_thermal_add (struct acpi_device *device) {int result =0 ;
@@ -1360,6 +1385,8 @@ static int acpi_thermal_add(struct acpi_device *device)if (result) goto free_memory; +acpi_thermal_guess_offset (tz); + result =acpi_thermal_register_thermal_zone (tz);if (result) goto free_memory;
Signature · 1 line
1.6.0.6
Len Brown
reviewerPATCH 3/17 ACPI: cpufreq: remove dupilcated #include
In reply to Len BrownFrom: Huang Weiyi <[email protected]>
Remove dupilicated #include in arch/x86/kernel/cpu/cpufreq/longhaul.c.
--- arch/x86/kernel/cpu/cpufreq/longhaul.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-)
arch/x86/kernel/cpu/cpufreq/longhaul.c +0 -1
@@ -33,7 +33,6 @@#include <linux/timex.h> #include <linux/io.h> #include <linux/acpi.h> -#include <linux/kernel.h> #include <asm/msr.h> #include <acpi/processor.h>
Signature · 1 line
1.6.0.6
Len Brown
reviewerPATCH 5/17 ACPI: delete acpi_device.g_list
In reply to Len BrownFrom: Len Brown <[email protected]>
unused
--- drivers/acpi/scan.c | 17 ++++------------- include/acpi/acpi_bus.h | 1 - 2 files changed, 4 insertions(+), 14 deletions(-)
drivers/acpi/scan.c +4 -13
@@ -491,7 +491,6 @@ static int acpi_device_register(struct acpi_device *device,*/ INIT_LIST_HEAD (&device->children);INIT_LIST_HEAD (&device->node); -INIT_LIST_HEAD (&device->g_list);INIT_LIST_HEAD (&device->wakeup_list); new_bus_id =kzalloc (sizeof (struct acpi_device_bus_id ),GFP_KERNEL );
@@ -521,11 +520,9 @@ static int acpi_device_register(struct acpi_device *device, }dev_set_name (&device->dev,"%s:%02x" , acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no); -if (device->parent) { +if (device->parent)list_add_tail (&device->node, &device->parent->children); -list_add_tail (&device->g_list, &device->parent->g_list); - }else -list_add_tail (&device->g_list, &acpi_device_list); +if (device->wakeup.flags.valid)list_add_tail (&device->wakeup_list, &acpi_wakeup_device_list);mutex_unlock (&acpi_device_lock);
@@ -550,11 +547,8 @@ static int acpi_device_register(struct acpi_device *device,return 0 ; end:mutex_lock (&acpi_device_lock); -if (device->parent) { +if (device->parent)list_del (&device->node); -list_del (&device->g_list); - }else -list_del (&device->g_list);list_del (&device->wakeup_list);mutex_unlock (&acpi_device_lock);return result;
@@ -563,11 +557,8 @@ static int acpi_device_register(struct acpi_device *device,static void acpi_device_unregister (struct acpi_device *device,int type) {mutex_lock (&acpi_device_lock); -if (device->parent) { +if (device->parent)list_del (&device->node); -list_del (&device->g_list); - }else -list_del (&device->g_list);list_del (&device->wakeup_list);mutex_unlock (&acpi_device_lock);
include/acpi/acpi_bus.h +0 -1
@@ -270,7 +270,6 @@ struct acpi_device {struct list_head children;struct list_head node;struct list_head wakeup_list; -struct list_head g_list;struct acpi_device_status status;struct acpi_device_flags flags;struct acpi_device_pnp pnp;
Signature · 1 line
1.6.0.6
Len Brown
reviewerPATCH 4/17 NULL noise: drivers/platform/x86/panasonic-laptop.c
In reply to Len BrownFrom: Hannes Eder <[email protected]>
Fix this sparse warning:
drivers/platform/x86/panasonic-laptop.c:273:70: warning: Using plain integer as NULL pointer
--- drivers/platform/x86/panasonic-laptop.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/platform/x86/panasonic-laptop.c +1 -1
@@ -271,7 +271,7 @@ static int acpi_pcc_retrieve_biosdata(struct pcc_acpi *pcc, u32 *sinf)union acpi_object *hkey =NULL ;int i; - status =acpi_evaluate_object (pcc->handle,METHOD_HKEY_SINF ,0 , + status =acpi_evaluate_object (pcc->handle,METHOD_HKEY_SINF ,NULL , &buffer);if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
Signature · 1 line
1.6.0.6
Len Brown
reviewerPATCH 8/17 ACPI: video: use .notify method instead of installing handler directly
In reply to Len BrownFrom: Bjorn Helgaas <[email protected]>
This patch adds a .notify() method. The presence of .notify() causes Linux/ACPI to manage event handlers and notify handlers on our behalf, so we don't have to install and remove them ourselves.
--- drivers/acpi/video.c | 30 +++++------------------------- 1 files changed, 5 insertions(+), 25 deletions(-)
drivers/acpi/video.c +5 -25
@@ -79,6 +79,7 @@ module_param(brightness_switch_enabled, bool, 0644);static int acpi_video_bus_add (struct acpi_device *device);static int acpi_video_bus_remove (struct acpi_device *device,int type);static int acpi_video_resume (struct acpi_device *device); +static void acpi_video_bus_notify (struct acpi_device *device,u32 event);static const struct acpi_device_id video_device_ids[] = { {ACPI_VIDEO_HID ,0 },
@@ -94,6 +95,7 @@ static struct acpi_driver acpi_video_bus = { .add = acpi_video_bus_add, .remove = acpi_video_bus_remove, .resume = acpi_video_resume, + .notify = acpi_video_bus_notify, }, };
@@ -1986,17 +1988,15 @@ static int acpi_video_bus_stop_devices(struct acpi_video_bus *video)return acpi_video_bus_DOS (video,0 ,1 ); } -static void acpi_video_bus_notify (acpi_handle handle,u32 event,void *data) +static void acpi_video_bus_notify (struct acpi_device *device,u32 event) { -struct acpi_video_bus *video = data; -struct acpi_device *device =NULL ; +struct acpi_video_bus *video =acpi_driver_data (device);struct input_dev *input;int keycode;if (!video)return ; - device = video->device; input = video->input;switch (event) {
@@ -2127,7 +2127,6 @@ static int acpi_video_resume(struct acpi_device *device)static int acpi_video_bus_add (struct acpi_device *device) { -acpi_status status;struct acpi_video_bus *video;struct input_dev *input;int error;
@@ -2169,20 +2168,10 @@ static int acpi_video_bus_add(struct acpi_device *device)acpi_video_bus_get_devices (video, device);acpi_video_bus_start_devices (video); - status =acpi_install_notify_handler (device->handle, -ACPI_DEVICE_NOTIFY , - acpi_video_bus_notify, video); -if (ACPI_FAILURE (status)) { - printk(KERN_ERR PREFIX - "Error installing notify handler\n"); - error = -ENODEV ; - goto err_stop_video; - } - video->input = input =input_allocate_device ();if (!input) { error = -ENOMEM ; - goto err_uninstall_notify; + goto err_stop_video; } snprintf(video->phys, sizeof(video->phys),
@@ -2218,9 +2207,6 @@ static int acpi_video_bus_add(struct acpi_device *device) err_free_input_dev:input_free_device (input); - err_uninstall_notify: -acpi_remove_notify_handler (device->handle,ACPI_DEVICE_NOTIFY , - acpi_video_bus_notify); err_stop_video:acpi_video_bus_stop_devices (video);acpi_video_bus_put_devices (video);
@@ -2235,7 +2221,6 @@ static int acpi_video_bus_add(struct acpi_device *device)static int acpi_video_bus_remove (struct acpi_device *device,int type) { -acpi_status status =0 ;struct acpi_video_bus *video =NULL ;
@@ -2245,11 +2230,6 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type) video =acpi_driver_data (device);acpi_video_bus_stop_devices (video); - - status =acpi_remove_notify_handler (video->device->handle, -ACPI_DEVICE_NOTIFY , - acpi_video_bus_notify); -acpi_video_bus_put_devices (video);acpi_video_bus_remove_fs (device);
Signature · 1 line
1.6.0.6
Len Brown
reviewerPATCH 1/17 ACPI: convert acpi_device_lock spinlock to mutex
In reply to Len BrownFrom: Shaohua Li <[email protected]>
Convert acpi_device_lock to a mutex to avoid
a potential race upon access to /proc/acpi/wakeup
Delete the lock entirely in wakeup.c
since it is not necessary (and can not sleep)
--- drivers/acpi/proc.c | 13 ++++--------- drivers/acpi/scan.c | 14 +++++++------- drivers/acpi/sleep.h | 3 +++ drivers/acpi/wakeup.c | 30 +++++++----------------------- 4 files changed, 21 insertions(+), 39 deletions(-)
drivers/acpi/proc.c +4 -9
@@ -343,9 +343,6 @@ acpi_system_write_alarm(struct file *file, }#endif /* HAVE_ACPI_LEGACY_ALARM */ -extern struct list_head acpi_wakeup_device_list; -extern spinlock_t acpi_device_lock; -static int acpi_system_wakeup_device_seq_show (struct seq_file *seq,void *offset) {
@@ -353,7 +350,7 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)seq_printf (seq,"Device\tS-state\t Status Sysfs node\n" ); -spin_lock (&acpi_device_lock); +mutex_lock (&acpi_device_lock);list_for_each_safe (node, next, &acpi_wakeup_device_list) {struct acpi_device *dev = container_of(node, struct acpi_device, wakeup_list);
@@ -361,7 +358,6 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)if (!dev->wakeup.flags.valid)continue ; -spin_unlock (&acpi_device_lock); ldev =acpi_get_physical_device (dev->handle); seq_printf(seq, "%s\t S%d\t%c%-8s ",
@@ -376,9 +372,8 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)seq_printf (seq,"\n" );put_device (ldev); -spin_lock (&acpi_device_lock); } -spin_unlock (&acpi_device_lock); +mutex_unlock (&acpi_device_lock);return 0 ; }
@@ -409,7 +404,7 @@ acpi_system_write_wakeup_device(struct file *file, strbuf[len] ='\0' ;sscanf (strbuf,"%s" , str); -spin_lock (&acpi_device_lock); +mutex_lock (&acpi_device_lock);list_for_each_safe (node, next, &acpi_wakeup_device_list) {struct acpi_device *dev = container_of(node, struct acpi_device, wakeup_list);
@@ -446,7 +441,7 @@ acpi_system_write_wakeup_device(struct file *file, } } } -spin_unlock (&acpi_device_lock); +mutex_unlock (&acpi_device_lock);return count; }
drivers/acpi/scan.c +7 -7
@@ -24,7 +24,7 @@ extern struct acpi_device *acpi_root;static LIST_HEAD (acpi_device_list);static LIST_HEAD (acpi_bus_id_list); -DEFINE_SPINLOCK (acpi_device_lock); +DEFINE_MUTEX (acpi_device_lock);LIST_HEAD (acpi_wakeup_device_list);struct acpi_device_bus_id {
@@ -500,7 +500,7 @@ static int acpi_device_register(struct acpi_device *device,return -ENOMEM ; } -spin_lock (&acpi_device_lock); +mutex_lock (&acpi_device_lock);/* * Find suitable bus_id and instance number in acpi_bus_id_list * If failed, create one and link it into acpi_bus_id_list
@@ -528,7 +528,7 @@ static int acpi_device_register(struct acpi_device *device,list_add_tail (&device->g_list, &acpi_device_list);if (device->wakeup.flags.valid)list_add_tail (&device->wakeup_list, &acpi_wakeup_device_list); -spin_unlock (&acpi_device_lock); +mutex_unlock (&acpi_device_lock);if (device->parent) device->dev.parent = &parent->dev;
@@ -549,20 +549,20 @@ static int acpi_device_register(struct acpi_device *device, device->removal_type =ACPI_BUS_REMOVAL_NORMAL ;return 0 ; end: -spin_lock (&acpi_device_lock); +mutex_lock (&acpi_device_lock);if (device->parent) {list_del (&device->node);list_del (&device->g_list); }else list_del (&device->g_list);list_del (&device->wakeup_list); -spin_unlock (&acpi_device_lock); +mutex_unlock (&acpi_device_lock);return result; }static void acpi_device_unregister (struct acpi_device *device,int type) { -spin_lock (&acpi_device_lock); +mutex_lock (&acpi_device_lock);if (device->parent) {list_del (&device->node);list_del (&device->g_list);
@@ -570,7 +570,7 @@ static void acpi_device_unregister(struct acpi_device *device, int type)list_del (&device->g_list);list_del (&device->wakeup_list); -spin_unlock (&acpi_device_lock); +mutex_unlock (&acpi_device_lock);acpi_detach_data (device->handle, acpi_bus_data_handler);
drivers/acpi/sleep.h +3 -0
@@ -5,3 +5,6 @@ extern int acpi_suspend (u32 state);extern void acpi_enable_wakeup_device_prep (u8 sleep_state);extern void acpi_enable_wakeup_device (u8 sleep_state);extern void acpi_disable_wakeup_device (u8 sleep_state); + +extern struct list_head acpi_wakeup_device_list; +extern struct mutex acpi_device_lock;
drivers/acpi/wakeup.c +7 -23
@@ -12,12 +12,14 @@#include "internal.h" #include "sleep.h" +/* +* We didn't lock acpi_device_lock in the file, because it invokes oops in +* suspend/resume and isn't really required as this is called in S-state. At +* that time, there is no device hotplug +**/ #define _COMPONENT ACPI_SYSTEM_COMPONENTACPI_MODULE_NAME ("wakeup_devices" ) -extern struct list_head acpi_wakeup_device_list; -extern spinlock_t acpi_device_lock; -/** * acpi_enable_wakeup_device_prep - prepare wakeup devices * @sleep_state: ACPI state
@@ -29,7 +31,6 @@ void acpi_enable_wakeup_device_prep(u8 sleep_state) {struct list_head *node, *next; -spin_lock (&acpi_device_lock);list_for_each_safe (node, next, &acpi_wakeup_device_list) { struct acpi_device *dev = container_of(node, struct acpi_device,
@@ -40,11 +41,8 @@ void acpi_enable_wakeup_device_prep(u8 sleep_state) (sleep_state > (u32) dev->wakeup.sleep_state)) continue; -spin_unlock (&acpi_device_lock);acpi_enable_wakeup_device_power (dev, sleep_state); -spin_lock (&acpi_device_lock); } -spin_unlock (&acpi_device_lock); }/**
@@ -60,7 +58,6 @@ void acpi_enable_wakeup_device(u8 sleep_state)* Caution: this routine must be invoked when interrupt is disabled * Refer ACPI2.0: P212 */ -spin_lock (&acpi_device_lock);list_for_each_safe (node, next, &acpi_wakeup_device_list) {struct acpi_device *dev = container_of(node, struct acpi_device, wakeup_list);
@@ -74,22 +71,17 @@ void acpi_enable_wakeup_device(u8 sleep_state)if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared) || sleep_state > (u32 ) dev->wakeup.sleep_state) {if (dev->wakeup.flags.run_wake) { -spin_unlock (&acpi_device_lock);/* set_gpe_type will disable GPE, leave it like that */ acpi_set_gpe_type (dev->wakeup.gpe_device, dev->wakeup.gpe_number,ACPI_GPE_TYPE_RUNTIME ); -spin_lock (&acpi_device_lock); }continue ; } -spin_unlock (&acpi_device_lock);if (!dev->wakeup.flags.run_wake)acpi_enable_gpe (dev->wakeup.gpe_device, dev->wakeup.gpe_number); -spin_lock (&acpi_device_lock); } -spin_unlock (&acpi_device_lock); }/**
@@ -101,7 +93,6 @@ void acpi_disable_wakeup_device(u8 sleep_state) {struct list_head *node, *next; -spin_lock (&acpi_device_lock);list_for_each_safe (node, next, &acpi_wakeup_device_list) {struct acpi_device *dev = container_of(node, struct acpi_device, wakeup_list);
@@ -112,19 +103,16 @@ void acpi_disable_wakeup_device(u8 sleep_state)if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared) || sleep_state > (u32 ) dev->wakeup.sleep_state) {if (dev->wakeup.flags.run_wake) { -spin_unlock (&acpi_device_lock);acpi_set_gpe_type (dev->wakeup.gpe_device, dev->wakeup.gpe_number,ACPI_GPE_TYPE_WAKE_RUN );/* Re-enable it, since set_gpe_type will disable it */ acpi_enable_gpe (dev->wakeup.gpe_device, dev->wakeup.gpe_number); -spin_lock (&acpi_device_lock); }continue ; } -spin_unlock (&acpi_device_lock);acpi_disable_wakeup_device_power (dev);/* Never disable run-wake GPE */ if (!dev->wakeup.flags.run_wake) {
@@ -133,16 +121,14 @@ void acpi_disable_wakeup_device(u8 sleep_state)acpi_clear_gpe (dev->wakeup.gpe_device, dev->wakeup.gpe_number,ACPI_NOT_ISR ); } -spin_lock (&acpi_device_lock); } -spin_unlock (&acpi_device_lock); }int __init acpi_wakeup_device_init (void ) {struct list_head *node, *next; -spin_lock (&acpi_device_lock); +mutex_lock (&acpi_device_lock);list_for_each_safe (node, next, &acpi_wakeup_device_list) { struct acpi_device *dev = container_of(node, struct acpi_device,
@@ -150,15 +136,13 @@ int __init acpi_wakeup_device_init(void)/* In case user doesn't load button driver */ if (!dev->wakeup.flags.run_wake || dev->wakeup.state.enabled)continue ; -spin_unlock (&acpi_device_lock);acpi_set_gpe_type (dev->wakeup.gpe_device, dev->wakeup.gpe_number,ACPI_GPE_TYPE_WAKE_RUN );acpi_enable_gpe (dev->wakeup.gpe_device, dev->wakeup.gpe_number); dev->wakeup.state.enabled =1 ; -spin_lock (&acpi_device_lock); } -spin_unlock (&acpi_device_lock); +mutex_unlock (&acpi_device_lock);return 0 ; }
Signature · 1 line
1.6.0.6
Len Brown
reviewerPATCH 10/17 fujitsu-laptop: use .notify method instead of installing hotkey handler directly
In reply to Len BrownFrom: Bjorn Helgaas <[email protected]>
This patch adds a .notify() method. The presence of .notify() causes Linux/ACPI to manage event handlers and notify handlers on our behalf, so we don't have to install and remove them ourselves.
Tested by Tony on Fujitsu-Siemens Lifebook S6420 [FJNB1E6] with BIOS 1.18 (01/09/2009). Tested by Jonathan on Fujitsu S7020.
--- drivers/platform/x86/fujitsu-laptop.c | 32 +++++--------------------------- 1 files changed, 5 insertions(+), 27 deletions(-)
drivers/platform/x86/fujitsu-laptop.c +5 -27
@@ -174,8 +174,7 @@ struct fujitsu_hotkey_t {static struct fujitsu_hotkey_t *fujitsu_hotkey; -static void acpi_fujitsu_hotkey_notify (acpi_handle handle,u32 event, -void *data); +static void acpi_fujitsu_hotkey_notify (struct acpi_device *device,u32 event);#ifdef CONFIG_LEDS_CLASS static enum led_brightness logolamp_get (struct led_classdev *cdev);
@@ -816,7 +815,6 @@ static void acpi_fujitsu_notify(struct acpi_device *device, u32 event)static int acpi_fujitsu_hotkey_add (struct acpi_device *device) { -acpi_status status;acpi_handle handle;int result =0 ;int state =0 ;
@@ -833,17 +831,6 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device)sprintf (acpi_device_class (device),"%s" ,ACPI_FUJITSU_CLASS ); device->driver_data = fujitsu_hotkey; - status =acpi_install_notify_handler (device->handle, -ACPI_DEVICE_NOTIFY , - acpi_fujitsu_hotkey_notify, - fujitsu_hotkey); - -if (ACPI_FAILURE (status)) { -printk (KERN_ERR "Error installing notify handler\n" ); - error = -ENODEV ; - goto err_stop; - } -/* kfifo */ spin_lock_init (&fujitsu_hotkey->fifo_lock); fujitsu_hotkey->fifo =
@@ -858,7 +845,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) fujitsu_hotkey->input = input =input_allocate_device ();if (!input) { error = -ENOMEM ; - goto err_uninstall_notify; + goto err_free_fifo; } snprintf(fujitsu_hotkey->phys, sizeof(fujitsu_hotkey->phys),
@@ -954,9 +941,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) end: err_free_input_dev:input_free_device (input); -err_uninstall_notify: -acpi_remove_notify_handler (device->handle,ACPI_DEVICE_NOTIFY , - acpi_fujitsu_hotkey_notify); +err_free_fifo:kfifo_free (fujitsu_hotkey->fifo); err_stop:
@@ -965,7 +950,6 @@ err_stop:static int acpi_fujitsu_hotkey_remove (struct acpi_device *device,int type) { -acpi_status status;struct fujitsu_hotkey_t *fujitsu_hotkey =NULL ;if (!device || !acpi_driver_data (device))
@@ -973,10 +957,6 @@ static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type) fujitsu_hotkey =acpi_driver_data (device); - status =acpi_remove_notify_handler (fujitsu_hotkey->acpi_handle, -ACPI_DEVICE_NOTIFY , - acpi_fujitsu_hotkey_notify); - fujitsu_hotkey->acpi_handle =NULL ;kfifo_free (fujitsu_hotkey->fifo);
@@ -984,8 +964,7 @@ static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type)return 0 ; } -static void acpi_fujitsu_hotkey_notify (acpi_handle handle,u32 event, -void *data) +static void acpi_fujitsu_hotkey_notify (struct acpi_device *device,u32 event) {struct input_dev *input;int keycode, keycode_r;
@@ -1068,8 +1047,6 @@ static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,input_sync (input);break ; } - -return ; }/* Initialization */
@@ -1102,6 +1079,7 @@ static struct acpi_driver acpi_fujitsu_hotkey_driver = { .ops = { .add = acpi_fujitsu_hotkey_add, .remove = acpi_fujitsu_hotkey_remove, + .notify = acpi_fujitsu_hotkey_notify, }, };
Signature · 1 line
1.6.0.6
Len Brown
reviewerPATCH 11/17 panasonic-laptop: use .notify method instead of installing handler directly
In reply to Len BrownFrom: Bjorn Helgaas <[email protected]>
This patch adds a .notify() method. The presence of .notify() causes Linux/ACPI to manage event handlers and notify handlers on our behalf, so we don't have to install and remove them ourselves.
--- drivers/platform/x86/panasonic-laptop.c | 26 +++++--------------------- 1 files changed, 5 insertions(+), 21 deletions(-)
drivers/platform/x86/panasonic-laptop.c +5 -21
@@ -176,6 +176,7 @@ enum SINF_BITS { SINF_NUM_BATTERIES = 0,static int acpi_pcc_hotkey_add (struct acpi_device *device);static int acpi_pcc_hotkey_remove (struct acpi_device *device,int type);static int acpi_pcc_hotkey_resume (struct acpi_device *device); +static void acpi_pcc_hotkey_notify (struct acpi_device *device,u32 event);static const struct acpi_device_id pcc_device_ids[] = { {"MAT0012" ,0 },
@@ -194,6 +195,7 @@ static struct acpi_driver acpi_pcc_driver = { .add = acpi_pcc_hotkey_add, .remove = acpi_pcc_hotkey_remove, .resume = acpi_pcc_hotkey_resume, + .notify = acpi_pcc_hotkey_notify, }, };
@@ -527,9 +529,9 @@ static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc)return ; } -static void acpi_pcc_hotkey_notify (acpi_handle handle,u32 event,void *data) +static void acpi_pcc_hotkey_notify (struct acpi_device *device,u32 event) { -struct pcc_acpi *pcc = (struct pcc_acpi *) data; +struct pcc_acpi *pcc =acpi_driver_data (device);switch (event) {case HKEY_NOTIFY :
@@ -599,7 +601,6 @@ static int acpi_pcc_hotkey_resume(struct acpi_device *device)static int acpi_pcc_hotkey_add (struct acpi_device *device) { -acpi_status status;struct pcc_acpi *pcc;int num_sifr, result;
@@ -640,22 +641,11 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device) goto out_sinf; } -/* initialize hotkey input device */ - status =acpi_install_notify_handler (pcc->handle,ACPI_DEVICE_NOTIFY , - acpi_pcc_hotkey_notify, pcc); - -if (ACPI_FAILURE (status)) { -ACPI_DEBUG_PRINT ((ACPI_DB_ERROR , -"Error installing notify handler\n" )); - result = -ENODEV ; - goto out_input; - } -/* initialize backlight */ pcc->backlight =backlight_device_register ("panasonic" ,NULL , pcc, &pcc_backlight_ops);if (IS_ERR (pcc->backlight)) - goto out_notify; + goto out_input;if (!acpi_pcc_retrieve_biosdata (pcc, pcc->sinf)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
@@ -680,9 +670,6 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device) out_backlight:backlight_device_unregister (pcc->backlight); -out_notify: -acpi_remove_notify_handler (pcc->handle,ACPI_DEVICE_NOTIFY , - acpi_pcc_hotkey_notify); out_input:input_unregister_device (pcc->input_dev);/* no need to input_free_device() since core input API refcount and
@@ -723,9 +710,6 @@ static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type)backlight_device_unregister (pcc->backlight); -acpi_remove_notify_handler (pcc->handle,ACPI_DEVICE_NOTIFY , - acpi_pcc_hotkey_notify); -input_unregister_device (pcc->input_dev);/* no need to input_free_device() since core input API refcount and * free()s the device */
Signature · 1 line
1.6.0.6
Len Brown
reviewerPATCH 6/17 ACPI battery: fix async boot oops
In reply to Len BrownFrom: Vegard Nossum <[email protected]>
Quoted 1 line
BUG: unable to handle kernel NULL pointer dereference at (null)
What happens is that the battery module's init sections are being freed before the async callback (which was marked __init) has run. This theory is supported by the fact that the bad RIP value is a vmalloc address.
The immediate fix is to make this a non-init call.
(A better long-term fix is of course to wait with init-section unloading until a module's async initcalls have been run, which would allow us to discard this function which is still only run once, after all. Perhaps a new async_initcall() function for the async/module API, if this is needed for other modules in the future?)
--- drivers/acpi/battery.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/acpi/battery.c +1 -1
@@ -903,7 +903,7 @@ static struct acpi_driver acpi_battery_driver = { }, }; -static void __init acpi_battery_init_async (void *unused,async_cookie_t cookie) +static void acpi_battery_init_async (void *unused,async_cookie_t cookie) {if (acpi_disabled)return ;
Signature · 1 line
1.6.0.6
Len Brown
reviewerPATCH 9/17 fujitsu-laptop: use .notify method instead of installing handler directly
In reply to Len BrownFrom: Bjorn Helgaas <[email protected]>
This patch adds a .notify() method. The presence of .notify() causes Linux/ACPI to manage event handlers and notify handlers on our behalf, so we don't have to install and remove them ourselves.
Tested by Tony on Fujitsu-Siemens Lifebook S6420 [FJNB1E6] with BIOS 1.18 (01/09/2009). Tested by Jonathan on Fujitsu S7020.
--- drivers/platform/x86/fujitsu-laptop.c | 28 ++++------------------------ 1 files changed, 4 insertions(+), 24 deletions(-)
drivers/platform/x86/fujitsu-laptop.c +4 -24
@@ -203,7 +203,7 @@ struct led_classdev kblamps_led = {static u32 dbg_level =0x03 ;#endif -static void acpi_fujitsu_notify (acpi_handle handle,u32 event,void *data); +static void acpi_fujitsu_notify (struct acpi_device *device,u32 event);/* Fujitsu ACPI interface function */
@@ -658,7 +658,6 @@ static struct dmi_system_id fujitsu_dmi_table[] = {static int acpi_fujitsu_add (struct acpi_device *device) { -acpi_status status;acpi_handle handle;int result =0 ;int state =0 ;
@@ -673,20 +672,10 @@ static int acpi_fujitsu_add(struct acpi_device *device)sprintf (acpi_device_class (device),"%s" ,ACPI_FUJITSU_CLASS ); device->driver_data = fujitsu; - status =acpi_install_notify_handler (device->handle, -ACPI_DEVICE_NOTIFY , - acpi_fujitsu_notify, fujitsu); - -if (ACPI_FAILURE (status)) { -printk (KERN_ERR "Error installing notify handler\n" ); - error = -ENODEV ; - goto err_stop; - } - fujitsu->input = input =input_allocate_device ();if (!input) { error = -ENOMEM ; - goto err_uninstall_notify; + goto err_stop; } snprintf(fujitsu->phys, sizeof(fujitsu->phys),
@@ -743,9 +732,6 @@ static int acpi_fujitsu_add(struct acpi_device *device) end: err_free_input_dev:input_free_device (input); -err_uninstall_notify: -acpi_remove_notify_handler (device->handle,ACPI_DEVICE_NOTIFY , - acpi_fujitsu_notify); err_stop:return result;
@@ -753,7 +739,6 @@ err_stop:static int acpi_fujitsu_remove (struct acpi_device *device,int type) { -acpi_status status;struct fujitsu_t *fujitsu =NULL ;if (!device || !acpi_driver_data (device))
@@ -761,10 +746,6 @@ static int acpi_fujitsu_remove(struct acpi_device *device, int type) fujitsu =acpi_driver_data (device); - status =acpi_remove_notify_handler (fujitsu->acpi_handle, -ACPI_DEVICE_NOTIFY , - acpi_fujitsu_notify); -if (!device || !acpi_driver_data (device))return -EINVAL ;
@@ -775,7 +756,7 @@ static int acpi_fujitsu_remove(struct acpi_device *device, int type)/* Brightness notify */ -static void acpi_fujitsu_notify (acpi_handle handle,u32 event,void *data) +static void acpi_fujitsu_notify (struct acpi_device *device,u32 event) {struct input_dev *input;int keycode;
@@ -829,8 +810,6 @@ static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data)input_report_key (input, keycode,0 );input_sync (input); } - -return ; }/* ACPI device for hotkey handling */
@@ -1107,6 +1086,7 @@ static struct acpi_driver acpi_fujitsu_driver = { .ops = { .add = acpi_fujitsu_add, .remove = acpi_fujitsu_remove, + .notify = acpi_fujitsu_notify, }, };
Signature · 1 line
1.6.0.6
Len Brown
reviewerPATCH 7/17 ACPI: thermal: use .notify method instead of installing handler directly
In reply to Len BrownFrom: Bjorn Helgaas <[email protected]>
This patch adds a .notify() method. The presence of .notify() causes Linux/ACPI to manage event handlers and notify handlers on our behalf, so we don't have to install and remove them ourselves.
--- drivers/acpi/thermal.c | 27 ++++----------------------- 1 files changed, 4 insertions(+), 23 deletions(-)
drivers/acpi/thermal.c +4 -23
@@ -98,6 +98,7 @@ MODULE_PARM_DESC(psv, "Disable or override all passive trip points.");static int acpi_thermal_add (struct acpi_device *device);static int acpi_thermal_remove (struct acpi_device *device,int type);static int acpi_thermal_resume (struct acpi_device *device); +static void acpi_thermal_notify (struct acpi_device *device,u32 event);static int acpi_thermal_state_open_fs (struct inode *inode,struct file *file);static int acpi_thermal_temp_open_fs (struct inode *inode,struct file *file);static int acpi_thermal_trip_open_fs (struct inode *inode,struct file *file);
@@ -123,6 +124,7 @@ static struct acpi_driver acpi_thermal_driver = { .add = acpi_thermal_add, .remove = acpi_thermal_remove, .resume = acpi_thermal_resume, + .notify = acpi_thermal_notify, }, };
@@ -1264,17 +1266,14 @@ static int acpi_thermal_remove_fs(struct acpi_device *device)Driver Interface -------------------------------------------------------------------------- */ -static void acpi_thermal_notify (acpi_handle handle,u32 event,void *data) +static void acpi_thermal_notify (struct acpi_device *device,u32 event) { -struct acpi_thermal *tz = data; -struct acpi_device *device =NULL ; +struct acpi_thermal *tz =acpi_driver_data (device);if (!tz)return ; - device = tz->device; -switch (event) {case ACPI_THERMAL_NOTIFY_TEMPERATURE :acpi_thermal_check (tz);
@@ -1298,8 +1297,6 @@ static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) "Unsupported event [0x%x]\n", event));break ; } - -return ; }static int acpi_thermal_get_info (struct acpi_thermal *tz)
@@ -1337,7 +1334,6 @@ static int acpi_thermal_get_info(struct acpi_thermal *tz)static int acpi_thermal_add (struct acpi_device *device) {int result =0 ; -acpi_status status =AE_OK ;struct acpi_thermal *tz =NULL ;
@@ -1368,21 +1364,11 @@ static int acpi_thermal_add(struct acpi_device *device)if (result) goto unregister_thermal_zone; - status =acpi_install_notify_handler (device->handle, -ACPI_DEVICE_NOTIFY , - acpi_thermal_notify, tz); -if (ACPI_FAILURE (status)) { - result = -ENODEV ; - goto remove_fs; - } - printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n",acpi_device_name (device),acpi_device_bid (device), KELVIN_TO_CELSIUS(tz->temperature)); goto end; -remove_fs: -acpi_thermal_remove_fs (device); unregister_thermal_zone:thermal_zone_device_unregister (tz->thermal_zone); free_memory:
@@ -1393,7 +1379,6 @@ end:static int acpi_thermal_remove (struct acpi_device *device,int type) { -acpi_status status =AE_OK ;struct acpi_thermal *tz =NULL ;if (!device || !acpi_driver_data (device))
@@ -1401,10 +1386,6 @@ static int acpi_thermal_remove(struct acpi_device *device, int type) tz =acpi_driver_data (device); - status =acpi_remove_notify_handler (device->handle, -ACPI_DEVICE_NOTIFY , - acpi_thermal_notify); -acpi_thermal_remove_fs (device);acpi_thermal_unregister_thermal_zone (tz);mutex_destroy (&tz->lock);
Signature · 1 line
1.6.0.6
Len Brown
reviewerPATCH 12/17 sony-laptop: use .notify method instead of installing handler directly
In reply to Len BrownFrom: Bjorn Helgaas <[email protected]>
This patch adds a .notify() method. The presence of .notify() causes Linux/ACPI to manage event handlers and notify handlers on our behalf, so we don't have to install and remove them ourselves.
--- drivers/platform/x86/sony-laptop.c | 30 ++++-------------------------- 1 files changed, 4 insertions(+), 26 deletions(-)
drivers/platform/x86/sony-laptop.c +4 -26
@@ -914,7 +914,7 @@ static struct sony_nc_event sony_127_events[] = {/* * ACPI callbacks */ -static void sony_acpi_notify (acpi_handle handle,u32 event,void *data) +static void sony_nc_notify (struct acpi_device *device,u32 event) {u32 ev = event;
@@ -933,7 +933,7 @@ static void sony_acpi_notify(acpi_handle handle, u32 event, void *data)struct sony_nc_event *key_event;if (sony_call_snc_handle (key_handle,0x200 , &result)) { -dprintk ("sony_acpi_notify, unable to decode" +dprintk ("sony_nc_notify, unable to decode" " event 0x%.2x 0x%.2x\n" , key_handle, ev);/* restore the original event */
@@ -968,7 +968,7 @@ static void sony_acpi_notify(acpi_handle handle, u32 event, void *data) }else sony_laptop_report_input_event (ev); -dprintk ("sony_acpi_notify, event: 0x%.2x\n" , ev); +dprintk ("sony_nc_notify, event: 0x%.2x\n" , ev);acpi_bus_generate_proc_event (sony_nc_acpi_device,1 , ev); }
@@ -1276,15 +1276,6 @@ static int sony_nc_add(struct acpi_device *device) goto outwalk; } - status =acpi_install_notify_handler (sony_nc_acpi_handle, -ACPI_DEVICE_NOTIFY , - sony_acpi_notify,NULL ); -if (ACPI_FAILURE (status)) { - printk(KERN_WARNING DRV_PFX "unable to install notify handler (%u)\n", status); - result = -ENODEV ; - goto outinput; - } -if (acpi_video_backlight_support ()) { printk(KERN_INFO DRV_PFX "brightness ignored, must be " "controlled by ACPI video driver\n");
@@ -1362,13 +1353,6 @@ static int sony_nc_add(struct acpi_device *device)if (sony_backlight_device)backlight_device_unregister (sony_backlight_device); - status =acpi_remove_notify_handler (sony_nc_acpi_handle, -ACPI_DEVICE_NOTIFY , - sony_acpi_notify); -if (ACPI_FAILURE (status)) - printk(KERN_WARNING DRV_PFX "unable to remove notify handler\n"); - - outinput:sony_laptop_remove_input (); outwalk:
@@ -1378,7 +1362,6 @@ static int sony_nc_add(struct acpi_device *device)static int sony_nc_remove (struct acpi_device *device,int type) { -acpi_status status;struct sony_nc_value *item;if (sony_backlight_device)
@@ -1386,12 +1369,6 @@ static int sony_nc_remove(struct acpi_device *device, int type) sony_nc_acpi_device =NULL ; - status =acpi_remove_notify_handler (sony_nc_acpi_handle, -ACPI_DEVICE_NOTIFY , - sony_acpi_notify); -if (ACPI_FAILURE (status)) - printk(KERN_WARNING DRV_PFX "unable to remove notify handler\n"); -for (item = sony_nc_values; item->name; ++item) {device_remove_file (&sony_pf_device->dev, &item->devattr); }
@@ -1425,6 +1402,7 @@ static struct acpi_driver sony_nc_driver = { .add = sony_nc_add, .remove = sony_nc_remove, .resume = sony_nc_resume, + .notify = sony_nc_notify, }, };
Signature · 1 line
1.6.0.6
Len Brown
reviewerPATCH 13/17 ACPI: WMI: use .notify method instead of installing handler directly
In reply to Len BrownFrom: Bjorn Helgaas <[email protected]>
This patch adds a .notify() method. The presence of .notify() causes Linux/ACPI to manage event handlers and notify handlers on our behalf, so we don't have to install and remove them ourselves.
--- drivers/platform/x86/wmi.c | 15 +++------------ 1 files changed, 3 insertions(+), 12 deletions(-)
drivers/platform/x86/wmi.c +3 -12
@@ -81,6 +81,7 @@ static struct wmi_block wmi_blocks;static int acpi_wmi_remove (struct acpi_device *device,int type);static int acpi_wmi_add (struct acpi_device *device); +static void acpi_wmi_notify (struct acpi_device *device,u32 event);static const struct acpi_device_id wmi_device_ids[] = { {"PNP0C14" ,0 },
@@ -96,6 +97,7 @@ static struct acpi_driver acpi_wmi_driver = { .ops = { .add = acpi_wmi_add, .remove = acpi_wmi_remove, + .notify = acpi_wmi_notify, }, };
@@ -643,12 +645,11 @@ acpi_wmi_ec_space_handler(u32 function, acpi_physical_address address, } } -static void acpi_wmi_notify (acpi_handle handle,u32 event,void *data) +static void acpi_wmi_notify (struct acpi_device *device,u32 event) {struct guid_block *block;struct wmi_block *wblock;struct list_head *p; -struct acpi_device *device = data;list_for_each (p, &wmi_blocks.list) { wblock = list_entry(p, struct wmi_block, list);
@@ -669,9 +670,6 @@ static void acpi_wmi_notify(acpi_handle handle, u32 event, void *data)static int acpi_wmi_remove (struct acpi_device *device,int type) { -acpi_remove_notify_handler (device->handle,ACPI_DEVICE_NOTIFY , - acpi_wmi_notify); -acpi_remove_address_space_handler (device->handle,ACPI_ADR_SPACE_EC , &acpi_wmi_ec_space_handler);
@@ -683,13 +681,6 @@ static int __init acpi_wmi_add(struct acpi_device *device)acpi_status status;int result =0 ; - status =acpi_install_notify_handler (device->handle,ACPI_DEVICE_NOTIFY , - acpi_wmi_notify, device); -if (ACPI_FAILURE (status)) { - printk(KERN_ERR PREFIX "Error installing notify handler\n"); -return -ENODEV ; - } - status = acpi_install_address_space_handler(device->handle, ACPI_ADR_SPACE_EC, &acpi_wmi_ec_space_handler,
Signature · 1 line
1.6.0.6
Len Brown
reviewerPATCH 14/17 ACPICA: delete check for AML access to port 0x81-83
In reply to Len BrownFrom: Len Brown <[email protected]>
Sony laptops apparently write 4-bytes (rather than 1 byte) to debug port 0x80, which spews error messages:
Denied AML access to port 0x00000080/4 (DMA1 0x0081-0x0083) [20090320]
http://bugzilla.kernel.org/show_bug.cgi?id=13036
--- drivers/acpi/acpica/hwvalid.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-)
drivers/acpi/acpica/hwvalid.c +0 -1
@@ -90,7 +90,6 @@ static const struct acpi_port_info acpi_protected_ports[] = { {"PIT2", 0x0048, 0x004B, ACPI_OSI_WIN_XP}, {"RTC", 0x0070, 0x0071, ACPI_OSI_WIN_XP}, {"CMOS", 0x0074, 0x0076, ACPI_OSI_WIN_XP}, - {"DMA1", 0x0081, 0x0083, ACPI_OSI_WIN_XP}, {"DMA1L", 0x0087, 0x0087, ACPI_OSI_WIN_XP}, {"DMA2", 0x0089, 0x008B, ACPI_OSI_WIN_XP}, {"DMA2L", 0x008F, 0x008F, ACPI_OSI_WIN_XP},
Signature · 1 line
1.6.0.6
Len Brown
reviewerPATCH 16/17 ACPI x86: Make aperf/mperf MSR access in acpi_cpufreq read_only
In reply to Len BrownFrom: Venkatesh Pallipadi <[email protected]>
Do not write zeroes to APERF and MPERF by ondemand governor. With this change, other users can share these MSRs for reads.
--- arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 15 ++++++++++----- 1 files changed, 10 insertions(+), 5 deletions(-)
arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +10 -5
@@ -68,6 +68,7 @@ struct acpi_cpufreq_data {unsigned int max_freq;unsigned int resume;unsigned int cpu_feature; +u64 saved_aperf, saved_mperf; }; static DEFINE_PER_CPU(struct acpi_cpufreq_data *, drv_data);
@@ -259,9 +260,6 @@ static long read_measured_perf_ctrs(void *_cur)rdmsr (MSR_IA32_APERF , cur->aperf.split.lo, cur->aperf.split.hi);rdmsr (MSR_IA32_MPERF , cur->mperf.split.lo, cur->mperf.split.hi); -wrmsr (MSR_IA32_APERF ,0 ,0 ); -wrmsr (MSR_IA32_MPERF ,0 ,0 ); -return 0 ; }
@@ -281,13 +279,20 @@ static long read_measured_perf_ctrs(void *_cur)static unsigned int get_measured_perf (struct cpufreq_policy *policy,unsigned int cpu) { -struct perf_pair cur; +struct perf_pair readin, cur;unsigned int perf_percent;unsigned int retval; -if (!work_on_cpu (cpu, read_measured_perf_ctrs, &cur)) +if (!work_on_cpu (cpu, read_measured_perf_ctrs, &readin))return 0 ; + cur.aperf.whole = readin.aperf.whole - +per_cpu (drv_data, cpu)->saved_aperf; + cur.mperf.whole = readin.mperf.whole - +per_cpu (drv_data, cpu)->saved_mperf; +per_cpu (drv_data, cpu)->saved_aperf = readin.aperf.whole; +per_cpu (drv_data, cpu)->saved_mperf = readin.mperf.whole; +#ifdef __i386__/* * We dont want to do 64 bit divide with 32 bit kernel
Signature · 1 line
1.6.0.6
Len Brown
reviewerPATCH 15/17 ACPI x86: Cleanup acpi_cpufreq structures related to aperf/mperf
In reply to Len BrownFrom: Venkatesh Pallipadi <[email protected]>
Change structure name to make the code cleaner and simpler. No functionality change in this patch.
--- arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 42 +++++++++++++-------------- 1 files changed, 20 insertions(+), 22 deletions(-)
arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +20 -22
@@ -241,23 +241,23 @@ static u32 get_cur_val(const struct cpumask *mask)return cmd.val; } -struct perf_cur { +struct perf_pair {union {struct {u32 lo;u32 hi; } split;u64 whole; - } aperf_cur, mperf_cur; + } aperf, mperf; };static long read_measured_perf_ctrs (void *_cur) { -struct perf_cur *cur = _cur; +struct perf_pair *cur = _cur; -rdmsr (MSR_IA32_APERF , cur->aperf_cur.split.lo, cur->aperf_cur.split.hi); -rdmsr (MSR_IA32_MPERF , cur->mperf_cur.split.lo, cur->mperf_cur.split.hi); +rdmsr (MSR_IA32_APERF , cur->aperf.split.lo, cur->aperf.split.hi); +rdmsr (MSR_IA32_MPERF , cur->mperf.split.lo, cur->mperf.split.hi);wrmsr (MSR_IA32_APERF ,0 ,0 );wrmsr (MSR_IA32_MPERF ,0 ,0 );
@@ -281,7 +281,7 @@ static long read_measured_perf_ctrs(void *_cur)static unsigned int get_measured_perf (struct cpufreq_policy *policy,unsigned int cpu) { -struct perf_cur cur; +struct perf_pair cur;unsigned int perf_percent;unsigned int retval;
@@ -294,39 +294,37 @@ static unsigned int get_measured_perf(struct cpufreq_policy *policy,* Get an approximate value. Return failure in case we cannot get * an approximate value. */ -if (unlikely (cur.aperf_cur.split.hi || cur.mperf_cur.split.hi)) { +if (unlikely (cur.aperf.split.hi || cur.mperf.split.hi)) {int shift_count;u32 h; - h =max_t (u32, cur.aperf_cur.split.hi, cur.mperf_cur.split.hi); + h =max_t (u32, cur.aperf.split.hi, cur.mperf.split.hi); shift_count =fls (h); - cur.aperf_cur.whole >>= shift_count; - cur.mperf_cur.whole >>= shift_count; + cur.aperf.whole >>= shift_count; + cur.mperf.whole >>= shift_count; } -if (((unsigned long )(-1 ) /100 ) < cur.aperf_cur.split.lo) { +if (((unsigned long )(-1 ) /100 ) < cur.aperf.split.lo) {int shift_count =7 ; - cur.aperf_cur.split.lo >>= shift_count; - cur.mperf_cur.split.lo >>= shift_count; + cur.aperf.split.lo >>= shift_count; + cur.mperf.split.lo >>= shift_count; } -if (cur.aperf_cur.split.lo && cur.mperf_cur.split.lo) - perf_percent = (cur.aperf_cur.split.lo *100 ) / - cur.mperf_cur.split.lo; +if (cur.aperf.split.lo && cur.mperf.split.lo) + perf_percent = (cur.aperf.split.lo *100 ) / cur.mperf.split.lo;else perf_percent =0 ;#else -if (unlikely (((unsigned long )(-1 ) /100 ) < cur.aperf_cur.whole)) { +if (unlikely (((unsigned long )(-1 ) /100 ) < cur.aperf.whole)) {int shift_count =7 ; - cur.aperf_cur.whole >>= shift_count; - cur.mperf_cur.whole >>= shift_count; + cur.aperf.whole >>= shift_count; + cur.mperf.whole >>= shift_count; } -if (cur.aperf_cur.whole && cur.mperf_cur.whole) - perf_percent = (cur.aperf_cur.whole *100 ) / - cur.mperf_cur.whole; +if (cur.aperf.whole && cur.mperf.whole) + perf_percent = (cur.aperf.whole *100 ) / cur.mperf.whole;else perf_percent =0 ;
Signature · 1 line
1.6.0.6
Len Brown
reviewerPATCH 17/17 x86 ACPI: Add support for Always Running APIC timer
In reply to Len BrownFrom: Venkatesh Pallipadi <[email protected]>
Add support for Always Running APIC timer, CPUID_0x6_EAX_Bit2. This bit means the APIC timer continues to run even when CPU is in deep C-states.
The advantage is that we can use LAPIC timer on these CPUs always, and there is no need for "slow to read and program" external timers (HPET/PIT) and the timer broadcast logic and related code in C-state entry and exit.
--- arch/x86/include/asm/cpufeature.h | 1 + arch/x86/kernel/apic/apic.c | 6 ++++++ arch/x86/kernel/cpu/addon_cpuid_features.c | 1 + drivers/acpi/processor_idle.c | 3 +++ 4 files changed, 11 insertions(+), 0 deletions(-)
arch/x86/include/asm/cpufeature.h +1 -0
@@ -154,6 +154,7 @@* CPUID levels like 0x6, 0xA etc */ #define X86_FEATURE_IDA (7*32+ 0)/* Intel Dynamic Acceleration */ +#define X86_FEATURE_ARAT (7*32+ 1)/* Always Running APIC Timer */ /* Virtualization flags: Linux defined */ #define X86_FEATURE_TPR_SHADOW (8*32+ 0)/* Intel TPR Shadow */
arch/x86/kernel/apic/apic.c +6 -0
@@ -431,6 +431,12 @@ static void __cpuinit setup_APIC_timer(void) {struct clock_event_device *levt = &__get_cpu_var (lapic_events); +if (cpu_has (¤t_cpu_data,X86_FEATURE_ARAT )) { + lapic_clockevent.features &= ~CLOCK_EVT_FEAT_C3STOP ; +/* Make LAPIC timer preferrable over percpu HPET */ + lapic_clockevent.rating =150 ; + } +memcpy (levt, &lapic_clockevent,sizeof (*levt)); levt->cpumask =cpumask_of (smp_processor_id ());
arch/x86/kernel/cpu/addon_cpuid_features.c +1 -0
@@ -31,6 +31,7 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)static const struct cpuid_bit __cpuinitconst cpuid_bits[] = { {X86_FEATURE_IDA ,CR_EAX ,1 ,0x00000006 }, + {X86_FEATURE_ARAT ,CR_EAX ,2 ,0x00000006 }, {0 ,0 ,0 ,0 } };
drivers/acpi/processor_idle.c +3 -0
@@ -145,6 +145,9 @@ static void acpi_timer_check_state(int state, struct acpi_processor *pr,struct acpi_processor_power *pwr = &pr->power;u8 type = local_apic_timer_c2_ok ?ACPI_STATE_C3 :ACPI_STATE_C2 ; +if (cpu_has (&cpu_data (pr->id),X86_FEATURE_ARAT )) +return ; +/* * Check, if one of the previous states already marked the lapic * unstable
Signature · 1 line
1.6.0.6