ACPI patch queue for 2.6.28
Subsystems (13)
Len Brown
reviewerThese patches are staged for 2.6.28,
please let me know if you see problems with them.
thanks,
-Len
Len Brown
reviewerPATCH 1/85 ACPI: Add missing acpi.debug_layer Documentation hunk from Thomas Renninger
From: Andi Kleen <[email protected]>
--- Documentation/kernel-parameters.txt | 47 ++++++++++++++++++++++++---------- 1 files changed, 33 insertions(+), 14 deletions(-)
Documentation/kernel-parameters.txt +33 -14
@@ -217,20 +217,39 @@ and is between 256 and 4096 characters. It is defined in the file acpi.debug_level= [HW,ACPI] Format: <int> Each bit of the <int> indicates an ACPI debug level, - 1: enable, 0: disable. It is useful for boot time - debugging. After system has booted up, it can be set - via /sys/module/acpi/parameters/debug_level. - CONFIG_ACPI_DEBUG must be enabled for this to produce any output. - Available bits (add the numbers together) to enable different - debug output levels of the ACPI subsystem: - 0x01 error 0x02 warn 0x04 init 0x08 debug object - 0x10 info 0x20 init names 0x40 parse 0x80 load - 0x100 dispatch 0x200 execute 0x400 names 0x800 operation region - 0x1000 bfield 0x2000 tables 0x4000 values 0x8000 objects - 0x10000 resources 0x20000 user requests 0x40000 package. - The number can be in decimal or prefixed with 0x in hex. - Warning: Many of these options can produce a lot of - output and make your system unusable. Be very careful. + which corresponds to the level in an ACPI_DEBUG_PRINT + statement. After system has booted up, this mask + can be set via /sys/module/acpi/parameters/debug_level. + + CONFIG_ACPI_DEBUG must be enabled for this to produce + any output. The number can be in decimal or prefixed + with 0x in hex. Some of these options produce so much + output that the system is unusable. + + The following global components are defined by the + ACPI CA: + 0x01 error + 0x02 warn + 0x04 init + 0x08 debug object + 0x10 info + 0x20 init names + 0x40 parse + 0x80 load + 0x100 dispatch + 0x200 execute + 0x400 names + 0x800 operation region + 0x1000 bfield + 0x2000 tables + 0x4000 values + 0x8000 objects + 0x10000 resources + 0x20000 user requests + 0x40000 package + The number can be in decimal or prefixed with 0x in hex. + Warning: Many of these options can produce a lot of + output and make your system unusable. Be very careful. acpi_pm_good [X86-32,X86-64] Override the pmtimer bug detection: force the kernel
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 2/85 acpi: replace AE_BAD_ADDRESS exception code with AE_ERROR
In reply to Len BrownFrom: Lin Ming <[email protected]>
The AE_BAD_ADDRESS exception code is now unused in ACPICA. For linux, it's only used at wmi.c and acer-wmi.c.
I checked both wmi.c and acer-wmi.c, the AE_BAD_ADDRESS exception code has no special meaning. The parent functions just call AE_SUCCESS() or AE_FAILURE() to check the return status.
So it's safe to replace AE_BAD_ADDRESS with AE_ERROR.
Signed-off-by Lin Ming <[email protected]>
--- drivers/acpi/wmi.c | 10 +++++----- drivers/misc/acer-wmi.c | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-)
drivers/acpi/wmi.c +5 -5
@@ -242,7 +242,7 @@ u32 method_id, const struct acpi_buffer *in, struct acpi_buffer *out)char method[4 ] ="WM" ;if (!find_guid (guid_string, &wblock)) -return AE_BAD_ADDRESS ; +return AE_ERROR ; block = &wblock->gblock; handle = wblock->handle;
@@ -304,7 +304,7 @@ struct acpi_buffer *out)return AE_BAD_PARAMETER ;if (!find_guid (guid_string, &wblock)) -return AE_BAD_ADDRESS ; +return AE_ERROR ; block = &wblock->gblock; handle = wblock->handle;
@@ -314,7 +314,7 @@ struct acpi_buffer *out)/* Check GUID is a data block */ if (block->flags & (ACPI_WMI_EVENT |ACPI_WMI_METHOD )) -return AE_BAD_ADDRESS ; +return AE_ERROR ; input.count =1 ; input.pointer = wq_params;
@@ -385,7 +385,7 @@ const struct acpi_buffer *in)return AE_BAD_DATA ;if (!find_guid (guid_string, &wblock)) -return AE_BAD_ADDRESS ; +return AE_ERROR ; block = &wblock->gblock; handle = wblock->handle;
@@ -395,7 +395,7 @@ const struct acpi_buffer *in)/* Check GUID is a data block */ if (block->flags & (ACPI_WMI_EVENT |ACPI_WMI_METHOD )) -return AE_BAD_ADDRESS ; +return AE_ERROR ; input.count =2 ; input.pointer = params;
drivers/misc/acer-wmi.c +5 -5
@@ -476,7 +476,7 @@ struct wmi_interface *iface) }break ;default : -return AE_BAD_ADDRESS ; +return AE_ERROR ; }return AE_OK ; }
@@ -514,7 +514,7 @@ static acpi_status AMW0_set_u32(u32 value, u32 cap, struct wmi_interface *iface)break ; }default : -return AE_BAD_ADDRESS ; +return AE_ERROR ; }/* Actually do the set */
@@ -689,7 +689,7 @@ struct wmi_interface *iface)return 0 ; }default : -return AE_BAD_ADDRESS ; +return AE_ERROR ; } status =WMI_execute_u32 (method_id,0 , &result);
@@ -735,7 +735,7 @@ static acpi_status WMID_set_u32(u32 value, u32 cap, struct wmi_interface *iface) }break ;default : -return AE_BAD_ADDRESS ; +return AE_ERROR ; }return WMI_execute_u32 (method_id, (u32 )value,NULL ); }
@@ -785,7 +785,7 @@ static struct wmi_interface wmid_interface = {static acpi_status get_u32 (u32 *value,u32 cap) { -acpi_status status =AE_BAD_ADDRESS ; +acpi_status status =AE_ERROR ;switch (interface->type) {case ACER_AMW0 :
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 3/85 ACPI: Get the device power state in the course of scanning device
In reply to Len BrownFrom: Zhao Yakui <[email protected]>
Get the device power state in the course of scanning device if the device power flag is power_managable. i.e. The device has the _PSx/_PRx object.
At the same time before the drivers/acpi/power module is loaded, there is no relation between acpi_power_resource and acpi device. So the first parameter of acpi_power_get_state is changed to acpi_handle.
http://bugzilla.kernel.org/show_bug.cgi?id=8049
http://bugzilla.kernel.org/show_bug.cgi?id=11000
--- drivers/acpi/power.c | 30 ++++++++++++++++-------------- drivers/acpi/scan.c | 1 + 2 files changed, 17 insertions(+), 14 deletions(-)
drivers/acpi/power.c +16 -14
@@ -128,16 +128,16 @@ acpi_power_get_context(acpi_handle handle,return 0 ; } -static int acpi_power_get_state (struct acpi_power_resource *resource,int *state) +static int acpi_power_get_state (acpi_handle handle,int *state) {acpi_status status =AE_OK ;unsigned long sta =0 ; -if (!resource || !state) +if (!handle || !state)return -EINVAL ; - status =acpi_evaluate_integer (resource->device->handle,"_STA" ,NULL , &sta); + status =acpi_evaluate_integer (handle,"_STA" ,NULL , &sta);if (ACPI_FAILURE (status))return -ENODEV ;
@@ -145,7 +145,7 @@ static int acpi_power_get_state(struct acpi_power_resource *resource, int *stateACPI_POWER_RESOURCE_STATE_OFF ;ACPI_DEBUG_PRINT ((ACPI_DB_INFO ,"Resource [%s] is %s\n" , - resource->name, state ?"on" :"off" )); +acpi_ut_get_node_name (handle), state ?"on" :"off" ));return 0 ; }
@@ -153,7 +153,6 @@ static int acpi_power_get_state(struct acpi_power_resource *resource, int *statestatic int acpi_power_get_list_state (struct acpi_handle_list *list,int *state) {int result =0 , state1; -struct acpi_power_resource *resource =NULL ;u32 i =0 ;
@@ -161,12 +160,15 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)return -EINVAL ;/* The state of the list is 'on' IFF all resources are 'on'. */ +/* */ for (i =0 ; i < list->count; i++) { - result =acpi_power_get_context (list->handles[i], &resource); -if (result) -return result; - result =acpi_power_get_state (resource, &state1); +/* +* The state of the power resource can be obtained by +* using the ACPI handle. In such case it is unnecessary to +* get the Power resource first and then get its state again. +*/ + result =acpi_power_get_state (list->handles[i], &state1);if (result)return result;
@@ -226,7 +228,7 @@ static int acpi_power_on(acpi_handle handle, struct acpi_device *dev)if (ACPI_FAILURE (status))return -ENODEV ; - result =acpi_power_get_state (resource, &state); + result =acpi_power_get_state (resource->device->handle, &state);if (result)return result;if (state !=ACPI_POWER_RESOURCE_STATE_ON )
@@ -277,7 +279,7 @@ static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev)if (ACPI_FAILURE (status))return -ENODEV ; - result =acpi_power_get_state (resource, &state); + result =acpi_power_get_state (handle, &state);if (result)return result;if (state !=ACPI_POWER_RESOURCE_STATE_OFF )
@@ -555,7 +557,7 @@ static int acpi_power_seq_show(struct seq_file *seq, void *offset)if (!resource) goto end; - result =acpi_power_get_state (resource, &state); + result =acpi_power_get_state (resource->device->handle, &state);if (result) goto end;
@@ -668,7 +670,7 @@ static int acpi_power_add(struct acpi_device *device) resource->system_level = acpi_object.power_resource.system_level; resource->order = acpi_object.power_resource.resource_order; - result =acpi_power_get_state (resource, &state); + result =acpi_power_get_state (device->handle, &state);if (result) goto end;
@@ -735,7 +737,7 @@ static int acpi_power_resume(struct acpi_device *device) resource = (struct acpi_power_resource *)acpi_driver_data (device); - result =acpi_power_get_state (resource, &state); + result =acpi_power_get_state (device->handle, &state);if (result)return result;
drivers/acpi/scan.c +1 -0
@@ -807,6 +807,7 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)/* TBD: System wake support and resource requirements. */ device->power.state =ACPI_STATE_UNKNOWN ; +acpi_bus_get_power (device->handle, &(device->power.state));return 0 ; }
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 4/85 ACPI: Attach the ACPI device to the ACPI handle as early as possible
In reply to Len BrownFrom: Zhao Yakui <[email protected]>
Attach the ACPI device to the ACPI handle as early as possible so that OS can get the corresponding ACPI device by the acpi handle in the course of getting the power/wakeup/performance flags.
http://bugzilla.kernel.org/show_bug.cgi?id=8049
http://bugzilla.kernel.org/show_bug.cgi?id=11000
--- drivers/acpi/scan.c | 12 ++++++++++-- 1 files changed, 10 insertions(+), 2 deletions(-)
drivers/acpi/scan.c +10 -2
@@ -1253,6 +1253,16 @@ acpi_add_single_object(struct acpi_device **child,acpi_device_set_id (device, parent, handle, type);/* +* The ACPI device is attached to acpi handle before getting +* the power/wakeup/peformance flags. Otherwise OS can't get +* the corresponding ACPI device by the acpi handle in the course +* of getting the power/wakeup/performance flags. +*/ + result =acpi_device_set_context (device, type); +if (result) + goto end; + +/* * Power Management * ---------------- */
@@ -1282,8 +1292,6 @@ acpi_add_single_object(struct acpi_device **child, goto end; } -if ((result =acpi_device_set_context (device, type))) - goto end; result =acpi_device_register (device, parent);
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 5/85 ACPI: Add "acpi.power_nocheck=1" to disable power state check in power transition
In reply to Len BrownFrom: Zhao Yakui <[email protected]>
Maybe the incorrect power state is returned on the bogus bios, which
is different with the real power state. For example: the bios returns D0 state and the real power state is D3. OS expects to set the device to D0 state. In such case if OS uses the power state returned by the BIOS and checks the device power state very strictly in power transition, the device can't be transited to the correct power state.
So the boot option of "acpi.power_nocheck=1" is added to avoid checking
the device power in the course of device power transition.
http://bugzilla.kernel.org/show_bug.cgi?id=8049
http://bugzilla.kernel.org/show_bug.cgi?id=11000
--- Documentation/kernel-parameters.txt | 8 ++++++ drivers/acpi/bus.c | 14 ++++++++++- drivers/acpi/power.c | 42 +++++++++++++++++++++++++--------- include/acpi/acpi_drivers.h | 1 + 4 files changed, 53 insertions(+), 12 deletions(-)
Documentation/kernel-parameters.txt +8 -0
@@ -251,6 +251,14 @@ and is between 256 and 4096 characters. It is defined in the file Warning: Many of these options can produce a lot of output and make your system unusable. Be very careful. + acpi.power_nocheck= [HW,ACPI] + Format: 1/0 enable/disable the check of power state. + On some bogus BIOS the _PSC object/_STA object of + power resource can't return the correct device power + state. In such case it is unneccessary to check its + power state again in power transition. + 1 : disable the power state check + acpi_pm_good [X86-32,X86-64] Override the pmtimer bug detection: force the kernel to assume that this machine's pmtimer latches its value
drivers/acpi/bus.c +13 -1
@@ -223,7 +223,19 @@ int acpi_bus_set_power(acpi_handle handle, int state)/* * Get device's current power state */ -acpi_bus_get_power (device->handle, &device->power.state); +if (!acpi_power_nocheck) { +/* +* Maybe the incorrect power state is returned on the bogus +* bios, which is different with the real power state. +* For example: the bios returns D0 state and the real power +* state is D3. OS expects to set the device to D0 state. In +* such case if OS uses the power state returned by the BIOS, +* the device can't be transisted to the correct power state. +* So if the acpi_power_nocheck is set, it is unnecessary to +* get the power state by calling acpi_bus_get_power. +*/ +acpi_bus_get_power (device->handle, &device->power.state); + }if ((state == device->power.state) && !device->flags.force_power_state) {ACPI_DEBUG_PRINT ((ACPI_DB_INFO ,"Device is already at D%d\n" , state));
drivers/acpi/power.c +31 -11
60 lines not on this page · raw message
include/acpi/acpi_drivers.h +1 -0
@@ -93,6 +93,7 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state);int acpi_disable_wakeup_device_power (struct acpi_device *dev);int acpi_power_get_inferred_state (struct acpi_device *device);int acpi_power_transition (struct acpi_device *device,int state); +extern int acpi_power_nocheck;#endif /* --------------------------------------------------------------------------
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 6/85 ACPI: Add DMI check to disable power state check in power transition
In reply to Len BrownFrom: Zhao Yakui <[email protected]>
Add the DMI check to disable power check in the course of device power transistion.
http://bugzilla.kernel.org/show_bug.cgi?id=11000
--- drivers/acpi/bus.c | 23 ++++++++++++++++++++++- 1 files changed, 22 insertions(+), 1 deletions(-)
drivers/acpi/bus.c +22 -1
@@ -48,6 +48,23 @@ EXPORT_SYMBOL(acpi_root_dir);#define STRUCT_TO_INT (s) (*((int*)&s)) +static int set_power_nocheck (const struct dmi_system_id *id) +{ + printk(KERN_NOTICE PREFIX "%s detected - " + "disable power check in power transistion\n", id->ident); + acpi_power_nocheck =1 ; +return 0 ; +} +static struct dmi_system_id __cpuinitdata power_nocheck_dmi_table[] = { + { + set_power_nocheck,"HP Pavilion 05" , { +DMI_MATCH (DMI_BIOS_VENDOR ,"Phoenix Technologies LTD" ), +DMI_MATCH (DMI_SYS_VENDOR ,"HP Pavilion 05" ), +DMI_MATCH (DMI_PRODUCT_VERSION ,"2001211RE101GLEND" ) },NULL }, + {}, +}; + +/* -------------------------------------------------------------------------- Device Management -------------------------------------------------------------------------- */
@@ -830,7 +847,11 @@ static int __init acpi_init(void) } }else disable_acpi (); - +/* +* If the laptop falls into the DMI check table, the power state check +* will be disabled in the course of device power transistion. +*/ +dmi_check_system (power_nocheck_dmi_table);return result; }
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 7/85 ACPI : Load device driver according to the status of acpi device
In reply to Len BrownFrom: Zhao Yakui <[email protected]>
According to ACPI spec when the status of some device is not present but functional, the device is valid and the children of this device should be enumerated. It means that the device should be added to linux acpi device tree. But the device driver for this device should not be loaded.
The detailed info can be found in the section 6.3.7 of ACPI 3.0b spec. _STA may return bit 0 clear (not present) with bit 3 set (device is
functional). This case is used to indicate a valid device for which no device driver should be loaded (for example, a bridge device.). Children of this device may be present and valid. OS should continue enumeration below a device whose _STA returns this bit combination
http://bugzilla.kernel.org/show_bug.cgi?id=3358
--- drivers/acpi/bus.c | 16 ++++++++-------- drivers/acpi/scan.c | 35 +++++++++++++++++++++++++---------- drivers/pnp/pnpacpi/core.c | 6 +++++- 3 files changed, 38 insertions(+), 19 deletions(-)
drivers/acpi/bus.c +8 -8
@@ -112,21 +112,21 @@ int acpi_bus_get_status(struct acpi_device *device) }/* -* Otherwise we assume the status of our parent (unless we don't -* have one, in which case status is implied). +* According to ACPI spec some device can be present and functional +* even if the parent is not present but functional. +* In such conditions the child device should not inherit the status +* from the parent. */ -else if (device->parent) - device->status = device->parent->status;else STRUCT_TO_INT (device->status) =ACPI_STA_DEVICE_PRESENT |ACPI_STA_DEVICE_ENABLED |ACPI_STA_DEVICE_UI |ACPI_STA_DEVICE_FUNCTIONING ;if (device->status.functional && !device->status.present) { - printk(KERN_WARNING PREFIX "Device [%s] status [%08x]: " -"functional but not present; setting present\n" , - device->pnp.bus_id, (u32) STRUCT_TO_INT(device->status)); - device->status.present =1 ; +ACPI_DEBUG_PRINT ((ACPI_DB_INFO ,"Device [%s] status [%08x]: " +"functional but not present;\n" , + device->pnp.bus_id, + (u32 )STRUCT_TO_INT (device->status))); } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n",
drivers/acpi/scan.c +25 -10
@@ -276,6 +276,13 @@ int acpi_match_device_ids(struct acpi_device *device, {const struct acpi_device_id *id; +/* +* If the device is not present, it is unnecessary to load device +* driver for it. +*/ +if (!device->status.present) +return -ENODEV ; +if (device->flags.hardware_id) {for (id = ids; id->id[0 ]; id++) {if (!strcmp ((char *)id->id, device->pnp.hardware_id))
@@ -1222,15 +1229,18 @@ acpi_add_single_object(struct acpi_device **child, result = -ENODEV ; goto end; } -if (!device->status.present) { -/* Bay and dock should be handled even if absent */ -if (!ACPI_SUCCESS ( -acpi_is_child_device (device, acpi_bay_match)) && - !ACPI_SUCCESS ( -acpi_is_child_device (device, acpi_dock_match))) { - result = -ENODEV ; - goto end; - } +/* +* When the device is neither present nor functional, the +* device should not be added to Linux ACPI device tree. +* When the status of the device is not present but functinal, +* it should be added to Linux ACPI tree. For example : bay +* device , dock device. +* In such conditions it is unncessary to check whether it is +* bay device or dock device. +*/ +if (!device->status.present && !device->status.functional) { + result = -ENODEV ; + goto end; }break ;default :
@@ -1411,7 +1421,12 @@ static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops)* TBD: Need notifications and other detection mechanisms * in place before we can fully implement this. */ -if (child->status.present) { +/* +* When the device is not present but functional, it is also +* necessary to scan the children of this device. +*/ +if (child->status.present || (!child->status.present && + child->status.functional)) { status =acpi_get_next_object (ACPI_TYPE_ANY , chandle,NULL ,NULL );if (ACPI_SUCCESS (status)) {
drivers/pnp/pnpacpi/core.c +5 -1
@@ -148,9 +148,13 @@ static int __init pnpacpi_add_device(struct acpi_device *device)acpi_status status;struct pnp_dev *dev; +/* +* If a PnPacpi device is not present , the device +* driver should not be loaded. +*/ status =acpi_get_handle (device->handle,"_CRS" , &temp);if (ACPI_FAILURE (status) || !ispnpidacpi (acpi_device_hid (device)) || -is_exclusive_device (device)) +is_exclusive_device (device) || (!device->status.present))return 0 ; dev =pnp_alloc_dev (&pnpacpi_protocol, num,acpi_device_hid (device));
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 8/85 ACPICA: Copy dynamically loaded tables to local buffer
In reply to Len BrownFrom: Dennis Noordsij <[email protected]>
Previously, dynamically loaded tables were simply mapped, but on some machines this memory is corrupted after suspend. Now copy the table to a local buffer. For OpRegion case, added checksum verify. Use the table length from the table header, not the region length. For Buffer case, use the table length also.
http://bugzilla.kernel.org/show_bug.cgi?id=10734
--- drivers/acpi/executer/exconfig.c | 113 +++++++++++++++++++++++++++---------- 1 files changed, 82 insertions(+), 31 deletions(-)
drivers/acpi/executer/exconfig.c +82 -31
@@ -280,6 +280,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, struct acpi_walk_state *walk_state) {union acpi_operand_object *ddb_handle; +struct acpi_table_header *table;struct acpi_table_desc table_desc;u32 table_index;acpi_status status;
@@ -294,9 +295,8 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {case ACPI_TYPE_REGION : -ACPI_DEBUG_PRINT ((ACPI_DB_EXEC ,"Load from Region %p %s\n" , - obj_desc, -acpi_ut_get_object_type_name (obj_desc))); +ACPI_DEBUG_PRINT ((ACPI_DB_EXEC , +"Load table from Region %p\n" , obj_desc));/* Region must be system_memory (from ACPI spec) */
@@ -316,61 +316,112 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, }/* -* We will simply map the memory region for the table. However, the -* memory region is technically not guaranteed to remain stable and -* we may eventually have to copy the table to a local buffer. +* Map the table header and get the actual table length. The region +* length is not guaranteed to be the same as the table length. +*/ + table =acpi_os_map_memory (obj_desc->region.address, +sizeof (struct acpi_table_header )); +if (!table) { +return_ACPI_STATUS (AE_NO_MEMORY ); + } + + length = table->length; +acpi_os_unmap_memory (table,sizeof (struct acpi_table_header )); + +/* Must have at least an ACPI table header */ + +if (length <sizeof (struct acpi_table_header )) { +return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH ); + } + +/* +* The memory region is not guaranteed to remain stable and we must +* copy the table to a local buffer. For example, the memory region +* is corrupted after suspend on some machines. Dynamically loaded +* tables are usually small, so this overhead is minimal. */ + +/* Allocate a buffer for the table */ + + table_desc.pointer =ACPI_ALLOCATE (length); +if (!table_desc.pointer) { +return_ACPI_STATUS (AE_NO_MEMORY ); + } + +/* Map the entire table and copy it */ + + table =acpi_os_map_memory (obj_desc->region.address, length); +if (!table) { +ACPI_FREE (table_desc.pointer); +return_ACPI_STATUS (AE_NO_MEMORY ); + } + +ACPI_MEMCPY (table_desc.pointer, table, length); +acpi_os_unmap_memory (table, length); + table_desc.address = obj_desc->region.address; - table_desc.length = obj_desc->region.length; - table_desc.flags =ACPI_TABLE_ORIGIN_MAPPED ;break ;case ACPI_TYPE_BUFFER :/* Buffer or resolved region_field */ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC , -"Load from Buffer or Field %p %s\n" , obj_desc, -acpi_ut_get_object_type_name (obj_desc))); - - length = obj_desc->buffer.length; +"Load table from Buffer or Field %p\n" , + obj_desc));/* Must have at least an ACPI table header */ -if (length <sizeof (struct acpi_table_header )) { +if (obj_desc->buffer.length <sizeof (struct acpi_table_header )) {return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH ); } -/* Validate checksum here. It won't get validated in tb_add_table */ +/* Get the actual table length from the table header */ - status = -acpi_tb_verify_checksum (ACPI_CAST_PTR - (struct acpi_table_header, - obj_desc->buffer.pointer), length); -if (ACPI_FAILURE (status)) { -return_ACPI_STATUS (status); + table = + ACPI_CAST_PTR(struct acpi_table_header, + obj_desc->buffer.pointer); + length = table->length; + +/* Table cannot extend beyond the buffer */ + +if (length > obj_desc->buffer.length) { +return_ACPI_STATUS (AE_AML_BUFFER_LIMIT ); + } +if (length <sizeof (struct acpi_table_header )) { +return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH ); }/* -* We need to copy the buffer since the original buffer could be -* changed or deleted in the future +* Copy the table from the buffer because the buffer could be modified +* or even deleted in the future */ table_desc.pointer =ACPI_ALLOCATE (length);if (!table_desc.pointer) {return_ACPI_STATUS (AE_NO_MEMORY ); } -ACPI_MEMCPY (table_desc.pointer, obj_desc->buffer.pointer, - length); - table_desc.length = length; - table_desc.flags =ACPI_TABLE_ORIGIN_ALLOCATED ; +ACPI_MEMCPY (table_desc.pointer, table, length); + table_desc.address =ACPI_TO_INTEGER (table_desc.pointer);break ;default :return_ACPI_STATUS (AE_AML_OPERAND_TYPE ); } -/* -* Install the new table into the local data structures -*/ +/* Validate table checksum (will not get validated in tb_add_table) */ + + status =acpi_tb_verify_checksum (table_desc.pointer, length); +if (ACPI_FAILURE (status)) { +ACPI_FREE (table_desc.pointer); +return_ACPI_STATUS (status); + } + +/* Complete the table descriptor */ + + table_desc.length = length; + table_desc.flags =ACPI_TABLE_ORIGIN_ALLOCATED ; + +/* Install the new table into the local data structures */ + status =acpi_tb_add_table (&table_desc, &table_index);if (ACPI_FAILURE (status)) { goto cleanup;
@@ -379,7 +430,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,/* * Add the table to the namespace. * -* Note: We load the table objects relative to the root of the namespace. +* Note: Load the table objects relative to the root of the namespace. * This appears to go against the ACPI specification, but we do it for * compatibility with other ACPI implementations. */
@@ -415,7 +466,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, cleanup:if (ACPI_FAILURE (status)) { -/* Delete allocated buffer or mapping */ +/* Delete allocated table buffer */ acpi_tb_delete_table (&table_desc); }
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 9/85 ACPICA: Add check for invalid handle in acpi_get_object_info
In reply to Len BrownFrom: Fiodor Suietov <[email protected]>
Return AE_BAD_PARAMETER if input handle is invalid.
http://www.acpica.org/bugzilla/show_bug.cgi?id=474
--- drivers/acpi/namespace/nsxfname.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
drivers/acpi/namespace/nsxfname.c +1 -0
@@ -253,6 +253,7 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) node =acpi_ns_map_handle_to_node (handle);if (!node) { (void )acpi_ut_release_mutex (ACPI_MTX_NAMESPACE ); + status =AE_BAD_PARAMETER ; goto cleanup; }
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 10/85 ACPICA: Allow same ACPI table to be loaded/unloaded more than once
In reply to Len BrownFrom: Bob Moore <[email protected]>
Without this change, a table cannot be loaded again once it has been loaded/unloaded one time. The current mechanism does not unregister a table upon an unload. During a load, if the same table is found, this no longer returns an exception.
http://www.acpica.org/bugzilla/show_bug.cgi?id=722
--- drivers/acpi/tables/tbinstal.c | 49 ++++++++++++++++++++++++++++++++++----- 1 files changed, 42 insertions(+), 7 deletions(-)
drivers/acpi/tables/tbinstal.c +42 -7
@@ -145,6 +145,8 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) } } +/* Check for a table match on the entire table length */ + length =ACPI_MIN (table_desc->length, acpi_gbl_root_table_list.tables[i].length); if (ACPI_MEMCMP(table_desc->pointer,
@@ -153,17 +155,49 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)continue ; } -/* Table is already registered */ - +/* +* Note: the current mechanism does not unregister a table if it is +* dynamically unloaded. The related namespace entries are deleted, +* but the table remains in the root table list. +* +* The assumption here is that the number of different tables that +* will be loaded is actually small, and there is minimal overhead +* in just keeping the table in case it is needed again. +* +* If this assumption changes in the future (perhaps on large +* machines with many table load/unload operations), tables will +* need to be unregistered when they are unloaded, and slots in the +* root table list should be reused when empty. +*/ + +/* +* Table is already registered. +* We can delete the table that was passed as a parameter. +*/ acpi_tb_delete_table (table_desc); *table_index = i; - status =AE_ALREADY_EXISTS ; - goto release; + +if (acpi_gbl_root_table_list.tables[i]. + flags &ACPI_TABLE_IS_LOADED ) { + +/* Table is still loaded, this is an error */ + + status =AE_ALREADY_EXISTS ; + goto release; + }else { +/* Table was unloaded, allow it to be reloaded */ + + table_desc->pointer = + acpi_gbl_root_table_list.tables[i].pointer; + table_desc->address = + acpi_gbl_root_table_list.tables[i].address; + status =AE_OK ; + goto print_header; + } } -/* -* Add the table to the global table list -*/ +/* Add the table to the global root table list */ + status =acpi_tb_store_table (table_desc->address, table_desc->pointer, table_desc->length, table_desc->flags, table_index);
@@ -171,6 +205,7 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) goto release; } + print_header:acpi_tb_print_table_header (table_desc->address, table_desc->pointer); release:
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 11/85 ACPICA: Fix wrong resource descriptor length for 64-bit build
In reply to Len BrownFrom: Bob Moore <[email protected]>
The "minimal" descriptors such as EndTag are calculated as 12 bytes long, but the actual length in the internal descriptor is 16 because of the round-up to 8 on 64-bit build.
http://www.acpica.org/bugzilla/show_bug.cgi?id=728
--- include/acpi/actypes.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
include/acpi/actypes.h +1 -1
@@ -1225,8 +1225,8 @@ struct acpi_resource {#pragma pack() -#define ACPI_RS_SIZE_MIN 12#define ACPI_RS_SIZE_NO_DATA 8/* Id + Length fields */ +#define ACPI_RS_SIZE_MIN (u32) ACPI_ROUND_UP_TO_NATIVE_WORD (12)#define ACPI_RS_SIZE (type) (u32) (ACPI_RS_SIZE_NO_DATA + sizeof (type))#define ACPI_NEXT_RESOURCE (res) (struct acpi_resource *)((u8 *) res + res->length)
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 12/85 ACPICA: Fix table compare code, length then data
In reply to Len BrownFrom: Bob Moore <[email protected]>
Split the ACPI table compare. First check that the lengths match exactly. Then compare the data.
--- drivers/acpi/tables/tbinstal.c | 14 +++++++++----- 1 files changed, 9 insertions(+), 5 deletions(-)
drivers/acpi/tables/tbinstal.c +9 -5
@@ -110,7 +110,6 @@ acpi_status acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) { u32 i; -u32 length;acpi_status status =AE_OK ;ACPI_FUNCTION_TRACE (tb_add_table);
@@ -145,13 +144,18 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) } } -/* Check for a table match on the entire table length */ +/* +* Check for a table match on the entire table length, +* not just the header. +*/ +if (table_desc->length != + acpi_gbl_root_table_list.tables[i].length) { +continue ; + } - length =ACPI_MIN (table_desc->length, - acpi_gbl_root_table_list.tables[i].length);if (ACPI_MEMCMP (table_desc->pointer, acpi_gbl_root_table_list.tables[i].pointer, - length)) { + acpi_gbl_root_table_list.tables[i].length)) {continue ; }
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 13/85 ACPICA: Return status from global init function
In reply to Len BrownFrom: Yi Yang <[email protected]>
Return status from acpi_ut_init_globals. This is used by both the kernel subsystem and the utilities such as iASL compiler. The function could possibly fail when the caches are initialized. Yang Yi.
--- drivers/acpi/utilities/utglobal.c | 8 ++++---- drivers/acpi/utilities/utxface.c | 7 ++++++- include/acpi/acutils.h | 2 +- 3 files changed, 11 insertions(+), 6 deletions(-)
drivers/acpi/utilities/utglobal.c +4 -4
@@ -677,14 +677,14 @@ u8 acpi_ut_valid_object_type(acpi_object_type type)* * PARAMETERS: None * -* RETURN: None +* RETURN: Status * * DESCRIPTION: Init library globals. All globals that require specific * initialization should be initialized here! * ******************************************************************************/ -void acpi_ut_init_globals (void ) +acpi_status acpi_ut_init_globals (void ) {acpi_status status;u32 i;
@@ -695,7 +695,7 @@ void acpi_ut_init_globals(void) status =acpi_ut_create_caches ();if (ACPI_FAILURE (status)) { -return ; +return_ACPI_STATUS (status); }/* Mutex locked flags */
@@ -772,7 +772,7 @@ void acpi_ut_init_globals(void) acpi_gbl_display_final_mem_stats = FALSE;#endif - return_VOID; +return_ACPI_STATUS (AE_OK ); }ACPI_EXPORT_SYMBOL (acpi_dbg_level)
drivers/acpi/utilities/utxface.c +6 -1
@@ -81,7 +81,12 @@ acpi_status __init acpi_initialize_subsystem(void)/* Initialize all globals used by the subsystem */ -acpi_ut_init_globals (); + status =acpi_ut_init_globals (); +if (ACPI_FAILURE (status)) { +ACPI_EXCEPTION ((AE_INFO , status, +"During initialization of globals" )); +return_ACPI_STATUS (status); + }/* Create the default mutex objects */
include/acpi/acutils.h +1 -1
@@ -110,7 +110,7 @@ struct acpi_pkg_info {/* * utglobal - Global data structures and procedures */ -void acpi_ut_init_globals (void ); +acpi_status acpi_ut_init_globals (void );#if defined(ACPI_DEBUG_OUTPUT ) || defined(ACPI_DEBUGGER )
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 14/85 ACPICA: Add function to dereference returned reference objects
In reply to Len BrownFrom: Lin Ming <[email protected]>
Examines the return object from a call to acpi_evaluate_object. Any Index or RefOf references are automatically dereferenced in an attempt to return something useful (these reference types cannot be converted into an external ACPI_OBJECT.) Lin Ming, Bob Moore.
http://bugzilla.kernel.org/show_bug.cgi?id=11105
--- drivers/acpi/namespace/nsxfeval.c | 79 +++++++++++++++++++++++++++++++++++++ 1 files changed, 79 insertions(+), 0 deletions(-)
drivers/acpi/namespace/nsxfeval.c +79 -0
@@ -45,9 +45,14 @@#include <acpi/acpi.h> #include <acpi/acnamesp.h> #include <acpi/acinterp.h> +#include <acpi/amlcode.h> #define _COMPONENT ACPI_NAMESPACEACPI_MODULE_NAME ("nsxfeval" ) + +/* Local prototypes */ +static void acpi_ns_resolve_references (struct acpi_evaluate_info *info); +#ifdef ACPI_FUTURE_USAGE /******************************************************************************* *
@@ -69,6 +74,7 @@ ACPI_MODULE_NAME("nsxfeval")* be valid (non-null) * ******************************************************************************/ + acpi_status acpi_evaluate_object_typed(acpi_handle handle, acpi_string pathname,
@@ -283,6 +289,10 @@ acpi_evaluate_object(acpi_handle handle,if (ACPI_SUCCESS (status)) { +/* Dereference Index and ref_of references */ + +acpi_ns_resolve_references (info); +/* Get the size of the returned object */ status =
@@ -352,6 +362,74 @@ ACPI_EXPORT_SYMBOL(acpi_evaluate_object)/******************************************************************************* * +* FUNCTION: acpi_ns_resolve_references +* +* PARAMETERS: Info - Evaluation info block +* +* RETURN: Info->return_object is replaced with the dereferenced object +* +* DESCRIPTION: Dereference certain reference objects. Called before an +* internal return object is converted to an external union acpi_object. +* +* Performs an automatic dereference of Index and ref_of reference objects. +* These reference objects are not supported by the union acpi_object, so this is a +* last resort effort to return something useful. Also, provides compatibility +* with other ACPI implementations. +* +* NOTE: does not handle references within returned package objects or nested +* references, but this support could be added later if found to be necessary. +* +******************************************************************************/ +static void acpi_ns_resolve_references (struct acpi_evaluate_info *info) +{ +union acpi_operand_object *obj_desc =NULL ; +struct acpi_namespace_node *node; + +/* We are interested in reference objects only */ + +if (ACPI_GET_OBJECT_TYPE (info->return_object) != +ACPI_TYPE_LOCAL_REFERENCE ) { +return ; + } + +/* +* Two types of references are supported - those created by Index and +* ref_of operators. A name reference (AML_NAMEPATH_OP) can be converted +* to an union acpi_object, so it is not dereferenced here. A ddb_handle +* (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to +* an union acpi_object. +*/ +switch (info->return_object->reference.opcode) { +case AML_INDEX_OP : + + obj_desc = *(info->return_object->reference.where); +break ; + +case AML_REF_OF_OP : + + node = info->return_object->reference.object; +if (node) { + obj_desc = node->object; + } +break ; + +default : +return ; + } + +/* Replace the existing reference object */ + +if (obj_desc) { +acpi_ut_add_reference (obj_desc); +acpi_ut_remove_reference (info->return_object); + info->return_object = obj_desc; + } + +return ; +} + +/******************************************************************************* +* * FUNCTION: acpi_walk_namespace * * PARAMETERS: Type - acpi_object_type to search for
@@ -379,6 +457,7 @@ ACPI_EXPORT_SYMBOL(acpi_evaluate_object)* function, etc. * ******************************************************************************/ + acpi_status acpi_walk_namespace(acpi_object_type type, acpi_handle start_object,
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 15/85 ACPICA: Fix warning for 64-bit build
In reply to Len BrownFrom: Bob Moore <[email protected]>
Fixes warning from exconfig.c on 64-bit build.
AK: This actually was fixed earlier in Linux, this just syncs with
AK: the version of the fix that went into the ACPCA codebase
--- drivers/acpi/executer/exconfig.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-)
drivers/acpi/executer/exconfig.c +1 -2
@@ -96,8 +96,7 @@ acpi_ex_add_table(u32 table_index,/* Install the new table into the local data structures */ - obj_desc->reference.object =ACPI_CAST_PTR (void, - (unsigned long )table_index); + obj_desc->reference.object =ACPI_TO_POINTER (table_index);/* Add the table to the namespace */
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 16/85 ACPICA: Cleanup macro definition file.
In reply to Len BrownFrom: Bob Moore <[email protected]>
Removed unused macros. Ensure that multiple parameters always have a space after a comma. Cleanup some comments.
--- include/acpi/acmacros.h | 248 ++++++++++++++++++++++------------------------- 1 files changed, 115 insertions(+), 133 deletions(-)
include/acpi/acmacros.h +115 -133
@@ -62,7 +62,7 @@#define ACPI_ARRAY_LENGTH (x) (sizeof(x) / sizeof((x)[0]))/* -* Extract data using a pointer. Any more than a byte and we +* Extract data using a pointer. Any more than a byte and we * get into potential aligment issues -- see the STORE macros below. * Use with care. */
@@ -80,21 +80,21 @@*/ #define ACPI_CAST_PTR (t, p) ((t *) (acpi_uintptr_t) (p))#define ACPI_CAST_INDIRECT_PTR (t, p) ((t **) (acpi_uintptr_t) (p)) -#define ACPI_ADD_PTR (t, a, b) ACPI_CAST_PTR (t, (ACPI_CAST_PTR (u8,(a)) + (acpi_size)(b))) -#define ACPI_PTR_DIFF (a, b) (acpi_size) (ACPI_CAST_PTR (u8,(a)) - ACPI_CAST_PTR (u8,(b))) +#define ACPI_ADD_PTR (t, a, b) ACPI_CAST_PTR (t, (ACPI_CAST_PTR (u8, (a)) + (acpi_size)(b))) +#define ACPI_PTR_DIFF (a, b) (acpi_size) (ACPI_CAST_PTR (u8, (a)) - ACPI_CAST_PTR (u8, (b)))/* Pointer/Integer type conversions */ #define ACPI_TO_POINTER (i) ACPI_ADD_PTR (void, (void *) NULL, (acpi_size) i) -#define ACPI_TO_INTEGER (p) ACPI_PTR_DIFF (p,(void *) NULL) -#define ACPI_OFFSET (d,f) (acpi_size) ACPI_PTR_DIFF (&(((d *)0)->f),(void *) NULL) +#define ACPI_TO_INTEGER (p) ACPI_PTR_DIFF (p, (void *) NULL) +#define ACPI_OFFSET (d, f) (acpi_size) ACPI_PTR_DIFF (&(((d *)0)->f), (void *) NULL)#define ACPI_PHYSADDR_TO_PTR (i) ACPI_TO_POINTER(i)#define ACPI_PTR_TO_PHYSADDR (i) ACPI_TO_INTEGER(i)#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED -#define ACPI_COMPARE_NAME (a,b) (*ACPI_CAST_PTR (u32,(a)) == *ACPI_CAST_PTR (u32,(b))) +#define ACPI_COMPARE_NAME (a, b) (*ACPI_CAST_PTR (u32, (a)) == *ACPI_CAST_PTR (u32, (b)))#else -#define ACPI_COMPARE_NAME (a,b) (!ACPI_STRNCMP (ACPI_CAST_PTR (char,(a)), ACPI_CAST_PTR (char,(b)), ACPI_NAME_SIZE)) +#define ACPI_COMPARE_NAME (a, b) (!ACPI_STRNCMP (ACPI_CAST_PTR (char, (a)), ACPI_CAST_PTR (char, (b)), ACPI_NAME_SIZE))#endif /*
@@ -114,7 +114,7 @@ struct acpi_integer_overlay {/* Split 64-bit integer into two 32-bit values. Use with %8.8_x%8.8_x */ -#define ACPI_FORMAT_UINT64 (i) ACPI_HIDWORD(i),ACPI_LODWORD(i) +#define ACPI_FORMAT_UINT64 (i) ACPI_HIDWORD(i), ACPI_LODWORD(i)#if ACPI_MACHINE_WIDTH ==64 #define ACPI_FORMAT_NATIVE_UINT (i) ACPI_FORMAT_UINT64(i)
@@ -132,37 +132,33 @@ struct acpi_integer_overlay {* Macros for big-endian machines */ -/* This macro sets a buffer index, starting from the end of the buffer */ - -#define ACPI_BUFFER_INDEX (buf_len,buf_offset,byte_gran) ((buf_len) - (((buf_offset)+1) * (byte_gran))) -/* These macros reverse the bytes during the move, converting little-endian to big endian */ /* Big Endian <== Little Endian */ /* Hi...Lo Lo...Hi */ /* 16-bit source, 16/32/64 destination */ -#define ACPI_MOVE_16_TO_16 (d,s) {(( u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[1];\ +#define ACPI_MOVE_16_TO_16 (d, s) {(( u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[1];\ (( u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[0];} -#define ACPI_MOVE_16_TO_32 (d,s) {(*(u32 *)(void *)(d))=0;\ +#define ACPI_MOVE_16_TO_32 (d, s) {(*(u32 *)(void *)(d))=0;\ ((u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[1];\ ((u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[0];} -#define ACPI_MOVE_16_TO_64 (d,s) {(*(u64 *)(void *)(d))=0;\ +#define ACPI_MOVE_16_TO_64 (d, s) {(*(u64 *)(void *)(d))=0;\ ((u8 *)(void *)(d))[6] = ((u8 *)(void *)(s))[1];\ ((u8 *)(void *)(d))[7] = ((u8 *)(void *)(s))[0];}/* 32-bit source, 16/32/64 destination */ -#define ACPI_MOVE_32_TO_16 (d,s) ACPI_MOVE_16_TO_16(d,s)/* Truncate to 16 */ +#define ACPI_MOVE_32_TO_16 (d, s) ACPI_MOVE_16_TO_16(d, s)/* Truncate to 16 */ -#define ACPI_MOVE_32_TO_32 (d,s) {(( u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[3];\ +#define ACPI_MOVE_32_TO_32 (d, s) {(( u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[3];\ (( u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[2];\ (( u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[1];\ (( u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[0];} -#define ACPI_MOVE_32_TO_64 (d,s) {(*(u64 *)(void *)(d))=0;\ +#define ACPI_MOVE_32_TO_64 (d, s) {(*(u64 *)(void *)(d))=0;\ ((u8 *)(void *)(d))[4] = ((u8 *)(void *)(s))[3];\ ((u8 *)(void *)(d))[5] = ((u8 *)(void *)(s))[2];\ ((u8 *)(void *)(d))[6] = ((u8 *)(void *)(s))[1];\
@@ -170,11 +166,11 @@ struct acpi_integer_overlay {/* 64-bit source, 16/32/64 destination */ -#define ACPI_MOVE_64_TO_16 (d,s) ACPI_MOVE_16_TO_16(d,s)/* Truncate to 16 */ +#define ACPI_MOVE_64_TO_16 (d, s) ACPI_MOVE_16_TO_16(d, s)/* Truncate to 16 */ -#define ACPI_MOVE_64_TO_32 (d,s) ACPI_MOVE_32_TO_32(d,s)/* Truncate to 32 */ +#define ACPI_MOVE_64_TO_32 (d, s) ACPI_MOVE_32_TO_32(d, s)/* Truncate to 32 */ -#define ACPI_MOVE_64_TO_64 (d,s) {(( u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[7];\ +#define ACPI_MOVE_64_TO_64 (d, s) {(( u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[7];\ (( u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[6];\ (( u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[5];\ (( u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[4];\
@@ -187,63 +183,59 @@ struct acpi_integer_overlay {* Macros for little-endian machines */ -/* This macro sets a buffer index, starting from the beginning of the buffer */ - -#define ACPI_BUFFER_INDEX (buf_len,buf_offset,byte_gran) (buf_offset) -#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED /* The hardware supports unaligned transfers, just do the little-endian move */ /* 16-bit source, 16/32/64 destination */ -#define ACPI_MOVE_16_TO_16 (d,s) *(u16 *)(void *)(d) = *(u16 *)(void *)(s) -#define ACPI_MOVE_16_TO_32 (d,s) *(u32 *)(void *)(d) = *(u16 *)(void *)(s) -#define ACPI_MOVE_16_TO_64 (d,s) *(u64 *)(void *)(d) = *(u16 *)(void *)(s) +#define ACPI_MOVE_16_TO_16 (d, s) *(u16 *)(void *)(d) = *(u16 *)(void *)(s) +#define ACPI_MOVE_16_TO_32 (d, s) *(u32 *)(void *)(d) = *(u16 *)(void *)(s) +#define ACPI_MOVE_16_TO_64 (d, s) *(u64 *)(void *)(d) = *(u16 *)(void *)(s)/* 32-bit source, 16/32/64 destination */ -#define ACPI_MOVE_32_TO_16 (d,s) ACPI_MOVE_16_TO_16(d,s)/* Truncate to 16 */ -#define ACPI_MOVE_32_TO_32 (d,s) *(u32 *)(void *)(d) = *(u32 *)(void *)(s) -#define ACPI_MOVE_32_TO_64 (d,s) *(u64 *)(void *)(d) = *(u32 *)(void *)(s) +#define ACPI_MOVE_32_TO_16 (d, s) ACPI_MOVE_16_TO_16(d, s)/* Truncate to 16 */ +#define ACPI_MOVE_32_TO_32 (d, s) *(u32 *)(void *)(d) = *(u32 *)(void *)(s) +#define ACPI_MOVE_32_TO_64 (d, s) *(u64 *)(void *)(d) = *(u32 *)(void *)(s)/* 64-bit source, 16/32/64 destination */ -#define ACPI_MOVE_64_TO_16 (d,s) ACPI_MOVE_16_TO_16(d,s)/* Truncate to 16 */ -#define ACPI_MOVE_64_TO_32 (d,s) ACPI_MOVE_32_TO_32(d,s)/* Truncate to 32 */ -#define ACPI_MOVE_64_TO_64 (d,s) *(u64 *)(void *)(d) = *(u64 *)(void *)(s) +#define ACPI_MOVE_64_TO_16 (d, s) ACPI_MOVE_16_TO_16(d, s)/* Truncate to 16 */ +#define ACPI_MOVE_64_TO_32 (d, s) ACPI_MOVE_32_TO_32(d, s)/* Truncate to 32 */ +#define ACPI_MOVE_64_TO_64 (d, s) *(u64 *)(void *)(d) = *(u64 *)(void *)(s)#else /* -* The hardware does not support unaligned transfers. We must move the -* data one byte at a time. These macros work whether the source or +* The hardware does not support unaligned transfers. We must move the +* data one byte at a time. These macros work whether the source or * the destination (or both) is/are unaligned. (Little-endian move) */ /* 16-bit source, 16/32/64 destination */ -#define ACPI_MOVE_16_TO_16 (d,s) {(( u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0];\ +#define ACPI_MOVE_16_TO_16 (d, s) {(( u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0];\ (( u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[1];} -#define ACPI_MOVE_16_TO_32 (d,s) {(*(u32 *)(void *)(d)) = 0; ACPI_MOVE_16_TO_16(d,s);} -#define ACPI_MOVE_16_TO_64 (d,s) {(*(u64 *)(void *)(d)) = 0; ACPI_MOVE_16_TO_16(d,s);} +#define ACPI_MOVE_16_TO_32 (d, s) {(*(u32 *)(void *)(d)) = 0; ACPI_MOVE_16_TO_16(d, s);} +#define ACPI_MOVE_16_TO_64 (d, s) {(*(u64 *)(void *)(d)) = 0; ACPI_MOVE_16_TO_16(d, s);}/* 32-bit source, 16/32/64 destination */ -#define ACPI_MOVE_32_TO_16 (d,s) ACPI_MOVE_16_TO_16(d,s)/* Truncate to 16 */ +#define ACPI_MOVE_32_TO_16 (d, s) ACPI_MOVE_16_TO_16(d, s)/* Truncate to 16 */ -#define ACPI_MOVE_32_TO_32 (d,s) {(( u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0];\ +#define ACPI_MOVE_32_TO_32 (d, s) {(( u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0];\ (( u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[1];\ (( u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[2];\ (( u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[3];} -#define ACPI_MOVE_32_TO_64 (d,s) {(*(u64 *)(void *)(d)) = 0; ACPI_MOVE_32_TO_32(d,s);} +#define ACPI_MOVE_32_TO_64 (d, s) {(*(u64 *)(void *)(d)) = 0; ACPI_MOVE_32_TO_32(d, s);}/* 64-bit source, 16/32/64 destination */ -#define ACPI_MOVE_64_TO_16 (d,s) ACPI_MOVE_16_TO_16(d,s)/* Truncate to 16 */ -#define ACPI_MOVE_64_TO_32 (d,s) ACPI_MOVE_32_TO_32(d,s)/* Truncate to 32 */ -#define ACPI_MOVE_64_TO_64 (d,s) {(( u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0];\ +#define ACPI_MOVE_64_TO_16 (d, s) ACPI_MOVE_16_TO_16(d, s)/* Truncate to 16 */ +#define ACPI_MOVE_64_TO_32 (d, s) ACPI_MOVE_32_TO_32(d, s)/* Truncate to 32 */ +#define ACPI_MOVE_64_TO_64 (d, s) {(( u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[0];\ (( u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[1];\ (( u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[2];\ (( u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[3];\
@@ -257,10 +249,10 @@ struct acpi_integer_overlay {/* Macros based on machine integer width */ #if ACPI_MACHINE_WIDTH ==32 -#define ACPI_MOVE_SIZE_TO_16 (d,s) ACPI_MOVE_32_TO_16(d,s) +#define ACPI_MOVE_SIZE_TO_16 (d, s) ACPI_MOVE_32_TO_16(d, s)#elif ACPI_MACHINE_WIDTH ==64 -#define ACPI_MOVE_SIZE_TO_16 (d,s) ACPI_MOVE_64_TO_16(d,s) +#define ACPI_MOVE_SIZE_TO_16 (d, s) ACPI_MOVE_64_TO_16(d, s)#else #error unknown ACPI_MACHINE_WIDTH
@@ -269,29 +261,29 @@ struct acpi_integer_overlay {/* * Fast power-of-two math macros for non-optimized compilers */ -#define _ACPI_DIV (value,power_of2) ((u32) ((value) >> (power_of2))) -#define _ACPI_MUL (value,power_of2) ((u32) ((value) << (power_of2))) -#define _ACPI_MOD (value,divisor) ((u32) ((value) & ((divisor) -1))) +#define _ACPI_DIV (value, power_of2) ((u32) ((value) >> (power_of2))) +#define _ACPI_MUL (value, power_of2) ((u32) ((value) << (power_of2))) +#define _ACPI_MOD (value, divisor) ((u32) ((value) & ((divisor) -1))) -#define ACPI_DIV_2 (a) _ACPI_DIV(a,1) -#define ACPI_MUL_2 (a) _ACPI_MUL(a,1) -#define ACPI_MOD_2 (a) _ACPI_MOD(a,2) +#define ACPI_DIV_2 (a) _ACPI_DIV(a, 1) +#define ACPI_MUL_2 (a) _ACPI_MUL(a, 1) +#define ACPI_MOD_2 (a) _ACPI_MOD(a, 2) -#define ACPI_DIV_4 (a) _ACPI_DIV(a,2) -#define ACPI_MUL_4 (a) _ACPI_MUL(a,2) -#define ACPI_MOD_4 (a) _ACPI_MOD(a,4) +#define ACPI_DIV_4 (a) _ACPI_DIV(a, 2) +#define ACPI_MUL_4 (a) _ACPI_MUL(a, 2) +#define ACPI_MOD_4 (a) _ACPI_MOD(a, 4) -#define ACPI_DIV_8 (a) _ACPI_DIV(a,3) -#define ACPI_MUL_8 (a) _ACPI_MUL(a,3) -#define ACPI_MOD_8 (a) _ACPI_MOD(a,8) +#define ACPI_DIV_8 (a) _ACPI_DIV(a, 3) +#define ACPI_MUL_8 (a) _ACPI_MUL(a, 3) +#define ACPI_MOD_8 (a) _ACPI_MOD(a, 8) -#define ACPI_DIV_16 (a) _ACPI_DIV(a,4) -#define ACPI_MUL_16 (a) _ACPI_MUL(a,4) -#define ACPI_MOD_16 (a) _ACPI_MOD(a,16) +#define ACPI_DIV_16 (a) _ACPI_DIV(a, 4) +#define ACPI_MUL_16 (a) _ACPI_MUL(a, 4) +#define ACPI_MOD_16 (a) _ACPI_MOD(a, 16) -#define ACPI_DIV_32 (a) _ACPI_DIV(a,5) -#define ACPI_MUL_32 (a) _ACPI_MUL(a,5) -#define ACPI_MOD_32 (a) _ACPI_MOD(a,32) +#define ACPI_DIV_32 (a) _ACPI_DIV(a, 5) +#define ACPI_MUL_32 (a) _ACPI_MUL(a, 5) +#define ACPI_MOD_32 (a) _ACPI_MOD(a, 32)/* * Rounding macros (Power of two boundaries only)
@@ -305,13 +297,13 @@ struct acpi_integer_overlay {/* Note: sizeof(acpi_size) evaluates to either 4 or 8 (32- vs 64-bit mode) */ -#define ACPI_ROUND_DOWN_TO_32BIT (a) ACPI_ROUND_DOWN(a,4) -#define ACPI_ROUND_DOWN_TO_64BIT (a) ACPI_ROUND_DOWN(a,8) -#define ACPI_ROUND_DOWN_TO_NATIVE_WORD (a) ACPI_ROUND_DOWN(a,sizeof(acpi_size)) +#define ACPI_ROUND_DOWN_TO_32BIT (a) ACPI_ROUND_DOWN(a, 4) +#define ACPI_ROUND_DOWN_TO_64BIT (a) ACPI_ROUND_DOWN(a, 8) +#define ACPI_ROUND_DOWN_TO_NATIVE_WORD (a) ACPI_ROUND_DOWN(a, sizeof(acpi_size)) -#define ACPI_ROUND_UP_TO_32BIT (a) ACPI_ROUND_UP(a,4) -#define ACPI_ROUND_UP_TO_64BIT (a) ACPI_ROUND_UP(a,8) -#define ACPI_ROUND_UP_TO_NATIVE_WORD (a) ACPI_ROUND_UP(a,sizeof(acpi_size)) +#define ACPI_ROUND_UP_TO_32BIT (a) ACPI_ROUND_UP(a, 4) +#define ACPI_ROUND_UP_TO_64BIT (a) ACPI_ROUND_UP(a, 8) +#define ACPI_ROUND_UP_TO_NATIVE_WORD (a) ACPI_ROUND_UP(a, sizeof(acpi_size))#define ACPI_ROUND_BITS_UP_TO_BYTES (a) ACPI_DIV_8((a) + 7)#define ACPI_ROUND_BITS_DOWN_TO_BYTES (a) ACPI_DIV_8((a))
@@ -320,9 +312,9 @@ struct acpi_integer_overlay {/* Generic (non-power-of-two) rounding */ -#define ACPI_ROUND_UP_TO (value,boundary) (((value) + ((boundary)-1)) / (boundary)) +#define ACPI_ROUND_UP_TO (value, boundary) (((value) + ((boundary)-1)) / (boundary)) -#define ACPI_IS_MISALIGNED (value) (((acpi_size)value) & (sizeof(acpi_size)-1)) +#define ACPI_IS_MISALIGNED (value) (((acpi_size) value) & (sizeof(acpi_size)-1))/* * Bitmask creation
@@ -333,8 +325,6 @@ struct acpi_integer_overlay {#define ACPI_MASK_BITS_ABOVE (position) (~((ACPI_INTEGER_MAX) << ((u32) (position))))#define ACPI_MASK_BITS_BELOW (position) ((ACPI_INTEGER_MAX) << ((u32) (position))) -#define ACPI_IS_OCTAL_DIGIT (d) (((char)(d) >= '0') && ((char)(d) <= '7')) -/* Bitfields within ACPI registers */ #define ACPI_REGISTER_PREPARE_BITS (val, pos, mask) ((val << pos) & mask)
@@ -342,39 +332,29 @@ struct acpi_integer_overlay {#define ACPI_INSERT_BITS (target, mask, source) target = ((target & (~(mask))) | (source & mask)) -/* Generate a UUID */ - -#define ACPI_INIT_UUID (a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \ - (a) & 0xFF, ((a) >> 8) & 0xFF, ((a) >> 16) & 0xFF, ((a) >> 24) & 0xFF, \ - (b) & 0xFF, ((b) >> 8) & 0xFF, \ - (c) & 0xFF, ((c) >> 8) & 0xFF, \ - (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) -/* -* An struct acpi_namespace_node * can appear in some contexts, -* where a pointer to an union acpi_operand_object can also -* appear. This macro is used to distinguish them. +* An struct acpi_namespace_node can appear in some contexts +* where a pointer to an union acpi_operand_object can also +* appear. This macro is used to distinguish them. * * The "Descriptor" field is the first field in both structures. */ #define ACPI_GET_DESCRIPTOR_TYPE (d) (((union acpi_descriptor *)(void *)(d))->common.descriptor_type) -#define ACPI_SET_DESCRIPTOR_TYPE (d,t) (((union acpi_descriptor *)(void *)(d))->common.descriptor_type = t) +#define ACPI_SET_DESCRIPTOR_TYPE (d, t) (((union acpi_descriptor *)(void *)(d))->common.descriptor_type = t)/* Macro to test the object type */ #define ACPI_GET_OBJECT_TYPE (d) (((union acpi_operand_object *)(void *)(d))->common.type) -/* Macro to check the table flags for SINGLE or MULTIPLE tables are allowed */ - -#define ACPI_IS_SINGLE_TABLE (x) (((x) & 0x01) == ACPI_TABLE_SINGLE ? 1 : 0) -/* * Macros for the master AML opcode table */ -#if defined(ACPI_DISASSEMBLER ) || defined (ACPI_DEBUG_OUTPUT ) -#define ACPI_OP (name,Pargs,Iargs,obj_type,class,type,flags) {name,(u32)(Pargs),(u32)(Iargs),(u32)(flags),obj_type,class,type} +#if defined (ACPI_DISASSEMBLER ) || defined (ACPI_DEBUG_OUTPUT ) +#define ACPI_OP (name, Pargs, Iargs, obj_type, class, type, flags) \ + {name, (u32)(Pargs), (u32)(Iargs), (u32)(flags), obj_type, class, type}#else -#define ACPI_OP (name,Pargs,Iargs,obj_type,class,type,flags) {(u32)(Pargs),(u32)(Iargs),(u32)(flags),obj_type,class,type} +#define ACPI_OP (name, Pargs, Iargs, obj_type, class, type, flags) \ + {(u32)(Pargs), (u32)(Iargs), (u32)(flags), obj_type, class, type}#endif #ifdef ACPI_DISASSEMBLER
@@ -392,18 +372,18 @@ struct acpi_integer_overlay {#define ARG_6 (x) ((u32)(x) << (5 * ARG_TYPE_WIDTH))#define ARGI_LIST1 (a) (ARG_1(a)) -#define ARGI_LIST2 (a,b) (ARG_1(b)|ARG_2(a)) -#define ARGI_LIST3 (a,b,c) (ARG_1(c)|ARG_2(b)|ARG_3(a)) -#define ARGI_LIST4 (a,b,c,d) (ARG_1(d)|ARG_2(c)|ARG_3(b)|ARG_4(a)) -#define ARGI_LIST5 (a,b,c,d,e) (ARG_1(e)|ARG_2(d)|ARG_3(c)|ARG_4(b)|ARG_5(a)) -#define ARGI_LIST6 (a,b,c,d,e,f) (ARG_1(f)|ARG_2(e)|ARG_3(d)|ARG_4(c)|ARG_5(b)|ARG_6(a)) +#define ARGI_LIST2 (a, b) (ARG_1(b)|ARG_2(a)) +#define ARGI_LIST3 (a, b, c) (ARG_1(c)|ARG_2(b)|ARG_3(a)) +#define ARGI_LIST4 (a, b, c, d) (ARG_1(d)|ARG_2(c)|ARG_3(b)|ARG_4(a)) +#define ARGI_LIST5 (a, b, c, d, e) (ARG_1(e)|ARG_2(d)|ARG_3(c)|ARG_4(b)|ARG_5(a)) +#define ARGI_LIST6 (a, b, c, d, e, f) (ARG_1(f)|ARG_2(e)|ARG_3(d)|ARG_4(c)|ARG_5(b)|ARG_6(a))#define ARGP_LIST1 (a) (ARG_1(a)) -#define ARGP_LIST2 (a,b) (ARG_1(a)|ARG_2(b)) -#define ARGP_LIST3 (a,b,c) (ARG_1(a)|ARG_2(b)|ARG_3(c)) -#define ARGP_LIST4 (a,b,c,d) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)) -#define ARGP_LIST5 (a,b,c,d,e) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e)) -#define ARGP_LIST6 (a,b,c,d,e,f) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e)|ARG_6(f)) +#define ARGP_LIST2 (a, b) (ARG_1(a)|ARG_2(b)) +#define ARGP_LIST3 (a, b, c) (ARG_1(a)|ARG_2(b)|ARG_3(c)) +#define ARGP_LIST4 (a, b, c, d) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)) +#define ARGP_LIST5 (a, b, c, d, e) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e)) +#define ARGP_LIST6 (a, b, c, d, e, f) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e)|ARG_6(f))#define GET_CURRENT_ARG_TYPE (list) (list & ((u32) 0x1F))#define INCREMENT_ARG_LIST (list) (list >>= ((u32) ARG_TYPE_WIDTH))
@@ -434,8 +414,8 @@ struct acpi_integer_overlay {#define ACPI_WARNING (plist) acpi_ut_warning plist#define ACPI_EXCEPTION (plist) acpi_ut_exception plist#define ACPI_ERROR (plist) acpi_ut_error plist -#define ACPI_ERROR_NAMESPACE (s,e) acpi_ns_report_error (AE_INFO, s, e); -#define ACPI_ERROR_METHOD (s,n,p,e) acpi_ns_report_method_error (AE_INFO, s, n, p, e); +#define ACPI_ERROR_NAMESPACE (s, e) acpi_ns_report_error (AE_INFO, s, e); +#define ACPI_ERROR_METHOD (s, n, p, e) acpi_ns_report_method_error (AE_INFO, s, n, p, e);#else
@@ -445,8 +425,8 @@ struct acpi_integer_overlay {#define ACPI_WARNING (plist)#define ACPI_EXCEPTION (plist)#define ACPI_ERROR (plist) -#define ACPI_ERROR_NAMESPACE (s,e) -#define ACPI_ERROR_METHOD (s,n,p,e) +#define ACPI_ERROR_NAMESPACE (s, e) +#define ACPI_ERROR_METHOD (s, n, p, e)#endif /*
@@ -489,18 +469,18 @@ struct acpi_integer_overlay {#define ACPI_FUNCTION_TRACE (a) ACPI_FUNCTION_NAME(a) \ acpi_ut_trace(ACPI_DEBUG_PARAMETERS) -#define ACPI_FUNCTION_TRACE_PTR (a,b) ACPI_FUNCTION_NAME(a) \ - acpi_ut_trace_ptr(ACPI_DEBUG_PARAMETERS,(void *)b) -#define ACPI_FUNCTION_TRACE_U32 (a,b) ACPI_FUNCTION_NAME(a) \ - acpi_ut_trace_u32(ACPI_DEBUG_PARAMETERS,(u32)b) -#define ACPI_FUNCTION_TRACE_STR (a,b) ACPI_FUNCTION_NAME(a) \ - acpi_ut_trace_str(ACPI_DEBUG_PARAMETERS,(char *)b) +#define ACPI_FUNCTION_TRACE_PTR (a, b) ACPI_FUNCTION_NAME(a) \ + acpi_ut_trace_ptr(ACPI_DEBUG_PARAMETERS, (void *)b) +#define ACPI_FUNCTION_TRACE_U32 (a, b) ACPI_FUNCTION_NAME(a) \ + acpi_ut_trace_u32(ACPI_DEBUG_PARAMETERS, (u32)b) +#define ACPI_FUNCTION_TRACE_STR (a, b) ACPI_FUNCTION_NAME(a) \ + acpi_ut_trace_str(ACPI_DEBUG_PARAMETERS, (char *)b)#define ACPI_FUNCTION_ENTRY () acpi_ut_track_stack_ptr()/* * Function exit tracing. -* WARNING: These macros include a return statement. This is usually considered +* WARNING: These macros include a return statement. This is usually considered * bad form, but having a separate exit macro is very ugly and difficult to maintain. * One of the FUNCTION_TRACE macros above must be used in conjunction with these macros * so that "_AcpiFunctionName" is defined.
@@ -596,13 +576,13 @@ struct acpi_integer_overlay {/* Stack and buffer dumping */ -#define ACPI_DUMP_STACK_ENTRY (a) acpi_ex_dump_operand((a),0) -#define ACPI_DUMP_OPERANDS (a,b,c) acpi_ex_dump_operands(a,b,c) +#define ACPI_DUMP_STACK_ENTRY (a) acpi_ex_dump_operand((a), 0) +#define ACPI_DUMP_OPERANDS (a, b, c) acpi_ex_dump_operands(a, b, c) -#define ACPI_DUMP_ENTRY (a,b) acpi_ns_dump_entry (a,b) -#define ACPI_DUMP_PATHNAME (a,b,c,d) acpi_ns_dump_pathname(a,b,c,d) +#define ACPI_DUMP_ENTRY (a, b) acpi_ns_dump_entry (a, b) +#define ACPI_DUMP_PATHNAME (a, b, c, d) acpi_ns_dump_pathname(a, b, c, d)#define ACPI_DUMP_RESOURCE_LIST (a) acpi_rs_dump_resource_list(a) -#define ACPI_DUMP_BUFFER (a,b) acpi_ut_dump_buffer((u8 *)a,b,DB_BYTE_DISPLAY,_COMPONENT) +#define ACPI_DUMP_BUFFER (a, b) acpi_ut_dump_buffer((u8 *) a, b, DB_BYTE_DISPLAY, _COMPONENT)/* * Master debug print macros
@@ -625,20 +605,20 @@ struct acpi_integer_overlay {#define ACPI_DEBUG_ONLY_MEMBERS (a) do { } while(0)#define ACPI_FUNCTION_NAME (a) do { } while(0)#define ACPI_FUNCTION_TRACE (a) do { } while(0) -#define ACPI_FUNCTION_TRACE_PTR (a,b) do { } while(0) -#define ACPI_FUNCTION_TRACE_U32 (a,b) do { } while(0) -#define ACPI_FUNCTION_TRACE_STR (a,b) do { } while(0) +#define ACPI_FUNCTION_TRACE_PTR (a, b) do { } while(0) +#define ACPI_FUNCTION_TRACE_U32 (a, b) do { } while(0) +#define ACPI_FUNCTION_TRACE_STR (a, b) do { } while(0)#define ACPI_FUNCTION_EXIT do { } while(0)#define ACPI_FUNCTION_STATUS_EXIT (s) do { } while(0)#define ACPI_FUNCTION_VALUE_EXIT (s) do { } while(0)#define ACPI_FUNCTION_ENTRY () do { } while(0)#define ACPI_DUMP_STACK_ENTRY (a) do { } while(0) -#define ACPI_DUMP_OPERANDS (a,b,c) do { } while(0) -#define ACPI_DUMP_ENTRY (a,b) do { } while(0) -#define ACPI_DUMP_TABLES (a,b) do { } while(0) -#define ACPI_DUMP_PATHNAME (a,b,c,d) do { } while(0) +#define ACPI_DUMP_OPERANDS (a, b, c) do { } while(0) +#define ACPI_DUMP_ENTRY (a, b) do { } while(0) +#define ACPI_DUMP_TABLES (a, b) do { } while(0) +#define ACPI_DUMP_PATHNAME (a, b, c, d) do { } while(0)#define ACPI_DUMP_RESOURCE_LIST (a) do { } while(0) -#define ACPI_DUMP_BUFFER (a,b) do { } while(0) +#define ACPI_DUMP_BUFFER (a, b) do { } while(0)#define ACPI_DEBUG_PRINT (pl) do { } while(0)#define ACPI_DEBUG_PRINT_RAW (pl) do { } while(0)
@@ -677,15 +657,17 @@ struct acpi_integer_overlay {/* * Memory allocation tracking (DEBUG ONLY) */ +#define ACPI_MEM_PARAMETERS _COMPONENT, _acpi_module_name, __LINE__ +#ifndef ACPI_DBG_TRACK_ALLOCATIONS /* Memory allocation */ #ifndef ACPI_ALLOCATE -#define ACPI_ALLOCATE (a) acpi_ut_allocate((acpi_size)(a),_COMPONENT,_acpi_module_name,__LINE__) +#define ACPI_ALLOCATE (a) acpi_ut_allocate((acpi_size)(a), ACPI_MEM_PARAMETERS)#endif #ifndef ACPI_ALLOCATE_ZEROED -#define ACPI_ALLOCATE_ZEROED (a) acpi_ut_allocate_zeroed((acpi_size)(a), _COMPONENT,_acpi_module_name,__LINE__) +#define ACPI_ALLOCATE_ZEROED (a) acpi_ut_allocate_zeroed((acpi_size)(a), ACPI_MEM_PARAMETERS)#endif #ifndef ACPI_FREE #define ACPI_FREE (a) acpio_os_free(a)
@@ -696,9 +678,9 @@ struct acpi_integer_overlay {/* Memory allocation */ -#define ACPI_ALLOCATE (a) acpi_ut_allocate_and_track((acpi_size)(a),_COMPONENT,_acpi_module_name,__LINE__) -#define ACPI_ALLOCATE_ZEROED (a) acpi_ut_allocate_zeroed_and_track((acpi_size)(a), _COMPONENT,_acpi_module_name,__LINE__) -#define ACPI_FREE (a) acpi_ut_free_and_track(a,_COMPONENT,_acpi_module_name,__LINE__) +#define ACPI_ALLOCATE (a) acpi_ut_allocate_and_track((acpi_size)(a), ACPI_MEM_PARAMETERS) +#define ACPI_ALLOCATE_ZEROED (a) acpi_ut_allocate_zeroed_and_track((acpi_size)(a), ACPI_MEM_PARAMETERS) +#define ACPI_FREE (a) acpi_ut_free_and_track(a, ACPI_MEM_PARAMETERS)#define ACPI_MEM_TRACKING (a) a#endif /* ACPI_DBG_TRACK_ALLOCATIONS */
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 17/85 ACPICA: Return method arg count from acpi_get_object_info
In reply to Len BrownFrom: Bob Moore <[email protected]>
Also update the debugger so that the correct number of arguments is passed to the method. Prevents a warning message from the debugger.
--- drivers/acpi/namespace/nsxfname.c | 4 ++++ include/acpi/actypes.h | 1 + 2 files changed, 5 insertions(+), 0 deletions(-)
drivers/acpi/namespace/nsxfname.c +4 -0
@@ -264,6 +264,10 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) info->name = node->name.integer; info->valid =0 ; +if (node->type ==ACPI_TYPE_METHOD ) { + info->param_count = node->object->method.param_count; + } + status =acpi_ut_release_mutex (ACPI_MTX_NAMESPACE );if (ACPI_FAILURE (status)) { goto cleanup;
include/acpi/actypes.h +1 -0
@@ -859,6 +859,7 @@ struct acpi_obj_info_header {struct acpi_device_info {ACPI_COMMON_OBJ_INFO ; +u32 param_count;/* If a method, required parameter count */ u32 valid;/* Indicates which fields below are valid */ u32 current_status;/* _STA value */ acpi_integer address;/* _ADR value if any */
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 18/85 ACPICA: Update version to 20080701
In reply to Len BrownFrom: Bob Moore <[email protected]>
Update version to 20080701.
--- include/acpi/acconfig.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
include/acpi/acconfig.h +1 -1
@@ -63,7 +63,7 @@/* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20080609 +#define ACPI_CA_VERSION 0x20080701/* * OS name, used for the _OS object. The _OS object is essentially obsolete,
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 19/85 ACPICA: Add function to decode reference obj types to strings
In reply to Len BrownFrom: Bob Moore <[email protected]>
Created for improved error messages.
--- drivers/acpi/utilities/utglobal.c | 36 ++++++++++++++++++++++++++++++++++++ include/acpi/acutils.h | 2 ++ 2 files changed, 38 insertions(+), 0 deletions(-)
drivers/acpi/utilities/utglobal.c +36 -0
@@ -45,6 +45,7 @@#include <acpi/acpi.h> #include <acpi/acnamesp.h> +#include <acpi/amlcode.h> ACPI_EXPORT_SYMBOL(acpi_gbl_FADT)#define _COMPONENT ACPI_UTILITIES
@@ -575,6 +576,41 @@ char *acpi_ut_get_descriptor_name(void *object) } +/******************************************************************************* +* +* FUNCTION: acpi_ut_get_reference_name +* +* PARAMETERS: Object - An ACPI reference object +* +* RETURN: Pointer to a string +* +* DESCRIPTION: Decode a reference object sub-type to a string. +* +******************************************************************************/ + +/* Printable names of reference object sub-types */ + +const char *acpi_ut_get_reference_name (union acpi_operand_object *object) +{ + +switch (object->reference.opcode) { +case AML_INT_NAMEPATH_OP : +return "Name" ; + +case AML_LOAD_OP : +return "DDB-Handle" ; + +case AML_REF_OF_OP : +return "RefOf" ; + +case AML_INDEX_OP : +return "Index" ; + +default : +return "Unknown" ; + } +} +#if defined(ACPI_DEBUG_OUTPUT ) || defined(ACPI_DEBUGGER )/* * Strings and procedures used for debug only
include/acpi/acutils.h +2 -0
@@ -126,6 +126,8 @@ char *acpi_ut_get_node_name(void *object);char *acpi_ut_get_descriptor_name (void *object); +const char *acpi_ut_get_reference_name (union acpi_operand_object *object); +char *acpi_ut_get_object_type_name (union acpi_operand_object *obj_desc);char *acpi_ut_get_region_name (u8 space_id);
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 20/85 ACPICA: Improve object conversion error messages
In reply to Len BrownFrom: Bob Moore <[email protected]>
Better error messages during object conversion from internal to the external ACPI_OBJECT. Used for external calls to acpi_evaluate_object.
--- drivers/acpi/utilities/utobject.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-)
drivers/acpi/utilities/utobject.c +6 -2
@@ -503,7 +503,9 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,* required eventually. */ ACPI_ERROR ((AE_INFO , -"Unsupported Reference opcode=%X in object %p" , +"Cannot convert to external object - " +"unsupported Reference type [%s] %X in object %p" , +acpi_ut_get_reference_name (internal_object), internal_object->reference.opcode, internal_object)); status =AE_TYPE ;
@@ -513,7 +515,9 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,default : -ACPI_ERROR ((AE_INFO ,"Unsupported type=%X in object %p" , +ACPI_ERROR ((AE_INFO ,"Cannot convert to external object - " +"unsupported type [%s] %X in object %p" , +acpi_ut_get_object_type_name (internal_object),ACPI_GET_OBJECT_TYPE (internal_object), internal_object)); status =AE_TYPE ;
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 21/85 ACPICA: x2APIC support: changes for MADT and SRAT ACPI tables
In reply to Len BrownFrom: Bob Moore <[email protected]>
Support for the x2APIC. There are 2 new subtables for the MADT and one new subtable for the SRAT. Includes disassembler and acpisrc support. Data from the Intel 64 Architecture x2APIC Specification, June 2008.
--- include/acpi/acdisasm.h | 4 +++ include/acpi/actbl1.h | 51 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 49 insertions(+), 6 deletions(-)
include/acpi/acdisasm.h +4 -0
@@ -186,6 +186,8 @@ extern struct acpi_dmtable_info acpi_dm_table_info_madt5[];extern struct acpi_dmtable_info acpi_dm_table_info_madt6[];extern struct acpi_dmtable_info acpi_dm_table_info_madt7[];extern struct acpi_dmtable_info acpi_dm_table_info_madt8[]; +extern struct acpi_dmtable_info acpi_dm_table_info_madt9[]; +extern struct acpi_dmtable_info acpi_dm_table_info_madt10[];extern struct acpi_dmtable_info acpi_dm_table_info_madt_hdr[];extern struct acpi_dmtable_info acpi_dm_table_info_mcfg[];extern struct acpi_dmtable_info acpi_dm_table_info_mcfg0[];
@@ -197,8 +199,10 @@ extern struct acpi_dmtable_info acpi_dm_table_info_slit[];extern struct acpi_dmtable_info acpi_dm_table_info_spcr[];extern struct acpi_dmtable_info acpi_dm_table_info_spmi[];extern struct acpi_dmtable_info acpi_dm_table_info_srat[]; +extern struct acpi_dmtable_info acpi_dm_table_info_srat_hdr[];extern struct acpi_dmtable_info acpi_dm_table_info_srat0[];extern struct acpi_dmtable_info acpi_dm_table_info_srat1[]; +extern struct acpi_dmtable_info acpi_dm_table_info_srat2[];extern struct acpi_dmtable_info acpi_dm_table_info_tcpa[];extern struct acpi_dmtable_info acpi_dm_table_info_wdrt[];
include/acpi/actbl1.h +45 -6
83 lines not on this page · raw message
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 22/85 ACPICA: Update version to 20080729
In reply to Len BrownFrom: Bob Moore <[email protected]>
--- include/acpi/acconfig.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
include/acpi/acconfig.h +1 -1
@@ -63,7 +63,7 @@/* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20080701 +#define ACPI_CA_VERSION 0x20080729/* * OS name, used for the _OS object. The _OS object is essentially obsolete,
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 23/85 ACPI: Clear WAK_STS on resume
In reply to Len BrownFrom: Matthew Garrett <[email protected]>
The leading other brand OS appears to clear the WAK_STS flag on resume. When rebooted, certain BIOSes assume that the system is actually resuming if it's still set and so fail to reboot correctly. Make sure that it's cleared at resume time.
Comment clarified as suggested by Bob Moore
--- drivers/acpi/hardware/hwsleep.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
drivers/acpi/hardware/hwsleep.c +7 -0
@@ -627,6 +627,13 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) }/* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */ +/* +* Some BIOSes assume that WAK_STS will be cleared on resume and use +* it to determine whether the system is rebooting or resuming. Clear +* it for compatibility. +*/ +acpi_set_register (ACPI_BITREG_WAKE_STATUS ,1 ); + acpi_gbl_system_awake_and_running = TRUE;/* Enable power button */
Signature · 1 line
1.5.5.1
Re: [PATCH 23/85] ACPI: Clear WAK_STS on resume
Am Samstag, 11. Oktober 2008 schrieb Len Brown:
Quoted 7 lines
From: Matthew Garrett <[email protected]>
The leading other brand OS appears to clear the
WAK_STSflag on resume. When rebooted, certain BIOSes assume that the system is actually resuming if it's still set and so fail to reboot correctly. Make sure that it's cleared at resume time.
Quoted 5 lines
Comment clarified as suggested by Bob Moore
Signed-off-by Matthew Garrett <[email protected]>Signed-off-by Andi Kleen <[email protected]>Signed-off-by Len Brown <[email protected]>
This patch fixes reboot after suspend on my ASUS P5K.
Len Brown
reviewerPATCH 24/85 ACPI : Add the support for _TTS object
In reply to Len BrownFrom: Zhao Yakui <[email protected]>
The _TTS object is defined in the section 7.3 of acpi 3.0b spec. The _TTS control method is executed by the OSPM at the beginning of
the sleep transition process for S1,S2, S3, S4, and orderly S5 shutdown. OS will invoke _TTS before it has notified any native mode device drivers of the sleep state transition. The target sleeping state value is passed to the _TTS control method.
The _TTS control method is also executed by the OSPM at the end of
any sleep transition process when the system transitions to S0 from S1, S2, S3, or S4. The _TTS object should be evaluated after it has notified any native mode device drivers of the end of the sleep state transition. The working state value (0) is passed to the _TTS control method.
So it is necessary to add the support for _TTS object. The _TTS object
will be evaluated if it exists.
At the same time a block notifier is added to the reboot notifier list so
that the _TTS object will also be evaluated when the system shutdown.
lenb: note that as of Sep 2008, I've not yet seen _TTS in any shipping BIOS. So this patch is to future-proof Linux, rather than fix the installed base.
http://bugzilla.kernel.org/show_bug.cgi?id=11132
--- drivers/acpi/sleep/main.c | 49 ++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 48 insertions(+), 1 deletions(-)
drivers/acpi/sleep/main.c +48 -1
@@ -15,6 +15,7 @@#include <linux/dmi.h> #include <linux/device.h> #include <linux/suspend.h> +#include <linux/reboot.h> #include <asm/io.h>
@@ -24,6 +25,36 @@u8 sleep_states[ACPI_S_STATE_COUNT ]; +static void acpi_sleep_tts_switch (u32 acpi_state) +{ +union acpi_object in_arg = {ACPI_TYPE_INTEGER }; +struct acpi_object_list arg_list = {1 , &in_arg }; +acpi_status status =AE_OK ; + + in_arg.integer.value = acpi_state; + status =acpi_evaluate_object (NULL ,"\\_TTS" , &arg_list,NULL ); +if (ACPI_FAILURE (status) && status !=AE_NOT_FOUND ) { +/* +* OS can't evaluate the _TTS object correctly. Some warning +* message will be printed. But it won't break anything. +*/ +printk (KERN_NOTICE "Failure in evaluating _TTS object\n" ); + } +} + +static int tts_notify_reboot (struct notifier_block *this, +unsigned long code,void *x) +{ +acpi_sleep_tts_switch (ACPI_STATE_S5 ); +return NOTIFY_DONE ; +} + +static struct notifier_block tts_notifier = { + .notifier_call = tts_notify_reboot, + .next =NULL , + .priority =0 , +}; +static int acpi_sleep_prepare (u32 acpi_state) {#ifdef CONFIG_ACPI_SLEEP
@@ -131,6 +162,7 @@ static void acpi_pm_end(void)* failing transition to a sleep state. */ acpi_target_sleep_state =ACPI_STATE_S0 ; + acpi_sleep_tts_switch(acpi_target_sleep_state); }#endif /* CONFIG_PM_SLEEP */
@@ -155,6 +187,7 @@ static int acpi_suspend_begin(suspend_state_t pm_state)if (sleep_states[acpi_state]) { acpi_target_sleep_state = acpi_state; +acpi_sleep_tts_switch (acpi_target_sleep_state); }else {printk (KERN_ERR "ACPI does not support this state: %d\n" , pm_state);
@@ -313,6 +346,7 @@ void __init acpi_no_s4_hw_signature(void)static int acpi_hibernation_begin (void ) { acpi_target_sleep_state =ACPI_STATE_S4 ; +acpi_sleep_tts_switch (acpi_target_sleep_state);return 0 ; }
@@ -376,7 +410,15 @@ static struct platform_hibernation_ops acpi_hibernation_ops = {*/ static int acpi_hibernation_begin_old (void ) { -int error =acpi_sleep_prepare (ACPI_STATE_S4 ); +int error; +/* +* The _TTS object should always be evaluated before the _PTS object. +* When the old_suspended_ordering is true, the _PTS object is +* evaluated in the acpi_sleep_prepare. +*/ +acpi_sleep_tts_switch (ACPI_STATE_S4 ); + + error =acpi_sleep_prepare (ACPI_STATE_S4 );if (!error) acpi_target_sleep_state =ACPI_STATE_S4 ;
@@ -596,5 +638,10 @@ int __init acpi_sleep_init(void) pm_power_off = acpi_power_off; }printk (")\n" ); +/* +* Register the tts_notifier to reboot notifier list so that the _TTS +* object can also be evaluated when the system enters S5. +*/ +register_reboot_notifier (&tts_notifier);return 0 ; }
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 25/85 Introduce FW_BUG, FW_WARN and FW_INFO to consistenly tell users about BIOS bugs
In reply to Len BrownFrom: Thomas Renninger <[email protected]>
The idea is to add this to printk after the severity:printk(KERN_ERR FW_BUG "This is not our fault, BIOS developer: fix it by simply add ...\n");
If a Firmware issue should be hidden, because it is work-arounded, but you still want to see something popping up e.g. for info only:
printk(KERN_INFO FW_INFO "This is done stupid, we can handle it, but it should better be avoided in future\n");
or on the Linuxfirmwarekit to tell vendors that they did something stupid or wrong without bothering the user:
printk(KERN_INFO FW_BUG "This is done stupid, we can handle it, but it should better be avoided in future\n");
Some use cases:
- If a user sees a [Firmware Bug] message in the kernel he should first update the BIOS before wasting time with debugging and submiting on old firmware code to mailing lists.
- The linuxfirmwarekit (http://www.linuxfirmwarekit.org)
tries to detect firmware bugs. It currently is doing that in userspace which results in:
- Huge test scripts that could be a one liner in the kernel
- A lot of BIOS bugs are already absorbed by the kernel
What do we need such a stupid linuxfirmwarekit for?
- Vendors: Can test their BIOSes for Linux compatibility. There will be the time when vendors realize that the test utils on Linux are more strict and using them increases the qualitity and stability of their products.
- Vendors: Can easily fix up their BIOSes and be more Linux compatible by:
dmesg |grep "Firmware Bug"
and send the result to their BIOS developer colleagues who should know what the messages are about and how to fix them, without the need of studying kernel code.
- Distributions: can do a first automated HW/BIOS checks. This can then be done without the need of asking kernel developers who need to dig down the code and explain the details. Certification can/will just be rejected until
dmesg |grep "Firmware Bug" is empty.
- Thus this can be used as an instrument to enforce cleaner BIOS code. Currently every stupid Windows ACPI bug is re-implemented in Linux which is a rather unfortunate situation. We already have the power to avoid this in e.g. memory
or cpu hot-plug ACPI implementations, because Linux certification is a must for most vendors in the server area.
Working towards being able to do that in the laptop area (vendors are starting to look at Linux here also and will use this tool) is the goal. At least provide them a tool to make it as easy for this guys (e.g. not needing to browse kernel code) as possible.
- The ordinary Linux user: can go into the next shop, boots the firmwarekit on his most preferred machines. He chooses one without BIOS bugs. Unsupported HW is ok, he likes to try out latest projects which might support them or likes to dig on it on his own, but he hates to workaround broken BIOSes like hell.
I double checked with the firmwarekit.
There they have:
So the mapping generally is (also depending on how likely the BIOS is to blame, this could sometimes be difficult):
FW_INFO = INFO FW_WARN = WARN FW_BUG = FAIL
For more info about the linuxfirmwarekit and why this is needed can be found here:
http://www.linuxfirmwarekit.org
While severity matches with the firmwarekit, it might be tricky to hide messages from the user.
E.g. we recently found out that on HP BIOSes negative temperatures are returned, which seem to indicate that the thermal zone is invalid.
We can work around that gracefully by ignoring the thermal zone and we do not want to bother the ordinary user with a frightening
message: Firmware Bug: thermal management absolutely broken but want to hide it from the user.
But in the linuxfirmwarekit this should be shown as a real show stopper (the temperatures could really be wrong, broken thermal management is one of the worst things that can happen and the BIOS guys of the machine must implement this properly).
It is intended to do that (hide it from the user with KERN_INFO msg, but still print it as a BIOS bug) by:
printk(KERN_INFO FW_BUG "Negativ temperature values detected. Try to workarounded, BIOS must get fixed\n");
Hope that works out..., no idea how to better hide it as printk is the only way to easily provide this functionality.
--- include/linux/kernel.h | 24 ++++++++++++++++++++++++ 1 files changed, 24 insertions(+), 0 deletions(-)
include/linux/kernel.h +24 -0
@@ -190,6 +190,30 @@ extern int kernel_text_address(unsigned long addr);struct pid ;extern struct pid *session_of_pgrp (struct pid *pgrp); +/* +* FW_BUG +* Add this to a message where you are sure the firmware is buggy or behaves +* really stupid or out of spec. Be aware that the responsible BIOS developer +* should be able to fix this issue or at least get a concrete idea of the +* problem by reading your message without the need of looking at the kernel +* code. +* +* Use it for definite and high priority BIOS bugs. +* +* FW_WARN +* Use it for not that clear (e.g. could the kernel messed up things already?) +* and medium priority BIOS bugs. +* +* FW_INFO +* Use this one if you want to tell the user or vendor about something +* suspicious, but generally harmless related to the firmware. +* +* Use it for information or very low priority BIOS bugs. +*/ +#define FW_BUG "[Firmware Bug]: " +#define FW_WARN "[Firmware Warn]: " +#define FW_INFO "[Firmware Info]: " +#ifdef CONFIG_PRINTK asmlinkage int vprintk(const char *fmt, va_list args) __attribute__ ((format (printf,1 ,0 )));
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 26/85 ACPI: cpufreq, processor: Detect old BIOS, not supporting CPU freq on a recent CPU.
In reply to Len BrownFrom: Thomas Renninger <[email protected]>
On Intel CPUs it is rather common and a good hint that BIOSes which do provide _PPC func, but not the frequencies itself in _PSS function, are old and need to be updated for CPU freq support.
Tell the user/vendor he has a BIOS/firmware problem.
Make use of FW_BUG interface to give vendors and users the ability to automatically check with (or let linuxfirmwarekit do that):
dmesg |grep "Firmware Bug"
--- drivers/acpi/processor_perflib.c | 18 +++++++++++++++--- 1 files changed, 15 insertions(+), 3 deletions(-)
drivers/acpi/processor_perflib.c +15 -3
@@ -38,6 +38,7 @@#include <asm/uaccess.h> #endif +#include <asm/cpufeature.h> #include <acpi/acpi_bus.h> #include <acpi/processor.h>
@@ -334,7 +335,6 @@ static int acpi_processor_get_performance_info(struct acpi_processor *pr)acpi_status status =AE_OK ;acpi_handle handle =NULL ; -if (!pr || !pr->performance || !pr->handle)return -EINVAL ;
@@ -347,13 +347,25 @@ static int acpi_processor_get_performance_info(struct acpi_processor *pr) result =acpi_processor_get_performance_control (pr);if (result) -return result; + goto update_bios; result =acpi_processor_get_performance_states (pr);if (result) -return result; + goto update_bios;return 0 ; + +/* +* Having _PPC but missing frequencies (_PSS, _PCT) is a very good hint that +* the BIOS is older than the CPU and does not know its frequencies +*/ + update_bios: +if (ACPI_SUCCESS (acpi_get_handle (pr->handle,"_PPC" , &handle))){ +if (boot_cpu_has (X86_FEATURE_EST )) + printk(KERN_WARNING FW_BUG "BIOS needs update for CPU " +"frequency support\n" ); + } +return result; }int acpi_processor_notify_smm (struct module *calling_module)
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 27/85 CPUFREQ: powernow-k8: Try to detect old BIOS, not supporting CPU freq on a recent AMD CPUs.
In reply to Len BrownFrom: Thomas Renninger <[email protected]>
Make use of FW_BUG interface to give vendors and users the ability to automatically check for powernow-k8 related BIOS bugs by:
dmesg |grep "Firmware Bug"
--- arch/x86/kernel/cpu/cpufreq/powernow-k8.c | 42 ++++++++++++++++------------ 1 files changed, 24 insertions(+), 18 deletions(-)
arch/x86/kernel/cpu/cpufreq/powernow-k8.c +24 -18
@@ -45,7 +45,6 @@#endif #define PFX "powernow-k8: " -#define BFX PFX "BIOS error: "#define VERSION "version 2.20.00"#include "powernow-k8.h"
@@ -536,35 +535,40 @@ static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, u8for (j =0 ; j < data->numps; j++) {if (pst[j].vid >LEAST_VID ) { - printk(KERN_ERR PFX "vid %d invalid : 0x%x\n", j, pst[j].vid); + printk(KERN_ERR FW_BUG PFX "vid %d invalid : 0x%x\n", + j, pst[j].vid);return -EINVAL ; }if (pst[j].vid < data->rvo) {/* vid + rvo >= 0 */ - printk(KERN_ERR BFX "0 vid exceeded with pstate %d\n", j); + printk(KERN_ERR FW_BUG PFX "0 vid exceeded with pstate" + " %d\n", j);return -ENODEV ; }if (pst[j].vid < maxvid + data->rvo) {/* vid + rvo >= maxvid */ - printk(KERN_ERR BFX "maxvid exceeded with pstate %d\n", j); + printk(KERN_ERR FW_BUG PFX "maxvid exceeded with pstate" + " %d\n", j);return -ENODEV ; }if (pst[j].fid >MAX_FID ) { - printk(KERN_ERR BFX "maxfid exceeded with pstate %d\n", j); + printk(KERN_ERR FW_BUG PFX "maxfid exceeded with pstate" + " %d\n", j);return -ENODEV ; }if (j && (pst[j].fid <HI_FID_TABLE_BOTTOM )) {/* Only first fid is allowed to be in "low" range */ - printk(KERN_ERR BFX "two low fids - %d : 0x%x\n", j, pst[j].fid); + printk(KERN_ERR FW_BUG PFX "two low fids - %d : " + "0x%x\n", j, pst[j].fid);return -EINVAL ; }if (pst[j].fid < lastfid) lastfid = pst[j].fid; }if (lastfid &1 ) { - printk(KERN_ERR BFX "lastfid invalid\n"); + printk(KERN_ERR FW_BUG PFX "lastfid invalid\n");return -EINVAL ; }if (lastfid >LO_FID_TABLE_TOP ) - printk(KERN_INFO BFX "first fid not from lo freq table\n"); + printk(KERN_INFO FW_BUG PFX "first fid not from lo freq table\n");return 0 ; }
@@ -672,13 +676,13 @@ static int find_psb_table(struct powernow_k8_data *data)dprintk ("table vers: 0x%x\n" , psb->tableversion);if (psb->tableversion !=PSB_VERSION_1_4 ) { - printk(KERN_ERR BFX "PSB table is not v1.4\n"); + printk(KERN_ERR FW_BUG PFX "PSB table is not v1.4\n");return -ENODEV ; }dprintk ("flags: 0x%x\n" , psb->flags1);if (psb->flags1) { - printk(KERN_ERR BFX "unknown flags\n"); + printk(KERN_ERR FW_BUG PFX "unknown flags\n");return -ENODEV ; }
@@ -705,7 +709,7 @@ static int find_psb_table(struct powernow_k8_data *data) } }if (cpst !=1 ) { - printk(KERN_ERR BFX "numpst must be 1\n"); + printk(KERN_ERR FW_BUG PFX "numpst must be 1\n");return -ENODEV ; }
@@ -1130,17 +1134,19 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)"ACPI Processor module before starting this " "driver.\n");#else - printk(KERN_ERR PFX "Your BIOS does not provide ACPI " -"_PSS objects in a way that Linux understands. " -"Please report this to the Linux ACPI maintainers" - " and complain to your BIOS vendor.\n"); + printk(KERN_ERR FW_BUG PFX "Your BIOS does not provide" +" ACPI _PSS objects in a way that Linux " +"understands. Please report this to the Linux " +"ACPI maintainers and complain to your BIOS " + "vendor.\n");#endif kfree (data);return -ENODEV ; }if (pol->cpu !=0 ) { - printk(KERN_ERR PFX "No ACPI _PSS objects for CPU other than " - "CPU0. Complain to your BIOS vendor.\n"); + printk(KERN_ERR FW_BUG PFX "No ACPI _PSS objects for " +"CPU other than CPU0. Complain to your BIOS " + "vendor.\n");kfree (data);return -ENODEV ; }
@@ -1193,7 +1199,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)/* min/max the cpu is capable of */ if (cpufreq_frequency_table_cpuinfo (pol, data->powernow_table)) { - printk(KERN_ERR PFX "invalid powernow_table\n"); + printk(KERN_ERR FW_BUG PFX "invalid powernow_table\n");powernow_k8_cpu_exit_acpi (data);kfree (data->powernow_table);kfree (data);
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 28/85 ACPI: dock: avoid check _STA method
In reply to Len BrownFrom: Shaohua Li <[email protected]>
In some BIOSes, every _STA method call will send a notification again, this cause freeze. And in some BIOSes, it appears _STA should be called after _DCK. This tries to avoid calls _STA, and still keep the device present check.
http://bugzilla.kernel.org/show_bug.cgi?id=10431
--- drivers/acpi/dock.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-)
drivers/acpi/dock.c +4 -1
@@ -604,14 +604,17 @@ static int handle_eject_request(struct dock_station *ds, u32 event)static void dock_notify (acpi_handle handle,u32 event,void *data) {struct dock_station *ds = data; +struct acpi_device *tmp;switch (event) {case ACPI_NOTIFY_BUS_CHECK : -if (!dock_in_progress (ds) &&dock_present (ds)) { +if (!dock_in_progress (ds) &&acpi_bus_get_device (ds->handle, + &tmp)) {begin_dock (ds);dock (ds);if (!dock_present (ds)) { printk(KERN_ERR PREFIX "Unable to dock!\n"); +complete_dock (ds);break ; } atomic_notifier_call_chain(&dock_notifier_list,
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 29/85 dock: fix eject request process (2.6.27-rc1 regression)
In reply to Len BrownFrom: Shaohua Li <[email protected]>
commit 2a7feab28d3fc060d320eaba192e49dad1079b7e introduces a bug. My thinkpad actually will send an eject_request and we should follow the eject process to finish the eject, otherwise system still thinks the bay is present.
--- drivers/acpi/dock.c | 5 ----- 1 files changed, 0 insertions(+), 5 deletions(-)
drivers/acpi/dock.c +0 -5
@@ -575,11 +575,6 @@ static int handle_eject_request(struct dock_station *ds, u32 event)*/ dock_event (ds, event,UNDOCK_EVENT ); -if (!dock_present (ds)) { -complete_undock (ds); -return -ENODEV ; - } -hotplug_dock_devices (ds,ACPI_NOTIFY_EJECT_REQUEST );undock (ds);eject_dock (ds);
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 30/85 dock: add _LCK support
In reply to Len BrownFrom: Shaohua Li <[email protected]>
support _LCK method, which is a optional method for hotplug
lenb: we have not seen _LCK used in the field yet
--- drivers/acpi/dock.c | 21 +++++++++++++++++++++ 1 files changed, 21 insertions(+), 0 deletions(-)
drivers/acpi/dock.c +21 -0
@@ -452,6 +452,25 @@ static inline void complete_undock(struct dock_station *ds) ds->flags &= ~(DOCK_UNDOCKING ); } +static void dock_lock (struct dock_station *ds,int lock) +{ +struct acpi_object_list arg_list; +union acpi_object arg; +acpi_status status; + + arg_list.count =1 ; + arg_list.pointer = &arg; + arg.type =ACPI_TYPE_INTEGER ; + arg.integer.value = !!lock; + status =acpi_evaluate_object (ds->handle,"_LCK" , &arg_list,NULL ); +if (ACPI_FAILURE (status) && status !=AE_NOT_FOUND ) { +if (lock) + printk(KERN_WARNING PREFIX "Locking device failed\n"); +else + printk(KERN_WARNING PREFIX "Unlocking device failed\n"); + } +} +/** * dock_in_progress - see if we are in the middle of handling a dock event * @ds: the dock station
@@ -577,6 +596,7 @@ static int handle_eject_request(struct dock_station *ds, u32 event)hotplug_dock_devices (ds,ACPI_NOTIFY_EJECT_REQUEST );undock (ds); +dock_lock (ds,0 );eject_dock (ds);if (dock_present (ds)) { printk(KERN_ERR PREFIX "Unable to undock!\n");
@@ -617,6 +637,7 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)hotplug_dock_devices (ds, event);complete_dock (ds);dock_event (ds, event,DOCK_EVENT ); +dock_lock (ds,1 ); }break ;case ACPI_NOTIFY_DEVICE_CHECK :
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 31/85 dock: add bay and battery hotplug support
In reply to Len BrownFrom: Shaohua Li <[email protected]>
Make the dock driver support bay and battery hotplug. They are all regarded as dock, so handling can be unified.
--- drivers/acpi/dock.c | 223 ++++++++++++++++++++++++++++++++++++++++----------- 1 files changed, 175 insertions(+), 48 deletions(-)
drivers/acpi/dock.c +175 -48
@@ -48,7 +48,6 @@ MODULE_PARM_DESC(immediate_undock, "1 (default) will cause the driver to " " before undocking");static struct atomic_notifier_head dock_notifier_list; -static struct platform_device *dock_device;static char dock_device_name[] ="dock" ;static const struct acpi_device_id dock_device_ids[] = {
@@ -65,7 +64,12 @@ struct dock_station {struct mutex hp_lock;struct list_head dependent_devices;struct list_head hotplug_devices; + +struct list_head sibiling; +struct platform_device *dock_device; }; +static LIST_HEAD (dock_stations); +static int dock_station_count;struct dock_dependent_device {struct list_head list;
@@ -77,11 +81,12 @@ struct dock_dependent_device {#define DOCK_DOCKING 0x00000001#define DOCK_UNDOCKING 0x00000002 +#define DOCK_IS_DOCK 0x00000010 +#define DOCK_IS_ATA 0x00000020 +#define DOCK_IS_BAT 0x00000040#define DOCK_EVENT 3#define UNDOCK_EVENT 2 -static struct dock_station *dock_station; -/***************************************************************************** * Dock Dependent device functions * *****************************************************************************/
@@ -199,6 +204,60 @@ static int is_dock(acpi_handle handle)return 1 ; } +static int is_ejectable (acpi_handle handle) +{ +acpi_status status; +acpi_handle tmp; + + status =acpi_get_handle (handle,"_EJ0" , &tmp); +if (ACPI_FAILURE (status)) +return 0 ; +return 1 ; +} + +static int is_ata (acpi_handle handle) +{ +acpi_handle tmp; + +if ((ACPI_SUCCESS (acpi_get_handle (handle,"_GTF" , &tmp))) || + (ACPI_SUCCESS (acpi_get_handle (handle,"_GTM" , &tmp))) || + (ACPI_SUCCESS (acpi_get_handle (handle,"_STM" , &tmp))) || + (ACPI_SUCCESS (acpi_get_handle (handle,"_SDD" , &tmp)))) +return 1 ; + +return 0 ; +} + +static int is_battery (acpi_handle handle) +{ +struct acpi_device_info *info; +struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER ,NULL }; +int ret =1 ; + +if (!ACPI_SUCCESS (acpi_get_object_info (handle, &buffer))) +return 0 ; + info = buffer.pointer; +if (!(info->valid &ACPI_VALID_HID )) + ret =0 ; +else + ret = !strcmp ("PNP0C0A" , info->hardware_id.value); + +kfree (buffer.pointer); +return ret; +} + +static int is_ejectable_bay (acpi_handle handle) +{ +acpi_handle phandle; +if (!is_ejectable (handle)) +return 0 ; +if (is_battery (handle) ||is_ata (handle)) +return 1 ; +if (!acpi_get_parent (handle, &phandle) &&is_ata (phandle)) +return 1 ; +return 0 ; +} +/** * is_dock_device - see if a device is on a dock station * @handle: acpi handle of the device
@@ -209,11 +268,17 @@ static int is_dock(acpi_handle handle)*/ int is_dock_device (acpi_handle handle) { -if (!dock_station) +struct dock_station *dock_station; + +if (!dock_station_count)return 0 ; -if (is_dock (handle) ||find_dock_dependent_device (dock_station, handle)) +if (is_dock (handle))return 1 ; +list_for_each_entry (dock_station, &dock_stations, sibiling) { +if (find_dock_dependent_device (dock_station, handle)) +return 1 ; + }return 0 ; }
@@ -341,7 +406,7 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)static void dock_event (struct dock_station *ds,u32 event,int num) { -struct device *dev = &dock_device->dev; +struct device *dev = &ds->dock_device->dev;char event_string[13 ];char *envp[] = { event_string,NULL };
@@ -414,7 +479,7 @@ static void handle_dock(struct dock_station *ds, int dock) arg.type =ACPI_TYPE_INTEGER ; arg.integer.value = dock; status =acpi_evaluate_object (ds->handle,"_DCK" , &arg_list, &buffer); -if (ACPI_FAILURE (status)) +if (ACPI_FAILURE (status) && status !=AE_NOT_FOUND ) printk(KERN_ERR PREFIX "%s - failed to execute _DCK\n", (char *)name_buffer.pointer);kfree (buffer.pointer);
@@ -498,7 +563,7 @@ static int dock_in_progress(struct dock_station *ds)*/ int register_dock_notifier (struct notifier_block *nb) { -if (!dock_station) +if (!dock_station_count)return -ENODEV ;return atomic_notifier_chain_register (&dock_notifier_list, nb);
@@ -512,7 +577,7 @@ EXPORT_SYMBOL_GPL(register_dock_notifier);*/ void unregister_dock_notifier (struct notifier_block *nb) { -if (!dock_station) +if (!dock_station_count)return ;atomic_notifier_chain_unregister (&dock_notifier_list, nb);
@@ -535,20 +600,23 @@ register_hotplug_dock_device(acpi_handle handle, acpi_notify_handler handler, void *context) {struct dock_dependent_device *dd; +struct dock_station *dock_station; -if (!dock_station) +if (!dock_station_count)return -ENODEV ;/* * make sure this handle is for a device dependent on the dock, * this would include the dock station itself */ - dd =find_dock_dependent_device (dock_station, handle); -if (dd) { - dd->handler = handler; - dd->context = context; -dock_add_hotplug_device (dock_station, dd); -return 0 ; +list_for_each_entry (dock_station, &dock_stations, sibiling) { + dd =find_dock_dependent_device (dock_station, handle); +if (dd) { + dd->handler = handler; + dd->context = context; +dock_add_hotplug_device (dock_station, dd); +return 0 ; + } }return -EINVAL ;
@@ -563,13 +631,16 @@ EXPORT_SYMBOL_GPL(register_hotplug_dock_device);void unregister_hotplug_dock_device (acpi_handle handle) {struct dock_dependent_device *dd; +struct dock_station *dock_station; -if (!dock_station) +if (!dock_station_count)return ; - dd =find_dock_dependent_device (dock_station, handle); -if (dd) -dock_del_hotplug_device (dock_station, dd); +list_for_each_entry (dock_station, &dock_stations, sibiling) { + dd =find_dock_dependent_device (dock_station, handle); +if (dd) +dock_del_hotplug_device (dock_station, dd); + } }EXPORT_SYMBOL_GPL (unregister_hotplug_dock_device);
@@ -620,9 +691,28 @@ static void dock_notify(acpi_handle handle, u32 event, void *data) {struct dock_station *ds = data;struct acpi_device *tmp; +int surprise_removal =0 ; +/* +* According to acpi spec 3.0a, if a DEVICE_CHECK notification +* is sent and _DCK is present, it is assumed to mean an undock +* request. +*/ +if ((ds->flags &DOCK_IS_DOCK ) && event ==ACPI_NOTIFY_DEVICE_CHECK ) + event =ACPI_NOTIFY_EJECT_REQUEST ; + +/* +* dock station: BUS_CHECK - docked or surprise removal +* DEVICE_CHECK - undocked +* other device: BUS_CHECK/DEVICE_CHECK - added or surprise removal +* +* To simplify event handling, dock dependent device handler always +* get ACPI_NOTIFY_BUS_CHECK/ACPI_NOTIFY_DEVICE_CHECK for add and +* ACPI_NOTIFY_EJECT_REQUEST for removal +*/ switch (event) {case ACPI_NOTIFY_BUS_CHECK : +case ACPI_NOTIFY_DEVICE_CHECK :if (!dock_in_progress (ds) &&acpi_bus_get_device (ds->handle, &tmp)) {begin_dock (ds);
@@ -638,20 +728,17 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)complete_dock (ds);dock_event (ds, event,DOCK_EVENT );dock_lock (ds,1 ); +break ; } -break ; -case ACPI_NOTIFY_DEVICE_CHECK : -/* -* According to acpi spec 3.0a, if a DEVICE_CHECK notification -* is sent and _DCK is present, it is assumed to mean an -* undock request. This notify routine will only be called -* for objects defining _DCK, so we will fall through to eject -* request here. However, we will pass an eject request through -* to the driver who wish to hotplug. -*/ +if (dock_present (ds) ||dock_in_progress (ds)) +break ; +/* This is a surprise removal */ + surprise_removal =1 ; + event =ACPI_NOTIFY_EJECT_REQUEST ; +/* Fall back */ case ACPI_NOTIFY_EJECT_REQUEST :begin_undock (ds); -if (immediate_undock) +if (immediate_undock || surprise_removal)handle_eject_request (ds, event);else dock_event (ds, event,UNDOCK_EVENT );
@@ -707,6 +794,8 @@ fdd_out:static ssize_t show_docked (struct device *dev,struct device_attribute *attr,char *buf) { +struct dock_station *dock_station = *((struct dock_station **) + dev->platform_data);return snprintf (buf,PAGE_SIZE ,"%d\n" ,dock_present (dock_station)); }
@@ -718,6 +807,8 @@ static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL);static ssize_t show_flags (struct device *dev,struct device_attribute *attr,char *buf) { +struct dock_station *dock_station = *((struct dock_station **) + dev->platform_data);return snprintf (buf,PAGE_SIZE ,"%d\n" , dock_station->flags); }
@@ -730,6 +821,8 @@ static ssize_t write_undock(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int ret; +struct dock_station *dock_station = *((struct dock_station **) + dev->platform_data);if (!count)return -EINVAL ;
@@ -747,6 +840,8 @@ static ssize_t show_dock_uid(struct device *dev, struct device_attribute *attr, char *buf) { unsigned long lbuf; +struct dock_station *dock_station = *((struct dock_station **) + dev->platform_data);acpi_status status =acpi_evaluate_integer (dock_station->handle,"_UID" ,NULL , &lbuf);if (ACPI_FAILURE (status))
@@ -768,6 +863,8 @@ static int dock_add(acpi_handle handle)int ret;acpi_status status;struct dock_dependent_device *dd; +struct dock_station *dock_station; +struct platform_device *dock_device;/* allocate & initialize the dock_station private data */ dock_station =kzalloc (sizeof (*dock_station),GFP_KERNEL );
@@ -777,22 +874,34 @@ static int dock_add(acpi_handle handle) dock_station->last_dock_time = jiffies -HZ ;INIT_LIST_HEAD (&dock_station->dependent_devices);INIT_LIST_HEAD (&dock_station->hotplug_devices); +INIT_LIST_HEAD (&dock_station->sibiling);spin_lock_init (&dock_station->dd_lock);mutex_init (&dock_station->hp_lock);ATOMIC_INIT_NOTIFIER_HEAD (&dock_notifier_list);/* initialize platform device stuff */ - dock_device = -platform_device_register_simple (dock_device_name,0 ,NULL ,0 ); + dock_station->dock_device = +platform_device_register_simple (dock_device_name, + dock_station_count,NULL ,0 ); + dock_device = dock_station->dock_device;if (IS_ERR (dock_device)) {kfree (dock_station); dock_station =NULL ;return PTR_ERR (dock_device); } +platform_device_add_data (dock_device, &dock_station, +sizeof (struct dock_station *));/* we want the dock device to send uevents */ dock_device->dev.uevent_suppress =0 ; +if (is_dock (handle)) + dock_station->flags |=DOCK_IS_DOCK ; +if (is_ata (handle)) + dock_station->flags |=DOCK_IS_ATA ; +if (is_battery (handle)) + dock_station->flags |=DOCK_IS_BAT ; + ret =device_create_file (&dock_device->dev, &dev_attr_docked);if (ret) {printk ("Error %d adding sysfs file\n" , ret);
@@ -858,8 +967,8 @@ static int dock_add(acpi_handle handle) goto dock_add_err; } - printk(KERN_INFO PREFIX "%s\n", ACPI_DOCK_DRIVER_DESCRIPTION); - + dock_station_count++; +list_add (&dock_station->sibiling, &dock_stations);return 0 ; dock_add_err:
@@ -878,12 +987,13 @@ dock_add_err_unregister:/** * dock_remove - free up resources related to the dock station */ -static int dock_remove (void ) +static int dock_remove (struct dock_station *dock_station) {struct dock_dependent_device *dd, *tmp;acpi_status status; +struct platform_device *dock_device = dock_station->dock_device; -if (!dock_station) +if (!dock_station_count)return 0 ;/* remove dependent devices */
@@ -923,41 +1033,58 @@ static int dock_remove(void)static acpi_status find_dock (acpi_handle handle,u32 lvl,void *context,void **rv) { -int *count = context;acpi_status status =AE_OK ;if (is_dock (handle)) {if (dock_add (handle) >=0 ) { - (*count)++; status =AE_CTRL_TERMINATE ; } }return status; } -static int __init dock_init (void ) +static acpi_status +find_bay (acpi_handle handle,u32 lvl,void *context,void **rv) { -int num =0 ; - - dock_station =NULL ; +/* If bay is in a dock, it's already handled */ +if (is_ejectable_bay (handle) && !is_dock_device (handle)) +dock_add (handle); +return AE_OK ; +} +static int __init dock_init (void ) +{if (acpi_disabled)return 0 ;/* look for a dock station */ acpi_walk_namespace (ACPI_TYPE_DEVICE ,ACPI_ROOT_OBJECT , -ACPI_UINT32_MAX , find_dock, &num,NULL ); +ACPI_UINT32_MAX , find_dock,NULL ,NULL ); -if (!num) -printk (KERN_INFO "No dock devices found.\n" ); +/* look for bay */ +acpi_walk_namespace (ACPI_TYPE_DEVICE ,ACPI_ROOT_OBJECT , +ACPI_UINT32_MAX , find_bay,NULL ,NULL ); +if (!dock_station_count) { + printk(KERN_INFO PREFIX "No dock devices found.\n"); +return 0 ; + } + printk(KERN_INFO PREFIX "%s: %d docks/bays found\n", + ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count);return 0 ; } static void __exit dock_exit(void) { -dock_remove (); +struct dock_station *dock_station; + +list_for_each_entry (dock_station, &dock_stations, sibiling) +dock_remove (dock_station); } -postcore_initcall (dock_init); +/* +* Must be called before drivers of devices in dock, otherwise we can't know +* which devices are in a dock +*/ +subsys_initcall (dock_init);module_exit (dock_exit);
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 32/85 ACPI: introduce notifier change to avoid duplicates
In reply to Len BrownFrom: Shaohua Li <[email protected]>
The battery driver already registers notification handler. To avoid registering notification handler again, introduce a notifier chain in global system notifier handler and use it in dock driver.
--- drivers/acpi/bus.c | 15 +++++++++++++++ drivers/acpi/dock.c | 46 ++++++++++++++++++++++++---------------------- include/acpi/acpi_bus.h | 3 +++ 3 files changed, 42 insertions(+), 22 deletions(-)
drivers/acpi/bus.c +15 -0
@@ -496,6 +496,19 @@ static int acpi_bus_check_scope(struct acpi_device *device)return 0 ; } +static BLOCKING_NOTIFIER_HEAD (acpi_bus_notify_list); +int register_acpi_bus_notifier (struct notifier_block *nb) +{ +return blocking_notifier_chain_register (&acpi_bus_notify_list, nb); +} +EXPORT_SYMBOL_GPL (register_acpi_bus_notifier); + +void unregister_acpi_bus_notifier (struct notifier_block *nb) +{ +blocking_notifier_chain_unregister (&acpi_bus_notify_list, nb); +} +EXPORT_SYMBOL_GPL (unregister_acpi_bus_notifier); +/** * acpi_bus_notify * ---------------
@@ -506,6 +519,8 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)int result =0 ;struct acpi_device *device =NULL ; +blocking_notifier_call_chain (&acpi_bus_notify_list, + type, (void *)handle);if (acpi_bus_get_device (handle, &device))return ;
drivers/acpi/dock.c +24 -22
92 lines not on this page · raw message
include/acpi/acpi_bus.h +3 -0
@@ -327,6 +327,9 @@ int acpi_bus_get_private_data(acpi_handle, void **);extern int acpi_notifier_call_chain (struct acpi_device *,u32 ,u32 );extern int register_acpi_notifier (struct notifier_block *);extern int unregister_acpi_notifier (struct notifier_block *); + +extern int register_acpi_bus_notifier (struct notifier_block *nb); +extern void unregister_acpi_bus_notifier (struct notifier_block *nb);/* * External Functions */
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 33/85 ACPI: fix hotplug race
In reply to Len BrownFrom: Zhang Rui <[email protected]>
The hotplug notification handler and drivers' notification handler all run in one workqueue. Before hotplug removes an acpi device, the device driver's notification handler is already be recorded to run just after global notification handler. After hotplug notification handler runs, acpica will notice a NULL notification handler and crash.
So now we run run hotplug in another workqueue and wait for all acpi notication handlers finish.
This was found in battery hotplug, but actually all hotplug can be affected.
--- drivers/acpi/dock.c | 25 ++++++++++++++++++++++++- drivers/acpi/osl.c | 46 +++++++++++++++++++++++++++++++++++++++++----- include/acpi/acpiosxf.h | 3 +++ 3 files changed, 68 insertions(+), 6 deletions(-)
drivers/acpi/dock.c +24 -1
@@ -748,6 +748,20 @@ static void dock_notify(acpi_handle handle, u32 event, void *data) } } +struct dock_data { +acpi_handle handle; +unsigned long event; +struct dock_station *ds; +}; + +static void acpi_dock_deferred_cb (void *context) +{ +struct dock_data *data = (struct dock_data *)context; + +dock_notify (data->handle, data->event, data->ds); +kfree (data); +} +static int acpi_dock_notifier_call (struct notifier_block *this,unsigned long event,void *data) {
@@ -759,7 +773,16 @@ static int acpi_dock_notifier_call(struct notifier_block *this,return 0 ;list_for_each_entry (dock_station, &dock_stations, sibiling) {if (dock_station->handle == handle) { -dock_notify (handle, event, dock_station); +struct dock_data *dock_data; + + dock_data =kmalloc (sizeof (*dock_data),GFP_KERNEL ); +if (!dock_data) +return 0 ; + dock_data->handle = handle; + dock_data->event = event; + dock_data->ds = dock_station; +acpi_os_hotplug_execute (acpi_dock_deferred_cb, + dock_data);return 0 ; } }
drivers/acpi/osl.c +41 -5
76 lines not on this page · raw message
include/acpi/acpiosxf.h +3 -0
@@ -193,6 +193,9 @@ acpi_status acpi_os_execute(acpi_execute_type type, acpi_osd_exec_callback function, void *context); +acpi_status +acpi_os_hotplug_execute (acpi_osd_exec_callback function,void *context); +void acpi_os_wait_events_complete (void *context);void acpi_os_sleep (acpi_integer milliseconds);
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 34/85 libata: remove functions now handed by ACPI dock driver
In reply to Len BrownFrom: Shaohua Li <[email protected]>
dock driver can handle ata(bay) hotplug now. dock driver already handles _EJ0 and _STA, so remove them. Also libata doesn't need register notification handler anymore.
--- drivers/acpi/dock.c | 3 +- drivers/ata/libata-acpi.c | 107 ++++++--------------------------------------- 2 files changed, 16 insertions(+), 94 deletions(-)
drivers/acpi/dock.c +2 -1
@@ -738,7 +738,8 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)/* Fall back */ case ACPI_NOTIFY_EJECT_REQUEST :begin_undock (ds); -if (immediate_undock || surprise_removal) +if ((immediate_undock && !(ds->flags &DOCK_IS_ATA )) + || surprise_removal)handle_eject_request (ds, event);else dock_event (ds, event,UNDOCK_EVENT );
drivers/ata/libata-acpi.c +14 -93
175 lines not on this page · raw message
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 35/85 dock: introduce .uevent for devices in dock, eg libata
In reply to Len BrownFrom: Shaohua Li <[email protected]>
dock's uevent reported itself, not ata. It might be difficult to find an ata device just according to a dock. This patch introduces docking ops for each device in a dock. when docking, dock driver can send device specific uevent. This should help dock station too (not just bay)
--- drivers/acpi/dock.c | 22 ++++++++++++----- drivers/ata/libata-acpi.c | 44 ++++++++++++++++++++++++++++++++++- drivers/pci/hotplug/acpiphp_glue.c | 6 +++- include/acpi/acpi_drivers.h | 9 +++++- 4 files changed, 68 insertions(+), 13 deletions(-)
drivers/acpi/dock.c +15 -7
@@ -75,7 +75,7 @@ struct dock_dependent_device {struct list_head list;struct list_head hotplug_list;acpi_handle handle; -acpi_notify_handler handler; +struct acpi_dock_ops *ops;void *context; };
@@ -385,8 +385,8 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)* First call driver specific hotplug functions */ list_for_each_entry (dd, &ds->hotplug_devices, hotplug_list) { -if (dd->handler) - dd->handler (dd->handle, event, dd->context); +if (dd->ops && dd->ops->handler) + dd->ops->handler (dd->handle, event, dd->context); }/*
@@ -409,6 +409,7 @@ static void dock_event(struct dock_station *ds, u32 event, int num)struct device *dev = &ds->dock_device->dev;char event_string[13 ];char *envp[] = { event_string,NULL }; +struct dock_dependent_device *dd;if (num ==UNDOCK_EVENT )sprintf (event_string,"EVENT=undock" );
@@ -419,7 +420,14 @@ static void dock_event(struct dock_station *ds, u32 event, int num)* Indicate that the status of the dock station has * changed. */ -kobject_uevent_env (&dev->kobj,KOBJ_CHANGE , envp); +if (num ==DOCK_EVENT ) +kobject_uevent_env (&dev->kobj,KOBJ_CHANGE , envp); + +list_for_each_entry (dd, &ds->hotplug_devices, hotplug_list) +if (dd->ops && dd->ops->uevent) + dd->ops->uevent (dd->handle, event, dd->context); +if (num !=DOCK_EVENT ) +kobject_uevent_env (&dev->kobj,KOBJ_CHANGE , envp); }/**
@@ -588,7 +596,7 @@ EXPORT_SYMBOL_GPL(unregister_dock_notifier);/** * register_hotplug_dock_device - register a hotplug function * @handle: the handle of the device -* @handler: the acpi_notifier_handler to call after docking +* @ops: handlers to call after docking * @context: device specific data * * If a driver would like to perform a hotplug operation after a dock
@@ -596,7 +604,7 @@ EXPORT_SYMBOL_GPL(unregister_dock_notifier);* the dock driver after _DCK is executed. */ int -register_hotplug_dock_device (acpi_handle handle,acpi_notify_handler handler, +register_hotplug_dock_device (acpi_handle handle,struct acpi_dock_ops *ops,void *context) {struct dock_dependent_device *dd;
@@ -612,7 +620,7 @@ register_hotplug_dock_device(acpi_handle handle, acpi_notify_handler handler,list_for_each_entry (dock_station, &dock_stations, sibiling) { dd =find_dock_dependent_device (dock_station, handle);if (dd) { - dd->handler = handler; + dd->ops = ops; dd->context = context;dock_add_hotplug_device (dock_station, dd);return 0 ;
drivers/ata/libata-acpi.c +42 -2
62 lines not on this page · raw message
drivers/pci/hotplug/acpiphp_glue.c +4 -2
@@ -169,7 +169,9 @@ static int post_dock_fixups(struct notifier_block *nb, unsigned long val, } - +static struct acpi_dock_ops acpiphp_dock_ops = { + .handler = handle_hotplug_event_func, +};/* callback routine to register each ACPI PCI slot object */ static acpi_status
@@ -285,7 +287,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)*/ newfunc->flags &= ~FUNC_HAS_EJ0 ;if (register_hotplug_dock_device (handle, - handle_hotplug_event_func, newfunc)) + &acpiphp_dock_ops, newfunc))dbg ("failed to register dock device\n" );/* we need to be notified when dock events happen
include/acpi/acpi_drivers.h +7 -2
@@ -115,12 +115,17 @@ int acpi_processor_set_thermal_limit(acpi_handle handle, int type);/*-------------------------------------------------------------------------- Dock Station -------------------------------------------------------------------------- */ +struct acpi_dock_ops { +acpi_notify_handler handler; +acpi_notify_handler uevent; +}; +#if defined(CONFIG_ACPI_DOCK ) || defined(CONFIG_ACPI_DOCK_MODULE )extern int is_dock_device (acpi_handle handle);extern int register_dock_notifier (struct notifier_block *nb);extern void unregister_dock_notifier (struct notifier_block *nb);extern int register_hotplug_dock_device (acpi_handle handle, -acpi_notify_handler handler, +struct acpi_dock_ops *ops,void *context);extern void unregister_hotplug_dock_device (acpi_handle handle);#else
@@ -136,7 +141,7 @@ static inline void unregister_dock_notifier(struct notifier_block *nb) { }static inline int register_hotplug_dock_device (acpi_handle handle, -acpi_notify_handler handler, +struct acpi_dock_ops *ops,void *context) {return -ENODEV ;
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 36/85 bay: remove driver, all functions now handled by dock driver
In reply to Len BrownFrom: Shaohua Li <[email protected]>
--- drivers/acpi/Kconfig | 11 +- drivers/acpi/Makefile | 1 - drivers/acpi/bay.c | 411 ------------------------------------------------- 3 files changed, 2 insertions(+), 421 deletions(-) delete mode 100644 drivers/acpi/bay.c
drivers/acpi/Kconfig +2 -9
@@ -160,15 +160,8 @@ config ACPI_DOCK tristate "Dock" depends on EXPERIMENTAL help - This driver adds support for ACPI controlled docking stations - -config ACPI_BAY - tristate "Removable Drive Bay (EXPERIMENTAL)" - depends on EXPERIMENTAL - depends on ACPI_DOCK - help - This driver adds support for ACPI controlled removable drive - bays such as the IBM ultrabay or the Dell Module Bay. + This driver adds support for ACPI controlled docking stations and removable + drive bays such as the IBM ultrabay or the Dell Module Bay. config ACPI_PROCESSOR tristate "Processor"
drivers/acpi/Makefile +0 -1
@@ -45,7 +45,6 @@ obj-$(CONFIG_ACPI_BATTERY) += battery.o obj-$(CONFIG_ACPI_BUTTON) += button.o obj-$(CONFIG_ACPI_FAN) += fan.o obj-$(CONFIG_ACPI_DOCK) += dock.o -obj-$(CONFIG_ACPI_BAY) += bay.o obj-$(CONFIG_ACPI_VIDEO) += video.o obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o
drivers/acpi/bay.c deleted +0 -411
411 lines not on this page · raw message
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 37/85 dock: fix for ATA bay in a dock station
In reply to Len BrownFrom: Shaohua Li <[email protected]>
an ATA bay can be in a dock and itself can be ejected separately. This patch handles such eject bay. Found by Holger.
--- drivers/acpi/dock.c | 14 ++++++++++---- 1 files changed, 10 insertions(+), 4 deletions(-)
drivers/acpi/dock.c +10 -4
@@ -609,6 +609,7 @@ register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops, {struct dock_dependent_device *dd;struct dock_station *dock_station; +int ret = -EINVAL ;if (!dock_station_count)return -ENODEV ;
@@ -618,16 +619,21 @@ register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops,* this would include the dock station itself */ list_for_each_entry (dock_station, &dock_stations, sibiling) { +/* +* An ATA bay can be in a dock and itself can be ejected +* seperately, so there are two 'dock stations' which need the +* ops +*/ dd =find_dock_dependent_device (dock_station, handle);if (dd) { dd->ops = ops; dd->context = context;dock_add_hotplug_device (dock_station, dd); -return 0 ; + ret =0 ; } } -return -EINVAL ; +return ret; }EXPORT_SYMBOL_GPL (register_hotplug_dock_device);
@@ -1078,8 +1084,8 @@ find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)static acpi_status find_bay (acpi_handle handle,u32 lvl,void *context,void **rv) { -/* If bay is in a dock, it's already handled */ -if (is_ejectable_bay (handle) && !is_dock_device (handle)) +/* If bay is a dock, it's already handled */ +if (is_ejectable_bay (handle) && !is_dock (handle))dock_add (handle);return AE_OK ; }
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 38/85 dock: add 'type' sysfs file
In reply to Len BrownFrom: Shaohua Li <[email protected]>
add a sysfs file to present dock type. Suggested by Holger.
--- drivers/acpi/dock.c | 25 +++++++++++++++++++++++++ 1 files changed, 25 insertions(+), 0 deletions(-)
drivers/acpi/dock.c +25 -0
@@ -911,6 +911,26 @@ static ssize_t show_dock_uid(struct device *dev, } static DEVICE_ATTR(uid, S_IRUGO, show_dock_uid, NULL); +static ssize_t show_dock_type (struct device *dev, +struct device_attribute *attr,char *buf) +{ +struct dock_station *dock_station = *((struct dock_station **) + dev->platform_data); +char *type; + +if (dock_station->flags &DOCK_IS_DOCK ) + type ="dock_station" ; +else if (dock_station->flags &DOCK_IS_ATA ) + type ="ata_bay" ; +else if (dock_station->flags &DOCK_IS_BAT ) + type ="battery_bay" ; +else + type ="unknown" ; + +return snprintf (buf,PAGE_SIZE ,"%s\n" , type); +} +static DEVICE_ATTR(type, S_IRUGO, show_dock_type, NULL); +/** * dock_add - add a new dock station * @handle: the dock station handle
@@ -999,6 +1019,9 @@ static int dock_add(acpi_handle handle) dock_station =NULL ;return ret; } + ret =device_create_file (&dock_device->dev, &dev_attr_type); +if (ret) +printk (KERN_ERR "Error %d adding sysfs file\n" , ret);/* Find dependent devices */ acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
@@ -1020,6 +1043,7 @@ static int dock_add(acpi_handle handle)return 0 ; dock_add_err_unregister: +device_remove_file (&dock_device->dev, &dev_attr_type);device_remove_file (&dock_device->dev, &dev_attr_docked);device_remove_file (&dock_device->dev, &dev_attr_undock);device_remove_file (&dock_device->dev, &dev_attr_uid);
@@ -1047,6 +1071,7 @@ static int dock_remove(struct dock_station *dock_station)kfree (dd);/* cleanup sysfs */ +device_remove_file (&dock_device->dev, &dev_attr_type);device_remove_file (&dock_device->dev, &dev_attr_docked);device_remove_file (&dock_device->dev, &dev_attr_undock);device_remove_file (&dock_device->dev, &dev_attr_uid);
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 39/85 dock: Shaohua Li is new maintainer
In reply to Len BrownFrom: Len Brown <[email protected]>
--- MAINTAINERS | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
MAINTAINERS +2 -2
@@ -1417,8 +1417,8 @@ M: [email protected] S: Maintained DOCKING STATION DRIVER -P: Kristen Carlson Accardi -M: [email protected] +P: Shaohua Li +M: [email protected] L: [email protected] S: Supported
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 40/85 ACPI suspend: Always use the 32-bit waking vector
In reply to Len BrownFrom: Rafael J. Wysocki <[email protected]>
According to the ACPI specification 2.0c and later, the 64-bit waking vector should be cleared and the 32-bit waking vector should be used, unless we want the wake-up code to be called by the BIOS in Protected Mode. Moreover, some systems (for example HP dv5-1004nr) are known to fail to resume if the 64-bit waking vector is used. Therefore, modify the code to clear the 64-bit waking vector, for FACS version 1 or greater, and set the 32-bit one before suspend.
--- drivers/acpi/hardware/hwsleep.c | 39 ++++++++++++--------------------------- 1 files changed, 12 insertions(+), 27 deletions(-)
drivers/acpi/hardware/hwsleep.c +11 -26
@@ -78,19 +78,17 @@ acpi_set_firmware_waking_vector(acpi_physical_address physical_address)return_ACPI_STATUS (status); } -/* Set the vector */ +/* +* According to the ACPI specification 2.0c and later, the 64-bit +* waking vector should be cleared and the 32-bit waking vector should +* be used, unless we want the wake-up code to be called by the BIOS in +* Protected Mode. Some systems (for example HP dv5-1004nr) are known +* to fail to resume if the 64-bit vector is used. +*/ +if (facs->version >=1 ) + facs->xfirmware_waking_vector =0 ; -if ((facs->length <32 ) || (!(facs->xfirmware_waking_vector))) { -/* -* ACPI 1.0 FACS or short table or optional X_ field is zero -*/ - facs->firmware_waking_vector = (u32 ) physical_address; - }else { -/* -* ACPI 2.0 FACS with valid X_ field -*/ - facs->xfirmware_waking_vector = physical_address; - } + facs->firmware_waking_vector = (u32 )physical_address;return_ACPI_STATUS (AE_OK ); }
@@ -134,20 +132,7 @@ acpi_get_firmware_waking_vector(acpi_physical_address * physical_address) }/* Get the vector */ - -if ((facs->length <32 ) || (!(facs->xfirmware_waking_vector))) { -/* -* ACPI 1.0 FACS or short table or optional X_ field is zero -*/ - *physical_address = - (acpi_physical_address ) facs->firmware_waking_vector; - }else { -/* -* ACPI 2.0 FACS with valid X_ field -*/ - *physical_address = - (acpi_physical_address ) facs->xfirmware_waking_vector; - } + *physical_address = (acpi_physical_address )facs->firmware_waking_vector;return_ACPI_STATUS (AE_OK ); }
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 41/85 panasonic-laptop: add Panasonic Let's Note laptop extras driver v0.94
In reply to Len BrownFrom: Harald Welte <[email protected]>
This is a driver for ACPI extras such as hotkeys and backlight brightness control on various Panasonic "Let's Note" series laptop computers.
It exports the backlight via the backlight class device API, and the hotkeys as input event device. Some more esoteric items like number of installed batteries are exported via sysfs device attributes.
Hotkey events also generate old-style ACPI enents through /proc/acpi/event to interoperate with current versions of acpid.
--- MAINTAINERS | 5 + drivers/misc/Kconfig | 11 + drivers/misc/Makefile | 1 + drivers/misc/panasonic-laptop.c | 767 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 784 insertions(+), 0 deletions(-) create mode 100644 drivers/misc/panasonic-laptop.c
MAINTAINERS +5 -0
@@ -3148,6 +3148,11 @@ M: [email protected] L: [email protected] S: Maintained +PANASONIC LAPTOP ACPI EXTRAS DRIVER +P: Harald Welte +M: [email protected] +S: Maintained + PARALLEL PORT SUPPORT L: [email protected] (subscribers-only) S: Orphan
drivers/misc/Kconfig +11 -0
@@ -245,6 +245,17 @@ config MSI_LAPTOP If you have an MSI S270 laptop, say Y or M here. +config PANASONIC_LAPTOP + tristate "Panasonic Laptop Extras" + depends on X86 && INPUT + depends on BACKLIGHT_CLASS_DEVICE + ---help--- + This driver adds support for access to backlight control and hotkeys + on Panasonic Let's Note laptops. + + If you have a Panasonic Let's note laptop (such as the R1(N variant), + R2, R3, R5, T2, W2 and Y2 series), say Y. + config COMPAL_LAPTOP tristate "Compal Laptop Extras" depends on X86
drivers/misc/Makefile +1 -0
@@ -23,6 +23,7 @@ obj-$(CONFIG_SGI_IOC4) += ioc4.o obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o obj-$(CONFIG_FUJITSU_LAPTOP) += fujitsu-laptop.o +obj-$(CONFIG_PANASONIC_LAPTOP) += panasonic-laptop.o obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o obj-$(CONFIG_INTEL_MENLOW) += intel_menlow.o obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o
drivers/misc/panasonic-laptop.c new file +767 -0
767 lines not on this page · raw message
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 42/85 ACPI: EC: do transaction from interrupt context
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
It is easier and faster to do transaction directly from interrupt context rather than waking control thread.
Also, cleaner GPE storm avoidance is implemented.
References: http://bugzilla.kernel.org/show_bug.cgi?id=9998
http://bugzilla.kernel.org/show_bug.cgi?id=10724 http://bugzilla.kernel.org/show_bug.cgi?id=10919 http://bugzilla.kernel.org/show_bug.cgi?id=11309 http://bugzilla.kernel.org/show_bug.cgi?id=11549
--- drivers/acpi/ec.c | 309 +++++++++++++++++++++++++--------------------------- 1 files changed, 149 insertions(+), 160 deletions(-)
drivers/acpi/ec.c +149 -160
@@ -1,7 +1,7 @@/* -* ec.c - ACPI Embedded Controller Driver (v2.0) +* ec.c - ACPI Embedded Controller Driver (v2.1) * -* Copyright (C) 2006, 2007 Alexey Starikovskiy <[email protected]> +* Copyright (C) 2006-2008 Alexey Starikovskiy <[email protected]> * Copyright (C) 2006 Denis Sadykov <[email protected]> * Copyright (C) 2004 Luming Yu <[email protected]> * Copyright (C) 2001, 2002 Andy Grover <[email protected]>
@@ -26,7 +26,7 @@* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/* Uncomment next line to get verbose print outs*/ +/* Uncomment next line to get verbose printout */ /* #define DEBUG */ #include <linux/kernel.h>
@@ -38,6 +38,7 @@#include <linux/seq_file.h> #include <linux/interrupt.h> #include <linux/list.h> +#include <linux/spinlock.h> #include <asm/io.h> #include <acpi/acpi_bus.h> #include <acpi/acpi_drivers.h>
@@ -65,22 +66,21 @@ enum ec_command { ACPI_EC_COMMAND_QUERY = 0x84, }; -/* EC events */ -enum ec_event { -ACPI_EC_EVENT_OBF_1 =1 ,/* Output buffer full */ -ACPI_EC_EVENT_IBF_0 ,/* Input buffer empty */ -}; -#define ACPI_EC_DELAY 500/* Wait 500ms max. during EC ops */ #define ACPI_EC_UDELAY_GLK 1000/* Wait 1ms max. to get global lock */ #define ACPI_EC_UDELAY 100/* Wait 100us before polling EC again */ +#define ACPI_EC_STORM_THRESHOLD 20/* number of false interrupts +per one transaction */ +enum { -EC_FLAGS_WAIT_GPE =0 ,/* Don't check status until GPE arrives */ EC_FLAGS_QUERY_PENDING ,/* Query is pending */ -EC_FLAGS_GPE_MODE ,/* Expect GPE to be sent for status change */ +EC_FLAGS_GPE_MODE ,/* Expect GPE to be sent +* for status change */ EC_FLAGS_NO_GPE ,/* Don't use GPE mode */ -EC_FLAGS_RESCHEDULE_POLL /* Re-schedule poll */ +EC_FLAGS_GPE_STORM ,/* GPE storm detected */ +EC_FLAGS_HANDLERS_INSTALLED /* Handlers for GPE and +* OpReg are installed */ };/* If we find an EC via the ECDT, we need to keep a ptr to its context */
@@ -95,6 +95,14 @@ struct acpi_ec_query_handler {u8 query_bit; }; +struct transaction_data { +const u8 *wdata; +u8 *rdata; +unsigned short irq_count; +u8 wlen; +u8 rlen; +}; + static struct acpi_ec { acpi_handle handle; unsigned long gpe;
@@ -105,9 +113,8 @@ static struct acpi_ec {struct mutex lock;wait_queue_head_t wait;struct list_head list; -struct delayed_work work; -atomic_t irq_count; -u8 handlers_installed; +struct transaction_data *t; +spinlock_t t_lock; } *boot_ec, *first_ec;/*
@@ -150,7 +157,7 @@ static inline u8 acpi_ec_read_data(struct acpi_ec *ec) {u8 x =inb (ec->data_addr);pr_debug (PREFIX "---> data = 0x%2.2x\n" , x); -return inb (ec->data_addr); +return x; }static inline void acpi_ec_write_cmd (struct acpi_ec *ec,u8 command)
@@ -165,68 +172,79 @@ static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data)outb (data, ec->data_addr); } -static inline int acpi_ec_check_status (struct acpi_ec *ec,enum ec_event event) +static int ec_transaction_done (struct acpi_ec *ec) { -if (test_bit (EC_FLAGS_WAIT_GPE , &ec->flags)) -return 0 ; -if (event ==ACPI_EC_EVENT_OBF_1 ) { -if (acpi_ec_read_status (ec) &ACPI_EC_FLAG_OBF ) -return 1 ; - }else if (event ==ACPI_EC_EVENT_IBF_0 ) { -if (!(acpi_ec_read_status (ec) &ACPI_EC_FLAG_IBF )) -return 1 ; - } - -return 0 ; +unsigned long flags; +int ret =0 ; +spin_lock_irqsave (&ec->t_lock, flags); +if (!ec->t || (!ec->t->wlen && !ec->t->rlen)) + ret =1 ; +spin_unlock_irqrestore (&ec->t_lock, flags); +return ret; } -static void ec_schedule_ec_poll (struct acpi_ec *ec) +static void gpe_transaction (struct acpi_ec *ec,u8 status) { -if (test_bit (EC_FLAGS_RESCHEDULE_POLL , &ec->flags)) -schedule_delayed_work (&ec->work, -msecs_to_jiffies (ACPI_EC_DELAY )); +unsigned long flags; +spin_lock_irqsave (&ec->t_lock, flags); +if (!ec->t) + goto unlock; +if (ec->t->wlen >0 ) { +if ((status &ACPI_EC_FLAG_IBF ) ==0 ) { +acpi_ec_write_data (ec, *(ec->t->wdata++)); + --ec->t->wlen; + }else +/* false interrupt, state didn't change */ + ++ec->t->irq_count; + + }else if (ec->t->rlen >0 ) { +if ((status &ACPI_EC_FLAG_OBF ) ==1 ) { + *(ec->t->rdata++) =acpi_ec_read_data (ec); + --ec->t->rlen; + }else +/* false interrupt, state didn't change */ + ++ec->t->irq_count; + } +unlock: +spin_unlock_irqrestore (&ec->t_lock, flags); } -static void ec_switch_to_poll_mode (struct acpi_ec *ec) +static int acpi_ec_wait (struct acpi_ec *ec) { +if (wait_event_timeout (ec->wait,ec_transaction_done (ec), +msecs_to_jiffies (ACPI_EC_DELAY ))) +return 0 ; +/* missing GPEs, switch back to poll mode */ +if (printk_ratelimit ()) +pr_info (PREFIX "missing confirmations, " +"switch off interrupt mode.\n" );set_bit (EC_FLAGS_NO_GPE , &ec->flags);clear_bit (EC_FLAGS_GPE_MODE , &ec->flags); -acpi_disable_gpe (NULL , ec->gpe,ACPI_NOT_ISR ); -set_bit (EC_FLAGS_RESCHEDULE_POLL , &ec->flags); +return 1 ; } -static int acpi_ec_wait (struct acpi_ec *ec,enum ec_event event,int force_poll) +static void acpi_ec_gpe_query (void *ec_cxt); + +static int ec_check_sci (struct acpi_ec *ec,u8 state) { -atomic_set (&ec->irq_count,0 ); -if (likely (test_bit (EC_FLAGS_GPE_MODE , &ec->flags)) && -likely (!force_poll)) { -if (wait_event_timeout (ec->wait,acpi_ec_check_status (ec, event), -msecs_to_jiffies (ACPI_EC_DELAY ))) -return 0 ; -clear_bit (EC_FLAGS_WAIT_GPE , &ec->flags); -if (acpi_ec_check_status (ec, event)) { -/* missing GPEs, switch back to poll mode */ -if (printk_ratelimit ()) -pr_info (PREFIX "missing confirmations, " -"switch off interrupt mode.\n" ); -ec_switch_to_poll_mode (ec); -ec_schedule_ec_poll (ec); -return 0 ; - } - }else { -unsigned long delay = jiffies +msecs_to_jiffies (ACPI_EC_DELAY ); -clear_bit (EC_FLAGS_WAIT_GPE , &ec->flags); -while (time_before (jiffies, delay)) { -if (acpi_ec_check_status (ec, event)) -return 0 ; -msleep (1 ); - } -if (acpi_ec_check_status (ec,event)) +if (state &ACPI_EC_FLAG_SCI ) { +if (!test_and_set_bit (EC_FLAGS_QUERY_PENDING , &ec->flags)) +return acpi_os_execute (OSL_EC_BURST_HANDLER , + acpi_ec_gpe_query, ec); + } +return 0 ; +} + +static int ec_poll (struct acpi_ec *ec) +{ +unsigned long delay = jiffies +msecs_to_jiffies (ACPI_EC_DELAY ); +msleep (1 ); +while (time_before (jiffies, delay)) { +gpe_transaction (ec,acpi_ec_read_status (ec)); +msleep (1 ); +if (ec_transaction_done (ec))return 0 ; } -pr_err (PREFIX "acpi_ec_wait timeout, status = 0x%2.2x, event = %s\n" , -acpi_ec_read_status (ec), - (event ==ACPI_EC_EVENT_OBF_1 ) ?"\"b0=1\"" :"\"b1=0\"" );return -ETIME ; }
@@ -235,45 +253,51 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, u8 * rdata, unsigned rdata_len, int force_poll) { - int result = 0; -set_bit (EC_FLAGS_WAIT_GPE , &ec->flags); + unsigned long tmp; +struct transaction_data t = {.wdata = wdata, .rdata = rdata, + .wlen = wdata_len, .rlen = rdata_len, + .irq_count =0 }; +int ret =0 ;pr_debug (PREFIX "transaction start\n" ); -acpi_ec_write_cmd (ec, command); -for (; wdata_len >0 ; --wdata_len) { - result =acpi_ec_wait (ec,ACPI_EC_EVENT_IBF_0 , force_poll); -if (result) { -pr_err (PREFIX -"write_cmd timeout, command = %d\n" , command); - goto end; - } -set_bit (EC_FLAGS_WAIT_GPE , &ec->flags); -acpi_ec_write_data (ec, *(wdata++)); +/* disable GPE during transaction if storm is detected */ +if (test_bit (EC_FLAGS_GPE_STORM , &ec->flags)) { +clear_bit (EC_FLAGS_GPE_MODE , &ec->flags); +acpi_disable_gpe (NULL , ec->gpe,ACPI_NOT_ISR ); } - -if (!rdata_len) { - result =acpi_ec_wait (ec,ACPI_EC_EVENT_IBF_0 , force_poll); -if (result) { -pr_err (PREFIX -"finish-write timeout, command = %d\n" , command); - goto end; - } - }else if (command ==ACPI_EC_COMMAND_QUERY ) +/* start transaction */ +spin_lock_irqsave (&ec->t_lock, tmp); +/* following two actions should be kept atomic */ + ec->t = &t; +acpi_ec_write_cmd (ec, command); +if (command ==ACPI_EC_COMMAND_QUERY )clear_bit (EC_FLAGS_QUERY_PENDING , &ec->flags); - -for (; rdata_len >0 ; --rdata_len) { - result =acpi_ec_wait (ec,ACPI_EC_EVENT_OBF_1 , force_poll); -if (result) { -pr_err (PREFIX "read timeout, command = %d\n" , command); - goto end; - } -/* Don't expect GPE after last read */ -if (rdata_len >1 ) -set_bit (EC_FLAGS_WAIT_GPE , &ec->flags); - *(rdata++) =acpi_ec_read_data (ec); - } - end: +spin_unlock_irqrestore (&ec->t_lock, tmp); +/* if we selected poll mode or failed in GPE-mode do a poll loop */ +if (force_poll || + !test_bit (EC_FLAGS_GPE_MODE , &ec->flags) || +acpi_ec_wait (ec)) + ret =ec_poll (ec);pr_debug (PREFIX "transaction end\n" ); -return result; +spin_lock_irqsave (&ec->t_lock, tmp); + ec->t =NULL ; +spin_unlock_irqrestore (&ec->t_lock, tmp); +if (test_bit (EC_FLAGS_GPE_STORM , &ec->flags)) { +/* check if we received SCI during transaction */ +ec_check_sci (ec,acpi_ec_read_status (ec)); +/* it is safe to enable GPE outside of transaction */ +acpi_enable_gpe (NULL , ec->gpe,ACPI_NOT_ISR ); + }else if (test_bit (EC_FLAGS_GPE_MODE , &ec->flags) && + t.irq_count >ACPI_EC_STORM_THRESHOLD ) { +pr_debug (PREFIX "GPE storm detected\n" ); +set_bit (EC_FLAGS_GPE_STORM , &ec->flags); + } +return ret; +} + +static int ec_check_ibf0 (struct acpi_ec *ec) +{ +u8 status =acpi_ec_read_status (ec); +return (status &ACPI_EC_FLAG_IBF ) ==0 ; } static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
@@ -283,40 +307,34 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, {int status;u32 glk; -if (!ec || (wdata_len && !wdata) || (rdata_len && !rdata))return -EINVAL ; -if (rdata)memset (rdata,0 , rdata_len); -mutex_lock (&ec->lock);if (ec->global_lock) { status =acpi_acquire_global_lock (ACPI_EC_UDELAY_GLK , &glk);if (ACPI_FAILURE (status)) { -mutex_unlock (&ec->lock); -return -ENODEV ; + status = -ENODEV ; + goto unlock; } } - - status =acpi_ec_wait (ec,ACPI_EC_EVENT_IBF_0 ,0 ); -if (status) { +if (!wait_event_timeout (ec->wait,ec_check_ibf0 (ec), +msecs_to_jiffies (ACPI_EC_DELAY ))) {pr_err (PREFIX "input buffer is not empty, " "aborting transaction\n" ); + status = -ETIME ; goto end; } - status =acpi_ec_transaction_unlocked (ec, command, wdata, wdata_len, rdata, rdata_len, force_poll); - - end: - +end:if (ec->global_lock)acpi_release_global_lock (glk); +unlock:mutex_unlock (&ec->lock); -return status; }
@@ -332,7 +350,9 @@ int acpi_ec_burst_enable(struct acpi_ec *ec)int acpi_ec_burst_disable (struct acpi_ec *ec) { -return acpi_ec_transaction (ec,ACPI_EC_BURST_DISABLE ,NULL ,0 ,NULL ,0 ,0 ); +return (acpi_ec_read_status (ec) &ACPI_EC_FLAG_BURST ) ? +acpi_ec_transaction (ec,ACPI_EC_BURST_DISABLE , +NULL ,0 ,NULL ,0 ,0 ) :0 ; }static int acpi_ec_read (struct acpi_ec *ec,u8 address,u8 * data)
@@ -513,46 +533,26 @@ static void acpi_ec_gpe_query(void *ec_cxt)static u32 acpi_ec_gpe_handler (void *data) { -acpi_status status =AE_OK ;struct acpi_ec *ec = data; -u8 state =acpi_ec_read_status (ec); +u8 status;pr_debug (PREFIX "~~~> interrupt\n" ); -atomic_inc (&ec->irq_count); -if (atomic_read (&ec->irq_count) >5 ) { -pr_err (PREFIX "GPE storm detected, disabling EC GPE\n" ); -ec_switch_to_poll_mode (ec); - goto end; - } -clear_bit (EC_FLAGS_WAIT_GPE , &ec->flags); -if (test_bit (EC_FLAGS_GPE_MODE , &ec->flags)) + status =acpi_ec_read_status (ec); + +gpe_transaction (ec, status); +if (ec_transaction_done (ec) && (status &ACPI_EC_FLAG_IBF ) ==0 )wake_up (&ec->wait); -if (state &ACPI_EC_FLAG_SCI ) { -if (!test_and_set_bit (EC_FLAGS_QUERY_PENDING , &ec->flags)) - status =acpi_os_execute (OSL_EC_BURST_HANDLER , - acpi_ec_gpe_query, ec); - }else if (!test_bit (EC_FLAGS_GPE_MODE , &ec->flags) && - !test_bit (EC_FLAGS_NO_GPE , &ec->flags) && -in_interrupt ()) { +ec_check_sci (ec, status); +if (!test_bit (EC_FLAGS_GPE_MODE , &ec->flags) && + !test_bit (EC_FLAGS_NO_GPE , &ec->flags)) {/* this is non-query, must be confirmation */ if (printk_ratelimit ())pr_info (PREFIX "non-query interrupt received," " switching to interrupt mode\n" );set_bit (EC_FLAGS_GPE_MODE , &ec->flags); -clear_bit (EC_FLAGS_RESCHEDULE_POLL , &ec->flags); } -end: -ec_schedule_ec_poll (ec); -return ACPI_SUCCESS (status) ? -ACPI_INTERRUPT_HANDLED :ACPI_INTERRUPT_NOT_HANDLED ; -} - -static void do_ec_poll (struct work_struct *work) -{ - struct acpi_ec *ec = container_of(work, struct acpi_ec, work.work); -atomic_set (&ec->irq_count,0 ); - (void )acpi_ec_gpe_handler (ec); +return ACPI_INTERRUPT_HANDLED ; }/* --------------------------------------------------------------------------
@@ -696,8 +696,7 @@ static struct acpi_ec *make_acpi_ec(void)mutex_init (&ec->lock);init_waitqueue_head (&ec->wait);INIT_LIST_HEAD (&ec->list); -INIT_DELAYED_WORK_DEFERRABLE (&ec->work, do_ec_poll); -atomic_set (&ec->irq_count,0 ); +spin_lock_init (&ec->t_lock);return ec; }
@@ -736,22 +735,15 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)return AE_CTRL_TERMINATE ; } -static void ec_poll_stop (struct acpi_ec *ec) -{ -clear_bit (EC_FLAGS_RESCHEDULE_POLL , &ec->flags); -cancel_delayed_work (&ec->work); -} -static void ec_remove_handlers (struct acpi_ec *ec) { -ec_poll_stop (ec);if (ACPI_FAILURE (acpi_remove_address_space_handler (ec->handle,ACPI_ADR_SPACE_EC , &acpi_ec_space_handler)))pr_err (PREFIX "failed to remove space handler\n" );if (ACPI_FAILURE (acpi_remove_gpe_handler (NULL , ec->gpe, &acpi_ec_gpe_handler)))pr_err (PREFIX "failed to remove gpe handler\n" ); - ec->handlers_installed =0 ; +clear_bit (EC_FLAGS_HANDLERS_INSTALLED , &ec->flags); }static int acpi_ec_add (struct acpi_device *device)
@@ -846,17 +838,15 @@ ec_parse_io_ports(struct acpi_resource *resource, void *context)static int ec_install_handlers (struct acpi_ec *ec) {acpi_status status; -if (ec->handlers_installed) +if (test_bit (EC_FLAGS_HANDLERS_INSTALLED , &ec->flags))return 0 ; status =acpi_install_gpe_handler (NULL , ec->gpe, -ACPI_GPE_EDGE_TRIGGERED , - &acpi_ec_gpe_handler, ec); +ACPI_GPE_EDGE_TRIGGERED , + &acpi_ec_gpe_handler, ec);if (ACPI_FAILURE (status))return -ENODEV ; -acpi_set_gpe_type (NULL , ec->gpe,ACPI_GPE_TYPE_RUNTIME );acpi_enable_gpe (NULL , ec->gpe,ACPI_NOT_ISR ); - status = acpi_install_address_space_handler(ec->handle, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler,
@@ -866,7 +856,7 @@ static int ec_install_handlers(struct acpi_ec *ec)return -ENODEV ; } - ec->handlers_installed =1 ; +set_bit (EC_FLAGS_HANDLERS_INSTALLED , &ec->flags);return 0 ; }
@@ -887,7 +877,6 @@ static int acpi_ec_start(struct acpi_device *device)/* EC is fully operational, allow queries */ clear_bit (EC_FLAGS_QUERY_PENDING , &ec->flags); -ec_schedule_ec_poll (ec);return ret; }
@@ -906,7 +895,7 @@ static int acpi_ec_stop(struct acpi_device *device, int type)int __init acpi_boot_ec_enable (void ) { -if (!boot_ec || boot_ec->handlers_installed) +if (!boot_ec ||test_bit (EC_FLAGS_HANDLERS_INSTALLED , &boot_ec->flags))return 0 ;if (!ec_install_handlers (boot_ec)) { first_ec = boot_ec;
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 43/85 ACPI: EC: Rename some variables
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
No functional changes.
--- drivers/acpi/ec.c | 118 ++++++++++++++++++++++++++++------------------------- 1 files changed, 63 insertions(+), 55 deletions(-)
drivers/acpi/ec.c +63 -55
@@ -95,10 +95,11 @@ struct acpi_ec_query_handler {u8 query_bit; }; -struct transaction_data { +struct transaction {const u8 *wdata;u8 *rdata;unsigned short irq_count; +u8 command;u8 wlen;u8 rlen; };
@@ -113,8 +114,8 @@ static struct acpi_ec {struct mutex lock;wait_queue_head_t wait;struct list_head list; -struct transaction_data *t; -spinlock_t t_lock; +struct transaction *curr; +spinlock_t curr_lock; } *boot_ec, *first_ec;/*
@@ -176,37 +177,37 @@ static int ec_transaction_done(struct acpi_ec *ec) {unsigned long flags;int ret =0 ; -spin_lock_irqsave (&ec->t_lock, flags); -if (!ec->t || (!ec->t->wlen && !ec->t->rlen)) +spin_lock_irqsave (&ec->curr_lock, flags); +if (!ec->curr || (!ec->curr->wlen && !ec->curr->rlen)) ret =1 ; -spin_unlock_irqrestore (&ec->t_lock, flags); +spin_unlock_irqrestore (&ec->curr_lock, flags);return ret; }static void gpe_transaction (struct acpi_ec *ec,u8 status) {unsigned long flags; -spin_lock_irqsave (&ec->t_lock, flags); -if (!ec->t) +spin_lock_irqsave (&ec->curr_lock, flags); +if (!ec->curr) goto unlock; -if (ec->t->wlen >0 ) { +if (ec->curr->wlen >0 ) {if ((status &ACPI_EC_FLAG_IBF ) ==0 ) { -acpi_ec_write_data (ec, *(ec->t->wdata++)); - --ec->t->wlen; +acpi_ec_write_data (ec, *(ec->curr->wdata++)); + --ec->curr->wlen; }else /* false interrupt, state didn't change */ - ++ec->t->irq_count; + ++ec->curr->irq_count; - }else if (ec->t->rlen >0 ) { + }else if (ec->curr->rlen >0 ) {if ((status &ACPI_EC_FLAG_OBF ) ==1 ) { - *(ec->t->rdata++) =acpi_ec_read_data (ec); - --ec->t->rlen; + *(ec->curr->rdata++) =acpi_ec_read_data (ec); + --ec->curr->rlen; }else /* false interrupt, state didn't change */ - ++ec->t->irq_count; + ++ec->curr->irq_count; } unlock: -spin_unlock_irqrestore (&ec->t_lock, flags); +spin_unlock_irqrestore (&ec->curr_lock, flags); }static int acpi_ec_wait (struct acpi_ec *ec)
@@ -248,15 +249,11 @@ static int ec_poll(struct acpi_ec *ec)return -ETIME ; } -static int acpi_ec_transaction_unlocked (struct acpi_ec *ec,u8 command, -const u8 * wdata,unsigned wdata_len, -u8 * rdata,unsigned rdata_len, +static int acpi_ec_transaction_unlocked (struct acpi_ec *ec, +struct transaction *t,int force_poll) {unsigned long tmp; -struct transaction_data t = {.wdata = wdata, .rdata = rdata, - .wlen = wdata_len, .rlen = rdata_len, - .irq_count =0 };int ret =0 ;pr_debug (PREFIX "transaction start\n" );/* disable GPE during transaction if storm is detected */
@@ -265,29 +262,30 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,acpi_disable_gpe (NULL , ec->gpe,ACPI_NOT_ISR ); }/* start transaction */ -spin_lock_irqsave (&ec->t_lock, tmp); +spin_lock_irqsave (&ec->curr_lock, tmp);/* following two actions should be kept atomic */ - ec->t = &t; -acpi_ec_write_cmd (ec, command); -if (command ==ACPI_EC_COMMAND_QUERY ) + t->irq_count =0 ; + ec->curr = t; +acpi_ec_write_cmd (ec, ec->curr->command); +if (ec->curr->command ==ACPI_EC_COMMAND_QUERY )clear_bit (EC_FLAGS_QUERY_PENDING , &ec->flags); -spin_unlock_irqrestore (&ec->t_lock, tmp); +spin_unlock_irqrestore (&ec->curr_lock, tmp);/* if we selected poll mode or failed in GPE-mode do a poll loop */ if (force_poll || !test_bit (EC_FLAGS_GPE_MODE , &ec->flags) ||acpi_ec_wait (ec)) ret =ec_poll (ec);pr_debug (PREFIX "transaction end\n" ); -spin_lock_irqsave (&ec->t_lock, tmp); - ec->t =NULL ; -spin_unlock_irqrestore (&ec->t_lock, tmp); +spin_lock_irqsave (&ec->curr_lock, tmp); + ec->curr =NULL ; +spin_unlock_irqrestore (&ec->curr_lock, tmp);if (test_bit (EC_FLAGS_GPE_STORM , &ec->flags)) {/* check if we received SCI during transaction */ ec_check_sci (ec,acpi_ec_read_status (ec));/* it is safe to enable GPE outside of transaction */ acpi_enable_gpe (NULL , ec->gpe,ACPI_NOT_ISR ); }else if (test_bit (EC_FLAGS_GPE_MODE , &ec->flags) && - t.irq_count >ACPI_EC_STORM_THRESHOLD ) { + t->irq_count >ACPI_EC_STORM_THRESHOLD ) {pr_debug (PREFIX "GPE storm detected\n" );set_bit (EC_FLAGS_GPE_STORM , &ec->flags); }
@@ -300,17 +298,15 @@ static int ec_check_ibf0(struct acpi_ec *ec)return (status &ACPI_EC_FLAG_IBF ) ==0 ; } -static int acpi_ec_transaction (struct acpi_ec *ec,u8 command, -const u8 * wdata,unsigned wdata_len, -u8 * rdata,unsigned rdata_len, +static int acpi_ec_transaction (struct acpi_ec *ec,struct transaction *t,int force_poll) {int status;u32 glk; -if (!ec || (wdata_len && !wdata) || (rdata_len && !rdata)) +if (!ec || (!t) || (t->wlen && !t->wdata) || (t->rlen && !t->rdata))return -EINVAL ; -if (rdata) -memset (rdata,0 , rdata_len); +if (t->rdata) +memset (t->rdata,0 , t->rlen);mutex_lock (&ec->lock);if (ec->global_lock) { status =acpi_acquire_global_lock (ACPI_EC_UDELAY_GLK , &glk);
@@ -326,10 +322,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, status = -ETIME ; goto end; } - status =acpi_ec_transaction_unlocked (ec, command, - wdata, wdata_len, - rdata, rdata_len, - force_poll); + status =acpi_ec_transaction_unlocked (ec, t, force_poll); end:if (ec->global_lock)acpi_release_global_lock (glk);
@@ -345,23 +338,32 @@ unlock:int acpi_ec_burst_enable (struct acpi_ec *ec) {u8 d; -return acpi_ec_transaction (ec,ACPI_EC_BURST_ENABLE ,NULL ,0 , &d,1 ,0 ); +struct transaction t = {.command =ACPI_EC_BURST_ENABLE , + .wdata =NULL , .rdata = &d, + .wlen =0 , .rlen =1 }; + +return acpi_ec_transaction (ec, &t,0 ); }int acpi_ec_burst_disable (struct acpi_ec *ec) { +struct transaction t = {.command =ACPI_EC_BURST_DISABLE , + .wdata =NULL , .rdata =NULL , + .wlen =0 , .rlen =0 }; +return (acpi_ec_read_status (ec) &ACPI_EC_FLAG_BURST ) ? -acpi_ec_transaction (ec,ACPI_EC_BURST_DISABLE , -NULL ,0 ,NULL ,0 ,0 ) :0 ; +acpi_ec_transaction (ec, &t,0 ) :0 ; }static int acpi_ec_read (struct acpi_ec *ec,u8 address,u8 * data) {int result;u8 d; +struct transaction t = {.command =ACPI_EC_COMMAND_READ , + .wdata = &address, .rdata = &d, + .wlen =1 , .rlen =1 }; - result =acpi_ec_transaction (ec,ACPI_EC_COMMAND_READ , - &address,1 , &d,1 ,0 ); + result =acpi_ec_transaction (ec, &t,0 ); *data = d;return result; }
@@ -369,8 +371,11 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data)static int acpi_ec_write (struct acpi_ec *ec,u8 address,u8 data) {u8 wdata[2 ] = { address, data }; -return acpi_ec_transaction (ec,ACPI_EC_COMMAND_WRITE , - wdata,2 ,NULL ,0 ,0 ); +struct transaction t = {.command =ACPI_EC_COMMAND_WRITE , + .wdata = wdata, .rdata =NULL , + .wlen =2 , .rlen =0 }; + +return acpi_ec_transaction (ec, &t,0 ); }/*
@@ -432,12 +437,13 @@ int ec_transaction(u8 command, u8 * rdata, unsigned rdata_len, int force_poll) { + struct transaction t = {.command = command, + .wdata = wdata, .rdata = rdata, + .wlen = wdata_len, .rlen = rdata_len};if (!first_ec)return -ENODEV ; -return acpi_ec_transaction (first_ec, command, wdata, - wdata_len, rdata, rdata_len, - force_poll); +return acpi_ec_transaction (first_ec, &t, force_poll); }EXPORT_SYMBOL (ec_transaction);
@@ -446,7 +452,9 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data) {int result;u8 d; - +struct transaction t = {.command =ACPI_EC_COMMAND_QUERY , + .wdata =NULL , .rdata = &d, + .wlen =0 , .rlen =1 };if (!ec || !data)return -EINVAL ;
@@ -456,7 +464,7 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data)* bit to be cleared (and thus clearing the interrupt source). */ - result =acpi_ec_transaction (ec,ACPI_EC_COMMAND_QUERY ,NULL ,0 , &d,1 ,0 ); + result =acpi_ec_transaction (ec, &t,0 );if (result)return result;
@@ -696,7 +704,7 @@ static struct acpi_ec *make_acpi_ec(void)mutex_init (&ec->lock);init_waitqueue_head (&ec->wait);INIT_LIST_HEAD (&ec->list); -spin_lock_init (&ec->t_lock); +spin_lock_init (&ec->curr_lock);return ec; }
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 44/85 ACPICA: add preemption point after each opcode parse
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
Reference: http://marc.info/?l=linux-acpi&m=122236382701062&w=2
--- drivers/acpi/parser/psloop.c | 2 ++ include/acpi/acmacros.h | 5 +++++ include/acpi/platform/aclinux.h | 6 ++++++ 3 files changed, 13 insertions(+), 0 deletions(-)
drivers/acpi/parser/psloop.c +2 -0
@@ -719,6 +719,8 @@ acpi_ps_complete_op(struct acpi_walk_state *walk_state, *op =NULL ; } +ACPI_PREEMPTION_POINT (); +return_ACPI_STATUS (AE_OK ); }
include/acpi/acmacros.h +5 -0
@@ -703,4 +703,9 @@ struct acpi_integer_overlay {#endif /* ACPI_DBG_TRACK_ALLOCATIONS */ +/* Preemption point */ +#ifndef ACPI_PREEMPTION_POINT +#define ACPI_PREEMPTION_POINT ()/* no preemption */ +#endif +#endif /* ACMACROS_H */
include/acpi/platform/aclinux.h +6 -0
@@ -53,6 +53,7 @@#include <linux/kernel.h> #include <linux/module.h> #include <linux/ctype.h> +#include <linux/sched.h> #include <asm/system.h> #include <asm/atomic.h> #include <asm/div64.h>
@@ -137,4 +138,9 @@ static inline void *acpi_os_acquire_object(acpi_cache_t * cache)#define ACPI_ALLOCATE_ZEROED (a) acpi_os_allocate_zeroed(a)#define ACPI_FREE (a) kfree(a) +/* +* We need to show where it is safe to preempt execution of ACPICA +*/ +#define ACPI_PREEMPTION_POINT () cond_resched() +#endif /* __ACLINUX_H__ */
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 45/85 ACPI Suspend: Enable ACPI during resume if SCI_EN is not set
In reply to Len BrownFrom: Rafael J. Wysocki <[email protected]>
ACPI Suspend: Enable ACPI during resume if SCI_EN is not set
On some machines, like for example MSI Wind U100, the BIOS doesn't enable ACPI before returning control to the OS, which sometimes causes resume to fail. This is against the ACPI specification, which clearly states that "When the platform is waking from an S1, S2 or S3 state, OSPM assumes the hardware is already in the ACPI mode and will not issue an ACPI_ENABLE", but it won't hurt to check the SCI_EN bit and enable ACPI during resume from S3 if this bit is not set.
Fortunately, we already have acpi_enable() for that, so use it in the resume code path, before executing _BFS, in analogy with the resume-from-hibernation code path.
NOTE: We aren't supposed to set SCI_EN directly, because it's owned by the hardware.
--- drivers/acpi/sleep/main.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
drivers/acpi/sleep/main.c +2 -0
@@ -233,6 +233,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state)break ; } +/* If ACPI is not enabled by the BIOS, we need to enable it here. */ +acpi_enable ();/* Reprogram control registers and execute _BFS */ acpi_leave_sleep_state_prep (acpi_state);
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 46/85 ACPI: don't enable control method power button as wakeup device when Fixed Power button is used
In reply to Len BrownFrom: Zhang Rui <[email protected]>
don't enable control method power button as wakeup device when Fixed Power button is used.
http://bugzilla.kernel.org/show_bug.cgi?id=10503
--- drivers/acpi/scan.c | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-)
drivers/acpi/scan.c +10 -0
@@ -744,6 +744,16 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)if (!acpi_match_device_ids (device, button_device_ids)) device->wakeup.flags.run_wake =1 ; +/* +* Don't set Power button GPE as run_wake +* if Fixed Power button is used +*/ +if (!strcmp (device->pnp.hardware_id,"PNP0C0C" ) && + !(acpi_gbl_FADT.flags &ACPI_FADT_POWER_BUTTON )) { + device->wakeup.flags.run_wake =0 ; + device->wakeup.flags.valid =0 ; + } + end:if (ACPI_FAILURE (status)) device->flags.wake_capable =0 ;
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 47/85 acer-wmi: Add rfkill support for wireless and bluetooth
In reply to Len BrownFrom: Carlos Corbacho <[email protected]>
This patch implements rfkill support for the wireless and bluetooth devices commonly found on Acer laptops.
For now, we will always poll these devices once a second to guarantee we can catch state changes. On newer Acer laptops, it may be possible to rely on WMI events to do this instead, and experimental support for this will be added in a later patch.
3G has been deliberately left off for now, as we still have no way to detect it, (nor, AFAIK, has any Linux user tried the code) and on laptops that don't support 3G, trying to poll for the status will leave the logs full of ACPI tracebacks.
The old sysfs interface for wireless and bluetooth will be removed in a later patch.
(Thanks to Henrique de Moraes Holschuh and Dmitry Torokhov for reviewing this patch).
--- drivers/misc/Kconfig | 1 + drivers/misc/acer-wmi.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 130 insertions(+), 1 deletions(-)
drivers/misc/Kconfig +1 -0
@@ -145,6 +145,7 @@ config ACER_WMI depends on NEW_LEDS depends on BACKLIGHT_CLASS_DEVICE depends on SERIO_I8042 + depends on RFKILL select ACPI_WMI ---help--- This is a driver for newer Acer (and Wistron) laptops. It adds
drivers/misc/acer-wmi.c +129 -1
160 lines not on this page · raw message
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 48/85 acer-wmi: Remove wireless and bluetooth sysfs entries
In reply to Len BrownFrom: Carlos Corbacho <[email protected]>
These are now replaced by the rfkill interface.
--- Documentation/laptops/acer-wmi.txt | 28 ++--------- drivers/misc/acer-wmi.c | 101 ++++++++---------------------------- 2 files changed, 25 insertions(+), 104 deletions(-)
Documentation/laptops/acer-wmi.txt +4 -24
@@ -1,7 +1,7 @@ Acer Laptop WMI Extras Driver http://code.google.com/p/aceracpi -Version 0.1 -9th February 2008 +Version 0.2 +18th August 2008 Copyright 2007-2008 Carlos Corbacho <[email protected]>
@@ -87,17 +87,7 @@ acer-wmi come with built-in wireless. However, should you feel so inclined to ever wish to remove the card, or swap it out at some point, please get in touch with me, as we may well be able to gain some data on wireless card detection. -To read the status of the wireless radio (0=off, 1=on): -cat /sys/devices/platform/acer-wmi/wireless - -To enable the wireless radio: -echo 1 > /sys/devices/platform/acer-wmi/wireless - -To disable the wireless radio: -echo 0 > /sys/devices/platform/acer-wmi/wireless - -To set the state of the wireless radio when loading acer-wmi, pass: -wireless=X (where X is 0 or 1) +The wireless radio is exposed through rfkill. Bluetooth *********
@@ -117,17 +107,7 @@ For the adventurously minded - if you want to buy an internal bluetooth module off the internet that is compatible with your laptop and fit it, then it will work just fine with acer-wmi. -To read the status of the bluetooth module (0=off, 1=on): -cat /sys/devices/platform/acer-wmi/wireless - -To enable the bluetooth module: -echo 1 > /sys/devices/platform/acer-wmi/bluetooth - -To disable the bluetooth module: -echo 0 > /sys/devices/platform/acer-wmi/bluetooth - -To set the state of the bluetooth module when loading acer-wmi, pass: -bluetooth=X (where X is 0 or 1) +Bluetooth is exposed through rfkill. 3G **
drivers/misc/acer-wmi.c +21 -80
161 lines not on this page · raw message
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 49/85 ACPI: WMI: Enable event methods when registering notifiers
In reply to Len BrownFrom: Matthew Garrett <[email protected]>
According to the ACPI-WMI spec, event blocks may provide a function call for enabling/disabling them. This patch adds support for making these calls when registering or removing notifications. Without this, my Dell firmware provides no data in the event notification.
--- drivers/acpi/wmi.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 files changed, 37 insertions(+), 2 deletions(-)
drivers/acpi/wmi.c +37 -2
@@ -217,6 +217,35 @@ static bool find_guid(const char *guid_string, struct wmi_block **out)return 0 ; } +static acpi_status wmi_method_enable (struct wmi_block *wblock,int enable) +{ +struct guid_block *block =NULL ; +char method[5 ]; +struct acpi_object_list input; +union acpi_object params[1 ]; +acpi_status status; +acpi_handle handle; + + block = &wblock->gblock; + handle = wblock->handle; + +if (!block) +return AE_NOT_EXIST ; + + input.count =1 ; + input.pointer = params; + params[0 ].type =ACPI_TYPE_INTEGER ; + params[0 ].integer.value = enable; + +snprintf (method,5 ,"WE%02X" , block->notify_id); + status =acpi_evaluate_object (handle, method, &input,NULL ); + +if (status !=AE_OK && status !=AE_NOT_FOUND ) +return status; +else +return AE_OK ; +} +/* * Exported WMI functions */
@@ -427,6 +456,7 @@ acpi_status wmi_install_notify_handler(const char *guid, wmi_notify_handler handler, void *data) { struct wmi_block *block; +acpi_status status;if (!guid || !handler)return AE_BAD_PARAMETER ;
@@ -441,7 +471,9 @@ wmi_notify_handler handler, void *data) block->handler = handler; block->handler_data = data; -return AE_OK ; + status =wmi_method_enable (block,1 ); + +return status; }EXPORT_SYMBOL_GPL (wmi_install_notify_handler);
@@ -453,6 +485,7 @@ EXPORT_SYMBOL_GPL(wmi_install_notify_handler);acpi_status wmi_remove_notify_handler (const char *guid) {struct wmi_block *block; +acpi_status status;if (!guid)return AE_BAD_PARAMETER ;
@@ -464,10 +497,12 @@ acpi_status wmi_remove_notify_handler(const char *guid)if (!block->handler)return AE_NULL_ENTRY ; + status =wmi_method_enable (block,0 ); + block->handler =NULL ; block->handler_data =NULL ; -return AE_OK ; +return status; }EXPORT_SYMBOL_GPL (wmi_remove_notify_handler);
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 50/85 ACPI: Change acpi_evaluate_integer to support 64-bit on 32-bit kernels
In reply to Len BrownFrom: Matthew Wilcox <[email protected]>
As of version 2.0, ACPI can return 64-bit integers. The current acpi_evaluate_integer only supports 64-bit integers on 64-bit platforms. Change the argument to take a pointer to an acpi_integer so we support 64-bit integers on all platforms.
lenb: replaced use of "acpi_integer" with "unsigned long long"
--- arch/ia64/sn/kernel/io_acpi_init.c | 8 +++--- drivers/acpi/ac.c | 2 +- drivers/acpi/acpi_memhotplug.c | 5 +-- drivers/acpi/asus_acpi.c | 2 +- drivers/acpi/bay.c | 2 +- drivers/acpi/bus.c | 4 +- drivers/acpi/button.c | 4 +- drivers/acpi/container.c | 2 +- drivers/acpi/dock.c | 6 ++-- drivers/acpi/ec.c | 7 ++++- drivers/acpi/numa.c | 2 +- drivers/acpi/osl.c | 5 +-- drivers/acpi/pci_root.c | 2 +- drivers/acpi/pci_slot.c | 10 ++++---- drivers/acpi/power.c | 2 +- drivers/acpi/processor_core.c | 4 +- drivers/acpi/processor_perflib.c | 2 +- drivers/acpi/processor_throttling.c | 2 +- drivers/acpi/sbshc.c | 2 +- drivers/acpi/sleep/main.c | 2 +- drivers/acpi/thermal.c | 43 ++++++++++++++++++++++------------- drivers/acpi/utils.c | 4 +- drivers/acpi/video.c | 42 +++++++++++++++++----------------- drivers/ata/libata-acpi.c | 2 +- drivers/misc/asus-laptop.c | 12 +++++----- drivers/misc/eeepc-laptop.c | 2 +- drivers/misc/fujitsu-laptop.c | 8 +++--- drivers/misc/intel_menlow.c | 27 +++++++++++---------- drivers/pci/hotplug/acpiphp_glue.c | 14 +++++----- drivers/pci/hotplug/acpiphp_ibm.c | 2 +- drivers/pci/hotplug/sgi_hotplug.c | 4 +- include/acpi/acpi_bus.h | 2 +- 32 files changed, 125 insertions(+), 112 deletions(-)
arch/ia64/sn/kernel/io_acpi_init.c +4 -4
@@ -232,7 +232,7 @@ exit:static unsigned int get_host_devfn (acpi_handle device_handle,acpi_handle rootbus_handle) { -unsigned long adr; +unsigned long long adr;acpi_handle child;unsigned int devfn;int function;
@@ -292,8 +292,8 @@ get_host_devfn(acpi_handle device_handle, acpi_handle rootbus_handle)static acpi_status find_matching_device (acpi_handle handle,u32 lvl,void *context,void **rv) { -unsigned long bbn =-1 ; -unsigned long adr; +unsigned long long bbn =-1 ; +unsigned long long adr;acpi_handle parent =NULL ;acpi_status status;unsigned int devfn;
@@ -348,7 +348,7 @@ sn_acpi_get_pcidev_info(struct pci_dev *dev, struct pcidev_info **pcidev_info,unsigned int host_devfn;struct sn_pcidev_match pcidev_match;acpi_handle rootbus_handle; -unsigned long segment; +unsigned long long segment;acpi_status status; rootbus_handle =PCI_CONTROLLER (dev)->acpi_handle;
drivers/acpi/ac.c +1 -1
@@ -85,7 +85,7 @@ struct acpi_ac {struct power_supply charger;#endif struct acpi_device * device; -unsigned long state; +unsigned long long state; };#define to_acpi_ac (x) container_of(x, struct acpi_ac, charger);
drivers/acpi/acpi_memhotplug.c +2 -3
@@ -194,8 +194,7 @@ acpi_memory_get_device(acpi_handle handle,static int acpi_memory_check_device (struct acpi_memory_device *mem_device) { -unsigned long current_status; - +unsigned long long current_status;/* Get device present/absent information from the _STA */ if (ACPI_FAILURE(acpi_evaluate_integer(mem_device->device->handle, "_STA",
@@ -264,7 +263,7 @@ static int acpi_memory_powerdown_device(struct acpi_memory_device *mem_device)acpi_status status;struct acpi_object_list arg_list;union acpi_object arg; -unsigned long current_status; +unsigned long long current_status;/* Issue the _EJ0 command */
drivers/acpi/asus_acpi.c +1 -1
@@ -753,7 +753,7 @@ static int get_lcd_state(void)/* That's what the AML code does */ lcd = out_obj.integer.value >>8 ; }else if (hotk->model == F3Sa) { -unsigned long tmp; +unsigned long long tmp;union acpi_object param;struct acpi_object_list input;acpi_status status;
drivers/acpi/bay.c +1 -1
@@ -90,7 +90,7 @@ static int is_ejectable(acpi_handle handle)*/ static int bay_present (struct bay *bay) { -unsigned long sta; +unsigned long long sta;acpi_status status;if (bay) {
drivers/acpi/bus.c +2 -2
@@ -77,7 +77,7 @@ EXPORT_SYMBOL(acpi_bus_get_device);int acpi_bus_get_status (struct acpi_device *device) {acpi_status status =AE_OK ; -unsigned long sta =0 ; +unsigned long long sta =0 ;if (!device)
@@ -155,7 +155,7 @@ int acpi_bus_get_power(acpi_handle handle, int *state)int result =0 ;acpi_status status =0 ;struct acpi_device *device =NULL ; -unsigned long psc =0 ; +unsigned long long psc =0 ; result =acpi_bus_get_device (handle, &device);
drivers/acpi/button.c +2 -2
@@ -145,7 +145,7 @@ static int acpi_button_state_seq_show(struct seq_file *seq, void *offset) {struct acpi_button *button = seq->private;acpi_status status; -unsigned long state; +unsigned long long state;if (!button || !button->device)return 0 ;
@@ -253,7 +253,7 @@ static int acpi_button_remove_fs(struct acpi_device *device)-------------------------------------------------------------------------- */ static int acpi_lid_send_state (struct acpi_button *button) { -unsigned long state; +unsigned long long state;acpi_status status; status = acpi_evaluate_integer(button->device->handle, "_LID", NULL,
drivers/acpi/container.c +1 -1
@@ -76,7 +76,7 @@ static int is_device_present(acpi_handle handle) {acpi_handle temp;acpi_status status; -unsigned long sta; +unsigned long long sta; status =acpi_get_handle (handle,"_STA" , &temp);
drivers/acpi/dock.c +3 -3
@@ -229,7 +229,7 @@ EXPORT_SYMBOL_GPL(is_dock_device);*/ static int dock_present (struct dock_station *ds) { -unsigned long sta; +unsigned long long sta;acpi_status status;if (ds) {
@@ -727,13 +727,13 @@ static DEVICE_ATTR(undock, S_IWUSR, NULL, write_undock);static ssize_t show_dock_uid (struct device *dev,struct device_attribute *attr,char *buf) { -unsigned long lbuf; +unsigned long long lbuf;acpi_status status =acpi_evaluate_integer (dock_station->handle,"_UID" ,NULL , &lbuf);if (ACPI_FAILURE (status))return 0 ; -return snprintf (buf,PAGE_SIZE ,"%lx\n" , lbuf); +return snprintf (buf,PAGE_SIZE ,"%llx\n" , lbuf); } static DEVICE_ATTR(uid, S_IRUGO, show_dock_uid, NULL);
drivers/acpi/ec.c +5 -2
@@ -718,6 +718,7 @@ static acpi_status ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) { acpi_status status; +unsigned long long tmp;struct acpi_ec *ec = context; status = acpi_walk_resources(handle, METHOD_NAME__CRS,
@@ -727,11 +728,13 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)/* Get GPE bit assignment (EC events). */ /* TODO: Add support for _GPE returning a package */ - status =acpi_evaluate_integer (handle,"_GPE" ,NULL , &ec->gpe); + status =acpi_evaluate_integer (handle,"_GPE" ,NULL , &tmp);if (ACPI_FAILURE (status))return status; + ec->gpe = tmp;/* Use the global lock for all EC transactions? */ -acpi_evaluate_integer (handle,"_GLK" ,NULL , &ec->global_lock); +acpi_evaluate_integer (handle,"_GLK" ,NULL , &tmp); + ec->global_lock = tmp; ec->handle = handle;return AE_CTRL_TERMINATE ; }
drivers/acpi/numa.c +1 -1
@@ -258,7 +258,7 @@ int __init acpi_numa_init(void)int acpi_get_pxm (acpi_handle h) { -unsigned long pxm; +unsigned long long pxm;acpi_status status;acpi_handle handle;acpi_handle phandle = h;
drivers/acpi/osl.c +2 -3
@@ -608,7 +608,7 @@ static void acpi_os_derive_pci_id_2(acpi_handle rhandle, /* upper bound */acpi_handle handle;struct acpi_pci_id *pci_id = *id;acpi_status status; -unsigned long temp; +unsigned long long temp;acpi_object_type type;acpi_get_parent (chandle, &handle);
@@ -620,8 +620,7 @@ static void acpi_os_derive_pci_id_2(acpi_handle rhandle, /* upper bound */if ((ACPI_FAILURE (status)) || (type !=ACPI_TYPE_DEVICE ))return ; - status = -acpi_evaluate_integer (handle,METHOD_NAME__ADR ,NULL , + status =acpi_evaluate_integer (handle,METHOD_NAME__ADR ,NULL , &temp);if (ACPI_SUCCESS (status)) {u32 val;
drivers/acpi/pci_root.c +1 -1
@@ -190,7 +190,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)struct acpi_pci_root *root =NULL ;struct acpi_pci_root *tmp;acpi_status status =AE_OK ; -unsigned long value =0 ; +unsigned long long value =0 ;acpi_handle handle =NULL ;struct acpi_device *child;
drivers/acpi/pci_slot.c +5 -5
@@ -76,10 +76,10 @@ static struct acpi_pci_driver acpi_pci_slot_driver = { };static int -check_slot (acpi_handle handle,unsigned long *sun) +check_slot (acpi_handle handle,unsigned long long *sun) {int device =-1 ; -unsigned long adr, sta; +unsigned long long adr, sta;acpi_status status;struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER ,NULL };
@@ -132,7 +132,7 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) { int device; -unsigned long sun; +unsigned long long sun;char name[SLOT_NAME_SIZE ];struct acpi_pci_slot *slot;struct pci_slot *pci_slot;
@@ -182,7 +182,7 @@ static acpi_status walk_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) { int device, function; -unsigned long adr; +unsigned long long adr;acpi_status status;acpi_handle dummy_handle;acpi_walk_callback user_function;
@@ -239,7 +239,7 @@ static int walk_root_bridge(acpi_handle handle, acpi_walk_callback user_function) { int seg, bus; -unsigned long tmp; +unsigned long long tmp;acpi_status status;acpi_handle dummy_handle;struct pci_bus *pci_bus;
drivers/acpi/power.c +1 -1
@@ -131,7 +131,7 @@ acpi_power_get_context(acpi_handle handle,static int acpi_power_get_state (struct acpi_power_resource *resource,int *state) {acpi_status status =AE_OK ; -unsigned long sta =0 ; +unsigned long long sta =0 ;if (!resource || !state)
drivers/acpi/processor_core.c +2 -2
@@ -563,7 +563,7 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid)/* Check if it is a Device with HID and UID */ if (has_uid) { -unsigned long value; +unsigned long long value; status =acpi_evaluate_integer (pr->handle,METHOD_NAME__UID ,NULL , &value);if (ACPI_FAILURE (status)) {
@@ -875,7 +875,7 @@ static int acpi_processor_remove(struct acpi_device *device, int type)static int is_processor_present (acpi_handle handle) {acpi_status status; -unsigned long sta =0 ; +unsigned long long sta =0 ; status =acpi_evaluate_integer (handle,"_STA" ,NULL , &sta);
drivers/acpi/processor_perflib.c +1 -1
@@ -126,7 +126,7 @@ static struct notifier_block acpi_ppc_notifier_block = {static int acpi_processor_get_platform_limit (struct acpi_processor *pr) {acpi_status status =0 ; -unsigned long ppc =0 ; +unsigned long long ppc =0 ;if (!pr)
drivers/acpi/processor_throttling.c +1 -1
@@ -274,7 +274,7 @@ static int acpi_processor_throttling_notifier(unsigned long event, void *data)static int acpi_processor_get_platform_limit (struct acpi_processor *pr) {acpi_status status =0 ; -unsigned long tpc =0 ; +unsigned long long tpc =0 ;if (!pr)return -EINVAL ;
drivers/acpi/sbshc.c +1 -1
@@ -258,7 +258,7 @@ extern int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,static int acpi_smbus_hc_add (struct acpi_device *device) {int status; -unsigned long val; +unsigned long long val;struct acpi_smb_hc *hc;if (!device)
drivers/acpi/sleep/main.c +1 -1
@@ -444,7 +444,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p)acpi_handle handle =DEVICE_ACPI_HANDLE (dev);struct acpi_device *adev;char acpi_method[] ="_SxD" ; -unsigned long d_min, d_max; +unsigned long long d_min, d_max;if (!handle ||ACPI_FAILURE (acpi_bus_get_device (handle, &adev))) {printk (KERN_DEBUG "ACPI handle has no context!\n" );
drivers/acpi/thermal.c +27 -16
141 lines not on this page · raw message
drivers/acpi/utils.c +2 -2
@@ -256,7 +256,7 @@ EXPORT_SYMBOL(acpi_extract_package);acpi_status acpi_evaluate_integer (acpi_handle handle,acpi_string pathname, -struct acpi_object_list *arguments,unsigned long *data) +struct acpi_object_list *arguments,unsigned long long *data) {acpi_status status =AE_OK ;union acpi_object *element;
@@ -288,7 +288,7 @@ acpi_evaluate_integer(acpi_handle handle, *data = element->integer.value;kfree (element); -ACPI_DEBUG_PRINT ((ACPI_DB_INFO ,"Return value [%lu]\n" , *data)); +ACPI_DEBUG_PRINT ((ACPI_DB_INFO ,"Return value [%llu]\n" , *data));return AE_OK ; }
drivers/acpi/video.c +21 -21
167 lines not on this page · raw message
drivers/ata/libata-acpi.c +1 -1
@@ -180,7 +180,7 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,int wait =0 ;unsigned long flags;acpi_handle handle, tmphandle; -unsigned long sta; +unsigned long long sta;acpi_status status;if (dev) {
drivers/misc/asus-laptop.c +6 -6
@@ -280,7 +280,7 @@ static int write_acpi_int(acpi_handle handle, const char *method, int val,static int read_wireless_status (int mask) { -ulong status; +unsigned long long status;acpi_status rv =AE_OK ;if (!wireless_status_handle)
@@ -297,7 +297,7 @@ static int read_wireless_status(int mask)static int read_gps_status (void ) { -ulong status; +unsigned long long status;acpi_status rv =AE_OK ; rv =acpi_evaluate_integer (gps_status_handle,NULL ,NULL , &status);
@@ -404,7 +404,7 @@ static void lcd_blank(int blank)static int read_brightness (struct backlight_device *bd) { -ulong value; +unsigned long long value;acpi_status rv =AE_OK ; rv =acpi_evaluate_integer (brightness_get_handle,NULL ,NULL , &value);
@@ -455,7 +455,7 @@ static ssize_t show_infos(struct device *dev, struct device_attribute *attr, char *page) { int len = 0; -ulong temp; +unsigned long long temp;char buf[16 ];//enough for all info acpi_status rv =AE_OK ;
@@ -603,7 +603,7 @@ static void set_display(int value)static int read_display (void ) { -ulong value =0 ; +unsigned long long value =0 ;acpi_status rv =AE_OK ;/* In most of the case, we know how to set the display, but sometime
@@ -849,7 +849,7 @@ static int asus_hotk_get_info(void) {struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER ,NULL };union acpi_object *model =NULL ; -ulong bsts_result, hwrs_result; +unsigned long long bsts_result, hwrs_result;char *string =NULL ;acpi_status status;
drivers/misc/eeepc-laptop.c +1 -1
@@ -204,7 +204,7 @@ static int write_acpi_int(acpi_handle handle, const char *method, int val,static int read_acpi_int (acpi_handle handle,const char *method,int *val) {acpi_status status; -ulong result; +unsigned long long result; status =acpi_evaluate_integer (handle, (char *)method,NULL , &result);if (ACPI_FAILURE (status)) {
drivers/misc/fujitsu-laptop.c +4 -4
@@ -224,7 +224,7 @@ static int set_lcd_level_alt(int level)static int get_lcd_level (void ) { -unsigned long state =0 ; +unsigned long long state =0 ;acpi_status status =AE_OK ;vdbg_printk (FUJLAPTOP_DBG_TRACE ,"get lcd level via GBLL\n" );
@@ -246,7 +246,7 @@ static int get_lcd_level(void)static int get_max_brightness (void ) { -unsigned long state =0 ; +unsigned long long state =0 ;acpi_status status =AE_OK ;vdbg_printk (FUJLAPTOP_DBG_TRACE ,"get max lcd level via RBLL\n" );
@@ -263,7 +263,7 @@ static int get_max_brightness(void)static int get_lcd_level_alt (void ) { -unsigned long state =0 ; +unsigned long long state =0 ;acpi_status status =AE_OK ;vdbg_printk (FUJLAPTOP_DBG_TRACE ,"get lcd level via GBLS\n" );
@@ -384,7 +384,7 @@ static ssize_t store_lcd_level(struct device *dev,static int get_irb (void ) { -unsigned long state =0 ; +unsigned long long state =0 ;acpi_status status =AE_OK ;vdbg_printk (FUJLAPTOP_DBG_TRACE ,"Get irb\n" );
drivers/misc/intel_menlow.c +14 -13
@@ -57,7 +57,7 @@ static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev, {struct acpi_device *device = cdev->devdata;acpi_handle handle = device->handle; -unsigned long value; +unsigned long long value;struct acpi_object_list arg_list;union acpi_object arg;acpi_status status =AE_OK ;
@@ -90,7 +90,7 @@ static int memory_get_cur_bandwidth(struct thermal_cooling_device *cdev, {struct acpi_device *device = cdev->devdata;acpi_handle handle = device->handle; -unsigned long value; +unsigned long long value;struct acpi_object_list arg_list;union acpi_object arg;acpi_status status =AE_OK ;
@@ -115,7 +115,7 @@ static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,struct acpi_object_list arg_list;union acpi_object arg;acpi_status status; -int temp; +unsigned long long temp;unsigned long max_state;if (memory_get_int_max_bandwidth (cdev, &max_state))
@@ -131,7 +131,7 @@ static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev, status =acpi_evaluate_integer (handle,MEMORY_SET_BANDWIDTH , &arg_list, - (unsigned long *)&temp); + &temp);printk (KERN_INFO "Bandwidth value was %d: status is %d\n" , state, status);
@@ -252,7 +252,8 @@ static DEFINE_MUTEX(intel_menlow_attr_lock);* @auxtype : AUX0/AUX1 * @buf: syfs buffer */ -static int sensor_get_auxtrip (acpi_handle handle,int index,int *value) +static int sensor_get_auxtrip (acpi_handle handle,int index, +unsigned long long *value) {acpi_status status;
@@ -260,7 +261,7 @@ static int sensor_get_auxtrip(acpi_handle handle, int index, int *value)return -EINVAL ; status =acpi_evaluate_integer (handle, index ?GET_AUX1 :GET_AUX0 , -NULL , (unsigned long *)value); +NULL , value);if (ACPI_FAILURE (status))return -EIO ;
@@ -282,13 +283,13 @@ static int sensor_set_auxtrip(acpi_handle handle, int index, int value)struct acpi_object_list args = {1 , &arg }; -int temp; +unsigned long long temp;if (index !=0 && index !=1 )return -EINVAL ; status =acpi_evaluate_integer (handle, index ?GET_AUX0 :GET_AUX1 , -NULL , (unsigned long *)&temp); +NULL , &temp);if (ACPI_FAILURE (status))return -EIO ;if ((index && value < temp) || (!index && value > temp))
@@ -296,7 +297,7 @@ static int sensor_set_auxtrip(acpi_handle handle, int index, int value) arg.integer.value = value; status =acpi_evaluate_integer (handle, index ?SET_AUX1 :SET_AUX0 , - &args, (unsigned long *)&temp); + &args, &temp);if (ACPI_FAILURE (status))return -EIO ;
@@ -312,7 +313,7 @@ static ssize_t aux0_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct intel_menlow_attribute *attr = to_intel_menlow_attr(dev_attr); -int value; +unsigned long long value;int result; result =sensor_get_auxtrip (attr->handle,0 , &value);
@@ -324,7 +325,7 @@ static ssize_t aux1_show(struct device *dev, struct device_attribute *dev_attr, char *buf) { struct intel_menlow_attribute *attr = to_intel_menlow_attr(dev_attr); -int value; +unsigned long long value;int result; result =sensor_get_auxtrip (attr->handle,1 , &value);
@@ -376,7 +377,7 @@ static ssize_t bios_enabled_show(struct device *dev, struct device_attribute *attr, char *buf) { acpi_status status; -unsigned long bios_enabled; +unsigned long long bios_enabled; status =acpi_evaluate_integer (NULL ,BIOS_ENABLED ,NULL , &bios_enabled);if (ACPI_FAILURE (status))
@@ -492,7 +493,7 @@ static int __init intel_menlow_module_init(void) {int result = -ENODEV ;acpi_status status; -unsigned long enable; +unsigned long long enable;if (acpi_disabled)return result;
drivers/pci/hotplug/acpiphp_glue.c +7 -7
@@ -180,7 +180,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)struct acpiphp_func *newfunc;acpi_handle tmp;acpi_status status =AE_OK ; -unsigned long adr, sun; +unsigned long long adr, sun;int device, function, retval; status =acpi_evaluate_integer (handle,"_ADR" ,NULL , &adr);
@@ -528,7 +528,7 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) {acpi_status status;acpi_handle dummy_handle; -unsigned long tmp; +unsigned long long tmp;int device, function;struct pci_dev *dev;struct pci_bus *pci_bus = context;
@@ -573,7 +573,7 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)static int add_bridge (acpi_handle handle) {acpi_status status; -unsigned long tmp; +unsigned long long tmp;int seg, bus;acpi_handle dummy_handle;struct pci_bus *pci_bus;
@@ -767,7 +767,7 @@ static int get_gsi_base(acpi_handle handle, u32 *gsi_base) {acpi_status status;int result =-1 ; -unsigned long gsb; +unsigned long long gsb;struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER ,NULL };union acpi_object *obj;void *table;
@@ -808,7 +808,7 @@ static acpi_status ioapic_add(acpi_handle handle, u32 lvl, void *context, void **rv) { acpi_status status; -unsigned long sta; +unsigned long long sta;acpi_handle tmp;struct pci_dev *pdev;u32 gsi_base;
@@ -872,7 +872,7 @@ static acpi_status ioapic_remove(acpi_handle handle, u32 lvl, void *context, void **rv) { acpi_status status; -unsigned long sta; +unsigned long long sta;acpi_handle tmp;u32 gsi_base;struct acpiphp_ioapic *pos, *n, *ioapic =NULL ;
@@ -1264,7 +1264,7 @@ static int disable_device(struct acpiphp_slot *slot)static unsigned int get_slot_status (struct acpiphp_slot *slot) {acpi_status status; -unsigned long sta =0 ; +unsigned long long sta =0 ;u32 dvid;struct list_head *l;struct acpiphp_func *func;
drivers/pci/hotplug/acpiphp_ibm.c +1 -1
@@ -183,7 +183,7 @@ static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status)union acpi_object args[2 ];struct acpi_object_list params = { .pointer = args, .count =2 };acpi_status stat; -unsigned long rc; +unsigned long long rc;union apci_descriptor *ibm_slot; ibm_slot =ibm_slot_from_id (hpslot_to_sun (slot));
drivers/pci/hotplug/sgi_hotplug.c +2 -2
@@ -418,7 +418,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)/* * Add the slot's devices to the ACPI infrastructure */ if (SN_ACPI_BASE_SUPPORT () && ssdt) { -unsigned long adr; +unsigned long long adr;struct acpi_device *pdevice;struct acpi_device *device;acpi_handle phandle;
@@ -510,7 +510,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)/* free the ACPI resources for the slot */ if (SN_ACPI_BASE_SUPPORT () &&PCI_CONTROLLER (slot->pci_bus)->acpi_handle) { -unsigned long adr; +unsigned long long adr;struct acpi_device *device;acpi_handle phandle;acpi_handle chandle =NULL ;
include/acpi/acpi_bus.h +1 -1
@@ -46,7 +46,7 @@ acpi_extract_package(union acpi_object *package,acpi_status acpi_evaluate_integer (acpi_handle handle,acpi_string pathname, -struct acpi_object_list *arguments,unsigned long *data); +struct acpi_object_list *arguments,unsigned long long *data); acpi_status acpi_evaluate_reference(acpi_handle handle, acpi_string pathname,
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 51/85 ACPI: fix FADT parsing
In reply to Len BrownFrom: Jan Beulich <[email protected]>
The (1.0 inherited) separate length fields in the FADT are byte granular. Further, PM1a/b may have distinct lengths (if using the v2 fields was okay) and may live in distinct address spaces. acpi_tb_convert_fadt() should account for all of these conditions.
Apart from these changes I'm puzzled by the fact that, not just for acpi_gbl_xpm1{a,b}_enable, acpi_hw_low_level_{read,write}() get an explicit size passed rather than using the size found in the passed GAS. What happens on a platform that defines PM1{a,b} wider than 16 bits? Of course, acpi_hw_low_level_{read,write}() at present are entirely un-prepared to deal with sizes other than 8, 16, or 32, not to speak of a non-zero bit_offset or access_width...
--- drivers/acpi/tables/tbfadt.c | 32 +++++++++++++++++++++++++------- 1 files changed, 25 insertions(+), 7 deletions(-)
drivers/acpi/tables/tbfadt.c +25 -7
@@ -50,7 +50,7 @@ ACPI_MODULE_NAME("tbfadt")/* Local prototypes */ static void inline acpi_tb_init_generic_address (struct acpi_generic_address *generic_address, -u8 bit_width,u64 address); +u8 byte_width,u64 address);static void acpi_tb_convert_fadt (void );
@@ -111,7 +111,7 @@ static struct acpi_fadt_info fadt_info_table[] = {* FUNCTION: acpi_tb_init_generic_address * * PARAMETERS: generic_address - GAS struct to be initialized -* bit_width - Width of this register +* byte_width - Width of this register * Address - Address of the register * * RETURN: None
@@ -124,7 +124,7 @@ static struct acpi_fadt_info fadt_info_table[] = {static void inline acpi_tb_init_generic_address (struct acpi_generic_address *generic_address, -u8 bit_width,u64 address) +u8 byte_width,u64 address) {/*
@@ -136,7 +136,7 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,/* All other fields are byte-wide */ generic_address->space_id =ACPI_ADR_SPACE_SYSTEM_IO ; - generic_address->bit_width = bit_width; + generic_address->bit_width = byte_width <<3 ; generic_address->bit_offset =0 ; generic_address->access_width =0 ; }
@@ -342,9 +342,20 @@ static void acpi_tb_convert_fadt(void)* useful to calculate them once, here. * * The PM event blocks are split into two register blocks, first is the -* PM Status Register block, followed immediately by the PM Enable Register -* block. Each is of length (pm1_event_length/2) +* PM Status Register block, followed immediately by the PM Enable +* Register block. Each is of length (xpm1x_event_block.bit_width/2). +* +* On various systems the v2 fields (and particularly the bit widths) +* cannot be relied upon, though. Hence resort to using the v1 length +* here (and warn about the inconsistency). */ +if (acpi_gbl_FADT.xpm1a_event_block.bit_width + != acpi_gbl_FADT.pm1_event_length *8 ) +printk (KERN_WARNING "FADT: " +"X_PM1a_EVT_BLK.bit_width (%u) does not match" +" PM1_EVT_LEN (%u)\n" , + acpi_gbl_FADT.xpm1a_event_block.bit_width, + acpi_gbl_FADT.pm1_event_length); pm1_register_length = (u8 )ACPI_DIV_2 (acpi_gbl_FADT.pm1_event_length);/* The PM1A register block is required */
@@ -360,13 +371,20 @@ static void acpi_tb_convert_fadt(void)/* The PM1B register block is optional, ignore if not present */ if (acpi_gbl_FADT.xpm1b_event_block.address) { +if (acpi_gbl_FADT.xpm1b_event_block.bit_width + != acpi_gbl_FADT.pm1_event_length *8 ) +printk (KERN_WARNING "FADT: " +"X_PM1b_EVT_BLK.bit_width (%u) does not match" +" PM1_EVT_LEN (%u)\n" , + acpi_gbl_FADT.xpm1b_event_block.bit_width, + acpi_gbl_FADT.pm1_event_length);acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable, pm1_register_length, (acpi_gbl_FADT.xpm1b_event_block. address + pm1_register_length));/* Don't forget to copy space_id of the GAS */ acpi_gbl_xpm1b_enable.space_id = - acpi_gbl_FADT.xpm1a_event_block.space_id; + acpi_gbl_FADT.xpm1b_event_block.space_id; } }
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 52/85 fujitsu-laptop: better handling of P8010 hotkey
In reply to Len BrownFrom: Jonathan Woithe <[email protected]>
This patch (mostly from Peter Gruber) improves the handling of the hotkeys for P8010 laptops by passing more accurate input events back to userspace. This is needed because the P8010 labels these buttons quite differently to earlier laptops. As part of this, a P8010-specific DMI callback check has been implemented. Finally there's some minor whitespace cleanups from running the source through Lindent.
--- drivers/misc/fujitsu-laptop.c | 123 +++++++++++++++++++++++----------------- 1 files changed, 71 insertions(+), 52 deletions(-)
drivers/misc/fujitsu-laptop.c +71 -52
@@ -44,8 +44,9 @@* Hotkeys present on certain Fujitsu laptops (eg: the S6xxx series) are * also supported by this driver. * -* This driver has been tested on a Fujitsu Lifebook S6410 and S7020. It -* should work on most P-series and S-series Lifebooks, but YMMV. +* This driver has been tested on a Fujitsu Lifebook S6410, S7020 and +* P8010. It should work on most P-series and S-series Lifebooks, but +* YMMV. * * The module parameter use_alt_lcd_levels switches between different ACPI * brightness controls which are used by different Fujitsu laptops. In most
@@ -65,7 +66,7 @@#include <linux/video_output.h> #include <linux/platform_device.h> -#define FUJITSU_DRIVER_VERSION "0.4.2" +#define FUJITSU_DRIVER_VERSION "0.4.3"#define FUJITSU_LCD_N_LEVELS 8
@@ -83,10 +84,10 @@#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87/* Hotkey details */ -#define LOCK_KEY 0x410/* codes for the keys in the GIRB register */ -#define DISPLAY_KEY 0x411/* keys are mapped to KEY_SCREENLOCK (the key with the key symbol) */ -#define ENERGY_KEY 0x412/* KEY_MEDIA (the key with the laptop symbol, KEY_EMAIL (E key)) */ -#define REST_KEY 0x413/* KEY_SUSPEND (R key) */ +#define KEY1_CODE 0x410/* codes for the keys in the GIRB register */ +#define KEY2_CODE 0x411 +#define KEY3_CODE 0x412 +#define KEY4_CODE 0x413#define MAX_HOTKEY_RINGBUFFER_SIZE 100#define RINGBUFFERSIZE 40
@@ -123,6 +124,7 @@ struct fujitsu_t {char phys[32 ];struct backlight_device *bl_device;struct platform_device *pf_device; +int keycode1, keycode2, keycode3, keycode4;unsigned int max_brightness;unsigned int brightness_changed;
@@ -430,7 +432,7 @@ static struct platform_driver fujitsupf_driver = { } }; -static int dmi_check_cb_s6410 (const struct dmi_system_id *id) +static void dmi_check_cb_common (const struct dmi_system_id *id) {acpi_handle handle;int have_blnf;
@@ -452,24 +454,40 @@ static int dmi_check_cb_s6410(const struct dmi_system_id *id) "auto-detecting disable_adjust\n"); disable_brightness_adjust = have_blnf ?0 :1 ; } +} + +static int dmi_check_cb_s6410 (const struct dmi_system_id *id) +{ +dmi_check_cb_common (id); + fujitsu->keycode1 =KEY_SCREENLOCK ;/* "Lock" */ + fujitsu->keycode2 =KEY_HELP ;/* "Mobility Center" */ +return 0 ; +} + +static int dmi_check_cb_p8010 (const struct dmi_system_id *id) +{ +dmi_check_cb_common (id); + fujitsu->keycode1 =KEY_HELP ;/* "Support" */ + fujitsu->keycode3 =KEY_SWITCHVIDEOMODE ;/* "Presentation" */ + fujitsu->keycode4 =KEY_WWW ;/* "Internet" */ return 0 ; }static struct dmi_system_id __initdata fujitsu_dmi_table[] = { { - .ident ="Fujitsu Siemens" , + .ident ="Fujitsu Siemens S6410" , .matches = {DMI_MATCH (DMI_SYS_VENDOR ,"FUJITSU SIEMENS" ),DMI_MATCH (DMI_PRODUCT_NAME ,"LIFEBOOK S6410" ), }, .callback = dmi_check_cb_s6410}, { - .ident ="FUJITSU LifeBook P8010" , + .ident ="Fujitsu LifeBook P8010" , .matches = {DMI_MATCH (DMI_SYS_VENDOR ,"FUJITSU" ),DMI_MATCH (DMI_PRODUCT_NAME ,"LifeBook P8010" ), - }, - .callback = dmi_check_cb_s6410}, + }, + .callback = dmi_check_cb_p8010}, {} };
@@ -547,7 +565,6 @@ static int acpi_fujitsu_add(struct acpi_device *device) }/* do config (detect defaults) */ -dmi_check_system (fujitsu_dmi_table); use_alt_lcd_levels = use_alt_lcd_levels ==1 ?1 :0 ; disable_brightness_keys = disable_brightness_keys ==1 ?1 :0 ; disable_brightness_adjust = disable_brightness_adjust ==1 ?1 :0 ;
@@ -623,17 +640,17 @@ static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data) keycode =0 ;if (disable_brightness_keys !=1 ) {if (oldb ==0 ) { -acpi_bus_generate_proc_event (fujitsu-> - dev, -ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS , -0 ); +acpi_bus_generate_proc_event + (fujitsu->dev, +ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS , +0 ); keycode =KEY_BRIGHTNESSDOWN ; }else if (oldb == (fujitsu->max_brightness) -1 ) { -acpi_bus_generate_proc_event (fujitsu-> - dev, -ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS , -0 ); +acpi_bus_generate_proc_event + (fujitsu->dev, +ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS , +0 ); keycode =KEY_BRIGHTNESSUP ; } }
@@ -646,8 +663,7 @@ static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data) }if (disable_brightness_keys !=1 ) {acpi_bus_generate_proc_event (fujitsu->dev, -ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS , -0 ); +ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS ,0 ); keycode =KEY_BRIGHTNESSUP ; } }else if (oldb > newb) {
@@ -659,8 +675,7 @@ static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data) }if (disable_brightness_keys !=1 ) {acpi_bus_generate_proc_event (fujitsu->dev, -ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS , -0 ); +ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS ,0 ); keycode =KEY_BRIGHTNESSDOWN ; } }else {
@@ -742,10 +757,10 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) input->id.product =0x06 ; input->dev.parent = &device->dev; input->evbit[0 ] =BIT (EV_KEY ); -set_bit (KEY_SCREENLOCK , input->keybit); -set_bit (KEY_MEDIA , input->keybit); -set_bit (KEY_EMAIL , input->keybit); -set_bit (KEY_SUSPEND , input->keybit); +set_bit (fujitsu->keycode1, input->keybit); +set_bit (fujitsu->keycode2, input->keybit); +set_bit (fujitsu->keycode3, input->keybit); +set_bit (fujitsu->keycode4, input->keybit);set_bit (KEY_UNKNOWN , input->keybit); error =input_register_device (input);
@@ -833,24 +848,24 @@ static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event, irb);switch (irb &0x4ff ) { -case LOCK_KEY : - keycode =KEY_SCREENLOCK ; +case KEY1_CODE : + keycode = fujitsu->keycode1;break ; -case DISPLAY_KEY : - keycode =KEY_MEDIA ; +case KEY2_CODE : + keycode = fujitsu->keycode2;break ; -case ENERGY_KEY : - keycode =KEY_EMAIL ; +case KEY3_CODE : + keycode = fujitsu->keycode3;break ; -case REST_KEY : - keycode =KEY_SUSPEND ; +case KEY4_CODE : + keycode = fujitsu->keycode4;break ;case 0 : keycode =0 ;break ;default :vdbg_printk (FUJLAPTOP_DBG_WARN , -"Unknown GIRB result [%x]\n" , irb); +"Unknown GIRB result [%x]\n" , irb); keycode =-1 ;break ; }
@@ -859,12 +874,12 @@ static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,"Push keycode into ringbuffer [%d]\n" , keycode); status =kfifo_put (fujitsu_hotkey->fifo, - (unsigned char *)&keycode, -sizeof (keycode)); + (unsigned char *)&keycode, +sizeof (keycode));if (status !=sizeof (keycode)) {vdbg_printk (FUJLAPTOP_DBG_WARN , -"Could not push keycode [0x%x]\n" , - keycode); +"Could not push keycode [0x%x]\n" , + keycode); }else {input_report_key (input, keycode,1 );input_sync (input);
@@ -879,8 +894,8 @@ static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,input_report_key (input, keycode_r,0 );input_sync (input);vdbg_printk (FUJLAPTOP_DBG_TRACE , -"Pop keycode from ringbuffer [%d]\n" , - keycode_r); +"Pop keycode from ringbuffer [%d]\n" , + keycode_r); } } }
@@ -943,6 +958,11 @@ static int __init fujitsu_init(void)if (!fujitsu)return -ENOMEM ;memset (fujitsu,0 ,sizeof (struct fujitsu_t )); + fujitsu->keycode1 =KEY_PROG1 ; + fujitsu->keycode2 =KEY_PROG2 ; + fujitsu->keycode3 =KEY_PROG3 ; + fujitsu->keycode4 =KEY_PROG4 ; +dmi_check_system (fujitsu_dmi_table); result =acpi_bus_register_driver (&acpi_fujitsu_driver);if (result <0 ) {
@@ -1076,15 +1096,14 @@ MODULE_DESCRIPTION("Fujitsu laptop extras support");MODULE_VERSION (FUJITSU_DRIVER_VERSION );MODULE_LICENSE ("GPL" ); -MODULE_ALIAS - ("dmi:*:svnFUJITSUSIEMENS:*:pvr:rvnFUJITSU:rnFJNB1D3:*:cvrS6410:*" ); -MODULE_ALIAS - ("dmi:*:svnFUJITSU:*:pvr:rvnFUJITSU:rnFJNB19C:*:cvrS7020:*" ); +MODULE_ALIAS ("dmi:*:svnFUJITSUSIEMENS:*:pvr:rvnFUJITSU:rnFJNB1D3:*:cvrS6410:*" ); +MODULE_ALIAS ("dmi:*:svnFUJITSU:*:pvr:rvnFUJITSU:rnFJNB19C:*:cvrS7020:*" );static struct pnp_device_id pnp_ids[] = { - { .id ="FUJ02bf" }, - { .id ="FUJ02B1" }, - { .id ="FUJ02E3" }, - { .id ="" } + {.id ="FUJ02bf" }, + {.id ="FUJ02B1" }, + {.id ="FUJ02E3" }, + {.id ="" } }; +MODULE_DEVICE_TABLE (pnp, pnp_ids);
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 53/85 i7300_idle driver v1.55
In reply to Len BrownFrom: Venki Pallipadi <[email protected]>
The Intel 7300 Memory Controller supports dynamic throttling of memory which can be used to save power when system is idle. This driver does the memory throttling when all CPUs are idle on such a system.
Refer to "Intel 7300 Memory Controller Hub (MCH)" datasheet for the config space description.
--- MAINTAINERS | 6 ++++++ arch/x86/Kconfig | 2 ++ arch/x86/kernel/process_64.c | 7 +++++++ drivers/Makefile | 1 + drivers/dma/ioat_dma.c | 3 +++ include/asm-x86/idle.h | 1 + include/linux/pci_ids.h | 1 + 7 files changed, 21 insertions(+), 0 deletions(-)
MAINTAINERS +6 -0
@@ -2078,6 +2078,12 @@ L: [email protected] L: [email protected] S: Orphan +IDLE-I7300 +P: Andy Henroid +M: [email protected] +L: [email protected] +S: Supported + IEEE 1394 SUBSYSTEM (drivers/ieee1394) P: Ben Collins M: [email protected]
arch/x86/Kconfig +2 -0
@@ -1536,6 +1536,8 @@ source "arch/x86/kernel/cpu/cpufreq/Kconfig" source "drivers/cpuidle/Kconfig" +source "drivers/idle/Kconfig" + endmenu
arch/x86/kernel/process_64.c +7 -0
@@ -62,6 +62,13 @@ void idle_notifier_register(struct notifier_block *n) {atomic_notifier_chain_register (&idle_notifier, n); } +EXPORT_SYMBOL_GPL (idle_notifier_register); + +void idle_notifier_unregister (struct notifier_block *n) +{ +atomic_notifier_chain_unregister (&idle_notifier, n); +} +EXPORT_SYMBOL_GPL (idle_notifier_unregister);void enter_idle (void ) {
drivers/Makefile +1 -0
@@ -82,6 +82,7 @@ obj-$(CONFIG_EISA) += eisa/ obj-y += lguest/ obj-$(CONFIG_CPU_FREQ) += cpufreq/ obj-$(CONFIG_CPU_IDLE) += cpuidle/ +obj-y += idle/ obj-$(CONFIG_MMC) += mmc/ obj-$(CONFIG_MEMSTICK) += memstick/ obj-$(CONFIG_NEW_LEDS) += leds/
drivers/dma/ioat_dma.c +3 -0
@@ -171,6 +171,9 @@ static int ioat_dma_enumerate_channels(struct ioatdma_device *device) xfercap_scale =readb (device->reg_base +IOAT_XFERCAP_OFFSET ); xfercap = (xfercap_scale ==0 ?-1 : (1UL << xfercap_scale)); +#if CONFIG_I7300_IDLE_IOAT_CHANNEL + device->common.chancnt--; +#endif for (i =0 ; i < device->common.chancnt; i++) { ioat_chan =kzalloc (sizeof (*ioat_chan),GFP_KERNEL );if (!ioat_chan) {
include/asm-x86/idle.h +1 -0
@@ -6,6 +6,7 @@struct notifier_block ;void idle_notifier_register (struct notifier_block *n); +void idle_notifier_unregister (struct notifier_block *n);void enter_idle (void );void exit_idle (void );
include/linux/pci_ids.h +1 -0
@@ -2422,6 +2422,7 @@#define PCI_DEVICE_ID_INTEL_MCH_PC1 0x359a#define PCI_DEVICE_ID_INTEL_E7525_MCH 0x359e#define PCI_DEVICE_ID_INTEL_IOAT_CNB 0x360b +#define PCI_DEVICE_ID_INTEL_FBD_CNB 0x360c#define PCI_DEVICE_ID_INTEL_ICH10_0 0x3a14#define PCI_DEVICE_ID_INTEL_ICH10_1 0x3a16#define PCI_DEVICE_ID_INTEL_ICH10_2 0x3a18
Signature · 1 line
1.5.5.1
Re: [PATCH 53/85] i7300_idle driver v1.55
Len,
arch/x86/kernel/process_64.c void idle_notifier_register(struct notifier_block *n) · line 71
Quoted 13 lines · Len Brown
arch/x86/kernel/process_64.c +7
-0@@ -62,6 +62,13 @@ void idle_notifier_register(struct notifier_block *n) {atomic_notifier_chain_register (&idle_notifier, n); } +EXPORT_SYMBOL_GPL (idle_notifier_register); + +void idle_notifier_unregister (struct notifier_block *n) +{ +atomic_notifier_chain_unregister (&idle_notifier, n); +} +EXPORT_SYMBOL_GPL (idle_notifier_unregister);
hm, such x86 infrastructure changes should be submitted via the x86 tree, and you should at least have Cc:-ed the maintainers.
The thing is, we are _getting rid_ of the idle notifiers, not extending them. The last thing we need is random opaque stuff getting called in weird ordering when we enter/exit idle state. We want all that be visible and have explicit, in-source-code ordering.
Ingo
Len Brown
reviewerRe: [PATCH 53/85] i7300_idle driver v1.55
Quoted 18 lines
Quoted 5 lines
arch/x86/kernel/process_64.c void idle_notifier_register(struct notifier_block *n) · line 71
Quoted 10 lines
arch/x86/kernel/process_64.c +7
-0@@ -62,6 +62,13 @@ void idle_notifier_register(struct notifier_block *n) {atomic_notifier_chain_register (&idle_notifier, n); } +EXPORT_SYMBOL_GPL (idle_notifier_register); + +void idle_notifier_unregister (struct notifier_block *n) +{ +atomic_notifier_chain_unregister (&idle_notifier, n); +} +EXPORT_SYMBOL_GPL (idle_notifier_unregister);hm, such x86 infrastructure changes should be submitted via the x86 tree, and you should at least have Cc:-ed the maintainers.
I agree that this patch did not hit the list in the conventional way. I apologize for that, and I thank you, Ingo, for noticing the patch.
Quoted 4 lines
The thing is, we are
_gettingrid_of the idle notifiers, not extending them. The last thing we need is random opaque stuff getting called in weird ordering when we enter/exit idle state. We want all that be visible and have explicit, in-source-code ordering.
The patch on the table is basically a platform (chipset) idle hook. When the system is very idle, it saves energy in the memory sub-system. Linux customers are asking for this capability b/c it allows them to save energy and save money.
We considered putting a platform hook into the cpuidle code, but it seemed simpler this way -- since the new platform hook would end up looking almost exactly like the idle notifier that we have already. So x86-wise, all we did here is expose the register/unregister so the driver can be modular.
I'm certainly open to suggestions.
thanks,
-Len
Len Brown
reviewerPATCH 1/2 x86: allow module driver to register idle notifier
In reply to Ingo MolnarFrom: Venkatesh Pallipadi <[email protected]>
needed if the i7300_idle driver is to be a module.
--- arch/x86/kernel/process_64.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
arch/x86/kernel/process_64.c +7 -0
@@ -62,6 +62,13 @@ void idle_notifier_register(struct notifier_block *n) {atomic_notifier_chain_register (&idle_notifier, n); } +EXPORT_SYMBOL_GPL (idle_notifier_register); + +void idle_notifier_unregister (struct notifier_block *n) +{ +atomic_notifier_chain_unregister (&idle_notifier, n); +} +EXPORT_SYMBOL_GPL (idle_notifier_unregister);void enter_idle (void ) {
Signature · 1 line
1.6.0.2.532.g84ed4c
Len Brown
reviewerRe: [PATCH 1/2] x86: allow module driver to register idle notifier
Ingo,
How shall we proceed?
If you take this patch, we can ship a modular i7300_idle driver. If you do not take this patch, then we'll need to build it into the kernel and not allow it to un-register.
thanks,
-Len
Quoted 32 lines · Len Brown
From: Venkatesh Pallipadi <[email protected]>
needed if the
i7300_idledriver is to be a module.Signed-off-by Venkatesh Pallipadi <[email protected]>Signed-off-by Len Brown <[email protected]>--- arch/x86/kernel/process_64.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)arch/x86/kernel/process_64.c +7
-0@@ -62,6 +62,13 @@ void idle_notifier_register(struct notifier_block *n) {atomic_notifier_chain_register (&idle_notifier, n); } +EXPORT_SYMBOL_GPL (idle_notifier_register); + +void idle_notifier_unregister (struct notifier_block *n) +{ +atomic_notifier_chain_unregister (&idle_notifier, n); +} +EXPORT_SYMBOL_GPL (idle_notifier_unregister);void enter_idle (void ) {Signature · 1 line
1.6.0.2.532.g84ed4c
Ingo Molnar
Acked-byRe: [PATCH 1/2] x86: allow module driver to register idle notifier
Quoted 5 lines · Len Brown
Ingo,
How shall we proceed?
If you take this patch, we can ship a modulari7300_idledriver. If you do not take this patch, then we'll need to build it into the kernel and not allow it to un-register.
sorry - i got held up with other stuff.
Please just commit the export via your tree, we'll sort it out afterwards. Your use of the idle callback certainly looks reasonable for your purposes and the infrastructure was there after all. I dont want to complicate your workflow in any case.
Ingo
Len Brown
reviewerPATCH 2/2 i7300_idle driver v1.55
In reply to Ingo MolnarFrom: Andy Henroid <[email protected]>
The Intel 7300 Memory Controller supports dynamic throttling of memory which can be used to save power when system is idle. This driver does the memory throttling when all CPUs are idle on such a system.
Refer to "Intel 7300 Memory Controller Hub (MCH)" datasheet for the config space description.
--- MAINTAINERS | 6 + arch/x86/Kconfig | 2 + drivers/Makefile | 1 + drivers/dma/ioat_dma.c | 3 + drivers/idle/Kconfig | 16 + drivers/idle/Makefile | 2 + drivers/idle/i7300_idle.c | 674 +++++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/idle.h | 1 + include/linux/pci_ids.h | 1 + 9 files changed, 706 insertions(+), 0 deletions(-) create mode 100644 drivers/idle/Kconfig create mode 100644 drivers/idle/Makefile create mode 100644 drivers/idle/i7300_idle.c
MAINTAINERS +6 -0
@@ -2078,6 +2078,12 @@ L: [email protected] L: [email protected] S: Orphan +IDLE-I7300 +P: Andy Henroid +M: [email protected] +L: [email protected] +S: Supported + IEEE 1394 SUBSYSTEM (drivers/ieee1394) P: Ben Collins M: [email protected]
arch/x86/Kconfig +2 -0
@@ -1536,6 +1536,8 @@ source "arch/x86/kernel/cpu/cpufreq/Kconfig" source "drivers/cpuidle/Kconfig" +source "drivers/idle/Kconfig" + endmenu
drivers/Makefile +1 -0
@@ -82,6 +82,7 @@ obj-$(CONFIG_EISA) += eisa/ obj-y += lguest/ obj-$(CONFIG_CPU_FREQ) += cpufreq/ obj-$(CONFIG_CPU_IDLE) += cpuidle/ +obj-y += idle/ obj-$(CONFIG_MMC) += mmc/ obj-$(CONFIG_MEMSTICK) += memstick/ obj-$(CONFIG_NEW_LEDS) += leds/
drivers/dma/ioat_dma.c +3 -0
@@ -171,6 +171,9 @@ static int ioat_dma_enumerate_channels(struct ioatdma_device *device) xfercap_scale =readb (device->reg_base +IOAT_XFERCAP_OFFSET ); xfercap = (xfercap_scale ==0 ?-1 : (1UL << xfercap_scale)); +#if CONFIG_I7300_IDLE_IOAT_CHANNEL + device->common.chancnt--; +#endif for (i =0 ; i < device->common.chancnt; i++) { ioat_chan =kzalloc (sizeof (*ioat_chan),GFP_KERNEL );if (!ioat_chan) {
drivers/idle/Kconfig new file +16 -0
@@ -0,0 +1,16 @@ + +menu "Memory power savings" + +config I7300_IDLE_IOAT_CHANNEL + bool + +config I7300_IDLE + tristate "Intel chipset idle power saving driver" + select I7300_IDLE_IOAT_CHANNEL + depends on X86_64 + 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. + +endmenu
drivers/idle/Makefile new file +2 -0
@@ -0,0 +1,2 @@ +obj-$(CONFIG_I7300_IDLE) += i7300_idle.o +
drivers/idle/i7300_idle.c new file +674 -0
674 lines not on this page · raw message
include/asm-x86/idle.h +1 -0
@@ -6,6 +6,7 @@struct notifier_block ;void idle_notifier_register (struct notifier_block *n); +void idle_notifier_unregister (struct notifier_block *n);void enter_idle (void );void exit_idle (void );
include/linux/pci_ids.h +1 -0
@@ -2422,6 +2422,7 @@#define PCI_DEVICE_ID_INTEL_MCH_PC1 0x359a#define PCI_DEVICE_ID_INTEL_E7525_MCH 0x359e#define PCI_DEVICE_ID_INTEL_IOAT_CNB 0x360b +#define PCI_DEVICE_ID_INTEL_FBD_CNB 0x360c#define PCI_DEVICE_ID_INTEL_ICH10_0 0x3a14#define PCI_DEVICE_ID_INTEL_ICH10_1 0x3a16#define PCI_DEVICE_ID_INTEL_ICH10_2 0x3a18
Signature · 1 line
1.6.0.2.532.g84ed4c
Re: [PATCH 2/2] i7300_idle driver v1.55
Quoted 12 lines · On Thu, 16 Oct 2008 18:08:01 -0400 (EDT) Len Brown wrote:
From: Andy Henroid <[email protected]>
The Intel 7300 Memory Controller supports dynamic throttling of memory which can be used to save power when system is idle. This driver does the memory throttling when all CPUs are idle on such a system.
Refer to "Intel 7300 Memory Controller Hub (MCH)" datasheet for the config space description.
Signed-off-by Andy Henroid <[email protected]>Signed-off-by Len Brown <[email protected]>Signed-off-by Venkatesh Pallipadi <[email protected]>
Quoted 8 lines
--- MAINTAINERS | 6 + arch/x86/Kconfig | 2 + drivers/Makefile | 1 + drivers/dma/ioat_dma.c | 3 + drivers/idle/Kconfig | 16 + drivers/idle/Makefile | 2 + drivers/idle/i7300_idle.c | 674 +++++++++++++++++++++++++++++++++++++++++++++
Why not just use drivers/power/ instead of a new sub-directory?
Quoted 12 lines
include/asm-x86/idle.h | 1 + include/linux/pci_ids.h | 1 + 9 files changed, 706 insertions(+), 0 deletions(-) create mode 100644 drivers/idle/Kconfig create mode 100644 drivers/idle/Makefile create mode 100644 drivers/idle/i7300_idle.cMAINTAINERS +0
-0
MAINTAINERS L: [email protected] · line 2083
Quoted 6 lines
MAINTAINERS +3
-0@@ -2078,6 +2078,12 @@ L: [email protected] L: [email protected] S: Orphan +IDLE-I7300 +P: Andy Henroid +M: [email protected]
welcome back.
Quoted 17 lines
MAINTAINERS +3
-0+L: [email protected] +S: Supported + IEEE 1394 SUBSYSTEM (drivers/ieee1394) P: Ben Collins M: [email protected]drivers/idle/i7300_idle.c new file +4
-0@@ -0,0 +1,674 @@ +/* +* (C) Copyright 2008 Intel Corporation +* Authors: +* Andy Henroid <[email protected]>
drivers/idle/i7300_idle.c line 14
Quoted 10 lines
drivers/idle/i7300_idle.c new file +10
-0+* Venkatesh Pallipadi <[email protected]> +*/ + + +/* +* Value to set THRTLOW to when initiating throttling +* 0 = No throttling +* 1 = Throttle when > 4 activations per eval window (Maximum throttling) +* 2 = Throttle when > 8 activations +* 168 = Throttle when > 168 activations (Minimum throttling)
Why do some numbers mean > their value (i.e., 168) but others don't? Is it a linear value or logarithmic or what?
Quoted 13 lines
drivers/idle/i7300_idle.c new file +12
-0+*/ +#define MAX_THRTLWLIMIT 168 +static uint i7300_idle_thrtlowlm =1 ; +module_param_named (thrtlwlimit, i7300_idle_thrtlowlm, uint,0644 ); +MODULE_PARM_DESC (thrtlwlimit, +"Value for THRTLOWLM activation field " +"(0 = disable throttle, 1 = Max throttle, 168 = Min throttle)" ); + +/* Stop I/O AT memory copy */ +static void i7300_idle_ioat_stop (void ) +{ +int i;
drivers/idle/i7300_idle.c line 122
Quoted 10 lines
drivers/idle/i7300_idle.c new file +10
-0+u8 sts; + +for (i =0 ; i <5 ; i++) { +writeb (IOAT_CHANCMD_RESET , + ioat_chanbase +IOAT1_CHANCMD_OFFSET ); + +udelay (10 ); + + sts =readq (ioat_chanbase +IOAT1_CHANSTS_OFFSET ) & +IOAT_CHANSTS_DMA_TRANSFER_STATUS ;
readq() returns 64 bits. You only want to LS-byte of it here?
Quoted 13 lines
drivers/idle/i7300_idle.c new file +11
-0+if (sts !=IOAT_CHANSTS_DMA_TRANSFER_STATUS_ACTIVE ) +break ; + + } + +if (i ==5 ) +dprintk ("failed to suspend+reset I/O AT after 5 retries\n" ); + +} +struct debugfs_file_info { +void *ptr;
drivers/idle/i7300_idle.c line 612
Quoted 10 lines
drivers/idle/i7300_idle.c new file +10
-0+char name[32 ]; +struct dentry *file; +} debugfs_file_list[] = { + {&total_starts, "total_starts", NULL}, + {&total_us, "total_us", NULL}, +#ifdef DEBUG + {&past_skip, "past_skip", NULL}, +#endif + {NULL, "", NULL} + };
What is debugfs used for? any docs for it?
Does this build/work if CONFIG_DEBUG_FS=n?
Quoted 25 lines
drivers/idle/i7300_idle.c new file +25
-0+static int __init i7300_idle_init (void ) +{ +spin_lock_init (&i7300_idle_lock); +cpus_clear (idle_cpumask); + total_us =0 ; + +if (i7300_idle_platform_probe ()) +return -ENODEV ; + +if (i7300_idle_thrt_save ()) +return -ENODEV ; + +if (i7300_idle_ioat_init ()) +return -ENODEV ; + + debugfs_dir =debugfs_create_dir ("i7300_idle" ,NULL ); +if (debugfs_dir) { +int i =0 ; + +while (debugfs_file_list[i].ptr !=NULL ) { + debugfs_file_list[i].file = debugfs_create_file( + debugfs_file_list[i].name, + S_IRUSR, + debugfs_dir, + debugfs_file_list[i].ptr,
drivers/idle/i7300_idle.c line 648
Quoted 10 lines
drivers/idle/i7300_idle.c new file +10
-0+ &idle_fops); + i++; + } + } + +idle_notifier_register (&i7300_idle_nb); + +printk (KERN_INFO "i7300_idle: loaded v%s\n" ,I7300_IDLE_DRIVER_VERSION ); +return 0 ; +}
---
~Randy
RE: [PATCH 2/2] i7300_idle driver v1.55
Thanks for the review. Some comments below.
Thanks,
Venki
Quoted 22 lines
-----Original Message-----
From: Randy Dunlap [mailto:[email protected]]
Sent: Monday, October 20, 2008 10:32 AM
To: Len Brown
Cc: Ingo Molnar; [email protected]; Linux Kernel Mailing List; Pallipadi, Venkatesh; Henroid, Andrew D; Linus Torvalds; Thomas Gleixner; H. Peter Anvin; Andi Kleen
Subject: Re: [PATCH 2/2]i7300_idledriver v1.55Quoted 11 lines · On Thu, 16 Oct 2008 18:08:01 -0400 (EDT) Len Brown wrote:
Signed-off-by Andy Henroid <[email protected]>Signed-off-by Len Brown <[email protected]>Signed-off-by Venkatesh Pallipadi <[email protected]>--- MAINTAINERS | 6 + arch/x86/Kconfig | 2 + drivers/Makefile | 1 + drivers/dma/ioat_dma.c | 3 + drivers/idle/Kconfig | 16 + drivers/idle/Makefile | 2 + drivers/idle/i7300_idle.c | 674
Quoted 3 lines
+++++++++++++++++++++++++++++++++++++++++++++
Why not just use
drivers/power/instead of a new sub-directory?
As the driver was specific to idle system and specific to few platforms/chipset, we decided to put it in a separate directory. We had called the new directory as drivers/memory initially. But, idle seemed to suit it better.
I have no issues moving this over to drivers/power. Will send a incremental patch to move it if that suits better. But, if we Expect other platforms to have similar platform specific idle power savings through drivers like this, then having a separate dir to deal with idle optimization should be better.
Quoted 10 lines
Quoted 4 lines
+/*
+ * Value to set THRTLOW to when initiating throttling
+ * 0 = No throttling
+ * 1 = Throttle when > 4 activations per eval window(Maximum throttling)
Quoted 2 lines
+ * 2 = Throttle when > 8 activations
+ * 168 = Throttle when > 168 activations (Minimum throttling)Why do some numbers mean > their value (i.e., 168) but others don't? Is it a linear value or logarithmic or what?
That is a typo in the comment. These values are simple "multiply by 4". So, 168 should be 672 activations, and that is the minimum possible throttling.
Quoted 10 lines
drivers/idle/i7300_idle.c
Quoted 7 lines
+ */
drivers/idle/i7300_idle.c new file +6
-0+#define MAX_THRTLWLIMIT 168 +static uint i7300_idle_thrtlowlm =1 ; +module_param_named (thrtlwlimit, i7300_idle_thrtlowlm, uint,0644 ); +MODULE_PARM_DESC (thrtlwlimit, +"Value for THRTLOWLM activation field " + "(0 = disable throttle, 1 = Max throttle, 168= Min throttle)");
Quoted 1 line
+
Quoted 16 lines
Quoted 4 lines
drivers/idle/i7300_idle.c new file +4
-0+/* Stop I/O AT memory copy */ +static void i7300_idle_ioat_stop (void ) +{ +int i;drivers/idle/i7300_idle.c line 122
Quoted 10 lines
drivers/idle/i7300_idle.c new file +10
-0+u8 sts; + +for (i =0 ; i <5 ; i++) { +writeb (IOAT_CHANCMD_RESET , + ioat_chanbase +IOAT1_CHANCMD_OFFSET ); + +udelay (10 ); + + sts =readq (ioat_chanbase +IOAT1_CHANSTS_OFFSET ) & +IOAT_CHANSTS_DMA_TRANSFER_STATUS ;
readq()returns 64 bits. You only want to LS-byte of it here?
CHANSTS is a 64 bit register and we only use lower few bits around here. But, agree with your comment and will change it sts to u64 with an update patch. That will make it consistent with other reads of this register in this file
Quoted 13 lines
drivers/idle/i7300_idle.c
Quoted 8 lines
drivers/idle/i7300_idle.c new file +7
-0+if (sts !=IOAT_CHANSTS_DMA_TRANSFER_STATUS_ACTIVE ) +break ; + + } + +if (i ==5 ) + dprintk("failed to suspend+reset I/O AT after5 retries\n");
Quoted 2 lines
(quoted diff) +2
-0+ +}
Quoted 14 lines
drivers/idle/i7300_idle.c line 612
Quoted 12 lines
drivers/idle/i7300_idle.c new file +12
-0+struct debugfs_file_info { +void *ptr; +char name[32 ]; +struct dentry *file; +} debugfs_file_list[] = { + {&total_starts,"total_starts" ,NULL }, + {&total_us,"total_us" ,NULL }, +#ifdef DEBUG + {&past_skip,"past_skip" ,NULL }, +#endif + {NULL ,"" ,NULL } + };What is debugfs used for? any docs for it?
It has some statistics about how many times we went into "memory throttling" state and how long we stayed there since the boot. And one tunable that tunes a parameter changing the policy to start throttling. Will document this with an update patch.
Quoted 2 lines
Does this build/work if
CONFIG_DEBUG_FS=n?
Yes. Did not see any breakage with DEBIG_FS=n
Re: [PATCH 2/2] i7300_idle driver v1.55
Quoted 5 lines · Venkatesh
Thanks for the review. Some comments below.
Thanks,
Venki
Quoted 7 lines
Quoted 1 line
What is debugfs used for? any docs for it?
It has some statistics about how many times we went into "memory throttling" state and how long we stayed there since the boot. And one tunable that tunes a parameter changing the policy to start throttling. Will document this with an update patch.
"Normal" tunables should be in sysfs, not debugfs. Or is this just a debugging tunable?
You surely can't be certain (or require) that debugfs be available.
~Randy
RE: [PATCH 2/2] i7300_idle driver v1.55
Quoted 26 lines
-----Original Message-----
From: Randy Dunlap [mailto:[email protected]]
Sent: Tuesday, October 21, 2008 3:15 PM
To: Pallipadi, Venkatesh
Cc: Randy Dunlap; Len Brown; Ingo Molnar; [email protected]; Linux Kernel Mailing List; Henroid, Andrew D; Linus Torvalds; Thomas Gleixner; H. Peter Anvin; Andi Kleen
Subject: Re: [PATCH 2/2]i7300_idledriver v1.55Quoted 5 lines · Venkatesh
Thanks for the review. Some comments below.
Thanks,
VenkiQuoted 7 lines
Quoted 1 line
What is debugfs used for? any docs for it?
It has some statistics about how many times we went into "memory throttling" state and how long we stayed there since the boot. And one tunable that tunes a parameter changing the policy to start throttling. Will document this with an update patch.
Quoted 6 lines
"Normal" tunables should be in sysfs, not debugfs. Or is this just a debugging tunable?
You surely can't be certain (or require) that debugfs be available.
The lone tunable is debug only. It needs driver to be compiled with DEBUG flag to be present in debugfs. We don't want export it in sysfs and some random user app starts using it and then end up providing backward compatibility for it in future.
The other two read only variables give some stats about the driver usage and also kind of debuggish info that we used during development. Didn't seem worthy enough to go under sysfs.
Thanks,
Venki
Re: [PATCH 2/2] i7300_idle driver v1.55
In reply to Len Browndrivers/dma/ioat_dma.c static int ioat_dma_enumerate_channels(struct ioatdma_device *device) · line 176
Quoted 11 lines · Len Brown
drivers/dma/ioat_dma.c +3
-0@@ -171,6 +171,9 @@ static int ioat_dma_enumerate_channels(struct ioatdma_device *device) xfercap_scale =readb (device->reg_base +IOAT_XFERCAP_OFFSET ); xfercap = (xfercap_scale ==0 ?-1 : (1UL << xfercap_scale)); +#if CONFIG_I7300_IDLE_IOAT_CHANNEL + device->common.chancnt--; +#endif
I still think this lone decrement looks fishy. Can there please be some explanation how it exactly relates to the i7300 idle driver, where the matching increment is, etc.?
drivers/dma/ioat_dma.c static int ioat_dma_enumerate_channels(struct ioatdma_device *device) · line 178
Quoted 2 lines
drivers/dma/ioat_dma.c +2
-0+config I7300_IDLE + tristate"Intel chipset idle power saving driver"
It would be probably good to mention the word memory here.
drivers/dma/ioat_dma.c static int ioat_dma_enumerate_channels(struct ioatdma_device *device)
Quoted 4 lines
drivers/dma/ioat_dma.c +4
-0+ select I7300_IDLE_IOAT_CHANNEL + depends on X86_64 + help + Enable idle power savings with certain Intel server chipsets.
And here too.
drivers/dma/ioat_dma.c
Quoted 10 lines
drivers/dma/ioat_dma.c +7
-0+ 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. +static int debug; +module_param_named (debug, debug, uint,0644 ); +MODULE_PARM_DESC (debug,"Enable debug printks in this driver" ); +#define dprintk(fmt, arg...) \ + do { if (debug) printk(KERN_INFO I7300_PRINT fmt, ##arg); } while (0)
2.6.28 just got a new dynamic printk facility, which could be used.
drivers/dma/ioat_dma.c
Quoted 11 lines
drivers/dma/ioat_dma.c +11
-0+ +/* +* Value to set THRTLOW to when initiating throttling +* 0 = No throttling +* 1 = Throttle when > 4 activations per eval window (Maximum throttling) +* 2 = Throttle when > 8 activations +* 168 = Throttle when > 168 activations (Minimum throttling) +*/ +#define MAX_THRTLWLIMIT 168 +static uint i7300_idle_thrtlowlm =1 ; +module_param_named (thrtlwlimit, i7300_idle_thrtlowlm, uint,0644 );
Just imagining how someone would pronounce this parameter @) Will they get damages when their tongue ends up in a knot?
Quoted 1 line
+static
cpumask_tidle_cpumask;
Would it make sense to cache align this field? I could imagine it false sharing with some frequently written variable could be quite bad.
drivers/dma/ioat_dma.c
Quoted 7 lines
drivers/dma/ioat_dma.c +7
-0+writeb (IOAT_CHANCMD_RESET , ioat_chanbase +IOAT1_CHANCMD_OFFSET ); +writeb (IOAT_CHANCMD_START , ioat_chanbase +IOAT1_CHANCMD_OFFSET ); + +udelay (1000 ); + + chan_sts =readq (ioat_chanbase +IOAT1_CHANSTS_OFFSET ) & +IOAT_CHANSTS_DMA_TRANSFER_STATUS ;
Wouldn't it be better to poll here instead of udelay?
drivers/dma/ioat_dma.c
Quoted 13 lines
drivers/dma/ioat_dma.c +13
-0+/* Wait for a while for the channel to halt before releasing */ +for (i =0 ; i <10 ; i++) { +writeb (IOAT_CHANCMD_RESET , + ioat_chanbase +IOAT1_CHANCMD_OFFSET ); + + chan_sts =readq (ioat_chanbase +IOAT1_CHANSTS_OFFSET ) & +IOAT_CHANSTS_DMA_TRANSFER_STATUS ; + +if (chan_sts !=IOAT_CHANSTS_DMA_TRANSFER_STATUS_ACTIVE ) { +writew (0 , ioat_chanbase +IOAT_CHANCTRL_OFFSET ); +break ; + } +udelay (1000 );
Same here.
drivers/dma/ioat_dma.c
Quoted 1 line
drivers/dma/ioat_dma.c +1
-0+spin_lock_irqsave (&i7300_idle_lock, flags);
This lock still scares me. In the worst case with very frequent idle frequencies this could bounce around a lot.
It would be better to only invoke it less frequently, i.e. when the driver determines there is a long idle time coming up.
drivers/dma/ioat_dma.c
Quoted 6 lines
drivers/dma/ioat_dma.c +6
-0+/* 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 )
Is there a specific reason you cannot match this by pci vendor/devid like all standard drivers do?
If there is a good reason add a comment.
;
drivers/dma/ioat_dma.c
Quoted 3 lines
drivers/dma/ioat_dma.c +3
-0+static void __exit i7300_idle_exit(void) +{ +idle_notifier_unregister (&i7300_idle_nb);
I still think this needs some kind of idle synchronization.
-Andi
RE: [PATCH 2/2] i7300_idle driver v1.55
Quoted 22 lines
-----Original Message-----
From: Andi Kleen [mailto:[email protected]]
Sent: Tuesday, October 21, 2008 9:48 AM
To: Len Brown
Cc: Ingo Molnar; [email protected]; Linux Kernel Mailing List; Pallipadi, Venkatesh; Henroid, Andrew D; Linus Torvalds; Thomas Gleixner; H. Peter Anvin
Subject: Re: [PATCH 2/2]i7300_idledriver v1.55drivers/dma/ioat_dma.c static int
Quoted 5 lines · Len Brown
drivers/dma/ioat_dma.c +0
-0@@ -171,6 +171,9 @@ static int
ioat_dma_enumerate_channels(struct ioatdma_device *device)Quoted 3 lines
drivers/dma/ioat_dma.c +0
-0xfercap_scale =readb (device->reg_base +IOAT_XFERCAP_OFFSET ); xfercap = (xfercap_scale ==0 ?-1 : (1UL << xfercap_scale));
Quoted 7 lines
drivers/dma/ioat_dma.c static int ioat_dma_enumerate_channels(struct ioatdma_device *device) · line 176
Quoted 3 lines
drivers/dma/ioat_dma.c +3
-0+#if CONFIG_I7300_IDLE_IOAT_CHANNEL + device->common.chancnt--; +#endif I still think this lone decrement looks fishy. Can there please be some explanation how it exactly relates to the i7300 idle driver, where the matching increment is, etc.?
No. This is not a increment/decrement thing. It is basically telling other Users of IOAT that they have one IOAT channel less that they can use. The last IOAT channel is used by i7300 idle driver to get the throttling to work.
Quoted 11 lines
drivers/dma/ioat_dma.c static int · line 178
Quoted 2 lines
drivers/dma/ioat_dma.c +2
-0+config I7300_IDLE + tristate"Intel chipset idle power saving driver" It would be probably good to mention the word memory here.
drivers/dma/ioat_dma.c static int
Quoted 4 lines
drivers/dma/ioat_dma.c +4
-0+ select I7300_IDLE_IOAT_CHANNEL + depends on X86_64 + help + Enable idle power savings with certain Intel server chipsets.And here too.
OK. Will do.
Quoted 9 lines
drivers/dma/ioat_dma.c
Quoted 2 lines
drivers/dma/ioat_dma.c +2
-0+ The chipset must have I/O AT support, such as the Intel 7300. + The power savings depends on the type and quantityof DRAM devices.
Quoted 3 lines
drivers/dma/ioat_dma.c +3
-0+static int debug; +module_param_named (debug, debug, uint,0644 ); +MODULE_PARM_DESC (debug,"Enable debug printks in this driver" );
Quoted 5 lines
drivers/dma/ioat_dma.c
Quoted 2 lines
drivers/dma/ioat_dma.c +2
-0+#define dprintk(fmt, arg...) \ + do { if (debug) printk(KERN_INFO I7300_PRINT fmt,##arg); } while (0)
2.6.28 just got a new dynamic printk facility, which could be used.
Haven't looked at dynamic printk yet. Will take a look at it and update.
Quoted 6 lines
drivers/dma/ioat_dma.c
Quoted 5 lines
drivers/dma/ioat_dma.c +5
-0+ +/* +* Value to set THRTLOW to when initiating throttling +* 0 = No throttling +* 1 = Throttle when > 4 activations per eval window (Maximum throttling)
Quoted 9 lines
drivers/dma/ioat_dma.c
Quoted 6 lines
+ * 2 = Throttle when > 8 activations
+ * 168 = Throttle when > 168 activations (Minimum throttling)
+ */drivers/dma/ioat_dma.c +3
-0+#define MAX_THRTLWLIMIT 168 +static uint i7300_idle_thrtlowlm =1 ; +module_param_named (thrtlwlimit, i7300_idle_thrtlowlm, uint,0644 );Just imagining how someone would pronounce this parameter @) Will they get damages when their tongue ends up in a knot?
:-). It was a balance between keeping the name short and have all the words idle, 7300, throttle, low and limit. And initially it wasn't through mod param. I guess this being modparam, I can remove i7300 and idle and make it just throttle_limit
Quoted 9 lines
Quoted 1 line
+static
cpumask_tidle_cpumask;Would it make sense to cache align this field? I could imagine it false sharing with some frequently written variable could be quite bad.
Quoted 1 line
+ writeb(IOAT_CHANCMD_RESET,
ioat_chanbase+
IOAT1_CHANCMD_OFFSET);Quoted 1 line
+ writeb(IOAT_CHANCMD_START,
ioat_chanbase+
Quoted 8 lines
IOAT1_CHANCMD_OFFSET);drivers/dma/ioat_dma.c
Quoted 5 lines
drivers/dma/ioat_dma.c +5
-0+ +udelay (1000 ); + + chan_sts =readq (ioat_chanbase +IOAT1_CHANSTS_OFFSET ) & +IOAT_CHANSTS_DMA_TRANSFER_STATUS ;Wouldn't it be better to poll here instead of udelay?
udelay may be more power efficient than polling. We wont be reading from chipset continuously. But on the other hand polling seems better choice if we are too far off from our 1000 uS guess. Will try polling and check how long we are really waiting here...
Quoted 21 lines
drivers/dma/ioat_dma.c
Quoted 7 lines
drivers/dma/ioat_dma.c +6
-0+/* Wait for a while for the channel to halt before releasing */ +for (i =0 ; i <10 ; i++) { +writeb (IOAT_CHANCMD_RESET , + ioat_chanbase +IOAT1_CHANCMD_OFFSET ); + + chan_sts = readq(ioat_chanbase +
IOAT1_CHANSTS_OFFSET) &drivers/dma/ioat_dma.c
Quoted 3 lines
drivers/dma/ioat_dma.c +3
-0+IOAT_CHANSTS_DMA_TRANSFER_STATUS ; + + if (chan_sts !=
IOAT_CHANSTS_DMA_TRANSFER_STATUS_ACTIVE) {Quoted 1 line
+ writew(0,
ioat_chanbase+
IOAT_CHANCTRL_OFFSET);drivers/dma/ioat_dma.c
Quoted 3 lines
drivers/dma/ioat_dma.c +3
-0+break ; + } +udelay (1000 );Same here.
Quoted 8 lines
Quoted 1 line
+
spin_lock_irqsave(&i7300_idle_lock, flags);This lock still scares me. In the worst case with very frequent idle frequencies this could bounce around a lot.
It would be better to only invoke it less frequently, i.e. when the driver determines there is a long idle time coming up.
Agreed. First version was to get the low hanging fruit of huge power savings that we can get on these platforms by throttling memory. We did not spend enough time on optimizing this for performance. Will do this as a follow up.
Quoted 11 lines
drivers/dma/ioat_dma.c
Quoted 6 lines
drivers/dma/ioat_dma.c +6
-0+/* 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 )Is there a specific reason you cannot match this by pci vendor/devid like all standard drivers do?
If there is a good reason add a comment.
They have to match vendor device and function. Its not unique to just vendor and device id.
Quoted 6 lines
;
drivers/dma/ioat_dma.c
Quoted 3 lines
drivers/dma/ioat_dma.c +3
-0+static void __exit i7300_idle_exit(void) +{ +idle_notifier_unregister (&i7300_idle_nb);I still think this needs some kind of idle synchronization.
This unregister uses atomic_notifier_chain_unregister() which uses RCU and handles the race conditions that way. I did not see any race conditions with module unload in my analysis.
Thanks,
Venki
Re: [PATCH 2/2] i7300_idle driver v1.55
Quoted 8 lines · Venkatesh
Quoted 7 lines
drivers/dma/ioat_dma.c static int ioat_dma_enumerate_channels(struct ioatdma_device *device) · line 176
Quoted 4 lines
drivers/dma/ioat_dma.c +3
-0+#if CONFIG_I7300_IDLE_IOAT_CHANNEL + device->common.chancnt--; +#endif I still think this lone decrement looks fishy. Can there please be some explanation how it exactly relates to the i7300 idle driver, where the matching increment is, etc.?
Quoted 4 lines
No. This is not a increment/decrement thing. It is basically telling other Users of IOAT that they have one IOAT channel less that they can use. The last IOAT channel is used by i7300 idle driver to get the throttling to work.
Ok then it should be made conditional on the i7300 actually be available in the system? It looks like you do it always no matter what chipset is in there.
Quoted 1 line
udelay may be more power efficient than polling.
Isn't that function a one off anyways?
Quoted 9 lines
Quoted 9 lines
drivers/idle/i7300_idle.c
Quoted 6 lines
drivers/idle/i7300_idle.c new file +6
-0+/* 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 )Is there a specific reason you cannot match this by pci vendor/devid like all standard drivers do?
Quoted 4 lines
Quoted 1 line
If there is a good reason add a comment.
They have to match vendor device and function. Its not unique to just vendor and device id.
It might be still better then to use the standard callback style and just ignore devices that don't match?
Quoted 9 lines
Quoted 6 lines
;
drivers/idle/i7300_idle.c line 652
Quoted 3 lines
drivers/idle/i7300_idle.c new file +3
-0+static void __exit i7300_idle_exit(void) +{ +idle_notifier_unregister (&i7300_idle_nb);I still think this needs some kind of idle synchronization.
This unregister uses
atomic_notifier_chain_unregister()which uses RCU and handles the race conditions that way.
I didn't do a full analysis, but I didn't think RCU protects against the idle handler itself. At least not standard RCU. You would need to go through at least two quiescent periods, not one as standard code.
There used to be an older
idle synchronization interface for this case (which was removed at some point), perhaps it needs to be readded.
Or just use stop_machine(). That protects against idle too and while it's a big hammer for unloading it should be ok.
-Andi
PATCH 1/1 Disable ioat channel only on platforms where ile driver can load
Quoted 9 lines · Andi Kleen
Quoted 8 lines · Venkatesh
Quoted 7 lines
Review
Quoted 4 lines
(quoted diff) +3
-0+#if CONFIG_I7300_IDLE_IOAT_CHANNEL + device->common.chancnt--; +#endifI still think this lone decrement looks fishy. Can there please be some explanation how it exactly relates to the i7300 idle driver, where the matching increment is, etc.?
Quoted 7 lines
Quoted 4 lines
No. This is not a increment/decrement thing. It is basically telling other Users of IOAT that they have one IOAT channel less that they can use. The last IOAT channel is used by i7300 idle driver to get the throttling to work.
Ok then it should be made conditional on the i7300 actually be available in the system? It looks like you do it always no matter what chipset is in there.
Does the patch below look OK?
Thanks,
Venki
Based on input from Andi Kleen:
share the platform detection code with ioat_dma and disable the channel in dma engine only for specific platforms.
--- drivers/dma/ioat_dma.c | 5 ++ drivers/idle/i7300_idle.c | 72 +-------------------------------------- include/linux/i7300_idle.h | 83 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 71 deletions(-)
drivers/idle/i7300_idle.c +2 -70
@@ -25,6 +25,7 @@#include <linux/delay.h> #include <linux/debugfs.h> #include <linux/stop_machine.h> +#include <linux/i7300_idle.h> #include <asm/idle.h>
@@ -505,77 +506,8 @@ static struct notifier_block i7300_idle_ .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); -/* 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) { fp->private_data = inode->i_private;
@@ -617,7 +549,7 @@ static int __init i7300_idle_init(void)cpus_clear (idle_cpumask); total_us =0 ; -if (i7300_idle_platform_probe ()) +if (i7300_idle_platform_probe (&fbd_dev, &ioat_dev))return -ENODEV ;if (i7300_idle_thrt_save ())
include/linux/i7300_idle.h new file +83 -0
83 lines not on this page · raw message
drivers/dma/ioat_dma.c +4 -1
@@ -33,6 +33,7 @@#include <linux/delay.h> #include <linux/dma-mapping.h> #include <linux/workqueue.h> +#include <linux/i7300_idle.h> #include "ioatdma.h" #include "ioatdma_registers.h" #include "ioatdma_hw.h"
@@ -172,7 +173,9 @@ static int ioat_dma_enumerate_channels(s xfercap = (xfercap_scale ==0 ?-1 : (1UL << xfercap_scale));#if CONFIG_I7300_IDLE_IOAT_CHANNEL - device->common.chancnt--; +if (i7300_idle_platform_probe (NULL ,NULL ) ==0 ) { + device->common.chancnt--; + }#endif for (i =0 ; i < device->common.chancnt; i++) { ioat_chan =kzalloc (sizeof (*ioat_chan),GFP_KERNEL );
Re: [PATCH] Cleanup of i7300_idle based on review comments
Cleanup of i7300 idle driver based on review comments from Randy Dunlap, Andi Kleen and Len Brown.
--- drivers/idle/Kconfig | 11 ++++++----- drivers/idle/i7300_idle.c | 33 ++++++++++++++++++--------------- 2 files changed, 24 insertions(+), 20 deletions(-)
drivers/idle/Kconfig +6 -5
@@ -5,12 +5,13 @@ config I7300_IDLE_IOAT_CHANNEL bool config I7300_IDLE - tristate "Intel chipset idle power saving driver" + tristate "Intel chipset idle memory power saving driver" select I7300_IDLE_IOAT_CHANNEL - depends on X86_64 + depends on X86_64 && EXPERIMENTAL 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
drivers/idle/i7300_idle.c +18 -15
@@ -35,6 +35,8 @@#define I7300_IDLE_DRIVER_VERSION "1.55"#define I7300_PRINT "i7300_idle:" +#define MAX_STOP_RETRIES 10 +static int debug;module_param_named (debug, debug, uint,0644 );MODULE_PARM_DESC (debug,"Enable debug printks in this driver" );
@@ -47,12 +49,12 @@ MODULE_PARM_DESC(debug, "Enable debug pr* 0 = No throttling * 1 = Throttle when > 4 activations per eval window (Maximum throttling) * 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 " "(0 = disable throttle, 1 = Max throttle, 168 = Min throttle)" );
@@ -111,9 +113,9 @@ static int i7300_idle_ioat_start(void)static void i7300_idle_ioat_stop (void ) {int i; -u8 sts; +u64 sts; -for (i =0 ; i <5 ; i++) { +for (i =0 ; i <MAX_STOP_RETRIES ; i++) {writeb (IOAT_CHANCMD_RESET , ioat_chanbase +IOAT1_CHANCMD_OFFSET );
@@ -127,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 */
@@ -276,7 +279,7 @@ static void __exit i7300_idle_ioat_exit(i7300_idle_ioat_stop ();/* 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 , ioat_chanbase +IOAT1_CHANCMD_OFFSET );
@@ -390,9 +393,9 @@ static void i7300_idle_start(void) new_ctl = i7300_idle_thrtctl_saved & ~DIMM_THRTCTL_THRMHUNT ;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);
@@ -441,7 +444,7 @@ static int i7300_idle_notifier(struct nostatic ktime_t idle_begin_time;static int time_init =1 ; -if (!i7300_idle_thrtlowlm) +if (!throttle_low_limit)return 0 ;if (unlikely (time_init)) {
Len Brown
reviewerRe: [PATCH] Cleanup of i7300_idle based on review comments
applied to acpi-test
thanks,
-len
Quoted 129 lines · Venki Pallipadi
Cleanup of i7300 idle driver based on review comments from Randy Dunlap, Andi Kleen and Len Brown.
Signed-off-by Venkatesh Pallipadi <[email protected]>--- drivers/idle/Kconfig | 11 ++++++----- drivers/idle/i7300_idle.c | 33 ++++++++++++++++++--------------- 2 files changed, 24 insertions(+), 20 deletions(-)Index: linux-acpi-2.6/drivers/idle/Kconfig
===================================================================drivers/idle/Kconfig +6
-5@@ -5,12 +5,13 @@ config I7300_IDLE_IOAT_CHANNEL bool config I7300_IDLE - tristate "Intel chipset idle power saving driver" + tristate "Intel chipset idle memory power saving driver" select I7300_IDLE_IOAT_CHANNEL - depends on X86_64 + depends on X86_64 && EXPERIMENTAL 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. endmenuIndex:
linux-acpi-2.6/drivers/idle/i7300_idle.c
===================================================================drivers/idle/i7300_idle.c +18
-16@@ -35,6 +35,8 @@#define I7300_IDLE_DRIVER_VERSION "1.55"#define I7300_PRINT "i7300_idle:" +#define MAX_STOP_RETRIES 10 +static int debug;module_param_named (debug, debug, uint,0644 );MODULE_PARM_DESC (debug,"Enable debug printks in this driver" );@@ -47,12 +49,12 @@ MODULE_PARM_DESC(debug, "Enable debug pr* 0 = No throttling * 1 = Throttle when > 4 activations per eval window (Maximum throttling) * 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 " "(0 = disable throttle, 1 = Max throttle, 168 = Min throttle)" );@@ -111,9 +113,9 @@ static int i7300_idle_ioat_start(void)static void i7300_idle_ioat_stop (void ) {int i; -u8 sts; +u64 sts; -for (i =0 ; i <5 ; i++) { +for (i =0 ; i <MAX_STOP_RETRIES ; i++) {writeb (IOAT_CHANCMD_RESET , ioat_chanbase +IOAT1_CHANCMD_OFFSET );@@ -127,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 */ @@ -276,7 +279,7 @@ static void __exit i7300_idle_ioat_exit(i7300_idle_ioat_stop ();/* 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 , ioat_chanbase +IOAT1_CHANCMD_OFFSET );@@ -390,9 +393,9 @@ static void i7300_idle_start(void) new_ctl = i7300_idle_thrtctl_saved & ~DIMM_THRTCTL_THRMHUNT ;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);@@ -441,7 +444,7 @@ static int i7300_idle_notifier(struct nostatic ktime_t idle_begin_time;static int time_init =1 ; -if (!i7300_idle_thrtlowlm) +if (!throttle_low_limit)return 0 ;if (unlikely (time_init)) { --To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Len Brown
reviewerRe: [PATCH] Disable ioat channel only on platforms where ile driver can load
In reply to Venki Pallipadiapplied to acpi-test
thanks,
-len
Quoted 251 lines · Venki Pallipadi
Quoted 9 lines · Andi Kleen
Quoted 8 lines · Venkatesh
Quoted 7 lines
Review
Quoted 4 lines
(quoted diff) +3
-0+#if CONFIG_I7300_IDLE_IOAT_CHANNEL + device->common.chancnt--; +#endifI still think this lone decrement looks fishy. Can there please be some explanation how it exactly relates to the i7300 idle driver, where the matching increment is, etc.?
Quoted 7 lines
Quoted 4 lines
No. This is not a increment/decrement thing. It is basically telling other Users of IOAT that they have one IOAT channel less that they can use. The last IOAT channel is used by i7300 idle driver to get the throttling to work.
Ok then it should be made conditional on the i7300 actually be available in the system? It looks like you do it always no matter what chipset is in there.
Does the patch below look OK?
Thanks,
VenkiBased on input from Andi Kleen:
share the platform detection code withioat_dmaand disable the channel in dma engine only for specific platforms.Signed-off-by Venkatesh Pallipadi <[email protected]>--- drivers/dma/ioat_dma.c | 5 ++ drivers/idle/i7300_idle.c | 72 +-------------------------------------- include/linux/i7300_idle.h | 83 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 71 deletions(-)Index:
linux-acpi-2.6/drivers/idle/i7300_idle.c
===================================================================drivers/idle/i7300_idle.c +2
-70@@ -25,6 +25,7 @@#include <linux/delay.h> #include <linux/debugfs.h> #include <linux/stop_machine.h> +#include <linux/i7300_idle.h> #include <asm/idle.h> @@ -505,77 +506,8 @@ static struct notifier_block i7300_idle_ .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); -/* 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) { fp->private_data = inode->i_private;@@ -617,7 +549,7 @@ static int __init i7300_idle_init(void)cpus_clear (idle_cpumask); total_us =0 ; -if (i7300_idle_platform_probe ()) +if (i7300_idle_platform_probe (&fbd_dev, &ioat_dev))return -ENODEV ;if (i7300_idle_thrt_save ())Index:
linux-acpi-2.6/include/linux/i7300_idle.h
===================================================================include/linux/i7300_idle.h new file +83
-0@@ -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 Index:
linux-acpi-2.6/drivers/dma/ioat_dma.c
===================================================================drivers/dma/ioat_dma.c +4
-2@@ -33,6 +33,7 @@#include <linux/delay.h> #include <linux/dma-mapping.h> #include <linux/workqueue.h> +#include <linux/i7300_idle.h> #include "ioatdma.h" #include "ioatdma_registers.h" #include "ioatdma_hw.h" @@ -172,7 +173,9 @@ static int ioat_dma_enumerate_channels(s xfercap = (xfercap_scale ==0 ?-1 : (1UL << xfercap_scale));#if CONFIG_I7300_IDLE_IOAT_CHANNEL - device->common.chancnt--; +if (i7300_idle_platform_probe (NULL ,NULL ) ==0 ) { + device->common.chancnt--; + }#endif for (i =0 ; i < device->common.chancnt; i++) { ioat_chan =kzalloc (sizeof (*ioat_chan),GFP_KERNEL ); --To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
A message that is not in the archive (sent off-list or not yet received): [email protected]
RE: [PATCH] Disable ioat channel only on platforms where ile driver can load
Quoted 41 lines
---------- Original message ----------
From: Venki Pallipadi <[email protected]>
Date: Oct 23, 2008 12:34 AM
Subject: [PATCH] Disable ioat channel only on platforms where ile driver can load
To: Andi Kleen <[email protected]>
Cc: "Pallipadi, Venkatesh" <[email protected]>, Len Brown <[email protected]>, Ingo Molnar <[email protected]>, "[email protected]" <[email protected]>, Linux Kernel Mailing List <[email protected]>, "Henroid, Andrew D" <[email protected]>, Linus Torvalds <[email protected]>, Thomas Gleixner <[email protected]>, "H. Peter Anvin" <[email protected]>Quoted 15 lines · Andi Kleen
Quoted 8 lines · Venkatesh
Quoted 7 lines
Review
Quoted 4 lines
(quoted diff) +3
-0+#if CONFIG_I7300_IDLE_IOAT_CHANNEL + device->common.chancnt--; +#endifI still think this lone decrement looks fishy. Can there please be some explanation how it exactly relates to the i7300 idle driver, where the matching increment is, etc.?
Quoted 5 lines
No. This is not a increment/decrement thing. It is basically telling other Users of IOAT that they have one IOAT channel less that they can use.
The last IOAT channel is used by i7300 idle driver to get the throttling to work.Quoted 4 lines
Ok then it should be made conditional on the i7300 actually be available
in the system? It looks like you do it always no matter what chipset is in there.Does the patch below look OK?
Thanks,
Venki
Quoted 8 lines
Based on input from Andi Kleen:
share the platform detection code withioat_dmaand disable the channel in
dma engine only for specific platforms.Signed-off-by Venkatesh Pallipadi <[email protected]>---
Hi Venki,
Why for your purposes don't you use dmaengine to request an ioatdma channel from ioatdma driver?
This way sharing of this channel with other clients
(like TCP which uses ioatdma for receive offloading) would be possible . In the previous approach your change was not acceptable from ioatdma perspective
(for IOAT_VER_3_0 there are 8 ioat devices, each with single channel
- in this case you would take away all 8 channels and make ioat ver.3.0
totally disfunctional).
Even with this approach (assuming that it would affect IOAT_VER_1_2 only)
you reserve one channel of four statically for your purposes only, leaving for TCP receive offloading 75% of ioatdma resources and thus affecting its efficiency.
Dan, what do you think?
BTW, could you please next time in case of ioat/dmaengine changes include Dan and me in the list?
Thanks,
Maciej
Quoted 25 lines
Index:
linux-acpi-2.6/drivers/dma/ioat_dma.c
===================================================================
---linux-acpi-2.6.orig/drivers/dma/ioat_dma.c2008-10-22 11:42:04.000000000 -0700
+++linux-acpi-2.6/drivers/dma/ioat_dma.c2008-10-22
11:42:46.000000000 -0700drivers/dma/ioat_dma.c +4
-1@@ -33,6 +33,7 @@#include <linux/delay.h> #include <linux/dma-mapping.h> #include <linux/workqueue.h> +#include <linux/i7300_idle.h> #include "ioatdma.h" #include "ioatdma_registers.h" #include "ioatdma_hw.h" @@ -172,7 +173,9 @@ static int ioat_dma_enumerate_channels(s xfercap = (xfercap_scale ==0 ?-1 : (1UL << xfercap_scale));#if CONFIG_I7300_IDLE_IOAT_CHANNEL - device->common.chancnt--; +if (i7300_idle_platform_probe (NULL ,NULL ) ==0 ) { + device->common.chancnt--; + }#endif for (i =0 ; i < device->common.chancnt; i++) { ioat_chan =kzalloc (sizeof (*ioat_chan),GFP_KERNEL );
Re: [PATCH 2/2] i7300_idle driver v1.55
In reply to Andi KleenQuoted 5 lines · Andi Kleen
Quoted 2 lines · Venkatesh
udelay may be more power efficient than polling.
Isn't that function a one off anyways?
Which function is one off?
Quoted 15 lines
Quoted 9 lines
Quoted 6 lines
;
drivers/idle/i7300_idle.c line 652
Quoted 3 lines
drivers/idle/i7300_idle.c new file +3
-0+static void __exit i7300_idle_exit(void) +{ +idle_notifier_unregister (&i7300_idle_nb);I still think this needs some kind of idle synchronization.
This unregister uses
atomic_notifier_chain_unregister()which uses RCU and handles the race conditions that way.I didn't do a full analysis, but I didn't think RCU protects against the idle handler itself. At least not standard RCU. You would need to go through at least two quiescent periods, not one as standard code.
Quoted 7 lines
There used to be an older
idle synchronization interface for this case (which was removed at some point), perhaps it needs to be readded.Or just use
stop_machine(). That protects against idle too and while it's a big hammer for unloading it should be ok.
stop_machine() for unregistering idle callback will deadlock due to RCU.
I am not sure why we need two cycles. RCU in the unregister makes sure that no CPU is executing the callback handler and only then unregister returns. So, that will mean no one can be in the callback rountine and we are safe to remove the module. Correct?
Thanks,
Venki
Re: [PATCH 2/2] i7300_idle driver v1.55
Quoted 6 lines · Venki Pallipadi
Quoted 3 lines · Andi Kleen
Quoted 1 line · Venkatesh
udelay may be more power efficient than polling.
Isn't that function a one off anyways?
Which function is one off?
The one with the udelays, as in being init code. Or maybe I misread the code.
Quoted 20 lines
Quoted 12 lines
Quoted 7 lines
Quoted 5 lines
;
drivers/idle/i7300_idle.c line 652
Quoted 3 lines
drivers/idle/i7300_idle.c new file +3
-0+static void __exit i7300_idle_exit(void) +{ +idle_notifier_unregister (&i7300_idle_nb);I still think this needs some kind of idle synchronization.
This unregister uses
atomic_notifier_chain_unregister()which uses RCU and handles the race conditions that way.I didn't do a full analysis, but I didn't think RCU protects against the idle handler itself. At least not standard RCU. You would need to go through at least two quiescent periods, not one as standard code.
Quoted 7 lines
There used to be an older
idle synchronization interface for this case (which was removed at some point), perhaps it needs to be readded.Or just use
stop_machine(). That protects against idle too and while it's a big hammer for unloading it should be ok.
Quoted 6 lines
stop_machine()for unregistering idle callback will deadlock due to RCU.I am not sure why we need two cycles. RCU in the unregister makes sure that no CPU is executing the callback handler and only then unregister returns. So, that will mean no one can be in the callback rountine and we are safe to remove the module. Correct?
Perhaps I'm confused, but I thought with noidlehz the RCU code got changed to take out idle CPUs out of the rcu masks. This makes normally sense because you don't want to delay the grace period for potentially very long sleeping CPUs.
But it means it won't work for code inside the idle loop. Ok maybe if you're very careful with the ordering, but I'm not sure that's the case currently.
Yes two cycles won't work either, sorry was confused earlier, because even the second cycle wouldn't force the CPU out of idle.
The old idle sync code was more a thread that just cycled through all the CPus. That would work.
cc Paul
-Andi
RE: [PATCH 2/2] i7300_idle driver v1.55
Quoted 50 lines
-----Original Message-----
From: Andi Kleen [mailto:[email protected]]
Sent: Wednesday, October 22, 2008 6:11 PM
To: Pallipadi, Venkatesh
Cc: Len Brown; Ingo Molnar; [email protected]; Linux Kernel Mailing List; Henroid, Andrew D; Linus Torvalds; Thomas Gleixner; H. Peter Anvin; [email protected]
Subject: Re: [PATCH 2/2]i7300_idledriver v1.55Quoted 16 lines
Quoted 16 lines
Quoted 7 lines
Quoted 5 lines
;
drivers/idle/i7300_idle.c line 652
Quoted 3 lines
drivers/idle/i7300_idle.c new file +3
-0+static void __exit i7300_idle_exit(void) +{ +idle_notifier_unregister (&i7300_idle_nb);I still think this needs some kind of idle synchronization.
This unregister uses
atomic_notifier_chain_unregister()which uses RCU and handles the race conditions that way.I didn't do a full analysis, but I didn't think RCU protects against the idle handler itself. At least not standard RCU. You would need to go through at least two quiescent periods, not one as standard code.
There used to be an older
idle synchronization interface for this case (which was removed at some point), perhaps it needs to be readded.Quoted 5 lines
Quoted 3 lines
Or just use
stop_machine(). That protects against idle too and while it's a big hammer for unloading it should be ok.
stop_machine()for unregistering idle callback will deadlockdue to RCU.
Quoted 5 lines
I am not sure why we need two cycles. RCU in the unregister makes sure that no CPU is executing the callback handler
and only then unregister
returns. So, that will mean no one can be in the callbackrountine and we are
Quoted 1 line
safe to remove the module. Correct?
Perhaps I'm confused, but I thought with noidlehz the RCU code got changed to take out idle CPUs out of the rcu masks. This makes normally sense because you don't want to delay the grace period for potentially very long sleeping CPUs.
But it means it won't work for code inside the idle loop. Ok maybe if you're very careful with the ordering, but I'm not sure that's the case currently.
Quoted 6 lines
Yes two cycles won't work either, sorry was confused earlier, because even the second cycle wouldn't force the CPU out of idle.
The old idle sync code was more a thread that just cycled through all the CPus. That would work.
This should not matter as we can safely remove the module even when one or more CPUs are idle. As long as one CPU is running, we are sure that throttling is not in effect. And as long as we make sure no one is executing the notifier that is going to be rmmoded, we should be OK. Say one CPU comes out of the idle later, it wont see the notifier in the notifier list anymore, because of RCU in atomic notifier and things will work fine. I mean we are not rmmoding the routine that enters the idle state. We are just rmmoding the routine that Can get called before and after idle routine.
Thanks,
Venki
Re: [PATCH 2/2] i7300_idle driver v1.55
Quoted 10 lines
This should not matter as we can safely remove the module even when one or more CPUs are idle. As long as one CPU is running, we are sure that throttling is not in effect. And as long as we make sure no one is executing the notifier that is going to be rmmoded, we should be OK. Say one CPU comes out of the idle later, it wont see the notifier in the notifier list anymore, because of RCU in atomic notifier and things will work fine. I mean we are not rmmoding the routine that enters the idle state. We are just rmmoding the routine that Can get called before and after idle routine.
That means there is a ordering dependency between the RCU idle state getting updated and your code running. That is what I meant with "very careful with idle". Even if it worked right now would seem fragile to me.
-Andi
Re: [PATCH 2/2] i7300_idle driver v1.55
In reply to Pallipadi, VenkateshQuoted 57 lines · Venkatesh
Quoted 50 lines
-----Original Message-----
From: Andi Kleen [mailto:[email protected]]
Sent: Wednesday, October 22, 2008 6:11 PM
To: Pallipadi, Venkatesh
Cc: Len Brown; Ingo Molnar; [email protected]; Linux Kernel Mailing List; Henroid, Andrew D; Linus Torvalds; Thomas Gleixner; H. Peter Anvin; [email protected]
Subject: Re: [PATCH 2/2]i7300_idledriver v1.55Quoted 16 lines
Quoted 16 lines
Quoted 7 lines
Quoted 5 lines
;
Review
Quoted 3 lines
(quoted diff) +3
-0+static void __exit i7300_idle_exit(void) +{ + idle_notifier_unregister(&i7300_idle_nb);I still think this needs some kind of idle synchronization.
This unregister uses
atomic_notifier_chain_unregister()which uses RCU and handles the race conditions that way.I didn't do a full analysis, but I didn't think RCU protects against the idle handler itself. At least not standard RCU. You would need to go through at least two quiescent periods, not one as standard code.
There used to be an older
idle synchronization interface for this case (which was removed at some point), perhaps it needs to be readded.Quoted 5 lines
Quoted 3 lines
Or just use
stop_machine(). That protects against idle too and while it's a big hammer for unloading it should be ok.
stop_machine()for unregistering idle callback will deadlockdue to RCU.
Quoted 5 lines
I am not sure why we need two cycles. RCU in the unregister makes sure that no CPU is executing the callback handler
and only then unregister
returns. So, that will mean no one can be in the callbackrountine and we are
Quoted 1 line
safe to remove the module. Correct?
Perhaps I'm confused, but I thought with noidlehz the RCU code got changed to take out idle CPUs out of the rcu masks. This makes normally sense because you don't want to delay the grace period for potentially very long sleeping CPUs.
But it means it won't work for code inside the idle loop. Ok maybe if you're very careful with the ordering, but I'm not sure that's the case currently.
Quoted 6 lines
Yes two cycles won't work either, sorry was confused earlier, because even the second cycle wouldn't force the CPU out of idle.
The old idle sync code was more a thread that just cycled through all the CPus. That would work.
Quoted 9 lines
This should not matter as we can safely remove the module even when one or more CPUs are idle. As long as one CPU is running, we are sure that throttling is not in effect. And as long as we make sure no one is executing the notifier that is going to be rmmoded, we should be OK. Say one CPU comes out of the idle later, it wont see the notifier in the notifier list anymore, because of RCU in atomic notifier and things will work fine. I mean we are not rmmoding the routine that enters the idle state. We are just rmmoding the routine that Can get called before and after idle routine.
Suppose that one of the idle CPUs takes an interrupt, whose handler accesses the module being removed. How is this handled?
Thanx, Paul
Re: [PATCH 2/2] i7300_idle driver v1.55
Quoted 3 lines
Suppose that one of the idle CPUs takes an interrupt, whose handler accesses the module being removed. How is this handled?
We're just talking about idle notifier code here. Interrupts shouldn't ever call idle notifiers directly.
-Andi
Len Brown
reviewerPATCH 54/85 eeepc-laptop: Use standard interfaces
In reply to Len BrownFrom: Matthew Garrett <[email protected]>
eeepc-laptop currently only sends key events via ACPI and has non-standard rfkill control. Add an input device and use the rfkill infrastructure.
--- drivers/misc/eeepc-laptop.c | 228 +++++++++++++++++++++++++++++++++++++++---- 1 files changed, 209 insertions(+), 19 deletions(-)
drivers/misc/eeepc-laptop.c +209 -19
@@ -28,6 +28,8 @@#include <acpi/acpi_drivers.h> #include <acpi/acpi_bus.h> #include <linux/uaccess.h> +#include <linux/input.h> +#include <linux/rfkill.h> #define EEEPC_LAPTOP_VERSION "0.1"
@@ -125,6 +127,10 @@ struct eeepc_hotk {by this BIOS */ uint init_flag;/* Init flags */ u16 event_count[128 ];/* count for each event */ +struct input_dev *inputdev; +u16 *keycode_map; +struct rfkill *eeepc_wlan_rfkill; +struct rfkill *eeepc_bluetooth_rfkill; };/* The actual device the driver binds to */
@@ -140,6 +146,27 @@ static struct platform_driver platform_driver = {static struct platform_device *platform_device; +struct key_entry { +char type; +u8 code; +u16 keycode; +}; + +enum {KE_KEY ,KE_END }; + +static struct key_entry eeepc_keymap[] = { +/* Sleep already handled via generic ACPI code */ + {KE_KEY ,0x10 ,KEY_WLAN }, + {KE_KEY ,0x12 ,KEY_PROG1 }, + {KE_KEY ,0x13 ,KEY_MUTE }, + {KE_KEY ,0x14 ,KEY_VOLUMEDOWN }, + {KE_KEY ,0x15 ,KEY_VOLUMEUP }, + {KE_KEY ,0x30 ,KEY_SWITCHVIDEOMODE }, + {KE_KEY ,0x31 ,KEY_SWITCHVIDEOMODE }, + {KE_KEY ,0x32 ,KEY_SWITCHVIDEOMODE }, + {KE_END ,0 }, +}; +/* * The hotkey driver declaration */
@@ -261,6 +288,44 @@ static int update_bl_status(struct backlight_device *bd) }/* +* Rfkill helpers +*/ + +static int eeepc_wlan_rfkill_set (void *data,enum rfkill_state state) +{ +if (state ==RFKILL_STATE_SOFT_BLOCKED ) +return set_acpi (CM_ASL_WLAN ,0 ); +else +return set_acpi (CM_ASL_WLAN ,1 ); +} + +static int eeepc_wlan_rfkill_state (void *data,enum rfkill_state *state) +{ +if (get_acpi (CM_ASL_WLAN ) ==1 ) + *state =RFKILL_STATE_UNBLOCKED ; +else + *state =RFKILL_STATE_SOFT_BLOCKED ; +return 0 ; +} + +static int eeepc_bluetooth_rfkill_set (void *data,enum rfkill_state state) +{ +if (state ==RFKILL_STATE_SOFT_BLOCKED ) +return set_acpi (CM_ASL_BLUETOOTH ,0 ); +else +return set_acpi (CM_ASL_BLUETOOTH ,1 ); +} + +static int eeepc_bluetooth_rfkill_state (void *data,enum rfkill_state *state) +{ +if (get_acpi (CM_ASL_BLUETOOTH ) ==1 ) + *state =RFKILL_STATE_UNBLOCKED ; +else + *state =RFKILL_STATE_SOFT_BLOCKED ; +return 0 ; +} + +/* * Sys helpers */ static int parse_arg (const char *buf,unsigned long count,int *val)
@@ -311,13 +376,11 @@ static ssize_t show_sys_acpi(int cm, char *buf)EEEPC_CREATE_DEVICE_ATTR (camera,CM_ASL_CAMERA );EEEPC_CREATE_DEVICE_ATTR (cardr,CM_ASL_CARDREADER );EEEPC_CREATE_DEVICE_ATTR (disp,CM_ASL_DISPLAYSWITCH ); -EEEPC_CREATE_DEVICE_ATTR (wlan,CM_ASL_WLAN );static struct attribute *platform_attributes[] = { &dev_attr_camera.attr, &dev_attr_cardr.attr, &dev_attr_disp.attr, - &dev_attr_wlan.attr,NULL };
@@ -328,8 +391,64 @@ static struct attribute_group platform_attribute_group = {/* * Hotkey functions */ +static struct key_entry *eepc_get_entry_by_scancode (int code) +{ +struct key_entry *key; + +for (key = eeepc_keymap; key->type !=KE_END ; key++) +if (code == key->code) +return key; + +return NULL ; +} + +static struct key_entry *eepc_get_entry_by_keycode (int code) +{ +struct key_entry *key; + +for (key = eeepc_keymap; key->type !=KE_END ; key++) +if (code == key->keycode && key->type ==KE_KEY ) +return key; + +return NULL ; +} + +static int eeepc_getkeycode (struct input_dev *dev,int scancode,int *keycode) +{ +struct key_entry *key =eepc_get_entry_by_scancode (scancode); + +if (key && key->type ==KE_KEY ) { + *keycode = key->keycode; +return 0 ; + } + +return -EINVAL ; +} + +static int eeepc_setkeycode (struct input_dev *dev,int scancode,int keycode) +{ +struct key_entry *key; +int old_keycode; + +if (keycode <0 || keycode >KEY_MAX ) +return -EINVAL ; + + key =eepc_get_entry_by_scancode (scancode); +if (key && key->type ==KE_KEY ) { + old_keycode = key->keycode; + key->keycode = keycode; +set_bit (keycode, dev->keybit); +if (!eepc_get_entry_by_keycode (old_keycode)) +clear_bit (old_keycode, dev->keybit); +return 0 ; + } + +return -EINVAL ; +} +static int eeepc_hotk_check (void ) { +const struct key_entry *key;struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER ,NULL };int result;
@@ -356,6 +475,31 @@ static int eeepc_hotk_check(void)"Get control methods supported: 0x%x\n" , ehotk->cm_supported); } + ehotk->inputdev =input_allocate_device (); +if (!ehotk->inputdev) { +printk (EEEPC_INFO "Unable to allocate input device\n" ); +return 0 ; + } + ehotk->inputdev->name ="Asus EeePC extra buttons" ; + ehotk->inputdev->phys =EEEPC_HOTK_FILE "/input0" ; + ehotk->inputdev->id.bustype =BUS_HOST ; + ehotk->inputdev->getkeycode = eeepc_getkeycode; + ehotk->inputdev->setkeycode = eeepc_setkeycode; + +for (key = eeepc_keymap; key->type !=KE_END ; key++) { +switch (key->type) { +case KE_KEY : +set_bit (EV_KEY , ehotk->inputdev->evbit); +set_bit (key->keycode, ehotk->inputdev->keybit); +break ; + } + } + result =input_register_device (ehotk->inputdev); +if (result) { +printk (EEEPC_INFO "Unable to register input device\n" ); +input_free_device (ehotk->inputdev); +return 0 ; + } }else {printk (EEEPC_ERR "Hotkey device not present, aborting\n" );return -EINVAL ;
@@ -363,21 +507,6 @@ static int eeepc_hotk_check(void)return 0 ; } -static void notify_wlan (u32 *event) -{ -/* if DISABLE_ASL_WLAN is set, the notify code for fn+f2 -will always be 0x10 */ -if (ehotk->cm_supported & (0x1 <<CM_ASL_WLAN )) { -const char *method = cm_getv[CM_ASL_WLAN ]; -int value; -if (read_acpi_int (ehotk->handle, method, &value)) -printk (EEEPC_WARNING "Error reading %s\n" , - method); -else if (value ==1 ) - *event =0x11 ; - } -} -static void notify_brn (void ) {struct backlight_device *bd = eeepc_backlight_device;
@@ -386,14 +515,28 @@ static void notify_brn(void)static void eeepc_hotk_notify (acpi_handle handle,u32 event,void *data) { +static struct key_entry *key;if (!ehotk)return ; -if (event ==NOTIFY_WLAN_ON && (DISABLE_ASL_WLAN & ehotk->init_flag)) -notify_wlan (&event);if (event >=NOTIFY_BRN_MIN && event <=NOTIFY_BRN_MAX )notify_brn ();acpi_bus_generate_proc_event (ehotk->device, event, ehotk->event_count[event %128 ]++); +if (ehotk->inputdev) { + key =eepc_get_entry_by_scancode (event); +if (key) { +switch (key->type) { +case KE_KEY : +input_report_key (ehotk->inputdev, key->keycode, +1 ); +input_sync (ehotk->inputdev); +input_report_key (ehotk->inputdev, key->keycode, +0 ); +input_sync (ehotk->inputdev); +break ; + } + } + } }static int eeepc_hotk_add (struct acpi_device *device)
@@ -420,6 +563,47 @@ static int eeepc_hotk_add(struct acpi_device *device) eeepc_hotk_notify, ehotk);if (ACPI_FAILURE (status))printk (EEEPC_ERR "Error installing notify handler\n" ); + +if (get_acpi (CM_ASL_WLAN ) !=-1 ) { + ehotk->eeepc_wlan_rfkill =rfkill_allocate (&device->dev, +RFKILL_TYPE_WLAN ); + +if (!ehotk->eeepc_wlan_rfkill) + goto end; + + ehotk->eeepc_wlan_rfkill->name ="eeepc-wlan" ; + ehotk->eeepc_wlan_rfkill->toggle_radio = eeepc_wlan_rfkill_set; + ehotk->eeepc_wlan_rfkill->get_state = eeepc_wlan_rfkill_state; +if (get_acpi (CM_ASL_WLAN ) ==1 ) + ehotk->eeepc_wlan_rfkill->state = +RFKILL_STATE_UNBLOCKED ; +else + ehotk->eeepc_wlan_rfkill->state = +RFKILL_STATE_SOFT_BLOCKED ; +rfkill_register (ehotk->eeepc_wlan_rfkill); + } + +if (get_acpi (CM_ASL_BLUETOOTH ) !=-1 ) { + ehotk->eeepc_bluetooth_rfkill = +rfkill_allocate (&device->dev,RFKILL_TYPE_BLUETOOTH ); + +if (!ehotk->eeepc_bluetooth_rfkill) + goto end; + + ehotk->eeepc_bluetooth_rfkill->name ="eeepc-bluetooth" ; + ehotk->eeepc_bluetooth_rfkill->toggle_radio = + eeepc_bluetooth_rfkill_set; + ehotk->eeepc_bluetooth_rfkill->get_state = + eeepc_bluetooth_rfkill_state; +if (get_acpi (CM_ASL_BLUETOOTH ) ==1 ) + ehotk->eeepc_bluetooth_rfkill->state = +RFKILL_STATE_UNBLOCKED ; +else + ehotk->eeepc_bluetooth_rfkill->state = +RFKILL_STATE_SOFT_BLOCKED ; +rfkill_register (ehotk->eeepc_bluetooth_rfkill); + } + end:if (result) {kfree (ehotk);
@@ -553,6 +737,12 @@ static void eeepc_backlight_exit(void) {if (eeepc_backlight_device)backlight_device_unregister (eeepc_backlight_device); +if (ehotk->inputdev) +input_unregister_device (ehotk->inputdev); +if (ehotk->eeepc_wlan_rfkill) +rfkill_unregister (ehotk->eeepc_wlan_rfkill); +if (ehotk->eeepc_bluetooth_rfkill) +rfkill_unregister (ehotk->eeepc_bluetooth_rfkill); eeepc_backlight_device =NULL ; }
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 55/85 x86: remove magic number from ACPI sleep stack buffer
In reply to Len BrownFrom: Matt Mackall <[email protected]>
x86_64 SMP suspend to RAM uses a 10k temporary stack for saving the kernel state, but only 4k of it is used. Shrink it to 4k.
--- arch/x86/kernel/acpi/sleep.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
arch/x86/kernel/acpi/sleep.c +1 -1
@@ -97,7 +97,7 @@ int acpi_save_state_mem(void)#else /* CONFIG_64BIT */ header->trampoline_segment =setup_trampoline () >>4 ;#ifdef CONFIG_SMP - stack_start.sp = temp_stack +4096 ; + stack_start.sp = temp_stack +sizeof (temp_stack);#endif initial_code = (unsigned long )wakeup_long64; saved_magic =0x123456789abcdef0 ;
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 56/85 x86: trim ACPI sleep stack buffer
In reply to Len BrownFrom: Matt Mackall <[email protected]>
x86_64 SMP suspend to RAM uses a 10k temporary stack for saving the kernel state, but only 4k of it is used. Shrink it to 4k.
--- arch/x86/kernel/acpi/sleep.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
arch/x86/kernel/acpi/sleep.c +1 -1
@@ -21,7 +21,7 @@ unsigned long acpi_realmode_flags;static unsigned long acpi_realmode;#if defined(CONFIG_SMP ) && defined(CONFIG_64BIT ) -static char temp_stack[10240 ]; +static char temp_stack[4096 ];#endif /**
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 57/85 ACPI: acpi_driver_data could only be applied to acpi_device
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
--- drivers/acpi/scan.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/acpi/scan.c +1 -1
@@ -384,7 +384,7 @@ static int acpi_device_remove(struct device * dev) acpi_drv->ops.remove (acpi_dev, acpi_dev->removal_type); } acpi_dev->driver =NULL ; -acpi_driver_data (dev) =NULL ; +acpi_driver_data (acpi_dev) =NULL ;put_device (dev);return 0 ;
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 58/85 ACPI: toshiba_acpi.c fix sparse signedness mismatch warnings
In reply to Len BrownFrom: Harvey Harrison <[email protected]>
set_bit expects unsigned int, and we start with a u32 anyway. drivers/acpi/toshiba_acpi.c:397:14: warning: incorrect type in argument 1 (different signedness)drivers/acpi/toshiba_acpi.c:397:14: expected unsigned int [usertype] *worddrivers/acpi/toshiba_acpi.c:397:14: got int *<noident>drivers/acpi/toshiba_acpi.c:399:14: warning: incorrect type in argument 1 (different signedness)drivers/acpi/toshiba_acpi.c:399:14: expected unsigned int [usertype] *worddrivers/acpi/toshiba_acpi.c:399:14: got int *<noident>drivers/acpi/toshiba_acpi.c:401:14: warning: incorrect type in argument 1 (different signedness)drivers/acpi/toshiba_acpi.c:401:14: expected unsigned int [usertype] *worddrivers/acpi/toshiba_acpi.c:401:14: got int *<noident>
--- drivers/acpi/toshiba_acpi.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/acpi/toshiba_acpi.c +1 -1
@@ -392,7 +392,7 @@ static unsigned long write_video(const char *buffer, unsigned long count)hci_read1 (HCI_VIDEO_OUT , &video_out, &hci_result);if (hci_result ==HCI_SUCCESS ) { -int new_video_out = video_out; +unsigned int new_video_out = video_out;if (lcd_out !=-1 )_set_bit (&new_video_out,HCI_VIDEO_OUT_LCD , lcd_out);if (crt_out !=-1 )
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 59/85 ACPI: catch calls of acpi_driver_data on pointer of wrong type
In reply to Len BrownFrom: Pavel Machek <[email protected]>
Catch attempts to use of acpi_driver_data on pointers of wrong type.
akpm: rewritten to use proper C typechecking and remove the "function"-used-as-lvalue thing.
--- drivers/acpi/ac.c | 2 +- drivers/acpi/acpi_memhotplug.c | 2 +- drivers/acpi/asus_acpi.c | 2 +- drivers/acpi/battery.c | 2 +- drivers/acpi/button.c | 2 +- drivers/acpi/container.c | 2 +- drivers/acpi/ec.c | 4 ++-- drivers/acpi/fan.c | 2 +- drivers/acpi/pci_link.c | 2 +- drivers/acpi/pci_root.c | 2 +- drivers/acpi/power.c | 4 ++-- drivers/acpi/processor_core.c | 2 +- drivers/acpi/sbs.c | 2 +- drivers/acpi/sbshc.c | 4 ++-- drivers/acpi/scan.c | 4 ++-- drivers/acpi/thermal.c | 2 +- drivers/acpi/video.c | 6 +++--- drivers/misc/asus-laptop.c | 2 +- drivers/misc/eeepc-laptop.c | 2 +- drivers/misc/fujitsu-laptop.c | 4 ++-- drivers/misc/intel_menlow.c | 2 +- drivers/misc/thinkpad_acpi.c | 2 +- include/acpi/acpi_bus.h | 6 +++++- 23 files changed, 34 insertions(+), 30 deletions(-)
drivers/acpi/ac.c +1 -1
@@ -269,7 +269,7 @@ static int acpi_ac_add(struct acpi_device *device) ac->device = device;strcpy (acpi_device_name (device),ACPI_AC_DEVICE_NAME );strcpy (acpi_device_class (device),ACPI_AC_CLASS ); -acpi_driver_data (device) = ac; + device->driver_data = ac; result =acpi_ac_get_state (ac);if (result)
drivers/acpi/acpi_memhotplug.c +1 -1
@@ -403,7 +403,7 @@ static int acpi_memory_device_add(struct acpi_device *device) mem_device->device = device;sprintf (acpi_device_name (device),"%s" ,ACPI_MEMORY_DEVICE_NAME );sprintf (acpi_device_class (device),"%s" ,ACPI_MEMORY_DEVICE_CLASS ); -acpi_driver_data (device) = mem_device; + device->driver_data = mem_device;/* Get the range from the _CRS */ result =acpi_memory_get_device_resources (mem_device);
drivers/acpi/asus_acpi.c +1 -1
@@ -1321,7 +1321,7 @@ static int asus_hotk_add(struct acpi_device *device) hotk->handle = device->handle;strcpy (acpi_device_name (device),ACPI_HOTK_DEVICE_NAME );strcpy (acpi_device_class (device),ACPI_HOTK_CLASS ); -acpi_driver_data (device) = hotk; + device->driver_data = hotk; hotk->device = device; result =asus_hotk_check ();
drivers/acpi/battery.c +1 -1
@@ -804,7 +804,7 @@ static int acpi_battery_add(struct acpi_device *device) battery->device = device;strcpy (acpi_device_name (device),ACPI_BATTERY_DEVICE_NAME );strcpy (acpi_device_class (device),ACPI_BATTERY_CLASS ); -acpi_driver_data (device) = battery; + device->driver_data = battery;mutex_init (&battery->lock);acpi_battery_update (battery);#ifdef CONFIG_ACPI_PROCFS_POWER
drivers/acpi/button.c +1 -1
@@ -384,7 +384,7 @@ static int acpi_button_add(struct acpi_device *device)return -ENOMEM ; button->device = device; -acpi_driver_data (device) = button; + device->driver_data = button; button->input = input =input_allocate_device ();if (!input) {
drivers/acpi/container.c +1 -1
@@ -108,7 +108,7 @@ static int acpi_container_add(struct acpi_device *device) container->handle = device->handle;strcpy (acpi_device_name (device),ACPI_CONTAINER_DEVICE_NAME );strcpy (acpi_device_class (device),ACPI_CONTAINER_CLASS ); -acpi_driver_data (device) = container; + device->driver_data = container;ACPI_DEBUG_PRINT ((ACPI_DB_INFO ,"Device <%s> bid <%s>\n" ,acpi_device_name (device),acpi_device_bid (device)));
drivers/acpi/ec.c +2 -2
@@ -788,7 +788,7 @@ static int acpi_ec_add(struct acpi_device *device)if (!first_ec) first_ec = ec; -acpi_driver_data (device) = ec; + device->driver_data = ec;acpi_ec_add_fs (device);pr_info (PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n" , ec->gpe, ec->command_addr, ec->data_addr);
@@ -813,7 +813,7 @@ static int acpi_ec_remove(struct acpi_device *device, int type) }mutex_unlock (&ec->lock);acpi_ec_remove_fs (device); -acpi_driver_data (device) =NULL ; + device->driver_data =NULL ;if (ec == first_ec) first_ec =NULL ;kfree (ec);
drivers/acpi/fan.c +1 -1
@@ -265,7 +265,7 @@ static int acpi_fan_add(struct acpi_device *device)dev_info (&device->dev,"registered as cooling_device%d\n" , cdev->id); -acpi_driver_data (device) = cdev; + device->driver_data = cdev; result =sysfs_create_link (&device->dev.kobj, &cdev->device.kobj,"thermal_cooling" );
drivers/acpi/pci_link.c +1 -1
@@ -737,7 +737,7 @@ static int acpi_pci_link_add(struct acpi_device *device) link->device = device;strcpy (acpi_device_name (device),ACPI_PCI_LINK_DEVICE_NAME );strcpy (acpi_device_class (device),ACPI_PCI_LINK_CLASS ); -acpi_driver_data (device) = link; + device->driver_data = link;mutex_lock (&acpi_link_lock); result =acpi_pci_link_get_possible (link);
drivers/acpi/pci_root.c +1 -1
@@ -206,7 +206,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) root->device = device;strcpy (acpi_device_name (device),ACPI_PCI_ROOT_DEVICE_NAME );strcpy (acpi_device_class (device),ACPI_PCI_ROOT_CLASS ); -acpi_driver_data (device) = root; + device->driver_data = root; device->ops.bind = acpi_pci_bind;
drivers/acpi/power.c +2 -2
@@ -657,7 +657,7 @@ static int acpi_power_add(struct acpi_device *device)strcpy (resource->name, device->pnp.bus_id);strcpy (acpi_device_name (device),ACPI_POWER_DEVICE_NAME );strcpy (acpi_device_class (device),ACPI_POWER_CLASS ); -acpi_driver_data (device) = resource; + device->driver_data = resource;/* Evalute the object to get the system level and resource order. */ status =acpi_evaluate_object (device->handle,NULL ,NULL , &buffer);
@@ -733,7 +733,7 @@ static int acpi_power_resume(struct acpi_device *device)if (!device || !acpi_driver_data (device))return -EINVAL ; - resource = (struct acpi_power_resource *)acpi_driver_data (device); + resource =acpi_driver_data (device); result =acpi_power_get_state (resource, &state);if (result)
drivers/acpi/processor_core.c +1 -1
@@ -818,7 +818,7 @@ static int acpi_processor_add(struct acpi_device *device) pr->handle = device->handle;strcpy (acpi_device_name (device),ACPI_PROCESSOR_DEVICE_NAME );strcpy (acpi_device_class (device),ACPI_PROCESSOR_CLASS ); -acpi_driver_data (device) = pr; + device->driver_data = pr;return 0 ; }
drivers/acpi/sbs.c +1 -1
@@ -931,7 +931,7 @@ static int acpi_sbs_add(struct acpi_device *device) sbs->device = device;strcpy (acpi_device_name (device),ACPI_SBS_DEVICE_NAME );strcpy (acpi_device_class (device),ACPI_SBS_CLASS ); -acpi_driver_data (device) = sbs; + device->driver_data = sbs; result =acpi_charger_add (sbs);if (result)
drivers/acpi/sbshc.c +2 -2
@@ -282,7 +282,7 @@ static int acpi_smbus_hc_add(struct acpi_device *device) hc->ec =acpi_driver_data (device->parent); hc->offset = (val >>8 ) &0xff ; hc->query_bit = val &0xff ; -acpi_driver_data (device) = hc; + device->driver_data = hc;acpi_ec_add_query_handler (hc->ec, hc->query_bit,NULL , smbus_alarm, hc); printk(KERN_INFO PREFIX "SBS HC: EC = 0x%p, offset = 0x%0x, query_bit = 0x%0x\n",
@@ -303,7 +303,7 @@ static int acpi_smbus_hc_remove(struct acpi_device *device, int type) hc =acpi_driver_data (device);acpi_ec_remove_query_handler (hc->ec, hc->query_bit);kfree (hc); -acpi_driver_data (device) =NULL ; + device->driver_data =NULL ;return 0 ; }
drivers/acpi/scan.c +2 -2
@@ -384,7 +384,7 @@ static int acpi_device_remove(struct device * dev) acpi_drv->ops.remove (acpi_dev, acpi_dev->removal_type); } acpi_dev->driver =NULL ; -acpi_driver_data (acpi_dev) =NULL ; + acpi_dev->driver_data =NULL ;put_device (dev);return 0 ;
@@ -537,7 +537,7 @@ acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver) result = driver->ops.add (device);if (result) { device->driver =NULL ; -acpi_driver_data (device) =NULL ; + device->driver_data =NULL ;return result; }
drivers/acpi/thermal.c +1 -1
@@ -1647,7 +1647,7 @@ static int acpi_thermal_add(struct acpi_device *device)strcpy (tz->name, device->pnp.bus_id);strcpy (acpi_device_name (device),ACPI_THERMAL_DEVICE_NAME );strcpy (acpi_device_class (device),ACPI_THERMAL_CLASS ); -acpi_driver_data (device) = tz; + device->driver_data = tz;mutex_init (&tz->lock);
drivers/acpi/video.c +3 -3
@@ -1491,7 +1491,7 @@ acpi_video_bus_get_one_device(struct acpi_device *device,strcpy (acpi_device_name (device),ACPI_VIDEO_DEVICE_NAME );strcpy (acpi_device_class (device),ACPI_VIDEO_CLASS ); -acpi_driver_data (device) = data; + device->driver_data = data; data->device_id = device_id; data->video = video;
@@ -1982,7 +1982,7 @@ static int acpi_video_bus_add(struct acpi_device *device) video->device = device;strcpy (acpi_device_name (device),ACPI_VIDEO_BUS_NAME );strcpy (acpi_device_class (device),ACPI_VIDEO_CLASS ); -acpi_driver_data (device) = video; + device->driver_data = video;acpi_video_bus_find_cap (video); error =acpi_video_bus_check (video);
@@ -2058,7 +2058,7 @@ static int acpi_video_bus_add(struct acpi_device *device)acpi_video_bus_remove_fs (device); err_free_video:kfree (video); -acpi_driver_data (device) =NULL ; + device->driver_data =NULL ;return error; }
drivers/misc/asus-laptop.c +1 -1
@@ -996,7 +996,7 @@ static int asus_hotk_add(struct acpi_device *device) hotk->handle = device->handle;strcpy (acpi_device_name (device),ASUS_HOTK_DEVICE_NAME );strcpy (acpi_device_class (device),ASUS_HOTK_CLASS ); -acpi_driver_data (device) = hotk; + device->driver_data = hotk; hotk->device = device; result =asus_hotk_check ();
drivers/misc/eeepc-laptop.c +1 -1
@@ -411,7 +411,7 @@ static int eeepc_hotk_add(struct acpi_device *device) ehotk->handle = device->handle;strcpy (acpi_device_name (device),EEEPC_HOTK_DEVICE_NAME );strcpy (acpi_device_class (device),EEEPC_HOTK_CLASS ); -acpi_driver_data (device) = ehotk; + device->driver_data = ehotk; ehotk->device = device; result =eeepc_hotk_check ();if (result)
drivers/misc/fujitsu-laptop.c +2 -2
@@ -490,7 +490,7 @@ static int acpi_fujitsu_add(struct acpi_device *device) fujitsu->acpi_handle = device->handle;sprintf (acpi_device_name (device),"%s" ,ACPI_FUJITSU_DEVICE_NAME );sprintf (acpi_device_class (device),"%s" ,ACPI_FUJITSU_CLASS ); -acpi_driver_data (device) = fujitsu; + device->driver_data = fujitsu; status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
@@ -703,7 +703,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device)sprintf (acpi_device_name (device),"%s" ,ACPI_FUJITSU_HOTKEY_DEVICE_NAME );sprintf (acpi_device_class (device),"%s" ,ACPI_FUJITSU_CLASS ); -acpi_driver_data (device) = fujitsu_hotkey; + device->driver_data = fujitsu_hotkey; status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
drivers/misc/intel_menlow.c +1 -1
@@ -175,7 +175,7 @@ static int intel_menlow_memory_add(struct acpi_device *device) goto end; } -acpi_driver_data (device) = cdev; + device->driver_data = cdev; result =sysfs_create_link (&device->dev.kobj, &cdev->device.kobj,"thermal_cooling" );if (result)
drivers/misc/thinkpad_acpi.c +1 -1
@@ -543,7 +543,7 @@ static int __init setup_acpi_notify(struct ibm_struct *ibm)return -ENODEV ; } -acpi_driver_data (ibm->acpi->device) = ibm; + ibm->acpi->device->driver_data = ibm;sprintf (acpi_device_class (ibm->acpi->device),"%s/%s" ,TPACPI_ACPI_EVENT_PREFIX , ibm->name);
include/acpi/acpi_bus.h +5 -1
@@ -300,7 +300,11 @@ struct acpi_device {enum acpi_bus_removal_type removal_type;/* indicate for different removal type */ }; -#define acpi_driver_data (d) ((d)->driver_data) +static inline void *acpi_driver_data (struct acpi_device *d) +{ +return d->driver_data; +} +#define to_acpi_device (d) container_of(d, struct acpi_device, dev)#define to_acpi_driver (d) container_of(d, struct acpi_driver, drv)
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 60/85 toshiba_acpi: depends on INPUT
In reply to Len BrownFrom: Randy Dunlap <[email protected]>
CONFIG_ACPI_TOSHIBA can =y when CONFIG_INPUT=m, so prevent that combination and its subsequent build errors:
toshiba_acpi.c:(.text+0x3e877): undefined reference to input_event' toshiba_acpi.c:(.text+0x3e98a): undefined reference to input_unregister_polled_device' toshiba_acpi.c:(.text+0x3e994): undefined reference to input_free_polled_device' toshiba_acpi.c:(.init.text+0x21b4): undefined reference to input_allocate_polled_device' toshiba_acpi.c:(.init.text+0x2263): undefined reference to `input_register_polled_device' make[1]: *** [.tmp_vmlinux1] Error 1
--- drivers/acpi/Kconfig | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/acpi/Kconfig +1 -1
@@ -259,7 +259,7 @@ config ACPI_ASUS config ACPI_TOSHIBA tristate "Toshiba Laptop Extras" - depends on X86 + depends on X86 && INPUT select BACKLIGHT_CLASS_DEVICE ---help--- This driver adds support for access to certain system settings
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 61/85 PNP: fix debug formatting (cosmetic)
In reply to Len BrownFrom: Bjorn Helgaas <[email protected]>
This patch just fixes indentation of a couple debug messages.
--- drivers/pnp/resource.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/pnp/resource.c +2 -2
@@ -294,7 +294,7 @@ static int pci_dev_uses_irq(struct pnp_dev *pnp, struct pci_dev *pci,u8 progif;if (pci->irq == irq) { -dev_dbg (&pnp->dev,"device %s using irq %d\n" , +dev_dbg (&pnp->dev," device %s using irq %d\n" ,pci_name (pci), irq);return 1 ; }
@@ -316,7 +316,7 @@ static int pci_dev_uses_irq(struct pnp_dev *pnp, struct pci_dev *pci,if ((progif &0x5 ) !=0x5 )if (pci_get_legacy_ide_irq (pci,0 ) == irq ||pci_get_legacy_ide_irq (pci,1 ) == irq) { -dev_dbg (&pnp->dev,"legacy IDE device %s " +dev_dbg (&pnp->dev," legacy IDE device %s " "using irq %d\n" ,pci_name (pci), irq);return 1 ; }
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 62/85 PNPACPI: use dev_printk when possible
In reply to Len BrownFrom: Bjorn Helgaas <[email protected]>
Use dev_printk() when possible for more informative error messages.
--- drivers/pnp/pnpacpi/rsparser.c | 15 ++++++++------- 1 files changed, 8 insertions(+), 7 deletions(-)
drivers/pnp/pnpacpi/rsparser.c +8 -7
@@ -132,7 +132,8 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev,pnp_add_irq_resource (dev, irq, flags); } -static int dma_flags (int type,int bus_master,int transfer) +static int dma_flags (struct pnp_dev *dev,int type,int bus_master, +int transfer) {int flags =0 ;
@@ -154,7 +155,7 @@ static int dma_flags(int type, int bus_master, int transfer)default :/* Set a default value ? */ flags |=IORESOURCE_DMA_COMPATIBLE ; -pnp_err ("Invalid DMA type" ); +dev_err (&dev->dev,"invalid DMA type %d\n" , type); }switch (transfer) {case ACPI_TRANSFER_8 :
@@ -169,7 +170,7 @@ static int dma_flags(int type, int bus_master, int transfer)default :/* Set a default value ? */ flags |=IORESOURCE_DMA_8AND16BIT ; -pnp_err ("Invalid DMA transfer type" ); +dev_err (&dev->dev,"invalid DMA transfer type %d\n" , transfer); }return flags;
@@ -336,7 +337,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,case ACPI_RESOURCE_TYPE_DMA : dma = &res->data.dma;if (dma->channel_count >0 && dma->channels[0 ] != (u8) -1 ) - flags =dma_flags (dma->type, dma->bus_master, + flags =dma_flags (dev, dma->type, dma->bus_master, dma->transfer);else flags =IORESOURCE_DISABLED ;
@@ -477,7 +478,7 @@ static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev,for (i =0 ; i < p->channel_count; i++) map |=1 << p->channels[i]; - flags =dma_flags (p->type, p->bus_master, p->transfer); + flags =dma_flags (dev, p->type, p->bus_master, p->transfer);pnp_register_dma_resource (dev, option_flags, map, flags); }
@@ -608,8 +609,8 @@ static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,unsigned char flags =0 ; status =acpi_resource_to_address64 (r, p); -if (!ACPI_SUCCESS (status)) { -pnp_warn ("PnPACPI: failed to convert resource type %d" , +if (ACPI_FAILURE (status)) { +dev_warn (&dev->dev,"can't convert resource type %d\n" , r->type);return ; }
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 63/85 PNP: convert the last few pnp_info() uses to printk()
In reply to Len BrownFrom: Bjorn Helgaas <[email protected]>
There are only a few remaining uses of pnp_info(), so I just converted them to printk and removed the pnp_err(), pnp_info(), pnp_warn(), and pnp_dbg() wrappers.
I also removed a couple debug messages that don't seem useful any more ("driver registered", "driver unregistered", "driver attached").
--- drivers/pnp/driver.c | 4 ---- drivers/pnp/pnpacpi/core.c | 6 +++--- include/linux/pnp.h | 10 ---------- 3 files changed, 3 insertions(+), 17 deletions(-)
drivers/pnp/driver.c +0 -4
@@ -114,7 +114,6 @@ static int pnp_device_probe(struct device *dev) }else goto fail; -dev_dbg (dev,"driver attached\n" );return error; fail:
@@ -210,8 +209,6 @@ struct bus_type pnp_bus_type = {int pnp_register_driver (struct pnp_driver *drv) { -pnp_dbg ("the driver '%s' has been registered" , drv->name); - drv->driver.name = drv->name; drv->driver.bus = &pnp_bus_type;
@@ -221,7 +218,6 @@ int pnp_register_driver(struct pnp_driver *drv)void pnp_unregister_driver (struct pnp_driver *drv) {driver_unregister (&drv->driver); -pnp_dbg ("the driver '%s' has been unregistered" , drv->name); }/**
drivers/pnp/pnpacpi/core.c +3 -3
@@ -255,14 +255,14 @@ int pnpacpi_disabled __initdata;static int __init pnpacpi_init (void ) {if (acpi_disabled || pnpacpi_disabled) { -pnp_info ("PnP ACPI: disabled" ); +printk (KERN_INFO "pnp: PnP ACPI: disabled\n" );return 0 ; } -pnp_info ("PnP ACPI init" ); +printk (KERN_INFO "pnp: PnP ACPI init\n" );pnp_register_protocol (&pnpacpi_protocol);register_acpi_bus_type (&acpi_pnp_bus);acpi_get_devices (NULL , pnpacpi_add_device_handler,NULL ,NULL ); -pnp_info ("PnP ACPI: found %d devices" , num); +printk (KERN_INFO "pnp: PnP ACPI: found %d devices\n" , num);unregister_acpi_bus_type (&acpi_pnp_bus); pnp_platform_devices =1 ;return 0 ;
include/linux/pnp.h +0 -10
@@ -483,14 +483,4 @@ static inline void pnp_unregister_driver(struct pnp_driver *drv) { }#endif /* CONFIG_PNP */ -#define pnp_err(format, arg...) printk(KERN_ERR "pnp: " format "\n" , ## arg) -#define pnp_info(format, arg...) printk(KERN_INFO "pnp: " format "\n" , ## arg) -#define pnp_warn(format, arg...) printk(KERN_WARNING "pnp: " format "\n" , ## arg) - -#ifdef CONFIG_PNP_DEBUG -#define pnp_dbg(format, arg...) printk(KERN_DEBUG "pnp: " format "\n" , ## arg) -#else -#define pnp_dbg(format, arg...) do {} while (0) -#endif -#endif /* _LINUX_PNP_H */
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 64/85 PNP: use new vsprintf symbolic function pointer format
In reply to Len BrownFrom: Bjorn Helgaas <[email protected]>
Use the '%pF' format to get rid of an "#ifdef DEBUG".
--- drivers/pnp/quirks.c | 6 ++---- 1 files changed, 2 insertions(+), 4 deletions(-)
drivers/pnp/quirks.c +2 -4
@@ -337,10 +337,8 @@ void pnp_fixup_device(struct pnp_dev *dev)for (f = pnp_fixups; *f->id; f++) {if (!compare_pnp_id (dev->id, f->id))continue ; -#ifdef DEBUG -dev_dbg (&dev->dev,"%s: calling " , f->id); -print_fn_descriptor_symbol ("%s\n" , f->quirk_function); -#endif +dev_dbg (&dev->dev,"%s: calling %pF\n" , f->id, + f->quirk_function); f->quirk_function (dev); } }
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 65/85 PNP: remove some uses of DEBUG ifdef
In reply to Len BrownFrom: Bjorn Helgaas <[email protected]>
Use scnprintf() to build up a buffer of PNP IDs to print. This makes the printk atomic and helps get rid of an #ifdef.
Also remove an "#ifdef DEBUG" from some debug functions. The functions only produce debug output, so it's OK to run the function and just have the output be dropped at the end.
--- drivers/pnp/core.c | 18 ++++++++---------- drivers/pnp/support.c | 4 ---- 2 files changed, 8 insertions(+), 14 deletions(-)
drivers/pnp/core.c +8 -10
@@ -185,6 +185,9 @@ int __pnp_add_device(struct pnp_dev *dev)int pnp_add_device (struct pnp_dev *dev) {int ret; +char buf[128 ]; +int len =0 ; +struct pnp_id *id;if (dev->card)return -EINVAL ;
@@ -193,17 +196,12 @@ int pnp_add_device(struct pnp_dev *dev)if (ret)return ret; -#ifdef CONFIG_PNP_DEBUG - { -struct pnp_id *id; + buf[0 ] ='\0' ; +for (id = dev->id; id; id = id->next) + len +=scnprintf (buf + len,sizeof (buf) - len," %s" , id->id); -dev_printk (KERN_DEBUG , &dev->dev,"%s device, IDs" , - dev->protocol->name); -for (id = dev->id; id; id = id->next) -printk (" %s" , id->id); -printk (" (%s)\n" , dev->active ?"active" :"disabled" ); - } -#endif +dev_dbg (&dev->dev,"%s device, IDs%s (%s)\n" , + dev->protocol->name, buf, dev->active ?"active" :"disabled" );return 0 ; }
drivers/pnp/support.c +0 -4
@@ -75,7 +75,6 @@ char *pnp_resource_type_name(struct resource *res)void dbg_pnp_show_resources (struct pnp_dev *dev,char *desc) { -#ifdef DEBUG char buf[128 ];int len;struct pnp_resource *pnp_res;
@@ -118,7 +117,6 @@ void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc) }dev_dbg (&dev->dev,"%s\n" , buf); } -#endif }char *pnp_option_priority_name (struct pnp_option *option)
@@ -136,7 +134,6 @@ char *pnp_option_priority_name(struct pnp_option *option)void dbg_pnp_show_option (struct pnp_dev *dev,struct pnp_option *option) { -#ifdef DEBUG char buf[128 ];int len =0 , i;struct pnp_port *port;
@@ -209,5 +206,4 @@ void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option)break ; }dev_dbg (&dev->dev,"%s\n" , buf); -#endif }
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 66/85 PNP: add CONFIG_PNP_DEBUG_MESSAGES and pnp_dbg()
In reply to Len BrownFrom: Bjorn Helgaas <[email protected]>
This adds the core function pnp_dbg() and a new config option to enable it.
The PNP core debugging messages can be enabled at boot-time with the "pnp.debug" kernel parameter.
--- Documentation/kernel-parameters.txt | 4 ++++ drivers/pnp/Kconfig | 14 ++++++++++++++ drivers/pnp/base.h | 10 ++++++++++ drivers/pnp/core.c | 11 +++++++++++ 4 files changed, 39 insertions(+), 0 deletions(-)
Documentation/kernel-parameters.txt +4 -0
@@ -1660,6 +1660,10 @@ and is between 256 and 4096 characters. It is defined in the file Override pmtimer IOPort with a hex value. e.g. pmtmr=0x508 + pnp.debug [PNP] + Enable PNP debug messages. This depends on the + CONFIG_PNP_DEBUG_MESSAGES option. + pnpacpi= [ACPI] { off }
drivers/pnp/Kconfig +14 -0
@@ -20,6 +20,20 @@ menuconfig PNP If unsure, say Y. +config PNP_DEBUG_MESSAGES + default y + bool "PNP debugging messages" + depends on PNP + help + Say Y here if you want the PNP layer to be able to produce debugging + messages if needed. The messages can be enabled at boot-time with + the pnp.debug kernel parameter. + + This option allows you to save a bit of space if you do not want + the messages to even be built into the kernel. + + If you have any doubts about this, say Y here. + if PNP config PNP_DEBUG
drivers/pnp/base.h +10 -0
@@ -166,3 +166,13 @@ struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev,struct pnp_resource *pnp_add_mem_resource (struct pnp_dev *dev,resource_size_t start,resource_size_t end,int flags); + +extern int pnp_debug; + +#if defined(CONFIG_PNP_DEBUG_MESSAGES ) +#define pnp_dbg(dev, format, arg...) \ + ({ if (pnp_debug) dev_printk(KERN_DEBUG, dev, format, ## arg); 0; }) +#else +#define pnp_dbg(dev, format, arg...) \ + ({ if (0) dev_printk(KERN_DEBUG, dev, format, ## arg); 0; }) +#endif
drivers/pnp/core.c +11 -0
@@ -221,3 +221,14 @@ static int __init pnp_init(void) }subsys_initcall (pnp_init); + +int pnp_debug; + +#if defined(CONFIG_PNP_DEBUG_MESSAGES ) +static int __init pnp_debug_setup (char *__unused) +{ + pnp_debug =1 ; +return 1 ; +} +__setup ("pnp.debug" , pnp_debug_setup); +#endif
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 67/85 PNP: convert to using pnp_dbg()
In reply to Len BrownFrom: Bjorn Helgaas <[email protected]>
pnp_dbg() is equivalent to dev_dbg() except that we can turn it on at boot-time with the "pnp.debug" kernel parameter, so we don't have to build a new kernel image.
--- drivers/pnp/core.c | 2 +- drivers/pnp/isapnp/core.c | 12 ++++++------ drivers/pnp/manager.c | 34 +++++++++++++++++----------------- drivers/pnp/pnpacpi/core.c | 4 ++-- drivers/pnp/pnpacpi/rsparser.c | 28 ++++++++++++++-------------- drivers/pnp/pnpbios/core.c | 4 ++-- drivers/pnp/pnpbios/rsparser.c | 18 +++++++++--------- drivers/pnp/quirks.c | 2 +- drivers/pnp/resource.c | 12 ++++++------ drivers/pnp/support.c | 10 +++++----- 10 files changed, 63 insertions(+), 63 deletions(-)
drivers/pnp/core.c +1 -1
@@ -200,7 +200,7 @@ int pnp_add_device(struct pnp_dev *dev)for (id = dev->id; id; id = id->next) len +=scnprintf (buf + len,sizeof (buf) - len," %s" , id->id); -dev_dbg (&dev->dev,"%s device, IDs%s (%s)\n" , +pnp_dbg (&dev->dev,"%s device, IDs%s (%s)\n" , dev->protocol->name, buf, dev->active ?"active" :"disabled" );return 0 ; }
drivers/pnp/isapnp/core.c +6 -6
@@ -901,7 +901,7 @@ static int isapnp_get_resources(struct pnp_dev *dev) {int i, ret; -dev_dbg (&dev->dev,"get resources\n" ); +pnp_dbg (&dev->dev,"get resources\n" );pnp_init_resources (dev);isapnp_cfg_begin (dev->card->number, dev->number); dev->active =isapnp_read_byte (ISAPNP_CFG_ACTIVATE );
@@ -939,13 +939,13 @@ static int isapnp_set_resources(struct pnp_dev *dev)struct resource *res;int tmp; -dev_dbg (&dev->dev,"set resources\n" ); +pnp_dbg (&dev->dev,"set resources\n" );isapnp_cfg_begin (dev->card->number, dev->number); dev->active =1 ;for (tmp =0 ; tmp <ISAPNP_MAX_PORT ; tmp++) { res =pnp_get_resource (dev,IORESOURCE_IO , tmp);if (pnp_resource_enabled (res)) { -dev_dbg (&dev->dev," set io %d to %#llx\n" , +pnp_dbg (&dev->dev," set io %d to %#llx\n" , tmp, (unsigned long long ) res->start);isapnp_write_word (ISAPNP_CFG_PORT + (tmp <<1 ), res->start);
@@ -957,14 +957,14 @@ static int isapnp_set_resources(struct pnp_dev *dev)int irq = res->start;if (irq ==2 ) irq =9 ; -dev_dbg (&dev->dev," set irq %d to %d\n" , tmp, irq); +pnp_dbg (&dev->dev," set irq %d to %d\n" , tmp, irq);isapnp_write_byte (ISAPNP_CFG_IRQ + (tmp <<1 ), irq); } }for (tmp =0 ; tmp <ISAPNP_MAX_DMA ; tmp++) { res =pnp_get_resource (dev,IORESOURCE_DMA , tmp);if (pnp_resource_enabled (res)) { -dev_dbg (&dev->dev," set dma %d to %lld\n" , +pnp_dbg (&dev->dev," set dma %d to %lld\n" , tmp, (unsigned long long ) res->start);isapnp_write_byte (ISAPNP_CFG_DMA + tmp, res->start); }
@@ -972,7 +972,7 @@ static int isapnp_set_resources(struct pnp_dev *dev)for (tmp =0 ; tmp <ISAPNP_MAX_MEM ; tmp++) { res =pnp_get_resource (dev,IORESOURCE_MEM , tmp);if (pnp_resource_enabled (res)) { -dev_dbg (&dev->dev," set mem %d to %#llx\n" , +pnp_dbg (&dev->dev," set mem %d to %#llx\n" , tmp, (unsigned long long ) res->start);isapnp_write_word (ISAPNP_CFG_MEM + (tmp <<3 ), (res->start >>8 ) &0xffff );
drivers/pnp/manager.c +17 -17
@@ -25,7 +25,7 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) res =pnp_get_resource (dev,IORESOURCE_IO , idx);if (res) { -dev_dbg (&dev->dev," io %d already set to %#llx-%#llx " +pnp_dbg (&dev->dev," io %d already set to %#llx-%#llx " "flags %#lx\n" , idx, (unsigned long long ) res->start, (unsigned long long ) res->end, res->flags);return 0 ;
@@ -38,7 +38,7 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)if (!rule->size) { res->flags |=IORESOURCE_DISABLED ; -dev_dbg (&dev->dev," io %d disabled\n" , idx); +pnp_dbg (&dev->dev," io %d disabled\n" , idx); goto __add; }
@@ -49,7 +49,7 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) res->start += rule->align; res->end = res->start + rule->size -1 ;if (res->start > rule->max || !rule->align) { -dev_dbg (&dev->dev," couldn't assign io %d " +pnp_dbg (&dev->dev," couldn't assign io %d " "(min %#llx max %#llx)\n" , idx, (unsigned long long ) rule->min, (unsigned long long ) rule->max);
@@ -68,7 +68,7 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) res =pnp_get_resource (dev,IORESOURCE_MEM , idx);if (res) { -dev_dbg (&dev->dev," mem %d already set to %#llx-%#llx " +pnp_dbg (&dev->dev," mem %d already set to %#llx-%#llx " "flags %#lx\n" , idx, (unsigned long long ) res->start, (unsigned long long ) res->end, res->flags);return 0 ;
@@ -90,7 +90,7 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)if (!rule->size) { res->flags |=IORESOURCE_DISABLED ; -dev_dbg (&dev->dev," mem %d disabled\n" , idx); +pnp_dbg (&dev->dev," mem %d disabled\n" , idx); goto __add; }
@@ -101,7 +101,7 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) res->start += rule->align; res->end = res->start + rule->size -1 ;if (res->start > rule->max || !rule->align) { -dev_dbg (&dev->dev," couldn't assign mem %d " +pnp_dbg (&dev->dev," couldn't assign mem %d " "(min %#llx max %#llx)\n" , idx, (unsigned long long ) rule->min, (unsigned long long ) rule->max);
@@ -126,7 +126,7 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) res =pnp_get_resource (dev,IORESOURCE_IRQ , idx);if (res) { -dev_dbg (&dev->dev," irq %d already set to %d flags %#lx\n" , +pnp_dbg (&dev->dev," irq %d already set to %d flags %#lx\n" , idx, (int ) res->start, res->flags);return 0 ; }
@@ -138,7 +138,7 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)if (bitmap_empty (rule->map.bits,PNP_IRQ_NR )) { res->flags |=IORESOURCE_DISABLED ; -dev_dbg (&dev->dev," irq %d disabled\n" , idx); +pnp_dbg (&dev->dev," irq %d disabled\n" , idx); goto __add; }
@@ -160,11 +160,11 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) res->start =-1 ; res->end =-1 ; res->flags |=IORESOURCE_DISABLED ; -dev_dbg (&dev->dev," irq %d disabled (optional)\n" , idx); +pnp_dbg (&dev->dev," irq %d disabled (optional)\n" , idx); goto __add; } -dev_dbg (&dev->dev," couldn't assign irq %d\n" , idx); +pnp_dbg (&dev->dev," couldn't assign irq %d\n" , idx);return -EBUSY ; __add:
@@ -184,7 +184,7 @@ static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) res =pnp_get_resource (dev,IORESOURCE_DMA , idx);if (res) { -dev_dbg (&dev->dev," dma %d already set to %d flags %#lx\n" , +pnp_dbg (&dev->dev," dma %d already set to %d flags %#lx\n" , idx, (int ) res->start, res->flags);return 0 ; }
@@ -205,7 +205,7 @@ static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) res->start = res->end =MAX_DMA_CHANNELS ;#endif res->flags |=IORESOURCE_DISABLED ; -dev_dbg (&dev->dev," disable dma %d\n" , idx); +pnp_dbg (&dev->dev," disable dma %d\n" , idx); __add:pnp_add_dma_resource (dev, res->start, res->flags);
@@ -238,7 +238,7 @@ static int pnp_assign_resources(struct pnp_dev *dev, int set)int nport =0 , nmem =0 , nirq =0 , ndma =0 ;int ret =0 ; -dev_dbg (&dev->dev,"pnp_assign_resources, try dependent set %d\n" , set); +pnp_dbg (&dev->dev,"pnp_assign_resources, try dependent set %d\n" , set);mutex_lock (&pnp_res_mutex);pnp_clean_resource_table (dev);
@@ -270,7 +270,7 @@ static int pnp_assign_resources(struct pnp_dev *dev, int set)mutex_unlock (&pnp_res_mutex);if (ret <0 ) { -dev_dbg (&dev->dev,"pnp_assign_resources failed (%d)\n" , ret); +pnp_dbg (&dev->dev,"pnp_assign_resources failed (%d)\n" , ret);pnp_clean_resource_table (dev); }else dbg_pnp_show_resources (dev,"pnp_assign_resources succeeded" );
@@ -286,7 +286,7 @@ int pnp_auto_config_dev(struct pnp_dev *dev)int i, ret;if (!pnp_can_configure (dev)) { -dev_dbg (&dev->dev,"configuration not supported\n" ); +pnp_dbg (&dev->dev,"configuration not supported\n" );return -ENODEV ; }
@@ -313,7 +313,7 @@ int pnp_auto_config_dev(struct pnp_dev *dev)int pnp_start_dev (struct pnp_dev *dev) {if (!pnp_can_write (dev)) { -dev_dbg (&dev->dev,"activation not supported\n" ); +pnp_dbg (&dev->dev,"activation not supported\n" );return -EINVAL ; }
@@ -336,7 +336,7 @@ int pnp_start_dev(struct pnp_dev *dev)int pnp_stop_dev (struct pnp_dev *dev) {if (!pnp_can_disable (dev)) { -dev_dbg (&dev->dev,"disabling not supported\n" ); +pnp_dbg (&dev->dev,"disabling not supported\n" );return -EINVAL ; }if (dev->protocol->disable (dev) <0 ) {
drivers/pnp/pnpacpi/core.c +2 -2
@@ -75,7 +75,7 @@ static int __init ispnpidacpi(char *id)static int pnpacpi_get_resources (struct pnp_dev *dev) { -dev_dbg (&dev->dev,"get resources\n" ); +pnp_dbg (&dev->dev,"get resources\n" );return pnpacpi_parse_allocated_resource (dev); }
@@ -86,7 +86,7 @@ static int pnpacpi_set_resources(struct pnp_dev *dev)int ret;acpi_status status; -dev_dbg (&dev->dev,"set resources\n" ); +pnp_dbg (&dev->dev,"set resources\n" ); ret =pnpacpi_build_resource_template (dev, &buffer);if (ret)return ret;
drivers/pnp/pnpacpi/rsparser.c +14 -14
@@ -450,7 +450,7 @@ int pnpacpi_parse_allocated_resource(struct pnp_dev *dev)acpi_handle handle = dev->data;acpi_status status; -dev_dbg (&dev->dev,"parse allocated resources\n" ); +pnp_dbg (&dev->dev,"parse allocated resources\n" );pnp_init_resources (dev);
@@ -736,7 +736,7 @@ int __init pnpacpi_parse_resource_option_data(struct pnp_dev *dev)acpi_status status;struct acpipnp_parse_option_s parse_data; -dev_dbg (&dev->dev,"parse resource options\n" ); +pnp_dbg (&dev->dev,"parse resource options\n" ); parse_data.dev = dev; parse_data.option_flags =0 ;
@@ -844,7 +844,7 @@ static void pnpacpi_encode_irq(struct pnp_dev *dev,if (!pnp_resource_enabled (p)) { irq->interrupt_count =0 ; -dev_dbg (&dev->dev," encode irq (%s)\n" , +pnp_dbg (&dev->dev," encode irq (%s)\n" , p ?"disabled" :"missing" );return ; }
@@ -856,7 +856,7 @@ static void pnpacpi_encode_irq(struct pnp_dev *dev, irq->interrupt_count =1 ; irq->interrupts[0 ] = p->start; - dev_dbg(&dev->dev, " encode irq %d %s %s %s (%d-byte descriptor)\n", + pnp_dbg(&dev->dev, " encode irq %d %s %s %s (%d-byte descriptor)\n", (int) p->start, triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge", polarity == ACPI_ACTIVE_LOW ? "low" : "high",
@@ -873,7 +873,7 @@ static void pnpacpi_encode_ext_irq(struct pnp_dev *dev,if (!pnp_resource_enabled (p)) { extended_irq->interrupt_count =0 ; -dev_dbg (&dev->dev," encode extended irq (%s)\n" , +pnp_dbg (&dev->dev," encode extended irq (%s)\n" , p ?"disabled" :"missing" );return ; }
@@ -886,7 +886,7 @@ static void pnpacpi_encode_ext_irq(struct pnp_dev *dev, extended_irq->interrupt_count =1 ; extended_irq->interrupts[0 ] = p->start; -dev_dbg (&dev->dev," encode irq %d %s %s %s\n" , (int ) p->start, +pnp_dbg (&dev->dev," encode irq %d %s %s %s\n" , (int ) p->start, triggering ==ACPI_LEVEL_SENSITIVE ?"level" :"edge" , polarity ==ACPI_ACTIVE_LOW ?"low" :"high" , extended_irq->sharable ==ACPI_SHARED ?"shared" :"exclusive" );
@@ -900,7 +900,7 @@ static void pnpacpi_encode_dma(struct pnp_dev *dev,if (!pnp_resource_enabled (p)) { dma->channel_count =0 ; -dev_dbg (&dev->dev," encode dma (%s)\n" , +pnp_dbg (&dev->dev," encode dma (%s)\n" , p ?"disabled" :"missing" );return ; }
@@ -935,7 +935,7 @@ static void pnpacpi_encode_dma(struct pnp_dev *dev, dma->channel_count =1 ; dma->channels[0 ] = p->start; -dev_dbg (&dev->dev," encode dma %d " +pnp_dbg (&dev->dev," encode dma %d " "type %#x transfer %#x master %d\n" , (int ) p->start, dma->type, dma->transfer, dma->bus_master); }
@@ -959,7 +959,7 @@ static void pnpacpi_encode_io(struct pnp_dev *dev, io->address_length =0 ; } -dev_dbg (&dev->dev," encode io %#x-%#x decode %#x\n" , io->minimum, +pnp_dbg (&dev->dev," encode io %#x-%#x decode %#x\n" , io->minimum, io->minimum + io->address_length -1 , io->io_decode); }
@@ -977,7 +977,7 @@ static void pnpacpi_encode_fixed_io(struct pnp_dev *dev, fixed_io->address_length =0 ; } -dev_dbg (&dev->dev," encode fixed_io %#x-%#x\n" , fixed_io->address, +pnp_dbg (&dev->dev," encode fixed_io %#x-%#x\n" , fixed_io->address, fixed_io->address + fixed_io->address_length -1 ); }
@@ -1000,7 +1000,7 @@ static void pnpacpi_encode_mem24(struct pnp_dev *dev, memory24->address_length =0 ; } -dev_dbg (&dev->dev," encode mem24 %#x-%#x write_protect %#x\n" , +pnp_dbg (&dev->dev," encode mem24 %#x-%#x write_protect %#x\n" , memory24->minimum, memory24->minimum + memory24->address_length -1 , memory24->write_protect);
@@ -1024,7 +1024,7 @@ static void pnpacpi_encode_mem32(struct pnp_dev *dev, memory32->alignment =0 ; } -dev_dbg (&dev->dev," encode mem32 %#x-%#x write_protect %#x\n" , +pnp_dbg (&dev->dev," encode mem32 %#x-%#x write_protect %#x\n" , memory32->minimum, memory32->minimum + memory32->address_length -1 , memory32->write_protect);
@@ -1047,7 +1047,7 @@ static void pnpacpi_encode_fixed_mem32(struct pnp_dev *dev, fixed_memory32->address_length =0 ; } -dev_dbg (&dev->dev," encode fixed_mem32 %#x-%#x write_protect %#x\n" , +pnp_dbg (&dev->dev," encode fixed_mem32 %#x-%#x write_protect %#x\n" , fixed_memory32->address, fixed_memory32->address + fixed_memory32->address_length -1 , fixed_memory32->write_protect);
@@ -1061,7 +1061,7 @@ int pnpacpi_encode_resources(struct pnp_dev *dev, struct acpi_buffer *buffer)struct acpi_resource *resource = buffer->pointer;int port =0 , irq =0 , dma =0 , mem =0 ; -dev_dbg (&dev->dev,"encode %d resources\n" , res_cnt); +pnp_dbg (&dev->dev,"encode %d resources\n" , res_cnt);while (i < res_cnt) {switch (resource->type) {case ACPI_RESOURCE_TYPE_IRQ :
drivers/pnp/pnpbios/core.c +2 -2
@@ -211,7 +211,7 @@ static int pnpbios_get_resources(struct pnp_dev *dev)if (!pnpbios_is_dynamic (dev))return -EPERM ; -dev_dbg (&dev->dev,"get resources\n" ); +pnp_dbg (&dev->dev,"get resources\n" ); node =kzalloc (node_info.max_node_size,GFP_KERNEL );if (!node)return -1 ;
@@ -234,7 +234,7 @@ static int pnpbios_set_resources(struct pnp_dev *dev)if (!pnpbios_is_dynamic (dev))return -EPERM ; -dev_dbg (&dev->dev,"set resources\n" ); +pnp_dbg (&dev->dev,"set resources\n" ); node =kzalloc (node_info.max_node_size,GFP_KERNEL );if (!node)return -1 ;
drivers/pnp/pnpbios/rsparser.c +9 -9
@@ -87,7 +87,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(struct pnp_dev *dev,if (!p)return NULL ; -dev_dbg (&dev->dev,"parse allocated resources\n" ); +pnp_dbg (&dev->dev,"parse allocated resources\n" );pnp_init_resources (dev);
@@ -324,7 +324,7 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,if (!p)return NULL ; -dev_dbg (&dev->dev,"parse resource options\n" ); +pnp_dbg (&dev->dev,"parse resource options\n" ); option_flags =0 ;while ((char *)p < (char *)end) {
@@ -519,7 +519,7 @@ static void pnpbios_encode_mem(struct pnp_dev *dev, unsigned char *p, p[10 ] = (len >>8 ) &0xff ; p[11 ] = ((len >>8 ) >>8 ) &0xff ; -dev_dbg (&dev->dev," encode mem %#lx-%#lx\n" , base, base + len -1 ); +pnp_dbg (&dev->dev," encode mem %#lx-%#lx\n" , base, base + len -1 ); } static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p,
@@ -549,7 +549,7 @@ static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p, p[18 ] = (len >>16 ) &0xff ; p[19 ] = (len >>24 ) &0xff ; -dev_dbg (&dev->dev," encode mem32 %#lx-%#lx\n" , base, base + len -1 ); +pnp_dbg (&dev->dev," encode mem32 %#lx-%#lx\n" , base, base + len -1 ); } static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p,
@@ -575,7 +575,7 @@ static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p, p[10 ] = (len >>16 ) &0xff ; p[11 ] = (len >>24 ) &0xff ; -dev_dbg (&dev->dev," encode fixed_mem32 %#lx-%#lx\n" , base, +pnp_dbg (&dev->dev," encode fixed_mem32 %#lx-%#lx\n" , base, base + len -1 ); }
@@ -592,7 +592,7 @@ static void pnpbios_encode_irq(struct pnp_dev *dev, unsigned char *p, p[1 ] = map &0xff ; p[2 ] = (map >>8 ) &0xff ; -dev_dbg (&dev->dev," encode irq mask %#lx\n" , map); +pnp_dbg (&dev->dev," encode irq mask %#lx\n" , map); } static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p,
@@ -607,7 +607,7 @@ static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p, p[1 ] = map &0xff ; -dev_dbg (&dev->dev," encode dma mask %#lx\n" , map); +pnp_dbg (&dev->dev," encode dma mask %#lx\n" , map); } static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p,
@@ -630,7 +630,7 @@ static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p, p[5 ] = (base >>8 ) &0xff ; p[7 ] = len &0xff ; -dev_dbg (&dev->dev," encode io %#lx-%#lx\n" , base, base + len -1 ); +pnp_dbg (&dev->dev," encode io %#lx-%#lx\n" , base, base + len -1 ); } static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p,
@@ -651,7 +651,7 @@ static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p, p[2 ] = (base >>8 ) &0xff ; p[3 ] = len &0xff ; -dev_dbg (&dev->dev," encode fixed_io %#lx-%#lx\n" , base, +pnp_dbg (&dev->dev," encode fixed_io %#lx-%#lx\n" , base, base + len -1 ); }
drivers/pnp/quirks.c +1 -1
@@ -337,7 +337,7 @@ void pnp_fixup_device(struct pnp_dev *dev)for (f = pnp_fixups; *f->id; f++) {if (!compare_pnp_id (dev->id, f->id))continue ; -dev_dbg (&dev->dev,"%s: calling %pF\n" , f->id, +pnp_dbg (&dev->dev,"%s: calling %pF\n" , f->id, f->quirk_function); f->quirk_function (dev); }
drivers/pnp/resource.c +6 -6
@@ -294,7 +294,7 @@ static int pci_dev_uses_irq(struct pnp_dev *pnp, struct pci_dev *pci,u8 progif;if (pci->irq == irq) { -dev_dbg (&pnp->dev," device %s using irq %d\n" , +pnp_dbg (&pnp->dev," device %s using irq %d\n" ,pci_name (pci), irq);return 1 ; }
@@ -316,7 +316,7 @@ static int pci_dev_uses_irq(struct pnp_dev *pnp, struct pci_dev *pci,if ((progif &0x5 ) !=0x5 )if (pci_get_legacy_ide_irq (pci,0 ) == irq ||pci_get_legacy_ide_irq (pci,1 ) == irq) { -dev_dbg (&pnp->dev," legacy IDE device %s " +pnp_dbg (&pnp->dev," legacy IDE device %s " "using irq %d\n" ,pci_name (pci), irq);return 1 ; }
@@ -517,7 +517,7 @@ struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, res->start = irq; res->end = irq; -dev_dbg (&dev->dev," add irq %d flags %#x\n" , irq, flags); +pnp_dbg (&dev->dev," add irq %d flags %#x\n" , irq, flags);return pnp_res; }
@@ -538,7 +538,7 @@ struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma, res->start = dma; res->end = dma; -dev_dbg (&dev->dev," add dma %d flags %#x\n" , dma, flags); +pnp_dbg (&dev->dev," add dma %d flags %#x\n" , dma, flags);return pnp_res; }
@@ -562,7 +562,7 @@ struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev, res->start = start; res->end = end; -dev_dbg (&dev->dev," add io %#llx-%#llx flags %#x\n" , +pnp_dbg (&dev->dev," add io %#llx-%#llx flags %#x\n" , (unsigned long long ) start, (unsigned long long ) end, flags);return pnp_res; }
@@ -587,7 +587,7 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, res->start = start; res->end = end; -dev_dbg (&dev->dev," add mem %#llx-%#llx flags %#x\n" , +pnp_dbg (&dev->dev," add mem %#llx-%#llx flags %#x\n" , (unsigned long long ) start, (unsigned long long ) end, flags);return pnp_res; }
drivers/pnp/support.c +5 -5
@@ -81,11 +81,11 @@ void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc)struct resource *res;if (list_empty (&dev->resources)) { -dev_dbg (&dev->dev,"%s: no current resources\n" , desc); +pnp_dbg (&dev->dev,"%s: no current resources\n" , desc);return ; } -dev_dbg (&dev->dev,"%s: current resources:\n" , desc); +pnp_dbg (&dev->dev,"%s: current resources:\n" , desc);list_for_each_entry (pnp_res, &dev->resources, list) { res = &pnp_res->res; len =0 ;
@@ -94,7 +94,7 @@ void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc) pnp_resource_type_name(res));if (res->flags &IORESOURCE_DISABLED ) { -dev_dbg (&dev->dev,"%sdisabled\n" , buf); +pnp_dbg (&dev->dev,"%sdisabled\n" , buf);continue ; }
@@ -115,7 +115,7 @@ void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc) res->flags);break ; } -dev_dbg (&dev->dev,"%s\n" , buf); +pnp_dbg (&dev->dev,"%s\n" , buf); } }
@@ -205,5 +205,5 @@ void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option) "flags %#x", dma->map, dma->flags);break ; } -dev_dbg (&dev->dev,"%s\n" , buf); +pnp_dbg (&dev->dev,"%s\n" , buf); }
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 68/85 PNP: remove old CONFIG_PNP_DEBUG option
In reply to Len BrownFrom: Bjorn Helgaas <[email protected]>
CONFIG_PNP_DEBUG is no longer used to turn on dev_dbg() in PNP, since we have pnp_dbg() which can be enabled at boot-time, so this patch removes the config option.
Note that pnp_dock_event() checks "#ifdef DEBUG". But there's never been a clear path for enabling that via configgery. It happened that CONFIG_PNP_DEBUG enabled it after 1bd17e63a068db6, but that was accidental and only in 2.6.26.
--- drivers/pnp/Kconfig | 6 ------ drivers/pnp/Makefile | 4 ---- drivers/pnp/isapnp/Makefile | 4 ---- drivers/pnp/pnpacpi/Makefile | 4 ---- drivers/pnp/pnpbios/Makefile | 4 ---- 5 files changed, 0 insertions(+), 22 deletions(-)
drivers/pnp/Kconfig +0 -6
@@ -36,12 +36,6 @@ config PNP_DEBUG_MESSAGES if PNP -config PNP_DEBUG - bool "PnP Debug Messages" - help - Say Y if you want the Plug and Play Layer to print debug messages. - This is useful if you are developing a PnP driver or troubleshooting. - comment "Protocols" source "drivers/pnp/isapnp/Kconfig"
drivers/pnp/Makefile +0 -4
@@ -7,7 +7,3 @@ obj-y := core.o card.o driver.o resource.o manager.o support.o interface.o quir obj-$(CONFIG_PNPACPI) += pnpacpi/ obj-$(CONFIG_PNPBIOS) += pnpbios/ obj-$(CONFIG_ISAPNP) += isapnp/ - -ifeq ($(CONFIG_PNP_DEBUG),y) -EXTRA_CFLAGS += -DDEBUG -endif
drivers/pnp/isapnp/Makefile +0 -4
@@ -5,7 +5,3 @@ isapnp-proc-$(CONFIG_PROC_FS) = proc.o obj-y := core.o compat.o $(isapnp-proc-y) - -ifeq ($(CONFIG_PNP_DEBUG),y) -EXTRA_CFLAGS += -DDEBUG -endif
drivers/pnp/pnpacpi/Makefile +0 -4
@@ -3,7 +3,3 @@ # obj-y := core.o rsparser.o - -ifeq ($(CONFIG_PNP_DEBUG),y) -EXTRA_CFLAGS += -DDEBUG -endif
drivers/pnp/pnpbios/Makefile +0 -4
@@ -5,7 +5,3 @@ pnpbios-proc-$(CONFIG_PNPBIOS_PROC_FS) = proc.o obj-y := core.o bioscalls.o rsparser.o $(pnpbios-proc-y) - -ifeq ($(CONFIG_PNP_DEBUG),y) -EXTRA_CFLAGS += -DDEBUG -endif
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 69/85 ACPI: don't load acpi_cpufreq if acpi=off
In reply to Len BrownFrom: Yinghai Lu <[email protected]>
--- arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +3 -0
@@ -779,6 +779,9 @@ static int __init acpi_cpufreq_init(void) {int ret; +if (acpi_disabled) +return 0 ; +dprintk ("acpi_cpufreq_init\n" ); ret =acpi_cpufreq_early_init ();
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 70/85 ACPI: remove unused have_arch_parse_srat
In reply to Len BrownFrom: Yinghai Lu <[email protected]>
This was a workaround for 32bit numa SRAT processing, and we removed those workarounds, making 32 bit more like 64 bit. HAVE_ARCH_PARSE_SRAT is no longer defined anywhere.
--- include/linux/acpi.h | 8 -------- 1 files changed, 0 insertions(+), 8 deletions(-)
include/linux/acpi.h +0 -8
@@ -94,18 +94,10 @@ int acpi_parse_mcfg (struct acpi_table_header *header);void acpi_table_print_madt_entry (struct acpi_subtable_header *madt);/* the following four functions are architecture-dependent */ -#ifdef CONFIG_HAVE_ARCH_PARSE_SRAT -#define NR_NODE_MEMBLKS MAX_NUMNODES -#define acpi_numa_slit_init (slit) do {} while (0) -#define acpi_numa_processor_affinity_init (pa) do {} while (0) -#define acpi_numa_memory_affinity_init (ma) do {} while (0) -#define acpi_numa_arch_fixup () do {} while (0) -#else void acpi_numa_slit_init (struct acpi_table_slit *slit);void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa);void acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma);void acpi_numa_arch_fixup (void ); -#endif #ifdef CONFIG_ACPI_HOTPLUG_CPU /* Arch dependent functions for cpu hotplug support */
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 71/85 acer-wmi: Remove private workqueue
In reply to Len BrownFrom: Carlos Corbacho <[email protected]>
As per Dmitry Torokhov's suggestion, acer-wmi doesn't need a private workqueue, so remove it.
--- drivers/misc/acer-wmi.c | 18 ++---------------- 1 files changed, 2 insertions(+), 16 deletions(-)
drivers/misc/acer-wmi.c +2 -16
@@ -930,8 +930,6 @@ static void acer_backlight_exit(void)/* * Rfkill devices */ -static struct workqueue_struct *rfkill_workqueue; -static void acer_rfkill_update (struct work_struct *ignored); static DECLARE_DELAYED_WORK(acer_rfkill_work, acer_rfkill_update);static void acer_rfkill_update (struct work_struct *ignored)
@@ -952,8 +950,7 @@ static void acer_rfkill_update(struct work_struct *ignored) RFKILL_STATE_SOFT_BLOCKED); } -queue_delayed_work (rfkill_workqueue, &acer_rfkill_work, -round_jiffies_relative (HZ )); +schedule_delayed_work (&acer_rfkill_work,round_jiffies_relative (HZ )); }static int acer_rfkill_set (void *data,enum rfkill_state state)
@@ -1018,17 +1015,7 @@ static int acer_rfkill_init(struct device *dev) } } - rfkill_workqueue =create_singlethread_workqueue ("rfkill_workqueue" ); -if (!rfkill_workqueue) { -if (has_cap (ACER_CAP_BLUETOOTH )) { -kfree (bluetooth_rfkill->data); -rfkill_unregister (bluetooth_rfkill); - } -kfree (wireless_rfkill->data); -rfkill_unregister (wireless_rfkill); -return -ENOMEM ; - } -queue_delayed_work (rfkill_workqueue, &acer_rfkill_work,HZ ); +schedule_delayed_work (&acer_rfkill_work,round_jiffies_relative (HZ ));return 0 ; }
@@ -1036,7 +1023,6 @@ static int acer_rfkill_init(struct device *dev)static void acer_rfkill_exit (void ) {cancel_delayed_work_sync (&acer_rfkill_work); -destroy_workqueue (rfkill_workqueue);kfree (wireless_rfkill->data);rfkill_unregister (wireless_rfkill);if (has_cap (ACER_CAP_BLUETOOTH )) {
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 72/85 Subject: ACPI dock: Use ACPI_EXCEPTION instead of printk(KERN_ERR
In reply to Len BrownFrom: Thomas Renninger <[email protected]>
lenb: stripped patch down to what still applied to new dock.c
--- drivers/acpi/dock.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-)
drivers/acpi/dock.c +3 -2
@@ -488,8 +488,9 @@ static void handle_dock(struct dock_station *ds, int dock) arg.integer.value = dock; status =acpi_evaluate_object (ds->handle,"_DCK" , &arg_list, &buffer);if (ACPI_FAILURE (status) && status !=AE_NOT_FOUND ) - printk(KERN_ERR PREFIX "%s - failed to execute _DCK\n", - (char *)name_buffer.pointer); +ACPI_EXCEPTION ((AE_INFO , status,"%s - failed to execute" +" _DCK\n" , (char *)name_buffer.pointer)); +kfree (buffer.pointer);kfree (name_buffer.pointer); }
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 73/85 ACPI cm_sbs: Debug interface used for error message cleanup
In reply to Len BrownFrom: Thomas Renninger <[email protected]>
--- drivers/acpi/cm_sbs.c | 6 ++---- 1 files changed, 2 insertions(+), 4 deletions(-)
drivers/acpi/cm_sbs.c +2 -4
@@ -52,8 +52,7 @@ struct proc_dir_entry *acpi_lock_ac_dir(void)if (acpi_ac_dir) { lock_ac_dir_cnt++; }else { -ACPI_DEBUG_PRINT ((ACPI_DB_ERROR , -"Cannot create %s\n" ,ACPI_AC_CLASS )); +printk (KERN_ERR "Cannot create %s\n" ,ACPI_AC_CLASS ); }mutex_unlock (&cm_sbs_mutex);return acpi_ac_dir;
@@ -83,8 +82,7 @@ struct proc_dir_entry *acpi_lock_battery_dir(void)if (acpi_battery_dir) { lock_battery_dir_cnt++; }else { -ACPI_DEBUG_PRINT ((ACPI_DB_ERROR , -"Cannot create %s\n" ,ACPI_BATTERY_CLASS )); +printk (KERN_ERR "Cannot create %s\n" ,ACPI_BATTERY_CLASS ); }mutex_unlock (&cm_sbs_mutex);return acpi_battery_dir;
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 74/85 ACPI memhotplug: Debug interface used for error message cleanup
In reply to Len BrownFrom: Thomas Renninger <[email protected]>
AK: Added missing printk prefix
--- drivers/acpi/acpi_memhotplug.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/acpi/acpi_memhotplug.c +2 -2
@@ -454,8 +454,8 @@ static int acpi_memory_device_start (struct acpi_device *device)/* call add_memory func */ result =acpi_memory_enable_device (mem_device);if (result) -ACPI_DEBUG_PRINT ((ACPI_DB_ERROR , -"Error in acpi_memory_enable_device\n" )); +printk (KERN_ERR "Error in acpi_memory_enable_device [%d]\n" , + result); }return result; }
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 75/85 ACPI processor: Debug interface used for error message cleanup
In reply to Len BrownFrom: Thomas Renninger <[email protected]>
--- drivers/acpi/processor_perflib.c | 17 ++++++----------- drivers/acpi/processor_throttling.c | 17 ++++++----------- 2 files changed, 12 insertions(+), 22 deletions(-)
drivers/acpi/processor_perflib.c +6 -11
@@ -523,14 +523,9 @@ static int acpi_processor_get_psd(struct acpi_processor *pr) } psd = buffer.pointer; -if (!psd || (psd->type !=ACPI_TYPE_PACKAGE )) { -ACPI_DEBUG_PRINT ((ACPI_DB_ERROR ,"Invalid _PSD data\n" )); - result = -EFAULT ; - goto end; - } - -if (psd->package.count !=1 ) { -ACPI_DEBUG_PRINT ((ACPI_DB_ERROR ,"Invalid _PSD data\n" )); +if (!psd || (psd->type !=ACPI_TYPE_PACKAGE ) + || psd->package.count !=1 ) { +printk (KERN_ERR "Invalid _PSD data\n" ); result = -EFAULT ; goto end; }
@@ -543,19 +538,19 @@ static int acpi_processor_get_psd(struct acpi_processor *pr) status =acpi_extract_package (&(psd->package.elements[0 ]), &format, &state);if (ACPI_FAILURE (status)) { -ACPI_DEBUG_PRINT ((ACPI_DB_ERROR ,"Invalid _PSD data\n" )); +ACPI_EXCEPTION ((AE_INFO , status,"Invalid _PSD data" )); result = -EFAULT ; goto end; }if (pdomain->num_entries !=ACPI_PSD_REV0_ENTRIES ) { -ACPI_DEBUG_PRINT ((ACPI_DB_ERROR ,"Unknown _PSD:num_entries\n" )); +printk (KERN_ERR "Unknown _PSD:num_entries\n" ); result = -EFAULT ; goto end; }if (pdomain->revision !=ACPI_PSD_REV0_REVISION ) { -ACPI_DEBUG_PRINT ((ACPI_DB_ERROR ,"Unknown _PSD:revision\n" )); +printk (KERN_ERR "Unknown _PSD:revision\n" ); result = -EFAULT ; goto end; }
drivers/acpi/processor_throttling.c +6 -11
@@ -527,14 +527,9 @@ static int acpi_processor_get_tsd(struct acpi_processor *pr) } tsd = buffer.pointer; -if (!tsd || (tsd->type !=ACPI_TYPE_PACKAGE )) { -ACPI_DEBUG_PRINT ((ACPI_DB_ERROR ,"Invalid _TSD data\n" )); - result = -EFAULT ; - goto end; - } - -if (tsd->package.count !=1 ) { -ACPI_DEBUG_PRINT ((ACPI_DB_ERROR ,"Invalid _TSD data\n" )); +if (!tsd || (tsd->type !=ACPI_TYPE_PACKAGE ) + || tsd->package.count !=1 ) { +printk (KERN_INFO "Invalid _TSD data\n" ); result = -EFAULT ; goto end; }
@@ -547,19 +542,19 @@ static int acpi_processor_get_tsd(struct acpi_processor *pr) status =acpi_extract_package (&(tsd->package.elements[0 ]), &format, &state);if (ACPI_FAILURE (status)) { -ACPI_DEBUG_PRINT ((ACPI_DB_ERROR ,"Invalid _TSD data\n" )); +ACPI_EXCEPTION ((AE_INFO , status,"Invalid _TSD data" )); result = -EFAULT ; goto end; }if (pdomain->num_entries !=ACPI_TSD_REV0_ENTRIES ) { -ACPI_DEBUG_PRINT ((ACPI_DB_ERROR ,"Unknown _TSD:num_entries\n" )); +printk (KERN_ERR "Unknown _TSD:num_entries\n" ); result = -EFAULT ; goto end; }if (pdomain->revision !=ACPI_TSD_REV0_REVISION ) { -ACPI_DEBUG_PRINT ((ACPI_DB_ERROR ,"Unknown _TSD:revision\n" )); +printk (KERN_ERR "Unknown _TSD:revision\n" ); result = -EFAULT ; goto end; }
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 76/85 ACPI video: Debug interface used for error message cleanup
In reply to Len BrownFrom: Thomas Renninger <[email protected]>
--- drivers/acpi/video.c | 11 +++++------ 1 files changed, 5 insertions(+), 6 deletions(-)
drivers/acpi/video.c +5 -6
@@ -1530,8 +1530,8 @@ acpi_video_bus_get_one_device(struct acpi_device *device, acpi_video_device_notify, data);if (ACPI_FAILURE (status)) { -ACPI_DEBUG_PRINT ((ACPI_DB_ERROR , -"Error installing notify handler\n" )); +ACPI_EXCEPTION ((AE_INFO , status, +"Error installing notify handler" ));if (data->brightness)kfree (data->brightness->levels);kfree (data->brightness);
@@ -1745,8 +1745,7 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video, status =acpi_video_bus_get_one_device (dev, video);if (ACPI_FAILURE (status)) { -ACPI_DEBUG_PRINT ((ACPI_DB_WARN , -"Cant attach device" )); +printk (KERN_ERR "Cant attach device [%d]\n" , status);continue ; } }
@@ -2003,8 +2002,8 @@ static int acpi_video_bus_add(struct acpi_device *device)ACPI_DEVICE_NOTIFY , acpi_video_bus_notify, video);if (ACPI_FAILURE (status)) { -ACPI_DEBUG_PRINT ((ACPI_DB_ERROR , -"Error installing notify handler\n" )); +ACPI_EXCEPTION ((AE_INFO , status, +"Error installing notify handler" )); error = -ENODEV ; goto err_stop_video; }
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 77/85 ACPI scan: Debug interface used for error message cleanup
In reply to Len BrownFrom: Thomas Renninger <[email protected]>
--- drivers/acpi/scan.c | 11 ++++++----- 1 files changed, 6 insertions(+), 5 deletions(-)
drivers/acpi/scan.c +6 -5
@@ -113,16 +113,16 @@ static int acpi_bus_hot_remove_device(void *context)if (acpi_bus_trim (device,1 )) { -ACPI_DEBUG_PRINT ((ACPI_DB_ERROR , -"Removing device failed\n" )); +printk (KERN_ERR "Removing device [%s] failed\n" , +acpi_device_bid (device));return -1 ; }/* power off device */ status =acpi_evaluate_object (handle,"_PS3" ,NULL ,NULL );if (ACPI_FAILURE (status) && status !=AE_NOT_FOUND ) -ACPI_DEBUG_PRINT ((ACPI_DB_WARN , -"Power-off device failed\n" )); +ACPI_EXCEPTION ((AE_INFO , status, +"Power-off device failed" ));if (device->flags.lockable) { arg_list.count =1 ;
@@ -477,7 +477,8 @@ static int acpi_device_register(struct acpi_device *device, result =acpi_device_setup_files (device);if (result) -ACPI_DEBUG_PRINT ((ACPI_DB_ERROR ,"Error creating sysfs interface for device %s\n" , device->dev.bus_id)); +printk (KERN_ERR "Error creating sysfs interface for device" +" %s [%d]\n" , device->dev.bus_id, result); device->removal_type =ACPI_BUS_REMOVAL_NORMAL ;return 0 ;
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 78/85 ACPI fan: Debug interface used for error message cleanup
In reply to Len BrownFrom: Thomas Renninger <[email protected]>
--- drivers/acpi/fan.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/acpi/fan.c +2 -2
@@ -327,8 +327,8 @@ static int acpi_fan_resume(struct acpi_device *device) result =acpi_bus_get_power (device->handle, &power_state);if (result) { -ACPI_DEBUG_PRINT ((ACPI_DB_ERROR , -"Error reading fan power state\n" )); +printk (KERN_ERR "Error reading fan power state [%d]\n" , + result);return result; }
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 79/85 ACPI osl: Debug interface used for error message cleanup
In reply to Len BrownFrom: Thomas Renninger <[email protected]>
--- drivers/acpi/osl.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-)
drivers/acpi/osl.c +1 -2
@@ -729,8 +729,7 @@ acpi_status acpi_os_execute(acpi_execute_type type,INIT_WORK (&dpc->work, acpi_os_execute_deferred); queue = (type ==OSL_NOTIFY_HANDLER ) ? kacpi_notify_wq : kacpid_wq;if (!queue_work (queue, &dpc->work)) { -ACPI_DEBUG_PRINT ((ACPI_DB_ERROR , -"Call to queue_work() failed.\n" )); +printk (KERN_ERR "Call to queue_work() failed.\n" ); status =AE_ERROR ;kfree (dpc); }
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 80/85 ACPI thermal: Debug interface used for error message cleanup
In reply to Len BrownFrom: Thomas Renninger <[email protected]>
--- drivers/acpi/thermal.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/acpi/thermal.c +2 -2
@@ -1213,8 +1213,8 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) acpi_bus_private_data_handler, tz->thermal_zone);if (ACPI_FAILURE (status)) { -ACPI_DEBUG_PRINT ((ACPI_DB_ERROR , -"Error attaching device data\n" )); +ACPI_EXCEPTION ((AE_INFO , status, +"Error attaching device data" ));return -ENODEV ; }
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 81/85 ACPI system: Debug interface used for error message cleanup
In reply to Len BrownFrom: Thomas Renninger <[email protected]>
--- drivers/acpi/system.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/acpi/system.c +2 -2
@@ -387,8 +387,8 @@ static ssize_t counter_set(struct kobject *kobj, goto end;if (!(all_counters[index].flags &ACPI_EVENT_VALID )) { -ACPI_DEBUG_PRINT ((ACPI_DB_WARN , -"Can not change Invalid GPE/Fixed Event status\n" )); +printk (KERN_WARNING +"Can not change Invalid GPE/Fixed Event status\n" );return -EINVAL ; }
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 82/85 ACPI: remove unused acpi_is_child_device()
In reply to Len BrownFrom: Len Brown <[email protected]>
--- drivers/acpi/scan.c | 14 -------------- 1 files changed, 0 insertions(+), 14 deletions(-)
drivers/acpi/scan.c +0 -14
@@ -1161,20 +1161,6 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) }static int -acpi_is_child_device (struct acpi_device *device, -int (*matcher)(struct acpi_device *)) -{ -int result = -ENODEV ; - -do { -if (ACPI_SUCCESS (matcher (device))) -return AE_OK ; - }while ((device = device->parent)); - -return result; -} - -static int acpi_add_single_object (struct acpi_device **child,struct acpi_device *parent,acpi_handle handle,int type,struct acpi_bus_ops *ops)
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 83/85 ACPI: Enable EC device immediately after ACPI full initialization
In reply to Len BrownFrom: Zhao Yakui <[email protected]>
when there is no ECDT table and no _INI object for EC device, it will be enabled before scanning ACPI device. But it is too late after the following the commit is merged.
Quoted 3 lines
commit
7752d5cfe3d11ca0bb9c673ec38bd78ba6578f8eAuthor: Robert Hancock <[email protected]> Date: Fri Feb 15 01:27:20 2008 -0800
>x86: validate against acpi motherboard resources
After the above commit is merged, OS will check whether MCFG area is
reserved in ACPI motherboard resources by calling the function of acpi_get_devices when there exists MCFG table. In the acpi_get_devices the _STA object will be evaluated to check the status of the ACPI device. On some broken BIOS the MYEC object of EC device is initialized as one, which indicates that EC operation region is already accessible before enabling EC device.So on these broken BIOS the EC operation region will be accessed in course of evaluating the _STA object before enabling EC device, which causes that OS will print the following warning messages:
Quoted 1 line
ACPI Error (evregion-0315): No handler for Region [
EC__] (ffff88007f8145e8)
[EmbeddedControl] [20080609]
Quoted 2 lines
ACPI Error (exfldio-0290): Region EmbeddedControl(3) has no handler [20080321] ACPI Error (psparse-0530): Method parse/execution failed [\_SB_.PCI0.SBRG.
EC__.BAT1._STA] (Node ffff81013fc17a00), AE_NOT_EXIST
>ACPI Error (uteval-0233): Method execution failed [\_SB_.PCI0.SBRG.EC__.BAT1.
_STA] (Node ffff81013fc17a00), AE_NOT_EXISTAlthough the above warning message is harmless, it looks confusing. So it is necessary to enable EC device as early as possible.Maybe it is appropriate to enable it immediately after ACPI full initialization.
http://bugzilla.kernel.org/show_bug.cgi?id=11255
http://bugzilla.kernel.org/show_bug.cgi?id=11374
http://bugzilla.kernel.org/show_bug.cgi?id=11660
--- drivers/acpi/bus.c | 6 ++++++ drivers/acpi/scan.c | 4 ---- include/acpi/acpi_drivers.h | 1 + 3 files changed, 7 insertions(+), 4 deletions(-)
drivers/acpi/bus.c +6 -0
@@ -749,6 +749,12 @@ static int __init acpi_bus_init(void) goto error1; } +/* +* Maybe EC region is required at bus_scan/acpi_get_devices. So it +* is necessary to enable it as early as possible. +*/ +acpi_boot_ec_enable (); + printk(KERN_INFO PREFIX "Interpreter enabled\n");/* Initialize sleep structures */
drivers/acpi/scan.c +0 -4
@@ -1545,7 +1545,6 @@ static int acpi_bus_scan_fixed(struct acpi_device *root)return result; } -int __init acpi_boot_ec_enable (void );static int __init acpi_scan_init (void ) {
@@ -1579,9 +1578,6 @@ static int __init acpi_scan_init(void)*/ result =acpi_bus_scan_fixed (acpi_root); -/* EC region might be needed at bus_scan, so enable it now */ -acpi_boot_ec_enable (); -if (!result) result =acpi_bus_scan (acpi_root, &ops);
include/acpi/acpi_drivers.h +1 -0
@@ -100,6 +100,7 @@ int acpi_power_transition(struct acpi_device *device, int state);-------------------------------------------------------------------------- */ #ifdef CONFIG_ACPI_EC int acpi_ec_ecdt_probe (void ); +int acpi_boot_ec_enable (void );#endif /* --------------------------------------------------------------------------
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 84/85 delete drivers/acpi/bay.c
In reply to Len BrownFrom: Len Brown <[email protected]>
for some reason git didn't permit me to do this during the merge...
---
0 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 drivers/acpi/bay.c
drivers/acpi/bay.c deleted +0 -0
Signature · 1 line
1.5.5.1
Len Brown
reviewerPATCH 85/85 panasonic-laptop: fix build
In reply to Len BrownFrom: Len Brown <[email protected]>
sync with acpi_driver_data(device)
and acpi_evaluate_integer(..., long long)
changes that happened since this driver
was checked in.
--- drivers/misc/panasonic-laptop.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)
drivers/misc/panasonic-laptop.c +3 -3
@@ -252,7 +252,7 @@ static int acpi_pcc_write_sset(struct pcc_acpi *pcc, int func, int val)static inline int acpi_pcc_get_sqty (struct acpi_device *device) { -unsigned long s; +unsigned long long s;acpi_status status;ACPI_FUNCTION_TRACE ("acpi_pcc_get_sqty" );
@@ -500,7 +500,7 @@ static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc)struct input_dev *hotk_input_dev = pcc->input_dev;int rc;int key_code, hkey_num; -unsigned long result; +unsigned long long result;ACPI_FUNCTION_TRACE ("acpi_pcc_generate_keyinput" );
@@ -645,7 +645,7 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device) pcc->device = device; pcc->handle = device->handle; pcc->num_sifr = num_sifr; -acpi_driver_data (device) = pcc; + device->driver_data = pcc;strcpy (acpi_device_name (device),ACPI_PCC_DEVICE_NAME );strcpy (acpi_device_class (device),ACPI_PCC_CLASS );
Signature · 1 line
1.5.5.1