aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/Kconfig3
-rw-r--r--drivers/acpi/bay.c2
-rw-r--r--drivers/acpi/dispatcher/dsfield.c173
-rw-r--r--drivers/acpi/dispatcher/dsinit.c2
-rw-r--r--drivers/acpi/dispatcher/dsmethod.c57
-rw-r--r--drivers/acpi/dispatcher/dsmthdat.c2
-rw-r--r--drivers/acpi/dispatcher/dsobject.c101
-rw-r--r--drivers/acpi/dispatcher/dsopcode.c260
-rw-r--r--drivers/acpi/dispatcher/dsutils.c167
-rw-r--r--drivers/acpi/dispatcher/dswexec.c78
-rw-r--r--drivers/acpi/dispatcher/dswload.c37
-rw-r--r--drivers/acpi/dispatcher/dswscope.c2
-rw-r--r--drivers/acpi/dispatcher/dswstate.c517
-rw-r--r--drivers/acpi/ec.c240
-rw-r--r--drivers/acpi/events/evevent.c2
-rw-r--r--drivers/acpi/events/evgpe.c6
-rw-r--r--drivers/acpi/events/evgpeblk.c2
-rw-r--r--drivers/acpi/events/evmisc.c92
-rw-r--r--drivers/acpi/events/evregion.c4
-rw-r--r--drivers/acpi/events/evrgnini.c2
-rw-r--r--drivers/acpi/events/evsci.c2
-rw-r--r--drivers/acpi/events/evxface.c23
-rw-r--r--drivers/acpi/events/evxfevnt.c2
-rw-r--r--drivers/acpi/events/evxfregn.c2
-rw-r--r--drivers/acpi/executer/exconfig.c105
-rw-r--r--drivers/acpi/executer/exconvrt.c2
-rw-r--r--drivers/acpi/executer/excreate.c117
-rw-r--r--drivers/acpi/executer/exdump.c69
-rw-r--r--drivers/acpi/executer/exfield.c63
-rw-r--r--drivers/acpi/executer/exfldio.c46
-rw-r--r--drivers/acpi/executer/exmisc.c2
-rw-r--r--drivers/acpi/executer/exmutex.c237
-rw-r--r--drivers/acpi/executer/exnames.c2
-rw-r--r--drivers/acpi/executer/exoparg1.c25
-rw-r--r--drivers/acpi/executer/exoparg2.c21
-rw-r--r--drivers/acpi/executer/exoparg3.c3
-rw-r--r--drivers/acpi/executer/exoparg6.c10
-rw-r--r--drivers/acpi/executer/exprep.c17
-rw-r--r--drivers/acpi/executer/exregion.c10
-rw-r--r--drivers/acpi/executer/exresnte.c12
-rw-r--r--drivers/acpi/executer/exresolv.c55
-rw-r--r--drivers/acpi/executer/exresop.c13
-rw-r--r--drivers/acpi/executer/exstore.c119
-rw-r--r--drivers/acpi/executer/exstoren.c2
-rw-r--r--drivers/acpi/executer/exstorob.c2
-rw-r--r--drivers/acpi/executer/exsystem.c3
-rw-r--r--drivers/acpi/executer/exutils.c67
-rw-r--r--drivers/acpi/fan.c35
-rw-r--r--drivers/acpi/glue.c20
-rw-r--r--drivers/acpi/hardware/hwacpi.c2
-rw-r--r--drivers/acpi/hardware/hwgpe.c2
-rw-r--r--drivers/acpi/hardware/hwregs.c2
-rw-r--r--drivers/acpi/hardware/hwsleep.c16
-rw-r--r--drivers/acpi/hardware/hwtimer.c2
-rw-r--r--drivers/acpi/namespace/nsaccess.c101
-rw-r--r--drivers/acpi/namespace/nsalloc.c2
-rw-r--r--drivers/acpi/namespace/nsdump.c11
-rw-r--r--drivers/acpi/namespace/nsdumpdv.c2
-rw-r--r--drivers/acpi/namespace/nseval.c2
-rw-r--r--drivers/acpi/namespace/nsinit.c12
-rw-r--r--drivers/acpi/namespace/nsload.c6
-rw-r--r--drivers/acpi/namespace/nsnames.c8
-rw-r--r--drivers/acpi/namespace/nsobject.c2
-rw-r--r--drivers/acpi/namespace/nsparse.c33
-rw-r--r--drivers/acpi/namespace/nssearch.c2
-rw-r--r--drivers/acpi/namespace/nsutils.c2
-rw-r--r--drivers/acpi/namespace/nswalk.c6
-rw-r--r--drivers/acpi/namespace/nsxfeval.c15
-rw-r--r--drivers/acpi/namespace/nsxfname.c2
-rw-r--r--drivers/acpi/namespace/nsxfobj.c2
-rw-r--r--drivers/acpi/osl.c1
-rw-r--r--drivers/acpi/parser/psargs.c63
-rw-r--r--drivers/acpi/parser/psloop.c61
-rw-r--r--drivers/acpi/parser/psopcode.c38
-rw-r--r--drivers/acpi/parser/psparse.c45
-rw-r--r--drivers/acpi/parser/psscope.c2
-rw-r--r--drivers/acpi/parser/pstree.c4
-rw-r--r--drivers/acpi/parser/psutils.c2
-rw-r--r--drivers/acpi/parser/pswalk.c2
-rw-r--r--drivers/acpi/parser/psxface.c2
-rw-r--r--drivers/acpi/power.c2
-rw-r--r--drivers/acpi/processor_core.c31
-rw-r--r--drivers/acpi/processor_idle.c18
-rw-r--r--drivers/acpi/resources/rsaddr.c2
-rw-r--r--drivers/acpi/resources/rscalc.c26
-rw-r--r--drivers/acpi/resources/rscreate.c2
-rw-r--r--drivers/acpi/resources/rsdump.c10
-rw-r--r--drivers/acpi/resources/rsinfo.c2
-rw-r--r--drivers/acpi/resources/rsio.c41
-rw-r--r--drivers/acpi/resources/rsirq.c45
-rw-r--r--drivers/acpi/resources/rslist.c2
-rw-r--r--drivers/acpi/resources/rsmemory.c2
-rw-r--r--drivers/acpi/resources/rsmisc.c13
-rw-r--r--drivers/acpi/resources/rsutils.c8
-rw-r--r--drivers/acpi/resources/rsxface.c2
-rw-r--r--drivers/acpi/scan.c63
-rw-r--r--drivers/acpi/sleep/main.c42
-rw-r--r--drivers/acpi/tables/tbfadt.c2
-rw-r--r--drivers/acpi/tables/tbfind.c34
-rw-r--r--drivers/acpi/tables/tbinstal.c24
-rw-r--r--drivers/acpi/tables/tbutils.c4
-rw-r--r--drivers/acpi/tables/tbxface.c91
-rw-r--r--drivers/acpi/tables/tbxfroot.c2
-rw-r--r--drivers/acpi/thermal.c20
-rw-r--r--drivers/acpi/utilities/utalloc.c4
-rw-r--r--drivers/acpi/utilities/utcache.c2
-rw-r--r--drivers/acpi/utilities/utcopy.c61
-rw-r--r--drivers/acpi/utilities/utdebug.c19
-rw-r--r--drivers/acpi/utilities/utdelete.c23
-rw-r--r--drivers/acpi/utilities/uteval.c2
-rw-r--r--drivers/acpi/utilities/utglobal.c49
-rw-r--r--drivers/acpi/utilities/utinit.c5
-rw-r--r--drivers/acpi/utilities/utmath.c4
-rw-r--r--drivers/acpi/utilities/utmisc.c6
-rw-r--r--drivers/acpi/utilities/utmutex.c2
-rw-r--r--drivers/acpi/utilities/utobject.c8
-rw-r--r--drivers/acpi/utilities/utresrc.c2
-rw-r--r--drivers/acpi/utilities/utstate.c2
-rw-r--r--drivers/acpi/utilities/utxface.c41
-rw-r--r--drivers/acpi/utils.c2
-rw-r--r--drivers/acpi/video.c199
-rw-r--r--drivers/misc/Kconfig21
-rw-r--r--drivers/misc/Makefile3
-rw-r--r--drivers/misc/eeepc-laptop.c666
-rw-r--r--drivers/misc/thinkpad_acpi.c765
-rw-r--r--drivers/pnp/base.h74
-rw-r--r--drivers/pnp/card.c55
-rw-r--r--drivers/pnp/core.c46
-rw-r--r--drivers/pnp/driver.c28
-rw-r--r--drivers/pnp/interface.c111
-rw-r--r--drivers/pnp/isapnp/Makefile4
-rw-r--r--drivers/pnp/isapnp/core.c340
-rw-r--r--drivers/pnp/manager.c356
-rw-r--r--drivers/pnp/pnpacpi/Makefile4
-rw-r--r--drivers/pnp/pnpacpi/core.c92
-rw-r--r--drivers/pnp/pnpacpi/pnpacpi.h8
-rw-r--r--drivers/pnp/pnpacpi/rsparser.c589
-rw-r--r--drivers/pnp/pnpbios/Makefile4
-rw-r--r--drivers/pnp/pnpbios/bioscalls.c1
-rw-r--r--drivers/pnp/pnpbios/core.c31
-rw-r--r--drivers/pnp/pnpbios/pnpbios.h140
-rw-r--r--drivers/pnp/pnpbios/proc.c2
-rw-r--r--drivers/pnp/pnpbios/rsparser.c326
-rw-r--r--drivers/pnp/quirks.c15
-rw-r--r--drivers/pnp/resource.c361
-rw-r--r--drivers/pnp/support.c63
-rw-r--r--drivers/pnp/system.c21
-rw-r--r--drivers/rtc/rtc-cmos.c7
-rw-r--r--drivers/thermal/Kconfig4
-rw-r--r--drivers/thermal/Makefile2
-rw-r--r--drivers/thermal/thermal_sys.c (renamed from drivers/thermal/thermal.c)165
151 files changed, 5587 insertions, 2923 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index b4f5e8542829..c52fca833268 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -140,6 +140,7 @@ config ACPI_VIDEO
140 tristate "Video" 140 tristate "Video"
141 depends on X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL 141 depends on X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL
142 depends on INPUT 142 depends on INPUT
143 select THERMAL
143 help 144 help
144 This driver implement the ACPI Extensions For Display Adapters 145 This driver implement the ACPI Extensions For Display Adapters
145 for integrated graphics devices on motherboard, as specified in 146 for integrated graphics devices on motherboard, as specified in
@@ -151,6 +152,7 @@ config ACPI_VIDEO
151 152
152config ACPI_FAN 153config ACPI_FAN
153 tristate "Fan" 154 tristate "Fan"
155 select THERMAL
154 default y 156 default y
155 help 157 help
156 This driver adds support for ACPI fan devices, allowing user-mode 158 This driver adds support for ACPI fan devices, allowing user-mode
@@ -172,6 +174,7 @@ config ACPI_BAY
172 174
173config ACPI_PROCESSOR 175config ACPI_PROCESSOR
174 tristate "Processor" 176 tristate "Processor"
177 select THERMAL
175 default y 178 default y
176 help 179 help
177 This driver installs ACPI as the idle handler for Linux, and uses 180 This driver installs ACPI as the idle handler for Linux, and uses
diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c
index 1fa86811b8ee..d2fc94161848 100644
--- a/drivers/acpi/bay.c
+++ b/drivers/acpi/bay.c
@@ -201,6 +201,7 @@ static int is_ejectable_bay(acpi_handle handle)
201 return 0; 201 return 0;
202} 202}
203 203
204#if 0
204/** 205/**
205 * eject_removable_drive - try to eject this drive 206 * eject_removable_drive - try to eject this drive
206 * @dev : the device structure of the drive 207 * @dev : the device structure of the drive
@@ -225,6 +226,7 @@ int eject_removable_drive(struct device *dev)
225 return 0; 226 return 0;
226} 227}
227EXPORT_SYMBOL_GPL(eject_removable_drive); 228EXPORT_SYMBOL_GPL(eject_removable_drive);
229#endif /* 0 */
228 230
229static int acpi_bay_add_fs(struct bay *bay) 231static int acpi_bay_add_fs(struct bay *bay)
230{ 232{
diff --git a/drivers/acpi/dispatcher/dsfield.c b/drivers/acpi/dispatcher/dsfield.c
index f049639bac35..c78078315be9 100644
--- a/drivers/acpi/dispatcher/dsfield.c
+++ b/drivers/acpi/dispatcher/dsfield.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -89,12 +89,16 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op,
89 89
90 ACPI_FUNCTION_TRACE(ds_create_buffer_field); 90 ACPI_FUNCTION_TRACE(ds_create_buffer_field);
91 91
92 /* Get the name_string argument */ 92 /*
93 93 * Get the name_string argument (name of the new buffer_field)
94 */
94 if (op->common.aml_opcode == AML_CREATE_FIELD_OP) { 95 if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
96
97 /* For create_field, name is the 4th argument */
98
95 arg = acpi_ps_get_arg(op, 3); 99 arg = acpi_ps_get_arg(op, 3);
96 } else { 100 } else {
97 /* Create Bit/Byte/Word/Dword field */ 101 /* For all other create_xXXField operators, name is the 3rd argument */
98 102
99 arg = acpi_ps_get_arg(op, 2); 103 arg = acpi_ps_get_arg(op, 2);
100 } 104 }
@@ -107,26 +111,30 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op,
107 node = walk_state->deferred_node; 111 node = walk_state->deferred_node;
108 status = AE_OK; 112 status = AE_OK;
109 } else { 113 } else {
110 /* 114 /* Execute flag should always be set when this function is entered */
111 * During the load phase, we want to enter the name of the field into 115
112 * the namespace. During the execute phase (when we evaluate the size 116 if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
113 * operand), we want to lookup the name 117 return_ACPI_STATUS(AE_AML_INTERNAL);
114 */
115 if (walk_state->parse_flags & ACPI_PARSE_EXECUTE) {
116 flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE;
117 } else {
118 flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
119 ACPI_NS_ERROR_IF_FOUND;
120 } 118 }
121 119
122 /* 120 /* Creating new namespace node, should not already exist */
123 * Enter the name_string into the namespace 121
124 */ 122 flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
123 ACPI_NS_ERROR_IF_FOUND;
124
125 /* Mark node temporary if we are executing a method */
126
127 if (walk_state->method_node) {
128 flags |= ACPI_NS_TEMPORARY;
129 }
130
131 /* Enter the name_string into the namespace */
132
125 status = 133 status =
126 acpi_ns_lookup(walk_state->scope_info, 134 acpi_ns_lookup(walk_state->scope_info,
127 arg->common.value.string, ACPI_TYPE_ANY, 135 arg->common.value.string, ACPI_TYPE_ANY,
128 ACPI_IMODE_LOAD_PASS1, flags, walk_state, 136 ACPI_IMODE_LOAD_PASS1, flags, walk_state,
129 &(node)); 137 &node);
130 if (ACPI_FAILURE(status)) { 138 if (ACPI_FAILURE(status)) {
131 ACPI_ERROR_NAMESPACE(arg->common.value.string, status); 139 ACPI_ERROR_NAMESPACE(arg->common.value.string, status);
132 return_ACPI_STATUS(status); 140 return_ACPI_STATUS(status);
@@ -136,13 +144,13 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op,
136 /* 144 /*
137 * We could put the returned object (Node) on the object stack for later, 145 * We could put the returned object (Node) on the object stack for later,
138 * but for now, we will put it in the "op" object that the parser uses, 146 * but for now, we will put it in the "op" object that the parser uses,
139 * so we can get it again at the end of this scope 147 * so we can get it again at the end of this scope.
140 */ 148 */
141 op->common.node = node; 149 op->common.node = node;
142 150
143 /* 151 /*
144 * If there is no object attached to the node, this node was just created 152 * If there is no object attached to the node, this node was just created
145 * and we need to create the field object. Otherwise, this was a lookup 153 * and we need to create the field object. Otherwise, this was a lookup
146 * of an existing node and we don't want to create the field object again. 154 * of an existing node and we don't want to create the field object again.
147 */ 155 */
148 obj_desc = acpi_ns_get_attached_object(node); 156 obj_desc = acpi_ns_get_attached_object(node);
@@ -164,9 +172,8 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op,
164 } 172 }
165 173
166 /* 174 /*
167 * Remember location in AML stream of the field unit 175 * Remember location in AML stream of the field unit opcode and operands --
168 * opcode and operands -- since the buffer and index 176 * since the buffer and index operands must be evaluated.
169 * operands must be evaluated.
170 */ 177 */
171 second_desc = obj_desc->common.next_object; 178 second_desc = obj_desc->common.next_object;
172 second_desc->extra.aml_start = op->named.data; 179 second_desc->extra.aml_start = op->named.data;
@@ -261,7 +268,7 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info,
261 268
262 case AML_INT_NAMEDFIELD_OP: 269 case AML_INT_NAMEDFIELD_OP:
263 270
264 /* Lookup the name */ 271 /* Lookup the name, it should already exist */
265 272
266 status = acpi_ns_lookup(walk_state->scope_info, 273 status = acpi_ns_lookup(walk_state->scope_info,
267 (char *)&arg->named.name, 274 (char *)&arg->named.name,
@@ -272,20 +279,23 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info,
272 if (ACPI_FAILURE(status)) { 279 if (ACPI_FAILURE(status)) {
273 ACPI_ERROR_NAMESPACE((char *)&arg->named.name, 280 ACPI_ERROR_NAMESPACE((char *)&arg->named.name,
274 status); 281 status);
275 if (status != AE_ALREADY_EXISTS) { 282 return_ACPI_STATUS(status);
276 return_ACPI_STATUS(status);
277 }
278
279 /* Already exists, ignore error */
280 } else { 283 } else {
281 arg->common.node = info->field_node; 284 arg->common.node = info->field_node;
282 info->field_bit_length = arg->common.value.size; 285 info->field_bit_length = arg->common.value.size;
283 286
284 /* Create and initialize an object for the new Field Node */ 287 /*
285 288 * If there is no object attached to the node, this node was
286 status = acpi_ex_prep_field_value(info); 289 * just created and we need to create the field object.
287 if (ACPI_FAILURE(status)) { 290 * Otherwise, this was a lookup of an existing node and we
288 return_ACPI_STATUS(status); 291 * don't want to create the field object again.
292 */
293 if (!acpi_ns_get_attached_object
294 (info->field_node)) {
295 status = acpi_ex_prep_field_value(info);
296 if (ACPI_FAILURE(status)) {
297 return_ACPI_STATUS(status);
298 }
289 } 299 }
290 } 300 }
291 301
@@ -399,9 +409,27 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
399 union acpi_parse_object *arg = NULL; 409 union acpi_parse_object *arg = NULL;
400 struct acpi_namespace_node *node; 410 struct acpi_namespace_node *node;
401 u8 type = 0; 411 u8 type = 0;
412 u32 flags;
402 413
403 ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op); 414 ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op);
404 415
416 /* Execute flag should always be set when this function is entered */
417
418 if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
419 if (walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP) {
420
421 /* bank_field Op is deferred, just return OK */
422
423 return_ACPI_STATUS(AE_OK);
424 }
425
426 return_ACPI_STATUS(AE_AML_INTERNAL);
427 }
428
429 /*
430 * Get the field_list argument for this opcode. This is the start of the
431 * list of field elements.
432 */
405 switch (walk_state->opcode) { 433 switch (walk_state->opcode) {
406 case AML_FIELD_OP: 434 case AML_FIELD_OP:
407 arg = acpi_ps_get_arg(op, 2); 435 arg = acpi_ps_get_arg(op, 2);
@@ -422,20 +450,33 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
422 return_ACPI_STATUS(AE_BAD_PARAMETER); 450 return_ACPI_STATUS(AE_BAD_PARAMETER);
423 } 451 }
424 452
453 if (!arg) {
454 return_ACPI_STATUS(AE_AML_NO_OPERAND);
455 }
456
457 /* Creating new namespace node(s), should not already exist */
458
459 flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
460 ACPI_NS_ERROR_IF_FOUND;
461
462 /* Mark node(s) temporary if we are executing a method */
463
464 if (walk_state->method_node) {
465 flags |= ACPI_NS_TEMPORARY;
466 }
467
425 /* 468 /*
426 * Walk the list of entries in the field_list 469 * Walk the list of entries in the field_list
427 */ 470 */
428 while (arg) { 471 while (arg) {
429 472 /*
430 /* Ignore OFFSET and ACCESSAS terms here */ 473 * Ignore OFFSET and ACCESSAS terms here; we are only interested in the
431 474 * field names in order to enter them into the namespace.
475 */
432 if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { 476 if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
433 status = acpi_ns_lookup(walk_state->scope_info, 477 status = acpi_ns_lookup(walk_state->scope_info,
434 (char *)&arg->named.name, 478 (char *)&arg->named.name, type,
435 type, ACPI_IMODE_LOAD_PASS1, 479 ACPI_IMODE_LOAD_PASS1, flags,
436 ACPI_NS_NO_UPSEARCH |
437 ACPI_NS_DONT_OPEN_SCOPE |
438 ACPI_NS_ERROR_IF_FOUND,
439 walk_state, &node); 480 walk_state, &node);
440 if (ACPI_FAILURE(status)) { 481 if (ACPI_FAILURE(status)) {
441 ACPI_ERROR_NAMESPACE((char *)&arg->named.name, 482 ACPI_ERROR_NAMESPACE((char *)&arg->named.name,
@@ -452,7 +493,7 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
452 arg->common.node = node; 493 arg->common.node = node;
453 } 494 }
454 495
455 /* Move to next field in the list */ 496 /* Get the next field element in the list */
456 497
457 arg = arg->common.next; 498 arg = arg->common.next;
458 } 499 }
@@ -466,7 +507,7 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
466 * 507 *
467 * PARAMETERS: Op - Op containing the Field definition and args 508 * PARAMETERS: Op - Op containing the Field definition and args
468 * region_node - Object for the containing Operation Region 509 * region_node - Object for the containing Operation Region
469 * ` walk_state - Current method state 510 * walk_state - Current method state
470 * 511 *
471 * RETURN: Status 512 * RETURN: Status
472 * 513 *
@@ -513,36 +554,13 @@ acpi_ds_create_bank_field(union acpi_parse_object *op,
513 return_ACPI_STATUS(status); 554 return_ACPI_STATUS(status);
514 } 555 }
515 556
516 /* Third arg is the bank_value */ 557 /*
517 558 * Third arg is the bank_value
518 /* TBD: This arg is a term_arg, not a constant, and must be evaluated */ 559 * This arg is a term_arg, not a constant
519 560 * It will be evaluated later, by acpi_ds_eval_bank_field_operands
561 */
520 arg = arg->common.next; 562 arg = arg->common.next;
521 563
522 /* Currently, only the following constants are supported */
523
524 switch (arg->common.aml_opcode) {
525 case AML_ZERO_OP:
526 info.bank_value = 0;
527 break;
528
529 case AML_ONE_OP:
530 info.bank_value = 1;
531 break;
532
533 case AML_BYTE_OP:
534 case AML_WORD_OP:
535 case AML_DWORD_OP:
536 case AML_QWORD_OP:
537 info.bank_value = (u32) arg->common.value.integer;
538 break;
539
540 default:
541 info.bank_value = 0;
542 ACPI_ERROR((AE_INFO,
543 "Non-constant BankValue for BankField is not implemented"));
544 }
545
546 /* Fourth arg is the field flags */ 564 /* Fourth arg is the field flags */
547 565
548 arg = arg->common.next; 566 arg = arg->common.next;
@@ -553,8 +571,17 @@ acpi_ds_create_bank_field(union acpi_parse_object *op,
553 info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD; 571 info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD;
554 info.region_node = region_node; 572 info.region_node = region_node;
555 573
556 status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); 574 /*
575 * Use Info.data_register_node to store bank_field Op
576 * It's safe because data_register_node will never be used when create bank field
577 * We store aml_start and aml_length in the bank_field Op for late evaluation
578 * Used in acpi_ex_prep_field_value(Info)
579 *
580 * TBD: Or, should we add a field in struct acpi_create_field_info, like "void *ParentOp"?
581 */
582 info.data_register_node = (struct acpi_namespace_node *)op;
557 583
584 status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
558 return_ACPI_STATUS(status); 585 return_ACPI_STATUS(status);
559} 586}
560 587
diff --git a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c
index af923c388520..610b1ee102b0 100644
--- a/drivers/acpi/dispatcher/dsinit.c
+++ b/drivers/acpi/dispatcher/dsinit.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
index 1cbe61905824..e48a3ea03117 100644
--- a/drivers/acpi/dispatcher/dsmethod.c
+++ b/drivers/acpi/dispatcher/dsmethod.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -42,7 +42,6 @@
42 */ 42 */
43 43
44#include <acpi/acpi.h> 44#include <acpi/acpi.h>
45#include <acpi/acparser.h>
46#include <acpi/amlcode.h> 45#include <acpi/amlcode.h>
47#include <acpi/acdispat.h> 46#include <acpi/acdispat.h>
48#include <acpi/acinterp.h> 47#include <acpi/acinterp.h>
@@ -102,7 +101,7 @@ acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state)
102 walk_state->opcode, 101 walk_state->opcode,
103 walk_state->aml_offset, 102 walk_state->aml_offset,
104 NULL); 103 NULL);
105 (void)acpi_ex_enter_interpreter(); 104 acpi_ex_enter_interpreter();
106 } 105 }
107#ifdef ACPI_DISASSEMBLER 106#ifdef ACPI_DISASSEMBLER
108 if (ACPI_FAILURE(status)) { 107 if (ACPI_FAILURE(status)) {
@@ -232,9 +231,9 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
232 * recursive call. 231 * recursive call.
233 */ 232 */
234 if (!walk_state || 233 if (!walk_state ||
235 !obj_desc->method.mutex->mutex.owner_thread || 234 !obj_desc->method.mutex->mutex.thread_id ||
236 (walk_state->thread != 235 (walk_state->thread->thread_id !=
237 obj_desc->method.mutex->mutex.owner_thread)) { 236 obj_desc->method.mutex->mutex.thread_id)) {
238 /* 237 /*
239 * Acquire the method mutex. This releases the interpreter if we 238 * Acquire the method mutex. This releases the interpreter if we
240 * block (and reacquires it before it returns) 239 * block (and reacquires it before it returns)
@@ -254,8 +253,8 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
254 original_sync_level = 253 original_sync_level =
255 walk_state->thread->current_sync_level; 254 walk_state->thread->current_sync_level;
256 255
257 obj_desc->method.mutex->mutex.owner_thread = 256 obj_desc->method.mutex->mutex.thread_id =
258 walk_state->thread; 257 walk_state->thread->thread_id;
259 walk_state->thread->current_sync_level = 258 walk_state->thread->current_sync_level =
260 obj_desc->method.sync_level; 259 obj_desc->method.sync_level;
261 } else { 260 } else {
@@ -535,8 +534,6 @@ void
535acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, 534acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
536 struct acpi_walk_state *walk_state) 535 struct acpi_walk_state *walk_state)
537{ 536{
538 struct acpi_namespace_node *method_node;
539 acpi_status status;
540 537
541 ACPI_FUNCTION_TRACE_PTR(ds_terminate_control_method, walk_state); 538 ACPI_FUNCTION_TRACE_PTR(ds_terminate_control_method, walk_state);
542 539
@@ -551,34 +548,26 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
551 /* Delete all arguments and locals */ 548 /* Delete all arguments and locals */
552 549
553 acpi_ds_method_data_delete_all(walk_state); 550 acpi_ds_method_data_delete_all(walk_state);
554 }
555 551
556 /* 552 /*
557 * If method is serialized, release the mutex and restore the 553 * If method is serialized, release the mutex and restore the
558 * current sync level for this thread 554 * current sync level for this thread
559 */ 555 */
560 if (method_desc->method.mutex) { 556 if (method_desc->method.mutex) {
561 557
562 /* Acquisition Depth handles recursive calls */ 558 /* Acquisition Depth handles recursive calls */
563 559
564 method_desc->method.mutex->mutex.acquisition_depth--; 560 method_desc->method.mutex->mutex.acquisition_depth--;
565 if (!method_desc->method.mutex->mutex.acquisition_depth) { 561 if (!method_desc->method.mutex->mutex.acquisition_depth) {
566 walk_state->thread->current_sync_level = 562 walk_state->thread->current_sync_level =
567 method_desc->method.mutex->mutex. 563 method_desc->method.mutex->mutex.
568 original_sync_level; 564 original_sync_level;
569 565
570 acpi_os_release_mutex(method_desc->method.mutex->mutex. 566 acpi_os_release_mutex(method_desc->method.
571 os_mutex); 567 mutex->mutex.os_mutex);
572 method_desc->method.mutex->mutex.owner_thread = NULL; 568 method_desc->method.mutex->mutex.thread_id = 0;
569 }
573 } 570 }
574 }
575
576 if (walk_state) {
577 /*
578 * Delete any objects created by this method during execution.
579 * The method Node is stored in the walk state
580 */
581 method_node = walk_state->method_node;
582 571
583 /* 572 /*
584 * Delete any namespace objects created anywhere within 573 * Delete any namespace objects created anywhere within
@@ -620,7 +609,7 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
620 */ 609 */
621 if ((method_desc->method.method_flags & AML_METHOD_SERIALIZED) 610 if ((method_desc->method.method_flags & AML_METHOD_SERIALIZED)
622 && (!method_desc->method.mutex)) { 611 && (!method_desc->method.mutex)) {
623 status = acpi_ds_create_method_mutex(method_desc); 612 (void)acpi_ds_create_method_mutex(method_desc);
624 } 613 }
625 614
626 /* No more threads, we can free the owner_id */ 615 /* No more threads, we can free the owner_id */
diff --git a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c
index ba4626e06a5e..13c43eac35db 100644
--- a/drivers/acpi/dispatcher/dsmthdat.c
+++ b/drivers/acpi/dispatcher/dsmthdat.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c
index 954ac8ce958a..1022e38994c2 100644
--- a/drivers/acpi/dispatcher/dsobject.c
+++ b/drivers/acpi/dispatcher/dsobject.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -157,7 +157,9 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
157 * will remain as named references. This behavior is not described 157 * will remain as named references. This behavior is not described
158 * in the ACPI spec, but it appears to be an oversight. 158 * in the ACPI spec, but it appears to be an oversight.
159 */ 159 */
160 obj_desc = (union acpi_operand_object *)op->common.node; 160 obj_desc =
161 ACPI_CAST_PTR(union acpi_operand_object,
162 op->common.node);
161 163
162 status = 164 status =
163 acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR 165 acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR
@@ -172,7 +174,19 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
172 switch (op->common.node->type) { 174 switch (op->common.node->type) {
173 /* 175 /*
174 * For these types, we need the actual node, not the subobject. 176 * For these types, we need the actual node, not the subobject.
175 * However, the subobject got an extra reference count above. 177 * However, the subobject did not get an extra reference count above.
178 *
179 * TBD: should ex_resolve_node_to_value be changed to fix this?
180 */
181 case ACPI_TYPE_DEVICE:
182 case ACPI_TYPE_THERMAL:
183
184 acpi_ut_add_reference(op->common.node->object);
185
186 /*lint -fallthrough */
187 /*
188 * For these types, we need the actual node, not the subobject.
189 * The subobject got an extra reference count in ex_resolve_node_to_value.
176 */ 190 */
177 case ACPI_TYPE_MUTEX: 191 case ACPI_TYPE_MUTEX:
178 case ACPI_TYPE_METHOD: 192 case ACPI_TYPE_METHOD:
@@ -180,25 +194,15 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
180 case ACPI_TYPE_PROCESSOR: 194 case ACPI_TYPE_PROCESSOR:
181 case ACPI_TYPE_EVENT: 195 case ACPI_TYPE_EVENT:
182 case ACPI_TYPE_REGION: 196 case ACPI_TYPE_REGION:
183 case ACPI_TYPE_DEVICE:
184 case ACPI_TYPE_THERMAL:
185 197
186 obj_desc = 198 /* We will create a reference object for these types below */
187 (union acpi_operand_object *)op->common.
188 node;
189 break; 199 break;
190 200
191 default: 201 default:
192 break; 202 /*
193 } 203 * All other types - the node was resolved to an actual
194 204 * object, we are done.
195 /* 205 */
196 * If above resolved to an operand object, we are done. Otherwise,
197 * we have a NS node, we must create the package entry as a named
198 * reference.
199 */
200 if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) !=
201 ACPI_DESC_TYPE_NAMED) {
202 goto exit; 206 goto exit;
203 } 207 }
204 } 208 }
@@ -223,7 +227,7 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
223 227
224 exit: 228 exit:
225 *obj_desc_ptr = obj_desc; 229 *obj_desc_ptr = obj_desc;
226 return_ACPI_STATUS(AE_OK); 230 return_ACPI_STATUS(status);
227} 231}
228 232
229/******************************************************************************* 233/*******************************************************************************
@@ -369,7 +373,9 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
369 union acpi_parse_object *parent; 373 union acpi_parse_object *parent;
370 union acpi_operand_object *obj_desc = NULL; 374 union acpi_operand_object *obj_desc = NULL;
371 acpi_status status = AE_OK; 375 acpi_status status = AE_OK;
372 acpi_native_uint i; 376 unsigned i;
377 u16 index;
378 u16 reference_count;
373 379
374 ACPI_FUNCTION_TRACE(ds_build_internal_package_obj); 380 ACPI_FUNCTION_TRACE(ds_build_internal_package_obj);
375 381
@@ -447,13 +453,60 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
447 package. 453 package.
448 elements[i]); 454 elements[i]);
449 } 455 }
456
457 if (*obj_desc_ptr) {
458
459 /* Existing package, get existing reference count */
460
461 reference_count =
462 (*obj_desc_ptr)->common.reference_count;
463 if (reference_count > 1) {
464
465 /* Make new element ref count match original ref count */
466
467 for (index = 0; index < (reference_count - 1);
468 index++) {
469 acpi_ut_add_reference((obj_desc->
470 package.
471 elements[i]));
472 }
473 }
474 }
475
450 arg = arg->common.next; 476 arg = arg->common.next;
451 } 477 }
452 478
453 if (!arg) { 479 /* Check for match between num_elements and actual length of package_list */
480
481 if (arg) {
482 /*
483 * num_elements was exhausted, but there are remaining elements in the
484 * package_list.
485 *
486 * Note: technically, this is an error, from ACPI spec: "It is an error
487 * for NumElements to be less than the number of elements in the
488 * PackageList". However, for now, we just print an error message and
489 * no exception is returned.
490 */
491 while (arg) {
492
493 /* Find out how many elements there really are */
494
495 i++;
496 arg = arg->common.next;
497 }
498
499 ACPI_ERROR((AE_INFO,
500 "Package List length (%X) larger than NumElements count (%X), truncated\n",
501 i, element_count));
502 } else if (i < element_count) {
503 /*
504 * Arg list (elements) was exhausted, but we did not reach num_elements count.
505 * Note: this is not an error, the package is padded out with NULLs.
506 */
454 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 507 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
455 "Package List length larger than NumElements count (%X), truncated\n", 508 "Package List length (%X) smaller than NumElements count (%X), padded with null elements\n",
456 element_count)); 509 i, element_count));
457 } 510 }
458 511
459 obj_desc->package.flags |= AOPOBJ_DATA_VALID; 512 obj_desc->package.flags |= AOPOBJ_DATA_VALID;
@@ -721,6 +774,8 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
721 /* Node was saved in Op */ 774 /* Node was saved in Op */
722 775
723 obj_desc->reference.node = op->common.node; 776 obj_desc->reference.node = op->common.node;
777 obj_desc->reference.object =
778 op->common.node->object;
724 } 779 }
725 780
726 obj_desc->reference.opcode = opcode; 781 obj_desc->reference.opcode = opcode;
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c
index f501e083aac7..a818e0ddb996 100644
--- a/drivers/acpi/dispatcher/dsopcode.c
+++ b/drivers/acpi/dispatcher/dsopcode.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -49,6 +49,7 @@
49#include <acpi/acinterp.h> 49#include <acpi/acinterp.h>
50#include <acpi/acnamesp.h> 50#include <acpi/acnamesp.h>
51#include <acpi/acevents.h> 51#include <acpi/acevents.h>
52#include <acpi/actables.h>
52 53
53#define _COMPONENT ACPI_DISPATCHER 54#define _COMPONENT ACPI_DISPATCHER
54ACPI_MODULE_NAME("dsopcode") 55ACPI_MODULE_NAME("dsopcode")
@@ -219,6 +220,50 @@ acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc)
219 220
220/******************************************************************************* 221/*******************************************************************************
221 * 222 *
223 * FUNCTION: acpi_ds_get_bank_field_arguments
224 *
225 * PARAMETERS: obj_desc - A valid bank_field object
226 *
227 * RETURN: Status.
228 *
229 * DESCRIPTION: Get bank_field bank_value. This implements the late
230 * evaluation of these field attributes.
231 *
232 ******************************************************************************/
233
234acpi_status
235acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc)
236{
237 union acpi_operand_object *extra_desc;
238 struct acpi_namespace_node *node;
239 acpi_status status;
240
241 ACPI_FUNCTION_TRACE_PTR(ds_get_bank_field_arguments, obj_desc);
242
243 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
244 return_ACPI_STATUS(AE_OK);
245 }
246
247 /* Get the AML pointer (method object) and bank_field node */
248
249 extra_desc = acpi_ns_get_secondary_object(obj_desc);
250 node = obj_desc->bank_field.node;
251
252 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
253 (ACPI_TYPE_LOCAL_BANK_FIELD, node, NULL));
254 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n",
255 acpi_ut_get_node_name(node)));
256
257 /* Execute the AML code for the term_arg arguments */
258
259 status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node),
260 extra_desc->extra.aml_length,
261 extra_desc->extra.aml_start);
262 return_ACPI_STATUS(status);
263}
264
265/*******************************************************************************
266 *
222 * FUNCTION: acpi_ds_get_buffer_arguments 267 * FUNCTION: acpi_ds_get_buffer_arguments
223 * 268 *
224 * PARAMETERS: obj_desc - A valid Buffer object 269 * PARAMETERS: obj_desc - A valid Buffer object
@@ -770,7 +815,109 @@ acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state,
770 815
771 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", 816 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
772 obj_desc, 817 obj_desc,
773 ACPI_FORMAT_UINT64(obj_desc->region.address), 818 ACPI_FORMAT_NATIVE_UINT(obj_desc->region.address),
819 obj_desc->region.length));
820
821 /* Now the address and length are valid for this opregion */
822
823 obj_desc->region.flags |= AOPOBJ_DATA_VALID;
824
825 return_ACPI_STATUS(status);
826}
827
828/*******************************************************************************
829 *
830 * FUNCTION: acpi_ds_eval_table_region_operands
831 *
832 * PARAMETERS: walk_state - Current walk
833 * Op - A valid region Op object
834 *
835 * RETURN: Status
836 *
837 * DESCRIPTION: Get region address and length
838 * Called from acpi_ds_exec_end_op during data_table_region parse tree walk
839 *
840 ******************************************************************************/
841
842acpi_status
843acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state,
844 union acpi_parse_object *op)
845{
846 acpi_status status;
847 union acpi_operand_object *obj_desc;
848 union acpi_operand_object **operand;
849 struct acpi_namespace_node *node;
850 union acpi_parse_object *next_op;
851 acpi_native_uint table_index;
852 struct acpi_table_header *table;
853
854 ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op);
855
856 /*
857 * This is where we evaluate the signature_string and oem_iDString
858 * and oem_table_iDString of the data_table_region declaration
859 */
860 node = op->common.node;
861
862 /* next_op points to signature_string op */
863
864 next_op = op->common.value.arg;
865
866 /*
867 * Evaluate/create the signature_string and oem_iDString
868 * and oem_table_iDString operands
869 */
870 status = acpi_ds_create_operands(walk_state, next_op);
871 if (ACPI_FAILURE(status)) {
872 return_ACPI_STATUS(status);
873 }
874
875 /*
876 * Resolve the signature_string and oem_iDString
877 * and oem_table_iDString operands
878 */
879 status = acpi_ex_resolve_operands(op->common.aml_opcode,
880 ACPI_WALK_OPERANDS, walk_state);
881 if (ACPI_FAILURE(status)) {
882 return_ACPI_STATUS(status);
883 }
884
885 ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
886 acpi_ps_get_opcode_name(op->common.aml_opcode),
887 1, "after AcpiExResolveOperands");
888
889 operand = &walk_state->operands[0];
890
891 /* Find the ACPI table */
892
893 status = acpi_tb_find_table(operand[0]->string.pointer,
894 operand[1]->string.pointer,
895 operand[2]->string.pointer, &table_index);
896 if (ACPI_FAILURE(status)) {
897 return_ACPI_STATUS(status);
898 }
899
900 acpi_ut_remove_reference(operand[0]);
901 acpi_ut_remove_reference(operand[1]);
902 acpi_ut_remove_reference(operand[2]);
903
904 status = acpi_get_table_by_index(table_index, &table);
905 if (ACPI_FAILURE(status)) {
906 return_ACPI_STATUS(status);
907 }
908
909 obj_desc = acpi_ns_get_attached_object(node);
910 if (!obj_desc) {
911 return_ACPI_STATUS(AE_NOT_EXIST);
912 }
913
914 obj_desc->region.address =
915 (acpi_physical_address) ACPI_TO_INTEGER(table);
916 obj_desc->region.length = table->length;
917
918 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
919 obj_desc,
920 ACPI_FORMAT_NATIVE_UINT(obj_desc->region.address),
774 obj_desc->region.length)); 921 obj_desc->region.length));
775 922
776 /* Now the address and length are valid for this opregion */ 923 /* Now the address and length are valid for this opregion */
@@ -808,6 +955,12 @@ acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state,
808 955
809 /* The first operand (for all of these data objects) is the length */ 956 /* The first operand (for all of these data objects) is the length */
810 957
958 /*
959 * Set proper index into operand stack for acpi_ds_obj_stack_push
960 * invoked inside acpi_ds_create_operand.
961 */
962 walk_state->operand_index = walk_state->num_operands;
963
811 status = acpi_ds_create_operand(walk_state, op->common.value.arg, 1); 964 status = acpi_ds_create_operand(walk_state, op->common.value.arg, 1);
812 if (ACPI_FAILURE(status)) { 965 if (ACPI_FAILURE(status)) {
813 return_ACPI_STATUS(status); 966 return_ACPI_STATUS(status);
@@ -878,6 +1031,106 @@ acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state,
878 1031
879/******************************************************************************* 1032/*******************************************************************************
880 * 1033 *
1034 * FUNCTION: acpi_ds_eval_bank_field_operands
1035 *
1036 * PARAMETERS: walk_state - Current walk
1037 * Op - A valid bank_field Op object
1038 *
1039 * RETURN: Status
1040 *
1041 * DESCRIPTION: Get bank_field bank_value
1042 * Called from acpi_ds_exec_end_op during bank_field parse tree walk
1043 *
1044 ******************************************************************************/
1045
1046acpi_status
1047acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state,
1048 union acpi_parse_object *op)
1049{
1050 acpi_status status;
1051 union acpi_operand_object *obj_desc;
1052 union acpi_operand_object *operand_desc;
1053 struct acpi_namespace_node *node;
1054 union acpi_parse_object *next_op;
1055 union acpi_parse_object *arg;
1056
1057 ACPI_FUNCTION_TRACE_PTR(ds_eval_bank_field_operands, op);
1058
1059 /*
1060 * This is where we evaluate the bank_value field of the
1061 * bank_field declaration
1062 */
1063
1064 /* next_op points to the op that holds the Region */
1065
1066 next_op = op->common.value.arg;
1067
1068 /* next_op points to the op that holds the Bank Register */
1069
1070 next_op = next_op->common.next;
1071
1072 /* next_op points to the op that holds the Bank Value */
1073
1074 next_op = next_op->common.next;
1075
1076 /*
1077 * Set proper index into operand stack for acpi_ds_obj_stack_push
1078 * invoked inside acpi_ds_create_operand.
1079 *
1080 * We use walk_state->Operands[0] to store the evaluated bank_value
1081 */
1082 walk_state->operand_index = 0;
1083
1084 status = acpi_ds_create_operand(walk_state, next_op, 0);
1085 if (ACPI_FAILURE(status)) {
1086 return_ACPI_STATUS(status);
1087 }
1088
1089 status = acpi_ex_resolve_to_value(&walk_state->operands[0], walk_state);
1090 if (ACPI_FAILURE(status)) {
1091 return_ACPI_STATUS(status);
1092 }
1093
1094 ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
1095 acpi_ps_get_opcode_name(op->common.aml_opcode),
1096 1, "after AcpiExResolveOperands");
1097
1098 /*
1099 * Get the bank_value operand and save it
1100 * (at Top of stack)
1101 */
1102 operand_desc = walk_state->operands[0];
1103
1104 /* Arg points to the start Bank Field */
1105
1106 arg = acpi_ps_get_arg(op, 4);
1107 while (arg) {
1108
1109 /* Ignore OFFSET and ACCESSAS terms here */
1110
1111 if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
1112 node = arg->common.node;
1113
1114 obj_desc = acpi_ns_get_attached_object(node);
1115 if (!obj_desc) {
1116 return_ACPI_STATUS(AE_NOT_EXIST);
1117 }
1118
1119 obj_desc->bank_field.value =
1120 (u32) operand_desc->integer.value;
1121 }
1122
1123 /* Move to next field in the list */
1124
1125 arg = arg->common.next;
1126 }
1127
1128 acpi_ut_remove_reference(operand_desc);
1129 return_ACPI_STATUS(status);
1130}
1131
1132/*******************************************************************************
1133 *
881 * FUNCTION: acpi_ds_exec_begin_control_op 1134 * FUNCTION: acpi_ds_exec_begin_control_op
882 * 1135 *
883 * PARAMETERS: walk_list - The list that owns the walk stack 1136 * PARAMETERS: walk_list - The list that owns the walk stack
@@ -1070,8 +1323,7 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state,
1070 * is set to anything other than zero! 1323 * is set to anything other than zero!
1071 */ 1324 */
1072 walk_state->return_desc = walk_state->operands[0]; 1325 walk_state->return_desc = walk_state->operands[0];
1073 } else if ((walk_state->results) && 1326 } else if (walk_state->result_count) {
1074 (walk_state->results->results.num_results > 0)) {
1075 1327
1076 /* Since we have a real Return(), delete any implicit return */ 1328 /* Since we have a real Return(), delete any implicit return */
1077 1329
diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c
index 71503c036f7c..b398982f0d8b 100644
--- a/drivers/acpi/dispatcher/dsutils.c
+++ b/drivers/acpi/dispatcher/dsutils.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -278,7 +278,9 @@ acpi_ds_is_result_used(union acpi_parse_object * op,
278 AML_VAR_PACKAGE_OP) 278 AML_VAR_PACKAGE_OP)
279 || (op->common.parent->common.aml_opcode == AML_BUFFER_OP) 279 || (op->common.parent->common.aml_opcode == AML_BUFFER_OP)
280 || (op->common.parent->common.aml_opcode == 280 || (op->common.parent->common.aml_opcode ==
281 AML_INT_EVAL_SUBTREE_OP)) { 281 AML_INT_EVAL_SUBTREE_OP)
282 || (op->common.parent->common.aml_opcode ==
283 AML_BANK_FIELD_OP)) {
282 /* 284 /*
283 * These opcodes allow term_arg(s) as operands and therefore 285 * These opcodes allow term_arg(s) as operands and therefore
284 * the operands can be method calls. The result is used. 286 * the operands can be method calls. The result is used.
@@ -472,7 +474,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
472 /* A valid name must be looked up in the namespace */ 474 /* A valid name must be looked up in the namespace */
473 475
474 if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) && 476 if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) &&
475 (arg->common.value.string)) { 477 (arg->common.value.string) &&
478 !(arg->common.flags & ACPI_PARSEOP_IN_STACK)) {
476 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", 479 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n",
477 arg)); 480 arg));
478 481
@@ -595,7 +598,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
595 } else { 598 } else {
596 /* Check for null name case */ 599 /* Check for null name case */
597 600
598 if (arg->common.aml_opcode == AML_INT_NAMEPATH_OP) { 601 if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) &&
602 !(arg->common.flags & ACPI_PARSEOP_IN_STACK)) {
599 /* 603 /*
600 * If the name is null, this means that this is an 604 * If the name is null, this means that this is an
601 * optional result parameter that was not specified 605 * optional result parameter that was not specified
@@ -617,7 +621,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
617 return_ACPI_STATUS(AE_NOT_IMPLEMENTED); 621 return_ACPI_STATUS(AE_NOT_IMPLEMENTED);
618 } 622 }
619 623
620 if (op_info->flags & AML_HAS_RETVAL) { 624 if ((op_info->flags & AML_HAS_RETVAL)
625 || (arg->common.flags & ACPI_PARSEOP_IN_STACK)) {
621 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, 626 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
622 "Argument previously created, already stacked\n")); 627 "Argument previously created, already stacked\n"));
623 628
@@ -630,9 +635,7 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
630 * Use value that was already previously returned 635 * Use value that was already previously returned
631 * by the evaluation of this argument 636 * by the evaluation of this argument
632 */ 637 */
633 status = 638 status = acpi_ds_result_pop(&obj_desc, walk_state);
634 acpi_ds_result_pop_from_bottom(&obj_desc,
635 walk_state);
636 if (ACPI_FAILURE(status)) { 639 if (ACPI_FAILURE(status)) {
637 /* 640 /*
638 * Only error is underflow, and this indicates 641 * Only error is underflow, and this indicates
@@ -698,27 +701,52 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state,
698{ 701{
699 acpi_status status = AE_OK; 702 acpi_status status = AE_OK;
700 union acpi_parse_object *arg; 703 union acpi_parse_object *arg;
704 union acpi_parse_object *arguments[ACPI_OBJ_NUM_OPERANDS];
701 u32 arg_count = 0; 705 u32 arg_count = 0;
706 u32 index = walk_state->num_operands;
707 u32 i;
702 708
703 ACPI_FUNCTION_TRACE_PTR(ds_create_operands, first_arg); 709 ACPI_FUNCTION_TRACE_PTR(ds_create_operands, first_arg);
704 710
705 /* For all arguments in the list... */ 711 /* Get all arguments in the list */
706 712
707 arg = first_arg; 713 arg = first_arg;
708 while (arg) { 714 while (arg) {
709 status = acpi_ds_create_operand(walk_state, arg, arg_count); 715 if (index >= ACPI_OBJ_NUM_OPERANDS) {
710 if (ACPI_FAILURE(status)) { 716 return_ACPI_STATUS(AE_BAD_DATA);
711 goto cleanup;
712 } 717 }
713 718
714 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, 719 arguments[index] = arg;
715 "Arg #%d (%p) done, Arg1=%p\n", arg_count, 720 walk_state->operands[index] = NULL;
716 arg, first_arg));
717 721
718 /* Move on to next argument, if any */ 722 /* Move on to next argument, if any */
719 723
720 arg = arg->common.next; 724 arg = arg->common.next;
721 arg_count++; 725 arg_count++;
726 index++;
727 }
728
729 index--;
730
731 /* It is the appropriate order to get objects from the Result stack */
732
733 for (i = 0; i < arg_count; i++) {
734 arg = arguments[index];
735
736 /* Force the filling of the operand stack in inverse order */
737
738 walk_state->operand_index = (u8) index;
739
740 status = acpi_ds_create_operand(walk_state, arg, index);
741 if (ACPI_FAILURE(status)) {
742 goto cleanup;
743 }
744
745 index--;
746
747 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
748 "Arg #%d (%p) done, Arg1=%p\n", index, arg,
749 first_arg));
722 } 750 }
723 751
724 return_ACPI_STATUS(status); 752 return_ACPI_STATUS(status);
@@ -729,9 +757,112 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state,
729 * pop everything off of the operand stack and delete those 757 * pop everything off of the operand stack and delete those
730 * objects 758 * objects
731 */ 759 */
732 (void)acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state); 760 acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state);
761
762 ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %d", index));
763 return_ACPI_STATUS(status);
764}
765
766/*****************************************************************************
767 *
768 * FUNCTION: acpi_ds_evaluate_name_path
769 *
770 * PARAMETERS: walk_state - Current state of the parse tree walk,
771 * the opcode of current operation should be
772 * AML_INT_NAMEPATH_OP
773 *
774 * RETURN: Status
775 *
776 * DESCRIPTION: Translate the -name_path- parse tree object to the equivalent
777 * interpreter object, convert it to value, if needed, duplicate
778 * it, if needed, and push it onto the current result stack.
779 *
780 ****************************************************************************/
781
782acpi_status acpi_ds_evaluate_name_path(struct acpi_walk_state *walk_state)
783{
784 acpi_status status = AE_OK;
785 union acpi_parse_object *op = walk_state->op;
786 union acpi_operand_object **operand = &walk_state->operands[0];
787 union acpi_operand_object *new_obj_desc;
788 u8 type;
789
790 ACPI_FUNCTION_TRACE_PTR(ds_evaluate_name_path, walk_state);
791
792 if (!op->common.parent) {
793
794 /* This happens after certain exception processing */
795
796 goto exit;
797 }
798
799 if ((op->common.parent->common.aml_opcode == AML_PACKAGE_OP) ||
800 (op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP) ||
801 (op->common.parent->common.aml_opcode == AML_REF_OF_OP)) {
802
803 /* TBD: Should we specify this feature as a bit of op_info->Flags of these opcodes? */
804
805 goto exit;
806 }
807
808 status = acpi_ds_create_operand(walk_state, op, 0);
809 if (ACPI_FAILURE(status)) {
810 goto exit;
811 }
812
813 if (op->common.flags & ACPI_PARSEOP_TARGET) {
814 new_obj_desc = *operand;
815 goto push_result;
816 }
817
818 type = ACPI_GET_OBJECT_TYPE(*operand);
819
820 status = acpi_ex_resolve_to_value(operand, walk_state);
821 if (ACPI_FAILURE(status)) {
822 goto exit;
823 }
824
825 if (type == ACPI_TYPE_INTEGER) {
826
827 /* It was incremented by acpi_ex_resolve_to_value */
828
829 acpi_ut_remove_reference(*operand);
830
831 status =
832 acpi_ut_copy_iobject_to_iobject(*operand, &new_obj_desc,
833 walk_state);
834 if (ACPI_FAILURE(status)) {
835 goto exit;
836 }
837 } else {
838 /*
839 * The object either was anew created or is
840 * a Namespace node - don't decrement it.
841 */
842 new_obj_desc = *operand;
843 }
844
845 /* Cleanup for name-path operand */
846
847 status = acpi_ds_obj_stack_pop(1, walk_state);
848 if (ACPI_FAILURE(status)) {
849 walk_state->result_obj = new_obj_desc;
850 goto exit;
851 }
852
853 push_result:
854
855 walk_state->result_obj = new_obj_desc;
856
857 status = acpi_ds_result_push(walk_state->result_obj, walk_state);
858 if (ACPI_SUCCESS(status)) {
859
860 /* Force to take it from stack */
861
862 op->common.flags |= ACPI_PARSEOP_IN_STACK;
863 }
864
865 exit:
733 866
734 ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %d",
735 (arg_count + 1)));
736 return_ACPI_STATUS(status); 867 return_ACPI_STATUS(status);
737} 868}
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c
index 69693fa07224..b246b9657ead 100644
--- a/drivers/acpi/dispatcher/dswexec.c
+++ b/drivers/acpi/dispatcher/dswexec.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -285,11 +285,6 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,
285 switch (opcode_class) { 285 switch (opcode_class) {
286 case AML_CLASS_CONTROL: 286 case AML_CLASS_CONTROL:
287 287
288 status = acpi_ds_result_stack_push(walk_state);
289 if (ACPI_FAILURE(status)) {
290 goto error_exit;
291 }
292
293 status = acpi_ds_exec_begin_control_op(walk_state, op); 288 status = acpi_ds_exec_begin_control_op(walk_state, op);
294 break; 289 break;
295 290
@@ -305,20 +300,11 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,
305 status = acpi_ds_load2_begin_op(walk_state, NULL); 300 status = acpi_ds_load2_begin_op(walk_state, NULL);
306 } 301 }
307 302
308 if (op->common.aml_opcode == AML_REGION_OP) {
309 status = acpi_ds_result_stack_push(walk_state);
310 }
311 break; 303 break;
312 304
313 case AML_CLASS_EXECUTE: 305 case AML_CLASS_EXECUTE:
314 case AML_CLASS_CREATE: 306 case AML_CLASS_CREATE:
315 /* 307
316 * Most operators with arguments (except create_xxx_field operators)
317 * Start a new result/operand state
318 */
319 if (walk_state->op_info->object_type != ACPI_TYPE_BUFFER_FIELD) {
320 status = acpi_ds_result_stack_push(walk_state);
321 }
322 break; 308 break;
323 309
324 default: 310 default:
@@ -374,6 +360,7 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
374 /* Init the walk state */ 360 /* Init the walk state */
375 361
376 walk_state->num_operands = 0; 362 walk_state->num_operands = 0;
363 walk_state->operand_index = 0;
377 walk_state->return_desc = NULL; 364 walk_state->return_desc = NULL;
378 walk_state->result_obj = NULL; 365 walk_state->result_obj = NULL;
379 366
@@ -388,10 +375,17 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
388 /* Decode the Opcode Class */ 375 /* Decode the Opcode Class */
389 376
390 switch (op_class) { 377 switch (op_class) {
391 case AML_CLASS_ARGUMENT: /* constants, literals, etc. - do nothing */ 378 case AML_CLASS_ARGUMENT: /* Constants, literals, etc. */
379
380 if (walk_state->opcode == AML_INT_NAMEPATH_OP) {
381 status = acpi_ds_evaluate_name_path(walk_state);
382 if (ACPI_FAILURE(status)) {
383 goto cleanup;
384 }
385 }
392 break; 386 break;
393 387
394 case AML_CLASS_EXECUTE: /* most operators with arguments */ 388 case AML_CLASS_EXECUTE: /* Most operators with arguments */
395 389
396 /* Build resolved operand stack */ 390 /* Build resolved operand stack */
397 391
@@ -400,13 +394,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
400 goto cleanup; 394 goto cleanup;
401 } 395 }
402 396
403 /* Done with this result state (Now that operand stack is built) */
404
405 status = acpi_ds_result_stack_pop(walk_state);
406 if (ACPI_FAILURE(status)) {
407 goto cleanup;
408 }
409
410 /* 397 /*
411 * All opcodes require operand resolution, with the only exceptions 398 * All opcodes require operand resolution, with the only exceptions
412 * being the object_type and size_of operators. 399 * being the object_type and size_of operators.
@@ -487,16 +474,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
487 474
488 status = acpi_ds_exec_end_control_op(walk_state, op); 475 status = acpi_ds_exec_end_control_op(walk_state, op);
489 476
490 /* Make sure to properly pop the result stack */
491
492 if (ACPI_SUCCESS(status)) {
493 status = acpi_ds_result_stack_pop(walk_state);
494 } else if (status == AE_CTRL_PENDING) {
495 status = acpi_ds_result_stack_pop(walk_state);
496 if (ACPI_SUCCESS(status)) {
497 status = AE_CTRL_PENDING;
498 }
499 }
500 break; 477 break;
501 478
502 case AML_TYPE_METHOD_CALL: 479 case AML_TYPE_METHOD_CALL:
@@ -516,7 +493,7 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
516 493
517 op->common.node = 494 op->common.node =
518 (struct acpi_namespace_node *)op->asl.value. 495 (struct acpi_namespace_node *)op->asl.value.
519 arg->asl.node->object; 496 arg->asl.node;
520 acpi_ut_add_reference(op->asl.value.arg->asl. 497 acpi_ut_add_reference(op->asl.value.arg->asl.
521 node->object); 498 node->object);
522 return_ACPI_STATUS(AE_OK); 499 return_ACPI_STATUS(AE_OK);
@@ -632,13 +609,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
632 break; 609 break;
633 } 610 }
634 611
635 /* Done with result state (Now that operand stack is built) */
636
637 status = acpi_ds_result_stack_pop(walk_state);
638 if (ACPI_FAILURE(status)) {
639 goto cleanup;
640 }
641
642 /* 612 /*
643 * If a result object was returned from above, push it on the 613 * If a result object was returned from above, push it on the
644 * current result stack 614 * current result stack
@@ -671,8 +641,28 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
671 if (ACPI_FAILURE(status)) { 641 if (ACPI_FAILURE(status)) {
672 break; 642 break;
673 } 643 }
644 } else if (op->common.aml_opcode == AML_DATA_REGION_OP) {
645 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
646 "Executing DataTableRegion Strings Op=%p\n",
647 op));
648
649 status =
650 acpi_ds_eval_table_region_operands
651 (walk_state, op);
652 if (ACPI_FAILURE(status)) {
653 break;
654 }
655 } else if (op->common.aml_opcode == AML_BANK_FIELD_OP) {
656 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
657 "Executing BankField Op=%p\n",
658 op));
674 659
675 status = acpi_ds_result_stack_pop(walk_state); 660 status =
661 acpi_ds_eval_bank_field_operands(walk_state,
662 op);
663 if (ACPI_FAILURE(status)) {
664 break;
665 }
676 } 666 }
677 break; 667 break;
678 668
diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c
index 8ab9d1b29a4c..dff7a3e445a8 100644
--- a/drivers/acpi/dispatcher/dswload.c
+++ b/drivers/acpi/dispatcher/dswload.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -443,6 +443,15 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state)
443 if (ACPI_FAILURE(status)) { 443 if (ACPI_FAILURE(status)) {
444 return_ACPI_STATUS(status); 444 return_ACPI_STATUS(status);
445 } 445 }
446 } else if (op->common.aml_opcode == AML_DATA_REGION_OP) {
447 status =
448 acpi_ex_create_region(op->named.data,
449 op->named.length,
450 REGION_DATA_TABLE,
451 walk_state);
452 if (ACPI_FAILURE(status)) {
453 return_ACPI_STATUS(status);
454 }
446 } 455 }
447 } 456 }
448#endif 457#endif
@@ -767,6 +776,12 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
767 acpi_ns_lookup(walk_state->scope_info, buffer_ptr, 776 acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
768 object_type, ACPI_IMODE_LOAD_PASS2, flags, 777 object_type, ACPI_IMODE_LOAD_PASS2, flags,
769 walk_state, &node); 778 walk_state, &node);
779
780 if (ACPI_SUCCESS(status) && (flags & ACPI_NS_TEMPORARY)) {
781 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
782 "***New Node [%4.4s] %p is temporary\n",
783 acpi_ut_get_node_name(node), node));
784 }
770 break; 785 break;
771 } 786 }
772 787
@@ -823,6 +838,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
823 struct acpi_namespace_node *new_node; 838 struct acpi_namespace_node *new_node;
824#ifndef ACPI_NO_METHOD_EXECUTION 839#ifndef ACPI_NO_METHOD_EXECUTION
825 u32 i; 840 u32 i;
841 u8 region_space;
826#endif 842#endif
827 843
828 ACPI_FUNCTION_TRACE(ds_load2_end_op); 844 ACPI_FUNCTION_TRACE(ds_load2_end_op);
@@ -1003,11 +1019,6 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
1003 status = acpi_ex_create_event(walk_state); 1019 status = acpi_ex_create_event(walk_state);
1004 break; 1020 break;
1005 1021
1006 case AML_DATA_REGION_OP:
1007
1008 status = acpi_ex_create_table_region(walk_state);
1009 break;
1010
1011 case AML_ALIAS_OP: 1022 case AML_ALIAS_OP:
1012 1023
1013 status = acpi_ex_create_alias(walk_state); 1024 status = acpi_ex_create_alias(walk_state);
@@ -1035,6 +1046,15 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
1035 switch (op->common.aml_opcode) { 1046 switch (op->common.aml_opcode) {
1036#ifndef ACPI_NO_METHOD_EXECUTION 1047#ifndef ACPI_NO_METHOD_EXECUTION
1037 case AML_REGION_OP: 1048 case AML_REGION_OP:
1049 case AML_DATA_REGION_OP:
1050
1051 if (op->common.aml_opcode == AML_REGION_OP) {
1052 region_space = (acpi_adr_space_type)
1053 ((op->common.value.arg)->common.value.
1054 integer);
1055 } else {
1056 region_space = REGION_DATA_TABLE;
1057 }
1038 1058
1039 /* 1059 /*
1040 * If we are executing a method, initialize the region 1060 * If we are executing a method, initialize the region
@@ -1043,10 +1063,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
1043 status = 1063 status =
1044 acpi_ex_create_region(op->named.data, 1064 acpi_ex_create_region(op->named.data,
1045 op->named.length, 1065 op->named.length,
1046 (acpi_adr_space_type) 1066 region_space,
1047 ((op->common.value.
1048 arg)->common.value.
1049 integer),
1050 walk_state); 1067 walk_state);
1051 if (ACPI_FAILURE(status)) { 1068 if (ACPI_FAILURE(status)) {
1052 return (status); 1069 return (status);
diff --git a/drivers/acpi/dispatcher/dswscope.c b/drivers/acpi/dispatcher/dswscope.c
index 3927c495e4bf..9e6073265873 100644
--- a/drivers/acpi/dispatcher/dswscope.c
+++ b/drivers/acpi/dispatcher/dswscope.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c
index 5afcdd9c7449..1386ced332ec 100644
--- a/drivers/acpi/dispatcher/dswstate.c
+++ b/drivers/acpi/dispatcher/dswstate.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -49,85 +49,9 @@
49#define _COMPONENT ACPI_DISPATCHER 49#define _COMPONENT ACPI_DISPATCHER
50ACPI_MODULE_NAME("dswstate") 50ACPI_MODULE_NAME("dswstate")
51 51
52/* Local prototypes */ 52 /* Local prototypes */
53#ifdef ACPI_OBSOLETE_FUNCTIONS 53static acpi_status acpi_ds_result_stack_push(struct acpi_walk_state *ws);
54acpi_status 54static acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *ws);
55acpi_ds_result_insert(void *object,
56 u32 index, struct acpi_walk_state *walk_state);
57
58acpi_status acpi_ds_obj_stack_delete_all(struct acpi_walk_state *walk_state);
59
60acpi_status
61acpi_ds_obj_stack_pop_object(union acpi_operand_object **object,
62 struct acpi_walk_state *walk_state);
63
64void *acpi_ds_obj_stack_get_value(u32 index,
65 struct acpi_walk_state *walk_state);
66#endif
67
68#ifdef ACPI_FUTURE_USAGE
69/*******************************************************************************
70 *
71 * FUNCTION: acpi_ds_result_remove
72 *
73 * PARAMETERS: Object - Where to return the popped object
74 * Index - Where to extract the object
75 * walk_state - Current Walk state
76 *
77 * RETURN: Status
78 *
79 * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In
80 * other words, this is a FIFO.
81 *
82 ******************************************************************************/
83
84acpi_status
85acpi_ds_result_remove(union acpi_operand_object **object,
86 u32 index, struct acpi_walk_state *walk_state)
87{
88 union acpi_generic_state *state;
89
90 ACPI_FUNCTION_NAME(ds_result_remove);
91
92 state = walk_state->results;
93 if (!state) {
94 ACPI_ERROR((AE_INFO, "No result object pushed! State=%p",
95 walk_state));
96 return (AE_NOT_EXIST);
97 }
98
99 if (index >= ACPI_OBJ_MAX_OPERAND) {
100 ACPI_ERROR((AE_INFO,
101 "Index out of range: %X State=%p Num=%X",
102 index, walk_state, state->results.num_results));
103 }
104
105 /* Check for a valid result object */
106
107 if (!state->results.obj_desc[index]) {
108 ACPI_ERROR((AE_INFO,
109 "Null operand! State=%p #Ops=%X, Index=%X",
110 walk_state, state->results.num_results, index));
111 return (AE_AML_NO_RETURN_VALUE);
112 }
113
114 /* Remove the object */
115
116 state->results.num_results--;
117
118 *object = state->results.obj_desc[index];
119 state->results.obj_desc[index] = NULL;
120
121 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
122 "Obj=%p [%s] Index=%X State=%p Num=%X\n",
123 *object,
124 (*object) ? acpi_ut_get_object_type_name(*object) :
125 "NULL", index, walk_state,
126 state->results.num_results));
127
128 return (AE_OK);
129}
130#endif /* ACPI_FUTURE_USAGE */
131 55
132/******************************************************************************* 56/*******************************************************************************
133 * 57 *
@@ -138,122 +62,67 @@ acpi_ds_result_remove(union acpi_operand_object **object,
138 * 62 *
139 * RETURN: Status 63 * RETURN: Status
140 * 64 *
141 * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In 65 * DESCRIPTION: Pop an object off the top of this walk's result stack
142 * other words, this is a FIFO.
143 * 66 *
144 ******************************************************************************/ 67 ******************************************************************************/
145 68
146acpi_status 69acpi_status
147acpi_ds_result_pop(union acpi_operand_object ** object, 70acpi_ds_result_pop(union acpi_operand_object **object,
148 struct acpi_walk_state * walk_state) 71 struct acpi_walk_state *walk_state)
149{ 72{
150 acpi_native_uint index; 73 acpi_native_uint index;
151 union acpi_generic_state *state; 74 union acpi_generic_state *state;
75 acpi_status status;
152 76
153 ACPI_FUNCTION_NAME(ds_result_pop); 77 ACPI_FUNCTION_NAME(ds_result_pop);
154 78
155 state = walk_state->results; 79 state = walk_state->results;
156 if (!state) {
157 return (AE_OK);
158 }
159
160 if (!state->results.num_results) {
161 ACPI_ERROR((AE_INFO, "Result stack is empty! State=%p",
162 walk_state));
163 return (AE_AML_NO_RETURN_VALUE);
164 }
165 80
166 /* Remove top element */ 81 /* Incorrect state of result stack */
167 82
168 state->results.num_results--; 83 if (state && !walk_state->result_count) {
169 84 ACPI_ERROR((AE_INFO, "No results on result stack"));
170 for (index = ACPI_OBJ_NUM_OPERANDS; index; index--) { 85 return (AE_AML_INTERNAL);
171
172 /* Check for a valid result object */
173
174 if (state->results.obj_desc[index - 1]) {
175 *object = state->results.obj_desc[index - 1];
176 state->results.obj_desc[index - 1] = NULL;
177
178 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
179 "Obj=%p [%s] Index=%X State=%p Num=%X\n",
180 *object,
181 (*object) ?
182 acpi_ut_get_object_type_name(*object)
183 : "NULL", (u32) index - 1, walk_state,
184 state->results.num_results));
185
186 return (AE_OK);
187 }
188 } 86 }
189 87
190 ACPI_ERROR((AE_INFO, "No result objects! State=%p", walk_state)); 88 if (!state && walk_state->result_count) {
191 return (AE_AML_NO_RETURN_VALUE); 89 ACPI_ERROR((AE_INFO, "No result state for result stack"));
192} 90 return (AE_AML_INTERNAL);
193 91 }
194/*******************************************************************************
195 *
196 * FUNCTION: acpi_ds_result_pop_from_bottom
197 *
198 * PARAMETERS: Object - Where to return the popped object
199 * walk_state - Current Walk state
200 *
201 * RETURN: Status
202 *
203 * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In
204 * other words, this is a FIFO.
205 *
206 ******************************************************************************/
207
208acpi_status
209acpi_ds_result_pop_from_bottom(union acpi_operand_object ** object,
210 struct acpi_walk_state * walk_state)
211{
212 acpi_native_uint index;
213 union acpi_generic_state *state;
214 92
215 ACPI_FUNCTION_NAME(ds_result_pop_from_bottom); 93 /* Empty result stack */
216 94
217 state = walk_state->results;
218 if (!state) { 95 if (!state) {
219 ACPI_ERROR((AE_INFO, 96 ACPI_ERROR((AE_INFO, "Result stack is empty! State=%p",
220 "No result object pushed! State=%p", walk_state));
221 return (AE_NOT_EXIST);
222 }
223
224 if (!state->results.num_results) {
225 ACPI_ERROR((AE_INFO, "No result objects! State=%p",
226 walk_state)); 97 walk_state));
227 return (AE_AML_NO_RETURN_VALUE); 98 return (AE_AML_NO_RETURN_VALUE);
228 } 99 }
229 100
230 /* Remove Bottom element */ 101 /* Return object of the top element and clean that top element result stack */
231
232 *object = state->results.obj_desc[0];
233
234 /* Push entire stack down one element */
235
236 for (index = 0; index < state->results.num_results; index++) {
237 state->results.obj_desc[index] =
238 state->results.obj_desc[index + 1];
239 }
240 102
241 state->results.num_results--; 103 walk_state->result_count--;
242 104 index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM;
243 /* Check for a valid result object */
244 105
106 *object = state->results.obj_desc[index];
245 if (!*object) { 107 if (!*object) {
246 ACPI_ERROR((AE_INFO, 108 ACPI_ERROR((AE_INFO,
247 "Null operand! State=%p #Ops=%X Index=%X", 109 "No result objects on result stack, State=%p",
248 walk_state, state->results.num_results, 110 walk_state));
249 (u32) index));
250 return (AE_AML_NO_RETURN_VALUE); 111 return (AE_AML_NO_RETURN_VALUE);
251 } 112 }
252 113
253 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] Results=%p State=%p\n", 114 state->results.obj_desc[index] = NULL;
254 *object, 115 if (index == 0) {
255 (*object) ? acpi_ut_get_object_type_name(*object) : 116 status = acpi_ds_result_stack_pop(walk_state);
256 "NULL", state, walk_state)); 117 if (ACPI_FAILURE(status)) {
118 return (status);
119 }
120 }
121
122 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
123 "Obj=%p [%s] Index=%X State=%p Num=%X\n", *object,
124 acpi_ut_get_object_type_name(*object),
125 (u32) index, walk_state, walk_state->result_count));
257 126
258 return (AE_OK); 127 return (AE_OK);
259} 128}
@@ -276,39 +145,56 @@ acpi_ds_result_push(union acpi_operand_object * object,
276 struct acpi_walk_state * walk_state) 145 struct acpi_walk_state * walk_state)
277{ 146{
278 union acpi_generic_state *state; 147 union acpi_generic_state *state;
148 acpi_status status;
149 acpi_native_uint index;
279 150
280 ACPI_FUNCTION_NAME(ds_result_push); 151 ACPI_FUNCTION_NAME(ds_result_push);
281 152
153 if (walk_state->result_count > walk_state->result_size) {
154 ACPI_ERROR((AE_INFO, "Result stack is full"));
155 return (AE_AML_INTERNAL);
156 } else if (walk_state->result_count == walk_state->result_size) {
157
158 /* Extend the result stack */
159
160 status = acpi_ds_result_stack_push(walk_state);
161 if (ACPI_FAILURE(status)) {
162 ACPI_ERROR((AE_INFO,
163 "Failed to extend the result stack"));
164 return (status);
165 }
166 }
167
168 if (!(walk_state->result_count < walk_state->result_size)) {
169 ACPI_ERROR((AE_INFO, "No free elements in result stack"));
170 return (AE_AML_INTERNAL);
171 }
172
282 state = walk_state->results; 173 state = walk_state->results;
283 if (!state) { 174 if (!state) {
284 ACPI_ERROR((AE_INFO, "No result stack frame during push")); 175 ACPI_ERROR((AE_INFO, "No result stack frame during push"));
285 return (AE_AML_INTERNAL); 176 return (AE_AML_INTERNAL);
286 } 177 }
287 178
288 if (state->results.num_results == ACPI_OBJ_NUM_OPERANDS) {
289 ACPI_ERROR((AE_INFO,
290 "Result stack overflow: Obj=%p State=%p Num=%X",
291 object, walk_state, state->results.num_results));
292 return (AE_STACK_OVERFLOW);
293 }
294
295 if (!object) { 179 if (!object) {
296 ACPI_ERROR((AE_INFO, 180 ACPI_ERROR((AE_INFO,
297 "Null Object! Obj=%p State=%p Num=%X", 181 "Null Object! Obj=%p State=%p Num=%X",
298 object, walk_state, state->results.num_results)); 182 object, walk_state, walk_state->result_count));
299 return (AE_BAD_PARAMETER); 183 return (AE_BAD_PARAMETER);
300 } 184 }
301 185
302 state->results.obj_desc[state->results.num_results] = object; 186 /* Assign the address of object to the top free element of result stack */
303 state->results.num_results++; 187
188 index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM;
189 state->results.obj_desc[index] = object;
190 walk_state->result_count++;
304 191
305 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n", 192 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
306 object, 193 object,
307 object ?
308 acpi_ut_get_object_type_name((union 194 acpi_ut_get_object_type_name((union
309 acpi_operand_object *) 195 acpi_operand_object *)
310 object) : "NULL", 196 object), walk_state,
311 walk_state, state->results.num_results, 197 walk_state->result_count,
312 walk_state->current_result)); 198 walk_state->current_result));
313 199
314 return (AE_OK); 200 return (AE_OK);
@@ -322,16 +208,25 @@ acpi_ds_result_push(union acpi_operand_object * object,
322 * 208 *
323 * RETURN: Status 209 * RETURN: Status
324 * 210 *
325 * DESCRIPTION: Push an object onto the walk_state result stack. 211 * DESCRIPTION: Push an object onto the walk_state result stack
326 * 212 *
327 ******************************************************************************/ 213 ******************************************************************************/
328 214
329acpi_status acpi_ds_result_stack_push(struct acpi_walk_state * walk_state) 215static acpi_status acpi_ds_result_stack_push(struct acpi_walk_state *walk_state)
330{ 216{
331 union acpi_generic_state *state; 217 union acpi_generic_state *state;
332 218
333 ACPI_FUNCTION_NAME(ds_result_stack_push); 219 ACPI_FUNCTION_NAME(ds_result_stack_push);
334 220
221 /* Check for stack overflow */
222
223 if (((u32) walk_state->result_size + ACPI_RESULTS_FRAME_OBJ_NUM) >
224 ACPI_RESULTS_OBJ_NUM_MAX) {
225 ACPI_ERROR((AE_INFO, "Result stack overflow: State=%p Num=%X",
226 walk_state, walk_state->result_size));
227 return (AE_STACK_OVERFLOW);
228 }
229
335 state = acpi_ut_create_generic_state(); 230 state = acpi_ut_create_generic_state();
336 if (!state) { 231 if (!state) {
337 return (AE_NO_MEMORY); 232 return (AE_NO_MEMORY);
@@ -340,6 +235,10 @@ acpi_status acpi_ds_result_stack_push(struct acpi_walk_state * walk_state)
340 state->common.descriptor_type = ACPI_DESC_TYPE_STATE_RESULT; 235 state->common.descriptor_type = ACPI_DESC_TYPE_STATE_RESULT;
341 acpi_ut_push_generic_state(&walk_state->results, state); 236 acpi_ut_push_generic_state(&walk_state->results, state);
342 237
238 /* Increase the length of the result stack by the length of frame */
239
240 walk_state->result_size += ACPI_RESULTS_FRAME_OBJ_NUM;
241
343 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Results=%p State=%p\n", 242 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Results=%p State=%p\n",
344 state, walk_state)); 243 state, walk_state));
345 244
@@ -354,11 +253,11 @@ acpi_status acpi_ds_result_stack_push(struct acpi_walk_state * walk_state)
354 * 253 *
355 * RETURN: Status 254 * RETURN: Status
356 * 255 *
357 * DESCRIPTION: Pop an object off of the walk_state result stack. 256 * DESCRIPTION: Pop an object off of the walk_state result stack
358 * 257 *
359 ******************************************************************************/ 258 ******************************************************************************/
360 259
361acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state * walk_state) 260static acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *walk_state)
362{ 261{
363 union acpi_generic_state *state; 262 union acpi_generic_state *state;
364 263
@@ -367,18 +266,27 @@ acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state * walk_state)
367 /* Check for stack underflow */ 266 /* Check for stack underflow */
368 267
369 if (walk_state->results == NULL) { 268 if (walk_state->results == NULL) {
370 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Underflow - State=%p\n", 269 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
270 "Result stack underflow - State=%p\n",
371 walk_state)); 271 walk_state));
372 return (AE_AML_NO_OPERAND); 272 return (AE_AML_NO_OPERAND);
373 } 273 }
374 274
275 if (walk_state->result_size < ACPI_RESULTS_FRAME_OBJ_NUM) {
276 ACPI_ERROR((AE_INFO, "Insufficient result stack size"));
277 return (AE_AML_INTERNAL);
278 }
279
375 state = acpi_ut_pop_generic_state(&walk_state->results); 280 state = acpi_ut_pop_generic_state(&walk_state->results);
281 acpi_ut_delete_generic_state(state);
282
283 /* Decrease the length of result stack by the length of frame */
284
285 walk_state->result_size -= ACPI_RESULTS_FRAME_OBJ_NUM;
376 286
377 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 287 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
378 "Result=%p RemainingResults=%X State=%p\n", 288 "Result=%p RemainingResults=%X State=%p\n",
379 state, state->results.num_results, walk_state)); 289 state, walk_state->result_count, walk_state));
380
381 acpi_ut_delete_generic_state(state);
382 290
383 return (AE_OK); 291 return (AE_OK);
384} 292}
@@ -412,9 +320,13 @@ acpi_ds_obj_stack_push(void *object, struct acpi_walk_state * walk_state)
412 320
413 /* Put the object onto the stack */ 321 /* Put the object onto the stack */
414 322
415 walk_state->operands[walk_state->num_operands] = object; 323 walk_state->operands[walk_state->operand_index] = object;
416 walk_state->num_operands++; 324 walk_state->num_operands++;
417 325
326 /* For the usual order of filling the operand stack */
327
328 walk_state->operand_index++;
329
418 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n", 330 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
419 object, 331 object,
420 acpi_ut_get_object_type_name((union 332 acpi_ut_get_object_type_name((union
@@ -484,43 +396,36 @@ acpi_ds_obj_stack_pop(u32 pop_count, struct acpi_walk_state * walk_state)
484 * 396 *
485 ******************************************************************************/ 397 ******************************************************************************/
486 398
487acpi_status 399void
488acpi_ds_obj_stack_pop_and_delete(u32 pop_count, 400acpi_ds_obj_stack_pop_and_delete(u32 pop_count,
489 struct acpi_walk_state * walk_state) 401 struct acpi_walk_state *walk_state)
490{ 402{
491 u32 i; 403 acpi_native_int i;
492 union acpi_operand_object *obj_desc; 404 union acpi_operand_object *obj_desc;
493 405
494 ACPI_FUNCTION_NAME(ds_obj_stack_pop_and_delete); 406 ACPI_FUNCTION_NAME(ds_obj_stack_pop_and_delete);
495 407
496 for (i = 0; i < pop_count; i++) { 408 if (pop_count == 0) {
497 409 return;
498 /* Check for stack underflow */ 410 }
499 411
412 for (i = (acpi_native_int) (pop_count - 1); i >= 0; i--) {
500 if (walk_state->num_operands == 0) { 413 if (walk_state->num_operands == 0) {
501 ACPI_ERROR((AE_INFO, 414 return;
502 "Object stack underflow! Count=%X State=%p #Ops=%X",
503 pop_count, walk_state,
504 walk_state->num_operands));
505 return (AE_STACK_UNDERFLOW);
506 } 415 }
507 416
508 /* Pop the stack and delete an object if present in this stack entry */ 417 /* Pop the stack and delete an object if present in this stack entry */
509 418
510 walk_state->num_operands--; 419 walk_state->num_operands--;
511 obj_desc = walk_state->operands[walk_state->num_operands]; 420 obj_desc = walk_state->operands[i];
512 if (obj_desc) { 421 if (obj_desc) {
513 acpi_ut_remove_reference(walk_state-> 422 acpi_ut_remove_reference(walk_state->operands[i]);
514 operands[walk_state-> 423 walk_state->operands[i] = NULL;
515 num_operands]);
516 walk_state->operands[walk_state->num_operands] = NULL;
517 } 424 }
518 } 425 }
519 426
520 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n", 427 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
521 pop_count, walk_state, walk_state->num_operands)); 428 pop_count, walk_state, walk_state->num_operands));
522
523 return (AE_OK);
524} 429}
525 430
526/******************************************************************************* 431/*******************************************************************************
@@ -560,7 +465,7 @@ struct acpi_walk_state *acpi_ds_get_current_walk_state(struct acpi_thread_state
560 * 465 *
561 * RETURN: None 466 * RETURN: None
562 * 467 *
563 * DESCRIPTION: Place the Thread state at the head of the state list. 468 * DESCRIPTION: Place the Thread state at the head of the state list
564 * 469 *
565 ******************************************************************************/ 470 ******************************************************************************/
566 471
@@ -636,7 +541,6 @@ struct acpi_walk_state *acpi_ds_create_walk_state(acpi_owner_id owner_id, union
636 *thread) 541 *thread)
637{ 542{
638 struct acpi_walk_state *walk_state; 543 struct acpi_walk_state *walk_state;
639 acpi_status status;
640 544
641 ACPI_FUNCTION_TRACE(ds_create_walk_state); 545 ACPI_FUNCTION_TRACE(ds_create_walk_state);
642 546
@@ -659,14 +563,6 @@ struct acpi_walk_state *acpi_ds_create_walk_state(acpi_owner_id owner_id, union
659 acpi_ds_method_data_init(walk_state); 563 acpi_ds_method_data_init(walk_state);
660#endif 564#endif
661 565
662 /* Create an initial result stack entry */
663
664 status = acpi_ds_result_stack_push(walk_state);
665 if (ACPI_FAILURE(status)) {
666 ACPI_FREE(walk_state);
667 return_PTR(NULL);
668 }
669
670 /* Put the new state at the head of the walk list */ 566 /* Put the new state at the head of the walk list */
671 567
672 if (thread) { 568 if (thread) {
@@ -860,190 +756,3 @@ void acpi_ds_delete_walk_state(struct acpi_walk_state *walk_state)
860 ACPI_FREE(walk_state); 756 ACPI_FREE(walk_state);
861 return_VOID; 757 return_VOID;
862} 758}
863
864#ifdef ACPI_OBSOLETE_FUNCTIONS
865/*******************************************************************************
866 *
867 * FUNCTION: acpi_ds_result_insert
868 *
869 * PARAMETERS: Object - Object to push
870 * Index - Where to insert the object
871 * walk_state - Current Walk state
872 *
873 * RETURN: Status
874 *
875 * DESCRIPTION: Insert an object onto this walk's result stack
876 *
877 ******************************************************************************/
878
879acpi_status
880acpi_ds_result_insert(void *object,
881 u32 index, struct acpi_walk_state *walk_state)
882{
883 union acpi_generic_state *state;
884
885 ACPI_FUNCTION_NAME(ds_result_insert);
886
887 state = walk_state->results;
888 if (!state) {
889 ACPI_ERROR((AE_INFO, "No result object pushed! State=%p",
890 walk_state));
891 return (AE_NOT_EXIST);
892 }
893
894 if (index >= ACPI_OBJ_NUM_OPERANDS) {
895 ACPI_ERROR((AE_INFO,
896 "Index out of range: %X Obj=%p State=%p Num=%X",
897 index, object, walk_state,
898 state->results.num_results));
899 return (AE_BAD_PARAMETER);
900 }
901
902 if (!object) {
903 ACPI_ERROR((AE_INFO,
904 "Null Object! Index=%X Obj=%p State=%p Num=%X",
905 index, object, walk_state,
906 state->results.num_results));
907 return (AE_BAD_PARAMETER);
908 }
909
910 state->results.obj_desc[index] = object;
911 state->results.num_results++;
912
913 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
914 "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
915 object,
916 object ?
917 acpi_ut_get_object_type_name((union
918 acpi_operand_object *)
919 object) : "NULL",
920 walk_state, state->results.num_results,
921 walk_state->current_result));
922
923 return (AE_OK);
924}
925
926/*******************************************************************************
927 *
928 * FUNCTION: acpi_ds_obj_stack_delete_all
929 *
930 * PARAMETERS: walk_state - Current Walk state
931 *
932 * RETURN: Status
933 *
934 * DESCRIPTION: Clear the object stack by deleting all objects that are on it.
935 * Should be used with great care, if at all!
936 *
937 ******************************************************************************/
938
939acpi_status acpi_ds_obj_stack_delete_all(struct acpi_walk_state * walk_state)
940{
941 u32 i;
942
943 ACPI_FUNCTION_TRACE_PTR(ds_obj_stack_delete_all, walk_state);
944
945 /* The stack size is configurable, but fixed */
946
947 for (i = 0; i < ACPI_OBJ_NUM_OPERANDS; i++) {
948 if (walk_state->operands[i]) {
949 acpi_ut_remove_reference(walk_state->operands[i]);
950 walk_state->operands[i] = NULL;
951 }
952 }
953
954 return_ACPI_STATUS(AE_OK);
955}
956
957/*******************************************************************************
958 *
959 * FUNCTION: acpi_ds_obj_stack_pop_object
960 *
961 * PARAMETERS: Object - Where to return the popped object
962 * walk_state - Current Walk state
963 *
964 * RETURN: Status
965 *
966 * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT
967 * deleted by this routine.
968 *
969 ******************************************************************************/
970
971acpi_status
972acpi_ds_obj_stack_pop_object(union acpi_operand_object **object,
973 struct acpi_walk_state *walk_state)
974{
975 ACPI_FUNCTION_NAME(ds_obj_stack_pop_object);
976
977 /* Check for stack underflow */
978
979 if (walk_state->num_operands == 0) {
980 ACPI_ERROR((AE_INFO,
981 "Missing operand/stack empty! State=%p #Ops=%X",
982 walk_state, walk_state->num_operands));
983 *object = NULL;
984 return (AE_AML_NO_OPERAND);
985 }
986
987 /* Pop the stack */
988
989 walk_state->num_operands--;
990
991 /* Check for a valid operand */
992
993 if (!walk_state->operands[walk_state->num_operands]) {
994 ACPI_ERROR((AE_INFO,
995 "Null operand! State=%p #Ops=%X",
996 walk_state, walk_state->num_operands));
997 *object = NULL;
998 return (AE_AML_NO_OPERAND);
999 }
1000
1001 /* Get operand and set stack entry to null */
1002
1003 *object = walk_state->operands[walk_state->num_operands];
1004 walk_state->operands[walk_state->num_operands] = NULL;
1005
1006 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
1007 *object, acpi_ut_get_object_type_name(*object),
1008 walk_state, walk_state->num_operands));
1009
1010 return (AE_OK);
1011}
1012
1013/*******************************************************************************
1014 *
1015 * FUNCTION: acpi_ds_obj_stack_get_value
1016 *
1017 * PARAMETERS: Index - Stack index whose value is desired. Based
1018 * on the top of the stack (index=0 == top)
1019 * walk_state - Current Walk state
1020 *
1021 * RETURN: Pointer to the requested operand
1022 *
1023 * DESCRIPTION: Retrieve an object from this walk's operand stack. Index must
1024 * be within the range of the current stack pointer.
1025 *
1026 ******************************************************************************/
1027
1028void *acpi_ds_obj_stack_get_value(u32 index, struct acpi_walk_state *walk_state)
1029{
1030
1031 ACPI_FUNCTION_TRACE_PTR(ds_obj_stack_get_value, walk_state);
1032
1033 /* Can't do it if the stack is empty */
1034
1035 if (walk_state->num_operands == 0) {
1036 return_PTR(NULL);
1037 }
1038
1039 /* or if the index is past the top of the stack */
1040
1041 if (index > (walk_state->num_operands - (u32) 1)) {
1042 return_PTR(NULL);
1043 }
1044
1045 return_PTR(walk_state->
1046 operands[(acpi_native_uint) (walk_state->num_operands - 1) -
1047 index]);
1048}
1049#endif
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index e3f04b272f3f..0924992187e8 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -73,38 +73,14 @@ enum ec_event {
73 73
74#define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ 74#define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */
75#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ 75#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */
76#define ACPI_EC_UDELAY 100 /* Wait 100us before polling EC again */
76 77
77enum { 78enum {
78 EC_FLAGS_WAIT_GPE = 0, /* Don't check status until GPE arrives */ 79 EC_FLAGS_WAIT_GPE = 0, /* Don't check status until GPE arrives */
79 EC_FLAGS_QUERY_PENDING, /* Query is pending */ 80 EC_FLAGS_QUERY_PENDING, /* Query is pending */
80 EC_FLAGS_GPE_MODE, /* Expect GPE to be sent for status change */ 81 EC_FLAGS_GPE_MODE, /* Expect GPE to be sent for status change */
81 EC_FLAGS_NO_ADDRESS_GPE, /* Expect GPE only for non-address event */ 82 EC_FLAGS_NO_GPE, /* Don't use GPE mode */
82 EC_FLAGS_ADDRESS, /* Address is being written */ 83 EC_FLAGS_RESCHEDULE_POLL /* Re-schedule poll */
83 EC_FLAGS_NO_WDATA_GPE, /* Don't expect WDATA GPE event */
84 EC_FLAGS_WDATA, /* Data is being written */
85 EC_FLAGS_NO_OBF1_GPE, /* Don't expect GPE before read */
86};
87
88static int acpi_ec_remove(struct acpi_device *device, int type);
89static int acpi_ec_start(struct acpi_device *device);
90static int acpi_ec_stop(struct acpi_device *device, int type);
91static int acpi_ec_add(struct acpi_device *device);
92
93static const struct acpi_device_id ec_device_ids[] = {
94 {"PNP0C09", 0},
95 {"", 0},
96};
97
98static struct acpi_driver acpi_ec_driver = {
99 .name = "ec",
100 .class = ACPI_EC_CLASS,
101 .ids = ec_device_ids,
102 .ops = {
103 .add = acpi_ec_add,
104 .remove = acpi_ec_remove,
105 .start = acpi_ec_start,
106 .stop = acpi_ec_stop,
107 },
108}; 84};
109 85
110/* If we find an EC via the ECDT, we need to keep a ptr to its context */ 86/* If we find an EC via the ECDT, we need to keep a ptr to its context */
@@ -129,6 +105,8 @@ static struct acpi_ec {
129 struct mutex lock; 105 struct mutex lock;
130 wait_queue_head_t wait; 106 wait_queue_head_t wait;
131 struct list_head list; 107 struct list_head list;
108 struct delayed_work work;
109 atomic_t irq_count;
132 u8 handlers_installed; 110 u8 handlers_installed;
133} *boot_ec, *first_ec; 111} *boot_ec, *first_ec;
134 112
@@ -177,65 +155,52 @@ static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event)
177 return 0; 155 return 0;
178} 156}
179 157
180static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll) 158static void ec_schedule_ec_poll(struct acpi_ec *ec)
181{ 159{
182 int ret = 0; 160 if (test_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags))
161 schedule_delayed_work(&ec->work,
162 msecs_to_jiffies(ACPI_EC_DELAY));
163}
183 164
184 if (unlikely(event == ACPI_EC_EVENT_OBF_1 && 165static void ec_switch_to_poll_mode(struct acpi_ec *ec)
185 test_bit(EC_FLAGS_NO_OBF1_GPE, &ec->flags))) 166{
186 force_poll = 1; 167 set_bit(EC_FLAGS_NO_GPE, &ec->flags);
187 if (unlikely(test_bit(EC_FLAGS_ADDRESS, &ec->flags) && 168 clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
188 test_bit(EC_FLAGS_NO_ADDRESS_GPE, &ec->flags))) 169 acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
189 force_poll = 1; 170 set_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags);
190 if (unlikely(test_bit(EC_FLAGS_WDATA, &ec->flags) && 171}
191 test_bit(EC_FLAGS_NO_WDATA_GPE, &ec->flags))) 172
192 force_poll = 1; 173static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
174{
175 atomic_set(&ec->irq_count, 0);
193 if (likely(test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) && 176 if (likely(test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) &&
194 likely(!force_poll)) { 177 likely(!force_poll)) {
195 if (wait_event_timeout(ec->wait, acpi_ec_check_status(ec, event), 178 if (wait_event_timeout(ec->wait, acpi_ec_check_status(ec, event),
196 msecs_to_jiffies(ACPI_EC_DELAY))) 179 msecs_to_jiffies(ACPI_EC_DELAY)))
197 goto end; 180 return 0;
198 clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); 181 clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
199 if (acpi_ec_check_status(ec, event)) { 182 if (acpi_ec_check_status(ec, event)) {
200 if (event == ACPI_EC_EVENT_OBF_1) { 183 /* missing GPEs, switch back to poll mode */
201 /* miss OBF_1 GPE, don't expect it */ 184 if (printk_ratelimit())
202 pr_info(PREFIX "missing OBF confirmation, " 185 pr_info(PREFIX "missing confirmations, "
203 "don't expect it any longer.\n");
204 set_bit(EC_FLAGS_NO_OBF1_GPE, &ec->flags);
205 } else if (test_bit(EC_FLAGS_ADDRESS, &ec->flags)) {
206 /* miss address GPE, don't expect it anymore */
207 pr_info(PREFIX "missing address confirmation, "
208 "don't expect it any longer.\n");
209 set_bit(EC_FLAGS_NO_ADDRESS_GPE, &ec->flags);
210 } else if (test_bit(EC_FLAGS_WDATA, &ec->flags)) {
211 /* miss write data GPE, don't expect it */
212 pr_info(PREFIX "missing write data confirmation, "
213 "don't expect it any longer.\n");
214 set_bit(EC_FLAGS_NO_WDATA_GPE, &ec->flags);
215 } else {
216 /* missing GPEs, switch back to poll mode */
217 if (printk_ratelimit())
218 pr_info(PREFIX "missing confirmations, "
219 "switch off interrupt mode.\n"); 186 "switch off interrupt mode.\n");
220 clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); 187 ec_switch_to_poll_mode(ec);
221 } 188 ec_schedule_ec_poll(ec);
222 goto end; 189 return 0;
223 } 190 }
224 } else { 191 } else {
225 unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); 192 unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
226 clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); 193 clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
227 while (time_before(jiffies, delay)) { 194 while (time_before(jiffies, delay)) {
228 if (acpi_ec_check_status(ec, event)) 195 if (acpi_ec_check_status(ec, event))
229 goto end; 196 return 0;
197 udelay(ACPI_EC_UDELAY);
230 } 198 }
231 } 199 }
232 pr_err(PREFIX "acpi_ec_wait timeout," 200 pr_err(PREFIX "acpi_ec_wait timeout, status = 0x%2.2x, event = %s\n",
233 " status = %d, expect_event = %d\n", 201 acpi_ec_read_status(ec),
234 acpi_ec_read_status(ec), event); 202 (event == ACPI_EC_EVENT_OBF_1) ? "\"b0=1\"" : "\"b1=0\"");
235 ret = -ETIME; 203 return -ETIME;
236 end:
237 clear_bit(EC_FLAGS_ADDRESS, &ec->flags);
238 return ret;
239} 204}
240 205
241static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, 206static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
@@ -245,8 +210,8 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
245{ 210{
246 int result = 0; 211 int result = 0;
247 set_bit(EC_FLAGS_WAIT_GPE, &ec->flags); 212 set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
248 acpi_ec_write_cmd(ec, command);
249 pr_debug(PREFIX "transaction start\n"); 213 pr_debug(PREFIX "transaction start\n");
214 acpi_ec_write_cmd(ec, command);
250 for (; wdata_len > 0; --wdata_len) { 215 for (; wdata_len > 0; --wdata_len) {
251 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll); 216 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll);
252 if (result) { 217 if (result) {
@@ -254,15 +219,11 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
254 "write_cmd timeout, command = %d\n", command); 219 "write_cmd timeout, command = %d\n", command);
255 goto end; 220 goto end;
256 } 221 }
257 /* mark the address byte written to EC */
258 if (rdata_len + wdata_len > 1)
259 set_bit(EC_FLAGS_ADDRESS, &ec->flags);
260 set_bit(EC_FLAGS_WAIT_GPE, &ec->flags); 222 set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
261 acpi_ec_write_data(ec, *(wdata++)); 223 acpi_ec_write_data(ec, *(wdata++));
262 } 224 }
263 225
264 if (!rdata_len) { 226 if (!rdata_len) {
265 set_bit(EC_FLAGS_WDATA, &ec->flags);
266 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll); 227 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll);
267 if (result) { 228 if (result) {
268 pr_err(PREFIX 229 pr_err(PREFIX
@@ -527,47 +488,51 @@ static u32 acpi_ec_gpe_handler(void *data)
527{ 488{
528 acpi_status status = AE_OK; 489 acpi_status status = AE_OK;
529 struct acpi_ec *ec = data; 490 struct acpi_ec *ec = data;
491 u8 state = acpi_ec_read_status(ec);
530 492
531 pr_debug(PREFIX "~~~> interrupt\n"); 493 pr_debug(PREFIX "~~~> interrupt\n");
494 atomic_inc(&ec->irq_count);
495 if (atomic_read(&ec->irq_count) > 5) {
496 pr_err(PREFIX "GPE storm detected, disabling EC GPE\n");
497 ec_switch_to_poll_mode(ec);
498 goto end;
499 }
532 clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); 500 clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
533 if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) 501 if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))
534 wake_up(&ec->wait); 502 wake_up(&ec->wait);
535 503
536 if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_SCI) { 504 if (state & ACPI_EC_FLAG_SCI) {
537 if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) 505 if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
538 status = acpi_os_execute(OSL_EC_BURST_HANDLER, 506 status = acpi_os_execute(OSL_EC_BURST_HANDLER,
539 acpi_ec_gpe_query, ec); 507 acpi_ec_gpe_query, ec);
540 } else if (unlikely(!test_bit(EC_FLAGS_GPE_MODE, &ec->flags))) { 508 } else if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
509 !test_bit(EC_FLAGS_NO_GPE, &ec->flags) &&
510 in_interrupt()) {
541 /* this is non-query, must be confirmation */ 511 /* this is non-query, must be confirmation */
542 if (printk_ratelimit()) 512 if (printk_ratelimit())
543 pr_info(PREFIX "non-query interrupt received," 513 pr_info(PREFIX "non-query interrupt received,"
544 " switching to interrupt mode\n"); 514 " switching to interrupt mode\n");
545 set_bit(EC_FLAGS_GPE_MODE, &ec->flags); 515 set_bit(EC_FLAGS_GPE_MODE, &ec->flags);
516 clear_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags);
546 } 517 }
547 518end:
519 ec_schedule_ec_poll(ec);
548 return ACPI_SUCCESS(status) ? 520 return ACPI_SUCCESS(status) ?
549 ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; 521 ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
550} 522}
551 523
524static void do_ec_poll(struct work_struct *work)
525{
526 struct acpi_ec *ec = container_of(work, struct acpi_ec, work.work);
527 atomic_set(&ec->irq_count, 0);
528 (void)acpi_ec_gpe_handler(ec);
529}
530
552/* -------------------------------------------------------------------------- 531/* --------------------------------------------------------------------------
553 Address Space Management 532 Address Space Management
554 -------------------------------------------------------------------------- */ 533 -------------------------------------------------------------------------- */
555 534
556static acpi_status 535static acpi_status
557acpi_ec_space_setup(acpi_handle region_handle,
558 u32 function, void *handler_context, void **return_context)
559{
560 /*
561 * The EC object is in the handler context and is needed
562 * when calling the acpi_ec_space_handler.
563 */
564 *return_context = (function != ACPI_REGION_DEACTIVATE) ?
565 handler_context : NULL;
566
567 return AE_OK;
568}
569
570static acpi_status
571acpi_ec_space_handler(u32 function, acpi_physical_address address, 536acpi_ec_space_handler(u32 function, acpi_physical_address address,
572 u32 bits, acpi_integer *value, 537 u32 bits, acpi_integer *value,
573 void *handler_context, void *region_context) 538 void *handler_context, void *region_context)
@@ -704,6 +669,8 @@ static struct acpi_ec *make_acpi_ec(void)
704 mutex_init(&ec->lock); 669 mutex_init(&ec->lock);
705 init_waitqueue_head(&ec->wait); 670 init_waitqueue_head(&ec->wait);
706 INIT_LIST_HEAD(&ec->list); 671 INIT_LIST_HEAD(&ec->list);
672 INIT_DELAYED_WORK_DEFERRABLE(&ec->work, do_ec_poll);
673 atomic_set(&ec->irq_count, 0);
707 return ec; 674 return ec;
708} 675}
709 676
@@ -736,17 +703,21 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
736 status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe); 703 status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe);
737 if (ACPI_FAILURE(status)) 704 if (ACPI_FAILURE(status))
738 return status; 705 return status;
739 /* Find and register all query methods */
740 acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1,
741 acpi_ec_register_query_methods, ec, NULL);
742 /* Use the global lock for all EC transactions? */ 706 /* Use the global lock for all EC transactions? */
743 acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock); 707 acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
744 ec->handle = handle; 708 ec->handle = handle;
745 return AE_CTRL_TERMINATE; 709 return AE_CTRL_TERMINATE;
746} 710}
747 711
712static void ec_poll_stop(struct acpi_ec *ec)
713{
714 clear_bit(EC_FLAGS_RESCHEDULE_POLL, &ec->flags);
715 cancel_delayed_work(&ec->work);
716}
717
748static void ec_remove_handlers(struct acpi_ec *ec) 718static void ec_remove_handlers(struct acpi_ec *ec)
749{ 719{
720 ec_poll_stop(ec);
750 if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, 721 if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle,
751 ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) 722 ACPI_ADR_SPACE_EC, &acpi_ec_space_handler)))
752 pr_err(PREFIX "failed to remove space handler\n"); 723 pr_err(PREFIX "failed to remove space handler\n");
@@ -766,31 +737,28 @@ static int acpi_ec_add(struct acpi_device *device)
766 strcpy(acpi_device_class(device), ACPI_EC_CLASS); 737 strcpy(acpi_device_class(device), ACPI_EC_CLASS);
767 738
768 /* Check for boot EC */ 739 /* Check for boot EC */
769 if (boot_ec) { 740 if (boot_ec &&
770 if (boot_ec->handle == device->handle) { 741 (boot_ec->handle == device->handle ||
771 /* Pre-loaded EC from DSDT, just move pointer */ 742 boot_ec->handle == ACPI_ROOT_OBJECT)) {
772 ec = boot_ec; 743 ec = boot_ec;
773 boot_ec = NULL; 744 boot_ec = NULL;
774 goto end; 745 } else {
775 } else if (boot_ec->handle == ACPI_ROOT_OBJECT) { 746 ec = make_acpi_ec();
776 /* ECDT-based EC, time to shut it down */ 747 if (!ec)
777 ec_remove_handlers(boot_ec); 748 return -ENOMEM;
778 kfree(boot_ec); 749 if (ec_parse_device(device->handle, 0, ec, NULL) !=
779 first_ec = boot_ec = NULL; 750 AE_CTRL_TERMINATE) {
751 kfree(ec);
752 return -EINVAL;
780 } 753 }
781 } 754 }
782 755
783 ec = make_acpi_ec();
784 if (!ec)
785 return -ENOMEM;
786
787 if (ec_parse_device(device->handle, 0, ec, NULL) !=
788 AE_CTRL_TERMINATE) {
789 kfree(ec);
790 return -EINVAL;
791 }
792 ec->handle = device->handle; 756 ec->handle = device->handle;
793 end: 757
758 /* Find and register all query methods */
759 acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1,
760 acpi_ec_register_query_methods, ec, NULL);
761
794 if (!first_ec) 762 if (!first_ec)
795 first_ec = ec; 763 first_ec = ec;
796 acpi_driver_data(device) = ec; 764 acpi_driver_data(device) = ec;
@@ -865,7 +833,7 @@ static int ec_install_handlers(struct acpi_ec *ec)
865 status = acpi_install_address_space_handler(ec->handle, 833 status = acpi_install_address_space_handler(ec->handle,
866 ACPI_ADR_SPACE_EC, 834 ACPI_ADR_SPACE_EC,
867 &acpi_ec_space_handler, 835 &acpi_ec_space_handler,
868 &acpi_ec_space_setup, ec); 836 NULL, ec);
869 if (ACPI_FAILURE(status)) { 837 if (ACPI_FAILURE(status)) {
870 acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler); 838 acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
871 return -ENODEV; 839 return -ENODEV;
@@ -892,6 +860,7 @@ static int acpi_ec_start(struct acpi_device *device)
892 860
893 /* EC is fully operational, allow queries */ 861 /* EC is fully operational, allow queries */
894 clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); 862 clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
863 ec_schedule_ec_poll(ec);
895 return ret; 864 return ret;
896} 865}
897 866
@@ -919,6 +888,11 @@ int __init acpi_boot_ec_enable(void)
919 return -EFAULT; 888 return -EFAULT;
920} 889}
921 890
891static const struct acpi_device_id ec_device_ids[] = {
892 {"PNP0C09", 0},
893 {"", 0},
894};
895
922int __init acpi_ec_ecdt_probe(void) 896int __init acpi_ec_ecdt_probe(void)
923{ 897{
924 int ret; 898 int ret;
@@ -939,6 +913,7 @@ int __init acpi_ec_ecdt_probe(void)
939 boot_ec->data_addr = ecdt_ptr->data.address; 913 boot_ec->data_addr = ecdt_ptr->data.address;
940 boot_ec->gpe = ecdt_ptr->gpe; 914 boot_ec->gpe = ecdt_ptr->gpe;
941 boot_ec->handle = ACPI_ROOT_OBJECT; 915 boot_ec->handle = ACPI_ROOT_OBJECT;
916 acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle);
942 } else { 917 } else {
943 /* This workaround is needed only on some broken machines, 918 /* This workaround is needed only on some broken machines,
944 * which require early EC, but fail to provide ECDT */ 919 * which require early EC, but fail to provide ECDT */
@@ -968,6 +943,39 @@ int __init acpi_ec_ecdt_probe(void)
968 return -ENODEV; 943 return -ENODEV;
969} 944}
970 945
946static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state)
947{
948 struct acpi_ec *ec = acpi_driver_data(device);
949 /* Stop using GPE */
950 set_bit(EC_FLAGS_NO_GPE, &ec->flags);
951 clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
952 acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
953 return 0;
954}
955
956static int acpi_ec_resume(struct acpi_device *device)
957{
958 struct acpi_ec *ec = acpi_driver_data(device);
959 /* Enable use of GPE back */
960 clear_bit(EC_FLAGS_NO_GPE, &ec->flags);
961 acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
962 return 0;
963}
964
965static struct acpi_driver acpi_ec_driver = {
966 .name = "ec",
967 .class = ACPI_EC_CLASS,
968 .ids = ec_device_ids,
969 .ops = {
970 .add = acpi_ec_add,
971 .remove = acpi_ec_remove,
972 .start = acpi_ec_start,
973 .stop = acpi_ec_stop,
974 .suspend = acpi_ec_suspend,
975 .resume = acpi_ec_resume,
976 },
977};
978
971static int __init acpi_ec_init(void) 979static int __init acpi_ec_init(void)
972{ 980{
973 int result = 0; 981 int result = 0;
diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c
index 3048801a37b5..5d30e5be1b1c 100644
--- a/drivers/acpi/events/evevent.c
+++ b/drivers/acpi/events/evevent.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
index 0dadd2adc800..5354be44f876 100644
--- a/drivers/acpi/events/evgpe.c
+++ b/drivers/acpi/events/evgpe.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -248,10 +248,6 @@ acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
248 248
249 ACPI_FUNCTION_TRACE(ev_disable_gpe); 249 ACPI_FUNCTION_TRACE(ev_disable_gpe);
250 250
251 if (!(gpe_event_info->flags & ACPI_GPE_ENABLE_MASK)) {
252 return_ACPI_STATUS(AE_OK);
253 }
254
255 /* Make sure HW enable masks are updated */ 251 /* Make sure HW enable masks are updated */
256 252
257 status = 253 status =
diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c
index 361ebe6c4a6f..e6c4d4c49e79 100644
--- a/drivers/acpi/events/evgpeblk.c
+++ b/drivers/acpi/events/evgpeblk.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
index 21cb749d0c75..2113e58e2221 100644
--- a/drivers/acpi/events/evmisc.c
+++ b/drivers/acpi/events/evmisc.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -49,22 +49,7 @@
49#define _COMPONENT ACPI_EVENTS 49#define _COMPONENT ACPI_EVENTS
50ACPI_MODULE_NAME("evmisc") 50ACPI_MODULE_NAME("evmisc")
51 51
52/* Names for Notify() values, used for debug output */
53#ifdef ACPI_DEBUG_OUTPUT
54static const char *acpi_notify_value_names[] = {
55 "Bus Check",
56 "Device Check",
57 "Device Wake",
58 "Eject Request",
59 "Device Check Light",
60 "Frequency Mismatch",
61 "Bus Mode Mismatch",
62 "Power Fault"
63};
64#endif
65
66/* Pointer to FACS needed for the Global Lock */ 52/* Pointer to FACS needed for the Global Lock */
67
68static struct acpi_table_facs *facs = NULL; 53static struct acpi_table_facs *facs = NULL;
69 54
70/* Local prototypes */ 55/* Local prototypes */
@@ -94,7 +79,6 @@ u8 acpi_ev_is_notify_object(struct acpi_namespace_node *node)
94 switch (node->type) { 79 switch (node->type) {
95 case ACPI_TYPE_DEVICE: 80 case ACPI_TYPE_DEVICE:
96 case ACPI_TYPE_PROCESSOR: 81 case ACPI_TYPE_PROCESSOR:
97 case ACPI_TYPE_POWER:
98 case ACPI_TYPE_THERMAL: 82 case ACPI_TYPE_THERMAL:
99 /* 83 /*
100 * These are the ONLY objects that can receive ACPI notifications 84 * These are the ONLY objects that can receive ACPI notifications
@@ -139,17 +123,9 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
139 * initiate soft-off or sleep operation? 123 * initiate soft-off or sleep operation?
140 */ 124 */
141 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 125 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
142 "Dispatching Notify(%X) on node %p\n", notify_value, 126 "Dispatching Notify on [%4.4s] Node %p Value 0x%2.2X (%s)\n",
143 node)); 127 acpi_ut_get_node_name(node), node, notify_value,
144 128 acpi_ut_get_notify_name(notify_value)));
145 if (notify_value <= 7) {
146 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Notify value: %s\n",
147 acpi_notify_value_names[notify_value]));
148 } else {
149 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
150 "Notify value: 0x%2.2X **Device Specific**\n",
151 notify_value));
152 }
153 129
154 /* Get the notify object attached to the NS Node */ 130 /* Get the notify object attached to the NS Node */
155 131
@@ -159,10 +135,12 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
159 /* We have the notify object, Get the right handler */ 135 /* We have the notify object, Get the right handler */
160 136
161 switch (node->type) { 137 switch (node->type) {
138
139 /* Notify allowed only on these types */
140
162 case ACPI_TYPE_DEVICE: 141 case ACPI_TYPE_DEVICE:
163 case ACPI_TYPE_THERMAL: 142 case ACPI_TYPE_THERMAL:
164 case ACPI_TYPE_PROCESSOR: 143 case ACPI_TYPE_PROCESSOR:
165 case ACPI_TYPE_POWER:
166 144
167 if (notify_value <= ACPI_MAX_SYS_NOTIFY) { 145 if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
168 handler_obj = 146 handler_obj =
@@ -179,8 +157,13 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
179 } 157 }
180 } 158 }
181 159
182 /* If there is any handler to run, schedule the dispatcher */ 160 /*
183 161 * If there is any handler to run, schedule the dispatcher.
162 * Check for:
163 * 1) Global system notify handler
164 * 2) Global device notify handler
165 * 3) Per-device notify handler
166 */
184 if ((acpi_gbl_system_notify.handler 167 if ((acpi_gbl_system_notify.handler
185 && (notify_value <= ACPI_MAX_SYS_NOTIFY)) 168 && (notify_value <= ACPI_MAX_SYS_NOTIFY))
186 || (acpi_gbl_device_notify.handler 169 || (acpi_gbl_device_notify.handler
@@ -190,6 +173,13 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
190 return (AE_NO_MEMORY); 173 return (AE_NO_MEMORY);
191 } 174 }
192 175
176 if (!handler_obj) {
177 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
178 "Executing system notify handler for Notify (%4.4s, %X) node %p\n",
179 acpi_ut_get_node_name(node),
180 notify_value, node));
181 }
182
193 notify_info->common.descriptor_type = 183 notify_info->common.descriptor_type =
194 ACPI_DESC_TYPE_STATE_NOTIFY; 184 ACPI_DESC_TYPE_STATE_NOTIFY;
195 notify_info->notify.node = node; 185 notify_info->notify.node = node;
@@ -202,15 +192,12 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
202 if (ACPI_FAILURE(status)) { 192 if (ACPI_FAILURE(status)) {
203 acpi_ut_delete_generic_state(notify_info); 193 acpi_ut_delete_generic_state(notify_info);
204 } 194 }
205 } 195 } else {
206
207 if (!handler_obj) {
208 /* 196 /*
209 * There is no per-device notify handler for this device. 197 * There is no notify handler (per-device or system) for this device.
210 * This may or may not be a problem.
211 */ 198 */
212 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 199 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
213 "No notify handler for Notify(%4.4s, %X) node %p\n", 200 "No notify handler for Notify (%4.4s, %X) node %p\n",
214 acpi_ut_get_node_name(node), notify_value, 201 acpi_ut_get_node_name(node), notify_value,
215 node)); 202 node));
216 } 203 }
@@ -349,9 +336,10 @@ acpi_status acpi_ev_init_global_lock_handler(void)
349 336
350 ACPI_FUNCTION_TRACE(ev_init_global_lock_handler); 337 ACPI_FUNCTION_TRACE(ev_init_global_lock_handler);
351 338
352 status = 339 status = acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS,
353 acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, 340 ACPI_CAST_INDIRECT_PTR(struct
354 (struct acpi_table_header **)&facs); 341 acpi_table_header,
342 &facs));
355 if (ACPI_FAILURE(status)) { 343 if (ACPI_FAILURE(status)) {
356 return_ACPI_STATUS(status); 344 return_ACPI_STATUS(status);
357 } 345 }
@@ -439,7 +427,8 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
439 * Only one thread can acquire the GL at a time, the global_lock_mutex 427 * Only one thread can acquire the GL at a time, the global_lock_mutex
440 * enforces this. This interface releases the interpreter if we must wait. 428 * enforces this. This interface releases the interpreter if we must wait.
441 */ 429 */
442 status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, 0); 430 status = acpi_ex_system_wait_mutex(
431 acpi_gbl_global_lock_mutex->mutex.os_mutex, 0);
443 if (status == AE_TIME) { 432 if (status == AE_TIME) {
444 if (acpi_ev_global_lock_thread_id == acpi_os_get_thread_id()) { 433 if (acpi_ev_global_lock_thread_id == acpi_os_get_thread_id()) {
445 acpi_ev_global_lock_acquired++; 434 acpi_ev_global_lock_acquired++;
@@ -448,9 +437,9 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
448 } 437 }
449 438
450 if (ACPI_FAILURE(status)) { 439 if (ACPI_FAILURE(status)) {
451 status = 440 status = acpi_ex_system_wait_mutex(
452 acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, 441 acpi_gbl_global_lock_mutex->mutex.os_mutex,
453 timeout); 442 timeout);
454 } 443 }
455 if (ACPI_FAILURE(status)) { 444 if (ACPI_FAILURE(status)) {
456 return_ACPI_STATUS(status); 445 return_ACPI_STATUS(status);
@@ -460,6 +449,19 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
460 acpi_ev_global_lock_acquired++; 449 acpi_ev_global_lock_acquired++;
461 450
462 /* 451 /*
452 * Update the global lock handle and check for wraparound. The handle is
453 * only used for the external global lock interfaces, but it is updated
454 * here to properly handle the case where a single thread may acquire the
455 * lock via both the AML and the acpi_acquire_global_lock interfaces. The
456 * handle is therefore updated on the first acquire from a given thread
457 * regardless of where the acquisition request originated.
458 */
459 acpi_gbl_global_lock_handle++;
460 if (acpi_gbl_global_lock_handle == 0) {
461 acpi_gbl_global_lock_handle = 1;
462 }
463
464 /*
463 * Make sure that a global lock actually exists. If not, just treat 465 * Make sure that a global lock actually exists. If not, just treat
464 * the lock as a standard mutex. 466 * the lock as a standard mutex.
465 */ 467 */
@@ -555,7 +557,7 @@ acpi_status acpi_ev_release_global_lock(void)
555 /* Release the local GL mutex */ 557 /* Release the local GL mutex */
556 acpi_ev_global_lock_thread_id = NULL; 558 acpi_ev_global_lock_thread_id = NULL;
557 acpi_ev_global_lock_acquired = 0; 559 acpi_ev_global_lock_acquired = 0;
558 acpi_os_release_mutex(acpi_gbl_global_lock_mutex); 560 acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex);
559 return_ACPI_STATUS(status); 561 return_ACPI_STATUS(status);
560} 562}
561 563
diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c
index 58ad09725dd2..1628f5934752 100644
--- a/drivers/acpi/events/evregion.c
+++ b/drivers/acpi/events/evregion.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -394,7 +394,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
394 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, 394 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
395 "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", 395 "Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
396 &region_obj->region.handler->address_space, handler, 396 &region_obj->region.handler->address_space, handler,
397 ACPI_FORMAT_UINT64(address), 397 ACPI_FORMAT_NATIVE_UINT(address),
398 acpi_ut_get_region_name(region_obj->region. 398 acpi_ut_get_region_name(region_obj->region.
399 space_id))); 399 space_id)));
400 400
diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c
index b1aaa0e84588..2e3d2c5e4f4d 100644
--- a/drivers/acpi/events/evrgnini.c
+++ b/drivers/acpi/events/evrgnini.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/events/evsci.c b/drivers/acpi/events/evsci.c
index 7e5d15ce2395..2a8b77877610 100644
--- a/drivers/acpi/events/evsci.c
+++ b/drivers/acpi/events/evsci.c
@@ -6,7 +6,7 @@
6 ******************************************************************************/ 6 ******************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c
index 6d866a01f5f4..94a6efe020be 100644
--- a/drivers/acpi/events/evxface.c
+++ b/drivers/acpi/events/evxface.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -758,6 +758,12 @@ ACPI_EXPORT_SYMBOL(acpi_remove_gpe_handler)
758 * 758 *
759 * DESCRIPTION: Acquire the ACPI Global Lock 759 * DESCRIPTION: Acquire the ACPI Global Lock
760 * 760 *
761 * Note: Allows callers with the same thread ID to acquire the global lock
762 * multiple times. In other words, externally, the behavior of the global lock
763 * is identical to an AML mutex. On the first acquire, a new handle is
764 * returned. On any subsequent calls to acquire by the same thread, the same
765 * handle is returned.
766 *
761 ******************************************************************************/ 767 ******************************************************************************/
762acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle) 768acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle)
763{ 769{
@@ -770,14 +776,19 @@ acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle)
770 /* Must lock interpreter to prevent race conditions */ 776 /* Must lock interpreter to prevent race conditions */
771 777
772 acpi_ex_enter_interpreter(); 778 acpi_ex_enter_interpreter();
773 status = acpi_ev_acquire_global_lock(timeout); 779
774 acpi_ex_exit_interpreter(); 780 status = acpi_ex_acquire_mutex_object(timeout,
781 acpi_gbl_global_lock_mutex,
782 acpi_os_get_thread_id());
775 783
776 if (ACPI_SUCCESS(status)) { 784 if (ACPI_SUCCESS(status)) {
777 acpi_gbl_global_lock_handle++; 785
786 /* Return the global lock handle (updated in acpi_ev_acquire_global_lock) */
787
778 *handle = acpi_gbl_global_lock_handle; 788 *handle = acpi_gbl_global_lock_handle;
779 } 789 }
780 790
791 acpi_ex_exit_interpreter();
781 return (status); 792 return (status);
782} 793}
783 794
@@ -798,11 +809,11 @@ acpi_status acpi_release_global_lock(u32 handle)
798{ 809{
799 acpi_status status; 810 acpi_status status;
800 811
801 if (handle != acpi_gbl_global_lock_handle) { 812 if (!handle || (handle != acpi_gbl_global_lock_handle)) {
802 return (AE_NOT_ACQUIRED); 813 return (AE_NOT_ACQUIRED);
803 } 814 }
804 815
805 status = acpi_ev_release_global_lock(); 816 status = acpi_ex_release_mutex_object(acpi_gbl_global_lock_mutex);
806 return (status); 817 return (status);
807} 818}
808 819
diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c
index 9cbd3414a574..99a7502e6a87 100644
--- a/drivers/acpi/events/evxfevnt.c
+++ b/drivers/acpi/events/evxfevnt.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/events/evxfregn.c b/drivers/acpi/events/evxfregn.c
index 7bf09c5fb242..e8750807e57d 100644
--- a/drivers/acpi/events/evxfregn.c
+++ b/drivers/acpi/events/evxfregn.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
index 25802f302ffe..24da921d13e3 100644
--- a/drivers/acpi/executer/exconfig.c
+++ b/drivers/acpi/executer/exconfig.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -45,7 +45,6 @@
45#include <acpi/acinterp.h> 45#include <acpi/acinterp.h>
46#include <acpi/amlcode.h> 46#include <acpi/amlcode.h>
47#include <acpi/acnamesp.h> 47#include <acpi/acnamesp.h>
48#include <acpi/acevents.h>
49#include <acpi/actables.h> 48#include <acpi/actables.h>
50#include <acpi/acdispat.h> 49#include <acpi/acdispat.h>
51 50
@@ -138,6 +137,14 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
138 137
139 ACPI_FUNCTION_TRACE(ex_load_table_op); 138 ACPI_FUNCTION_TRACE(ex_load_table_op);
140 139
140 /* Validate lengths for the signature_string, OEMIDString, OEMtable_iD */
141
142 if ((operand[0]->string.length > ACPI_NAME_SIZE) ||
143 (operand[1]->string.length > ACPI_OEM_ID_SIZE) ||
144 (operand[2]->string.length > ACPI_OEM_TABLE_ID_SIZE)) {
145 return_ACPI_STATUS(AE_BAD_PARAMETER);
146 }
147
141 /* Find the ACPI table in the RSDT/XSDT */ 148 /* Find the ACPI table in the RSDT/XSDT */
142 149
143 status = acpi_tb_find_table(operand[0]->string.pointer, 150 status = acpi_tb_find_table(operand[0]->string.pointer,
@@ -229,11 +236,18 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
229 status = acpi_get_table_by_index(table_index, &table); 236 status = acpi_get_table_by_index(table_index, &table);
230 if (ACPI_SUCCESS(status)) { 237 if (ACPI_SUCCESS(status)) {
231 ACPI_INFO((AE_INFO, 238 ACPI_INFO((AE_INFO,
232 "Dynamic OEM Table Load - [%4.4s] OemId [%6.6s] OemTableId [%8.8s]", 239 "Dynamic OEM Table Load - [%.4s] OemId [%.6s] OemTableId [%.8s]",
233 table->signature, table->oem_id, 240 table->signature, table->oem_id,
234 table->oem_table_id)); 241 table->oem_table_id));
235 } 242 }
236 243
244 /* Invoke table handler if present */
245
246 if (acpi_gbl_table_handler) {
247 (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table,
248 acpi_gbl_table_handler_context);
249 }
250
237 *return_desc = ddb_handle; 251 *return_desc = ddb_handle;
238 return_ACPI_STATUS(status); 252 return_ACPI_STATUS(status);
239} 253}
@@ -268,6 +282,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
268 struct acpi_table_desc table_desc; 282 struct acpi_table_desc table_desc;
269 acpi_native_uint table_index; 283 acpi_native_uint table_index;
270 acpi_status status; 284 acpi_status status;
285 u32 length;
271 286
272 ACPI_FUNCTION_TRACE(ex_load_op); 287 ACPI_FUNCTION_TRACE(ex_load_op);
273 288
@@ -278,16 +293,16 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
278 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { 293 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
279 case ACPI_TYPE_REGION: 294 case ACPI_TYPE_REGION:
280 295
296 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Region %p %s\n",
297 obj_desc,
298 acpi_ut_get_object_type_name(obj_desc)));
299
281 /* Region must be system_memory (from ACPI spec) */ 300 /* Region must be system_memory (from ACPI spec) */
282 301
283 if (obj_desc->region.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) { 302 if (obj_desc->region.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) {
284 return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 303 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
285 } 304 }
286 305
287 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Region %p %s\n",
288 obj_desc,
289 acpi_ut_get_object_type_name(obj_desc)));
290
291 /* 306 /*
292 * If the Region Address and Length have not been previously evaluated, 307 * If the Region Address and Length have not been previously evaluated,
293 * evaluate them now and save the results. 308 * evaluate them now and save the results.
@@ -299,6 +314,11 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
299 } 314 }
300 } 315 }
301 316
317 /*
318 * We will simply map the memory region for the table. However, the
319 * memory region is technically not guaranteed to remain stable and
320 * we may eventually have to copy the table to a local buffer.
321 */
302 table_desc.address = obj_desc->region.address; 322 table_desc.address = obj_desc->region.address;
303 table_desc.length = obj_desc->region.length; 323 table_desc.length = obj_desc->region.length;
304 table_desc.flags = ACPI_TABLE_ORIGIN_MAPPED; 324 table_desc.flags = ACPI_TABLE_ORIGIN_MAPPED;
@@ -306,18 +326,41 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
306 326
307 case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */ 327 case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */
308 328
309 /* Simply extract the buffer from the buffer object */
310
311 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 329 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
312 "Load from Buffer or Field %p %s\n", obj_desc, 330 "Load from Buffer or Field %p %s\n", obj_desc,
313 acpi_ut_get_object_type_name(obj_desc))); 331 acpi_ut_get_object_type_name(obj_desc)));
314 332
315 table_desc.pointer = ACPI_CAST_PTR(struct acpi_table_header, 333 length = obj_desc->buffer.length;
316 obj_desc->buffer.pointer); 334
317 table_desc.length = table_desc.pointer->length; 335 /* Must have at least an ACPI table header */
318 table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED; 336
337 if (length < sizeof(struct acpi_table_header)) {
338 return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
339 }
340
341 /* Validate checksum here. It won't get validated in tb_add_table */
319 342
320 obj_desc->buffer.pointer = NULL; 343 status =
344 acpi_tb_verify_checksum(ACPI_CAST_PTR
345 (struct acpi_table_header,
346 obj_desc->buffer.pointer), length);
347 if (ACPI_FAILURE(status)) {
348 return_ACPI_STATUS(status);
349 }
350
351 /*
352 * We need to copy the buffer since the original buffer could be
353 * changed or deleted in the future
354 */
355 table_desc.pointer = ACPI_ALLOCATE(length);
356 if (!table_desc.pointer) {
357 return_ACPI_STATUS(AE_NO_MEMORY);
358 }
359
360 ACPI_MEMCPY(table_desc.pointer, obj_desc->buffer.pointer,
361 length);
362 table_desc.length = length;
363 table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED;
321 break; 364 break;
322 365
323 default: 366 default:
@@ -333,7 +376,8 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
333 } 376 }
334 377
335 status = 378 status =
336 acpi_ex_add_table(table_index, acpi_gbl_root_node, &ddb_handle); 379 acpi_ex_add_table(table_index, walk_state->scope_info->scope.node,
380 &ddb_handle);
337 if (ACPI_FAILURE(status)) { 381 if (ACPI_FAILURE(status)) {
338 382
339 /* On error, table_ptr was deallocated above */ 383 /* On error, table_ptr was deallocated above */
@@ -349,11 +393,23 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
349 393
350 /* table_ptr was deallocated above */ 394 /* table_ptr was deallocated above */
351 395
396 acpi_ut_remove_reference(ddb_handle);
352 return_ACPI_STATUS(status); 397 return_ACPI_STATUS(status);
353 } 398 }
354 399
400 /* Invoke table handler if present */
401
402 if (acpi_gbl_table_handler) {
403 (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD,
404 table_desc.pointer,
405 acpi_gbl_table_handler_context);
406 }
407
355 cleanup: 408 cleanup:
356 if (ACPI_FAILURE(status)) { 409 if (ACPI_FAILURE(status)) {
410
411 /* Delete allocated buffer or mapping */
412
357 acpi_tb_delete_table(&table_desc); 413 acpi_tb_delete_table(&table_desc);
358 } 414 }
359 return_ACPI_STATUS(status); 415 return_ACPI_STATUS(status);
@@ -376,6 +432,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
376 acpi_status status = AE_OK; 432 acpi_status status = AE_OK;
377 union acpi_operand_object *table_desc = ddb_handle; 433 union acpi_operand_object *table_desc = ddb_handle;
378 acpi_native_uint table_index; 434 acpi_native_uint table_index;
435 struct acpi_table_header *table;
379 436
380 ACPI_FUNCTION_TRACE(ex_unload_table); 437 ACPI_FUNCTION_TRACE(ex_unload_table);
381 438
@@ -395,17 +452,25 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
395 452
396 table_index = (acpi_native_uint) table_desc->reference.object; 453 table_index = (acpi_native_uint) table_desc->reference.object;
397 454
455 /* Invoke table handler if present */
456
457 if (acpi_gbl_table_handler) {
458 status = acpi_get_table_by_index(table_index, &table);
459 if (ACPI_SUCCESS(status)) {
460 (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_UNLOAD,
461 table,
462 acpi_gbl_table_handler_context);
463 }
464 }
465
398 /* 466 /*
399 * Delete the entire namespace under this table Node 467 * Delete the entire namespace under this table Node
400 * (Offset contains the table_id) 468 * (Offset contains the table_id)
401 */ 469 */
402 acpi_tb_delete_namespace_by_owner(table_index); 470 acpi_tb_delete_namespace_by_owner(table_index);
403 acpi_tb_release_owner_id(table_index); 471 (void)acpi_tb_release_owner_id(table_index);
404 472
405 acpi_tb_set_table_loaded_flag(table_index, FALSE); 473 acpi_tb_set_table_loaded_flag(table_index, FALSE);
406 474
407 /* Delete the table descriptor (ddb_handle) */ 475 return_ACPI_STATUS(AE_OK);
408
409 acpi_ut_remove_reference(table_desc);
410 return_ACPI_STATUS(status);
411} 476}
diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c
index 79f2c0d42c06..fd954b4ed83d 100644
--- a/drivers/acpi/executer/exconvrt.c
+++ b/drivers/acpi/executer/exconvrt.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c
index 6e9a23e47fef..60e62c4f0577 100644
--- a/drivers/acpi/executer/excreate.c
+++ b/drivers/acpi/executer/excreate.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -96,6 +96,9 @@ acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state)
96 * to the original Node. 96 * to the original Node.
97 */ 97 */
98 switch (target_node->type) { 98 switch (target_node->type) {
99
100 /* For these types, the sub-object can change dynamically via a Store */
101
99 case ACPI_TYPE_INTEGER: 102 case ACPI_TYPE_INTEGER:
100 case ACPI_TYPE_STRING: 103 case ACPI_TYPE_STRING:
101 case ACPI_TYPE_BUFFER: 104 case ACPI_TYPE_BUFFER:
@@ -103,9 +106,18 @@ acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state)
103 case ACPI_TYPE_BUFFER_FIELD: 106 case ACPI_TYPE_BUFFER_FIELD:
104 107
105 /* 108 /*
109 * These types open a new scope, so we need the NS node in order to access
110 * any children.
111 */
112 case ACPI_TYPE_DEVICE:
113 case ACPI_TYPE_POWER:
114 case ACPI_TYPE_PROCESSOR:
115 case ACPI_TYPE_THERMAL:
116 case ACPI_TYPE_LOCAL_SCOPE:
117
118 /*
106 * The new alias has the type ALIAS and points to the original 119 * The new alias has the type ALIAS and points to the original
107 * NS node, not the object itself. This is because for these 120 * NS node, not the object itself.
108 * types, the object can change dynamically via a Store.
109 */ 121 */
110 alias_node->type = ACPI_TYPE_LOCAL_ALIAS; 122 alias_node->type = ACPI_TYPE_LOCAL_ALIAS;
111 alias_node->object = 123 alias_node->object =
@@ -115,9 +127,7 @@ acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state)
115 case ACPI_TYPE_METHOD: 127 case ACPI_TYPE_METHOD:
116 128
117 /* 129 /*
118 * The new alias has the type ALIAS and points to the original 130 * Control method aliases need to be differentiated
119 * NS node, not the object itself. This is because for these
120 * types, the object can change dynamically via a Store.
121 */ 131 */
122 alias_node->type = ACPI_TYPE_LOCAL_METHOD_ALIAS; 132 alias_node->type = ACPI_TYPE_LOCAL_METHOD_ALIAS;
123 alias_node->object = 133 alias_node->object =
@@ -342,101 +352,6 @@ acpi_ex_create_region(u8 * aml_start,
342 352
343/******************************************************************************* 353/*******************************************************************************
344 * 354 *
345 * FUNCTION: acpi_ex_create_table_region
346 *
347 * PARAMETERS: walk_state - Current state
348 *
349 * RETURN: Status
350 *
351 * DESCRIPTION: Create a new data_table_region object
352 *
353 ******************************************************************************/
354
355acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state)
356{
357 acpi_status status;
358 union acpi_operand_object **operand = &walk_state->operands[0];
359 union acpi_operand_object *obj_desc;
360 struct acpi_namespace_node *node;
361 union acpi_operand_object *region_obj2;
362 acpi_native_uint table_index;
363 struct acpi_table_header *table;
364
365 ACPI_FUNCTION_TRACE(ex_create_table_region);
366
367 /* Get the Node from the object stack */
368
369 node = walk_state->op->common.node;
370
371 /*
372 * If the region object is already attached to this node,
373 * just return
374 */
375 if (acpi_ns_get_attached_object(node)) {
376 return_ACPI_STATUS(AE_OK);
377 }
378
379 /* Find the ACPI table */
380
381 status = acpi_tb_find_table(operand[1]->string.pointer,
382 operand[2]->string.pointer,
383 operand[3]->string.pointer, &table_index);
384 if (ACPI_FAILURE(status)) {
385 return_ACPI_STATUS(status);
386 }
387
388 /* Create the region descriptor */
389
390 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_REGION);
391 if (!obj_desc) {
392 return_ACPI_STATUS(AE_NO_MEMORY);
393 }
394
395 region_obj2 = obj_desc->common.next_object;
396 region_obj2->extra.region_context = NULL;
397
398 status = acpi_get_table_by_index(table_index, &table);
399 if (ACPI_FAILURE(status)) {
400 return_ACPI_STATUS(status);
401 }
402
403 /* Init the region from the operands */
404
405 obj_desc->region.space_id = REGION_DATA_TABLE;
406 obj_desc->region.address =
407 (acpi_physical_address) ACPI_TO_INTEGER(table);
408 obj_desc->region.length = table->length;
409 obj_desc->region.node = node;
410 obj_desc->region.flags = AOPOBJ_DATA_VALID;
411
412 /* Install the new region object in the parent Node */
413
414 status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_REGION);
415 if (ACPI_FAILURE(status)) {
416 goto cleanup;
417 }
418
419 status = acpi_ev_initialize_region(obj_desc, FALSE);
420 if (ACPI_FAILURE(status)) {
421 if (status == AE_NOT_EXIST) {
422 status = AE_OK;
423 } else {
424 goto cleanup;
425 }
426 }
427
428 obj_desc->region.flags |= AOPOBJ_SETUP_COMPLETE;
429
430 cleanup:
431
432 /* Remove local reference to the object */
433
434 acpi_ut_remove_reference(obj_desc);
435 return_ACPI_STATUS(status);
436}
437
438/*******************************************************************************
439 *
440 * FUNCTION: acpi_ex_create_processor 355 * FUNCTION: acpi_ex_create_processor
441 * 356 *
442 * PARAMETERS: walk_state - Current state 357 * PARAMETERS: walk_state - Current state
diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c
index 51c9c29987c3..74f1b22601b3 100644
--- a/drivers/acpi/executer/exdump.c
+++ b/drivers/acpi/executer/exdump.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -500,25 +500,28 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
500 acpi_os_printf("Reference: Debug\n"); 500 acpi_os_printf("Reference: Debug\n");
501 break; 501 break;
502 502
503 case AML_NAME_OP: 503 case AML_INDEX_OP:
504 504
505 ACPI_DUMP_PATHNAME(obj_desc->reference.object, 505 acpi_os_printf("Reference: Index %p\n",
506 "Reference: Name: ", ACPI_LV_INFO, 506 obj_desc->reference.object);
507 _COMPONENT);
508 ACPI_DUMP_ENTRY(obj_desc->reference.object,
509 ACPI_LV_INFO);
510 break; 507 break;
511 508
512 case AML_INDEX_OP: 509 case AML_LOAD_OP:
513 510
514 acpi_os_printf("Reference: Index %p\n", 511 acpi_os_printf("Reference: [DdbHandle] TableIndex %p\n",
515 obj_desc->reference.object); 512 obj_desc->reference.object);
516 break; 513 break;
517 514
518 case AML_REF_OF_OP: 515 case AML_REF_OF_OP:
519 516
520 acpi_os_printf("Reference: (RefOf) %p\n", 517 acpi_os_printf("Reference: (RefOf) %p [%s]\n",
521 obj_desc->reference.object); 518 obj_desc->reference.object,
519 acpi_ut_get_type_name(((union
520 acpi_operand_object
521 *)obj_desc->
522 reference.
523 object)->common.
524 type));
522 break; 525 break;
523 526
524 case AML_ARG_OP: 527 case AML_ARG_OP:
@@ -559,8 +562,9 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
559 562
560 case AML_INT_NAMEPATH_OP: 563 case AML_INT_NAMEPATH_OP:
561 564
562 acpi_os_printf("Reference.Node->Name %X\n", 565 acpi_os_printf("Reference: Namepath %X [%4.4s]\n",
563 obj_desc->reference.node->name.integer); 566 obj_desc->reference.node->name.integer,
567 obj_desc->reference.node->name.ascii);
564 break; 568 break;
565 569
566 default: 570 default:
@@ -640,8 +644,8 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
640 acpi_os_printf("\n"); 644 acpi_os_printf("\n");
641 } else { 645 } else {
642 acpi_os_printf(" base %8.8X%8.8X Length %X\n", 646 acpi_os_printf(" base %8.8X%8.8X Length %X\n",
643 ACPI_FORMAT_UINT64(obj_desc->region. 647 ACPI_FORMAT_NATIVE_UINT(obj_desc->region.
644 address), 648 address),
645 obj_desc->region.length); 649 obj_desc->region.length);
646 } 650 }
647 break; 651 break;
@@ -877,20 +881,43 @@ static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc)
877 ret_buf.length = ACPI_ALLOCATE_LOCAL_BUFFER; 881 ret_buf.length = ACPI_ALLOCATE_LOCAL_BUFFER;
878 882
879 if (obj_desc->reference.opcode == AML_INT_NAMEPATH_OP) { 883 if (obj_desc->reference.opcode == AML_INT_NAMEPATH_OP) {
880 acpi_os_printf("Named Object %p ", obj_desc->reference.node); 884 acpi_os_printf(" Named Object %p ", obj_desc->reference.node);
881 885
882 status = 886 status =
883 acpi_ns_handle_to_pathname(obj_desc->reference.node, 887 acpi_ns_handle_to_pathname(obj_desc->reference.node,
884 &ret_buf); 888 &ret_buf);
885 if (ACPI_FAILURE(status)) { 889 if (ACPI_FAILURE(status)) {
886 acpi_os_printf("Could not convert name to pathname\n"); 890 acpi_os_printf(" Could not convert name to pathname\n");
887 } else { 891 } else {
888 acpi_os_printf("%s\n", (char *)ret_buf.pointer); 892 acpi_os_printf("%s\n", (char *)ret_buf.pointer);
889 ACPI_FREE(ret_buf.pointer); 893 ACPI_FREE(ret_buf.pointer);
890 } 894 }
891 } else if (obj_desc->reference.object) { 895 } else if (obj_desc->reference.object) {
892 acpi_os_printf("\nReferenced Object: %p\n", 896 if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) ==
893 obj_desc->reference.object); 897 ACPI_DESC_TYPE_OPERAND) {
898 acpi_os_printf(" Target: %p",
899 obj_desc->reference.object);
900 if (obj_desc->reference.opcode == AML_LOAD_OP) {
901 /*
902 * For DDBHandle reference,
903 * obj_desc->Reference.Object is the table index
904 */
905 acpi_os_printf(" [DDBHandle]\n");
906 } else {
907 acpi_os_printf(" [%s]\n",
908 acpi_ut_get_type_name(((union
909 acpi_operand_object
910 *)
911 obj_desc->
912 reference.
913 object)->
914 common.
915 type));
916 }
917 } else {
918 acpi_os_printf(" Target: %p\n",
919 obj_desc->reference.object);
920 }
894 } 921 }
895} 922}
896 923
@@ -976,7 +1003,9 @@ acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc,
976 1003
977 case ACPI_TYPE_LOCAL_REFERENCE: 1004 case ACPI_TYPE_LOCAL_REFERENCE:
978 1005
979 acpi_os_printf("[Object Reference] "); 1006 acpi_os_printf("[Object Reference] %s",
1007 (acpi_ps_get_opcode_info
1008 (obj_desc->reference.opcode))->name);
980 acpi_ex_dump_reference_obj(obj_desc); 1009 acpi_ex_dump_reference_obj(obj_desc);
981 break; 1010 break;
982 1011
diff --git a/drivers/acpi/executer/exfield.c b/drivers/acpi/executer/exfield.c
index 2d88a3d8d1ad..3e440d84226a 100644
--- a/drivers/acpi/executer/exfield.c
+++ b/drivers/acpi/executer/exfield.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -71,7 +71,6 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
71 union acpi_operand_object *buffer_desc; 71 union acpi_operand_object *buffer_desc;
72 acpi_size length; 72 acpi_size length;
73 void *buffer; 73 void *buffer;
74 u8 locked;
75 74
76 ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc); 75 ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc);
77 76
@@ -111,9 +110,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
111 110
112 /* Lock entire transaction if requested */ 111 /* Lock entire transaction if requested */
113 112
114 locked = 113 acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
115 acpi_ex_acquire_global_lock(obj_desc->common_field.
116 field_flags);
117 114
118 /* 115 /*
119 * Perform the read. 116 * Perform the read.
@@ -125,7 +122,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
125 buffer.pointer), 122 buffer.pointer),
126 ACPI_READ | (obj_desc->field. 123 ACPI_READ | (obj_desc->field.
127 attribute << 16)); 124 attribute << 16));
128 acpi_ex_release_global_lock(locked); 125 acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
129 goto exit; 126 goto exit;
130 } 127 }
131 128
@@ -175,13 +172,12 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
175 172
176 /* Lock entire transaction if requested */ 173 /* Lock entire transaction if requested */
177 174
178 locked = 175 acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
179 acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
180 176
181 /* Read from the field */ 177 /* Read from the field */
182 178
183 status = acpi_ex_extract_from_field(obj_desc, buffer, (u32) length); 179 status = acpi_ex_extract_from_field(obj_desc, buffer, (u32) length);
184 acpi_ex_release_global_lock(locked); 180 acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
185 181
186 exit: 182 exit:
187 if (ACPI_FAILURE(status)) { 183 if (ACPI_FAILURE(status)) {
@@ -214,10 +210,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
214{ 210{
215 acpi_status status; 211 acpi_status status;
216 u32 length; 212 u32 length;
217 u32 required_length;
218 void *buffer; 213 void *buffer;
219 void *new_buffer;
220 u8 locked;
221 union acpi_operand_object *buffer_desc; 214 union acpi_operand_object *buffer_desc;
222 215
223 ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc); 216 ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc);
@@ -278,9 +271,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
278 271
279 /* Lock entire transaction if requested */ 272 /* Lock entire transaction if requested */
280 273
281 locked = 274 acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
282 acpi_ex_acquire_global_lock(obj_desc->common_field.
283 field_flags);
284 275
285 /* 276 /*
286 * Perform the write (returns status and perhaps data in the 277 * Perform the write (returns status and perhaps data in the
@@ -291,7 +282,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
291 (acpi_integer *) buffer, 282 (acpi_integer *) buffer,
292 ACPI_WRITE | (obj_desc->field. 283 ACPI_WRITE | (obj_desc->field.
293 attribute << 16)); 284 attribute << 16));
294 acpi_ex_release_global_lock(locked); 285 acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
295 286
296 *result_desc = buffer_desc; 287 *result_desc = buffer_desc;
297 return_ACPI_STATUS(status); 288 return_ACPI_STATUS(status);
@@ -319,35 +310,6 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
319 return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 310 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
320 } 311 }
321 312
322 /*
323 * We must have a buffer that is at least as long as the field
324 * we are writing to. This is because individual fields are
325 * indivisible and partial writes are not supported -- as per
326 * the ACPI specification.
327 */
328 new_buffer = NULL;
329 required_length =
330 ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length);
331
332 if (length < required_length) {
333
334 /* We need to create a new buffer */
335
336 new_buffer = ACPI_ALLOCATE_ZEROED(required_length);
337 if (!new_buffer) {
338 return_ACPI_STATUS(AE_NO_MEMORY);
339 }
340
341 /*
342 * Copy the original data to the new buffer, starting
343 * at Byte zero. All unused (upper) bytes of the
344 * buffer will be 0.
345 */
346 ACPI_MEMCPY((char *)new_buffer, (char *)buffer, length);
347 buffer = new_buffer;
348 length = required_length;
349 }
350
351 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, 313 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
352 "FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n", 314 "FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n",
353 source_desc, 315 source_desc,
@@ -366,19 +328,12 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
366 328
367 /* Lock entire transaction if requested */ 329 /* Lock entire transaction if requested */
368 330
369 locked = 331 acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
370 acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
371 332
372 /* Write to the field */ 333 /* Write to the field */
373 334
374 status = acpi_ex_insert_into_field(obj_desc, buffer, length); 335 status = acpi_ex_insert_into_field(obj_desc, buffer, length);
375 acpi_ex_release_global_lock(locked); 336 acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
376
377 /* Free temporary buffer if we used one */
378
379 if (new_buffer) {
380 ACPI_FREE(new_buffer);
381 }
382 337
383 return_ACPI_STATUS(status); 338 return_ACPI_STATUS(status);
384} 339}
diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c
index 65a48b6170ee..e336b5dc7a50 100644
--- a/drivers/acpi/executer/exfldio.c
+++ b/drivers/acpi/executer/exfldio.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -263,7 +263,8 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc,
263 rgn_desc->region.space_id, 263 rgn_desc->region.space_id,
264 obj_desc->common_field.access_byte_width, 264 obj_desc->common_field.access_byte_width,
265 obj_desc->common_field.base_byte_offset, 265 obj_desc->common_field.base_byte_offset,
266 field_datum_byte_offset, (void *)address)); 266 field_datum_byte_offset, ACPI_CAST_PTR(void,
267 address)));
267 268
268 /* Invoke the appropriate address_space/op_region handler */ 269 /* Invoke the appropriate address_space/op_region handler */
269 270
@@ -805,18 +806,39 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
805 u32 datum_count; 806 u32 datum_count;
806 u32 field_datum_count; 807 u32 field_datum_count;
807 u32 i; 808 u32 i;
809 u32 required_length;
810 void *new_buffer;
808 811
809 ACPI_FUNCTION_TRACE(ex_insert_into_field); 812 ACPI_FUNCTION_TRACE(ex_insert_into_field);
810 813
811 /* Validate input buffer */ 814 /* Validate input buffer */
812 815
813 if (buffer_length < 816 new_buffer = NULL;
814 ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length)) { 817 required_length =
815 ACPI_ERROR((AE_INFO, 818 ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length);
816 "Field size %X (bits) is too large for buffer (%X)", 819 /*
817 obj_desc->common_field.bit_length, buffer_length)); 820 * We must have a buffer that is at least as long as the field
821 * we are writing to. This is because individual fields are
822 * indivisible and partial writes are not supported -- as per
823 * the ACPI specification.
824 */
825 if (buffer_length < required_length) {
818 826
819 return_ACPI_STATUS(AE_BUFFER_OVERFLOW); 827 /* We need to create a new buffer */
828
829 new_buffer = ACPI_ALLOCATE_ZEROED(required_length);
830 if (!new_buffer) {
831 return_ACPI_STATUS(AE_NO_MEMORY);
832 }
833
834 /*
835 * Copy the original data to the new buffer, starting
836 * at Byte zero. All unused (upper) bytes of the
837 * buffer will be 0.
838 */
839 ACPI_MEMCPY((char *)new_buffer, (char *)buffer, buffer_length);
840 buffer = new_buffer;
841 buffer_length = required_length;
820 } 842 }
821 843
822 /* 844 /*
@@ -866,7 +888,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
866 merged_datum, 888 merged_datum,
867 field_offset); 889 field_offset);
868 if (ACPI_FAILURE(status)) { 890 if (ACPI_FAILURE(status)) {
869 return_ACPI_STATUS(status); 891 goto exit;
870 } 892 }
871 893
872 field_offset += obj_desc->common_field.access_byte_width; 894 field_offset += obj_desc->common_field.access_byte_width;
@@ -924,5 +946,11 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
924 mask, merged_datum, 946 mask, merged_datum,
925 field_offset); 947 field_offset);
926 948
949 exit:
950 /* Free temporary buffer if we used one */
951
952 if (new_buffer) {
953 ACPI_FREE(new_buffer);
954 }
927 return_ACPI_STATUS(status); 955 return_ACPI_STATUS(status);
928} 956}
diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c
index f13d1cec2d6d..cc956a5b5267 100644
--- a/drivers/acpi/executer/exmisc.c
+++ b/drivers/acpi/executer/exmisc.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c
index 6748e3ef0997..c873ab40cd0e 100644
--- a/drivers/acpi/executer/exmutex.c
+++ b/drivers/acpi/executer/exmutex.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -126,6 +126,79 @@ acpi_ex_link_mutex(union acpi_operand_object *obj_desc,
126 126
127/******************************************************************************* 127/*******************************************************************************
128 * 128 *
129 * FUNCTION: acpi_ex_acquire_mutex_object
130 *
131 * PARAMETERS: time_desc - Timeout in milliseconds
132 * obj_desc - Mutex object
133 * Thread - Current thread state
134 *
135 * RETURN: Status
136 *
137 * DESCRIPTION: Acquire an AML mutex, low-level interface. Provides a common
138 * path that supports multiple acquires by the same thread.
139 *
140 * MUTEX: Interpreter must be locked
141 *
142 * NOTE: This interface is called from three places:
143 * 1) From acpi_ex_acquire_mutex, via an AML Acquire() operator
144 * 2) From acpi_ex_acquire_global_lock when an AML Field access requires the
145 * global lock
146 * 3) From the external interface, acpi_acquire_global_lock
147 *
148 ******************************************************************************/
149
150acpi_status
151acpi_ex_acquire_mutex_object(u16 timeout,
152 union acpi_operand_object *obj_desc,
153 acpi_thread_id thread_id)
154{
155 acpi_status status;
156
157 ACPI_FUNCTION_TRACE_PTR(ex_acquire_mutex_object, obj_desc);
158
159 if (!obj_desc) {
160 return_ACPI_STATUS(AE_BAD_PARAMETER);
161 }
162
163 /* Support for multiple acquires by the owning thread */
164
165 if (obj_desc->mutex.thread_id == thread_id) {
166 /*
167 * The mutex is already owned by this thread, just increment the
168 * acquisition depth
169 */
170 obj_desc->mutex.acquisition_depth++;
171 return_ACPI_STATUS(AE_OK);
172 }
173
174 /* Acquire the mutex, wait if necessary. Special case for Global Lock */
175
176 if (obj_desc == acpi_gbl_global_lock_mutex) {
177 status = acpi_ev_acquire_global_lock(timeout);
178 } else {
179 status = acpi_ex_system_wait_mutex(obj_desc->mutex.os_mutex,
180 timeout);
181 }
182
183 if (ACPI_FAILURE(status)) {
184
185 /* Includes failure from a timeout on time_desc */
186
187 return_ACPI_STATUS(status);
188 }
189
190 /* Acquired the mutex: update mutex object */
191
192 obj_desc->mutex.thread_id = thread_id;
193 obj_desc->mutex.acquisition_depth = 1;
194 obj_desc->mutex.original_sync_level = 0;
195 obj_desc->mutex.owner_thread = NULL; /* Used only for AML Acquire() */
196
197 return_ACPI_STATUS(AE_OK);
198}
199
200/*******************************************************************************
201 *
129 * FUNCTION: acpi_ex_acquire_mutex 202 * FUNCTION: acpi_ex_acquire_mutex
130 * 203 *
131 * PARAMETERS: time_desc - Timeout integer 204 * PARAMETERS: time_desc - Timeout integer
@@ -151,7 +224,7 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,
151 return_ACPI_STATUS(AE_BAD_PARAMETER); 224 return_ACPI_STATUS(AE_BAD_PARAMETER);
152 } 225 }
153 226
154 /* Sanity check: we must have a valid thread ID */ 227 /* Must have a valid thread ID */
155 228
156 if (!walk_state->thread) { 229 if (!walk_state->thread) {
157 ACPI_ERROR((AE_INFO, 230 ACPI_ERROR((AE_INFO,
@@ -161,7 +234,7 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,
161 } 234 }
162 235
163 /* 236 /*
164 * Current Sync must be less than or equal to the sync level of the 237 * Current sync level must be less than or equal to the sync level of the
165 * mutex. This mechanism provides some deadlock prevention 238 * mutex. This mechanism provides some deadlock prevention
166 */ 239 */
167 if (walk_state->thread->current_sync_level > obj_desc->mutex.sync_level) { 240 if (walk_state->thread->current_sync_level > obj_desc->mutex.sync_level) {
@@ -172,51 +245,89 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,
172 return_ACPI_STATUS(AE_AML_MUTEX_ORDER); 245 return_ACPI_STATUS(AE_AML_MUTEX_ORDER);
173 } 246 }
174 247
175 /* Support for multiple acquires by the owning thread */ 248 status = acpi_ex_acquire_mutex_object((u16) time_desc->integer.value,
249 obj_desc,
250 walk_state->thread->thread_id);
251 if (ACPI_SUCCESS(status) && obj_desc->mutex.acquisition_depth == 1) {
176 252
177 if (obj_desc->mutex.owner_thread) { 253 /* Save Thread object, original/current sync levels */
178 if (obj_desc->mutex.owner_thread->thread_id == 254
179 walk_state->thread->thread_id) { 255 obj_desc->mutex.owner_thread = walk_state->thread;
180 /* 256 obj_desc->mutex.original_sync_level =
181 * The mutex is already owned by this thread, just increment the 257 walk_state->thread->current_sync_level;
182 * acquisition depth 258 walk_state->thread->current_sync_level =
183 */ 259 obj_desc->mutex.sync_level;
184 obj_desc->mutex.acquisition_depth++; 260
185 return_ACPI_STATUS(AE_OK); 261 /* Link the mutex to the current thread for force-unlock at method exit */
186 } 262
263 acpi_ex_link_mutex(obj_desc, walk_state->thread);
187 } 264 }
188 265
189 /* Acquire the mutex, wait if necessary. Special case for Global Lock */ 266 return_ACPI_STATUS(status);
267}
190 268
191 if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) { 269/*******************************************************************************
192 status = 270 *
193 acpi_ev_acquire_global_lock((u16) time_desc->integer.value); 271 * FUNCTION: acpi_ex_release_mutex_object
194 } else { 272 *
195 status = acpi_ex_system_wait_mutex(obj_desc->mutex.os_mutex, 273 * PARAMETERS: obj_desc - The object descriptor for this op
196 (u16) time_desc->integer. 274 *
197 value); 275 * RETURN: Status
276 *
277 * DESCRIPTION: Release a previously acquired Mutex, low level interface.
278 * Provides a common path that supports multiple releases (after
279 * previous multiple acquires) by the same thread.
280 *
281 * MUTEX: Interpreter must be locked
282 *
283 * NOTE: This interface is called from three places:
284 * 1) From acpi_ex_release_mutex, via an AML Acquire() operator
285 * 2) From acpi_ex_release_global_lock when an AML Field access requires the
286 * global lock
287 * 3) From the external interface, acpi_release_global_lock
288 *
289 ******************************************************************************/
290
291acpi_status acpi_ex_release_mutex_object(union acpi_operand_object *obj_desc)
292{
293 acpi_status status = AE_OK;
294
295 ACPI_FUNCTION_TRACE(ex_release_mutex_object);
296
297 if (obj_desc->mutex.acquisition_depth == 0) {
298 return (AE_NOT_ACQUIRED);
198 } 299 }
199 300
200 if (ACPI_FAILURE(status)) { 301 /* Match multiple Acquires with multiple Releases */
201 302
202 /* Includes failure from a timeout on time_desc */ 303 obj_desc->mutex.acquisition_depth--;
304 if (obj_desc->mutex.acquisition_depth != 0) {
203 305
204 return_ACPI_STATUS(status); 306 /* Just decrement the depth and return */
307
308 return_ACPI_STATUS(AE_OK);
205 } 309 }
206 310
207 /* Have the mutex: update mutex and walk info and save the sync_level */ 311 if (obj_desc->mutex.owner_thread) {
208 312
209 obj_desc->mutex.owner_thread = walk_state->thread; 313 /* Unlink the mutex from the owner's list */
210 obj_desc->mutex.acquisition_depth = 1;
211 obj_desc->mutex.original_sync_level =
212 walk_state->thread->current_sync_level;
213 314
214 walk_state->thread->current_sync_level = obj_desc->mutex.sync_level; 315 acpi_ex_unlink_mutex(obj_desc);
316 obj_desc->mutex.owner_thread = NULL;
317 }
215 318
216 /* Link the mutex to the current thread for force-unlock at method exit */ 319 /* Release the mutex, special case for Global Lock */
217 320
218 acpi_ex_link_mutex(obj_desc, walk_state->thread); 321 if (obj_desc == acpi_gbl_global_lock_mutex) {
219 return_ACPI_STATUS(AE_OK); 322 status = acpi_ev_release_global_lock();
323 } else {
324 acpi_os_release_mutex(obj_desc->mutex.os_mutex);
325 }
326
327 /* Clear mutex info */
328
329 obj_desc->mutex.thread_id = 0;
330 return_ACPI_STATUS(status);
220} 331}
221 332
222/******************************************************************************* 333/*******************************************************************************
@@ -253,22 +364,13 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
253 return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED); 364 return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED);
254 } 365 }
255 366
256 /* Sanity check: we must have a valid thread ID */
257
258 if (!walk_state->thread) {
259 ACPI_ERROR((AE_INFO,
260 "Cannot release Mutex [%4.4s], null thread info",
261 acpi_ut_get_node_name(obj_desc->mutex.node)));
262 return_ACPI_STATUS(AE_AML_INTERNAL);
263 }
264
265 /* 367 /*
266 * The Mutex is owned, but this thread must be the owner. 368 * The Mutex is owned, but this thread must be the owner.
267 * Special case for Global Lock, any thread can release 369 * Special case for Global Lock, any thread can release
268 */ 370 */
269 if ((obj_desc->mutex.owner_thread->thread_id != 371 if ((obj_desc->mutex.owner_thread->thread_id !=
270 walk_state->thread->thread_id) 372 walk_state->thread->thread_id)
271 && (obj_desc->mutex.os_mutex != acpi_gbl_global_lock_mutex)) { 373 && (obj_desc != acpi_gbl_global_lock_mutex)) {
272 ACPI_ERROR((AE_INFO, 374 ACPI_ERROR((AE_INFO,
273 "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX", 375 "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX",
274 (unsigned long)walk_state->thread->thread_id, 376 (unsigned long)walk_state->thread->thread_id,
@@ -278,45 +380,37 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
278 return_ACPI_STATUS(AE_AML_NOT_OWNER); 380 return_ACPI_STATUS(AE_AML_NOT_OWNER);
279 } 381 }
280 382
383 /* Must have a valid thread ID */
384
385 if (!walk_state->thread) {
386 ACPI_ERROR((AE_INFO,
387 "Cannot release Mutex [%4.4s], null thread info",
388 acpi_ut_get_node_name(obj_desc->mutex.node)));
389 return_ACPI_STATUS(AE_AML_INTERNAL);
390 }
391
281 /* 392 /*
282 * The sync level of the mutex must be less than or equal to the current 393 * The sync level of the mutex must be less than or equal to the current
283 * sync level 394 * sync level
284 */ 395 */
285 if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) { 396 if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) {
286 ACPI_ERROR((AE_INFO, 397 ACPI_ERROR((AE_INFO,
287 "Cannot release Mutex [%4.4s], incorrect SyncLevel", 398 "Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %d current %d",
288 acpi_ut_get_node_name(obj_desc->mutex.node))); 399 acpi_ut_get_node_name(obj_desc->mutex.node),
400 obj_desc->mutex.sync_level,
401 walk_state->thread->current_sync_level));
289 return_ACPI_STATUS(AE_AML_MUTEX_ORDER); 402 return_ACPI_STATUS(AE_AML_MUTEX_ORDER);
290 } 403 }
291 404
292 /* Match multiple Acquires with multiple Releases */ 405 status = acpi_ex_release_mutex_object(obj_desc);
293
294 obj_desc->mutex.acquisition_depth--;
295 if (obj_desc->mutex.acquisition_depth != 0) {
296
297 /* Just decrement the depth and return */
298
299 return_ACPI_STATUS(AE_OK);
300 }
301
302 /* Unlink the mutex from the owner's list */
303 406
304 acpi_ex_unlink_mutex(obj_desc); 407 if (obj_desc->mutex.acquisition_depth == 0) {
305 408
306 /* Release the mutex, special case for Global Lock */ 409 /* Restore the original sync_level */
307 410
308 if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) { 411 walk_state->thread->current_sync_level =
309 status = acpi_ev_release_global_lock(); 412 obj_desc->mutex.original_sync_level;
310 } else {
311 acpi_os_release_mutex(obj_desc->mutex.os_mutex);
312 } 413 }
313
314 /* Update the mutex and restore sync_level */
315
316 obj_desc->mutex.owner_thread = NULL;
317 walk_state->thread->current_sync_level =
318 obj_desc->mutex.original_sync_level;
319
320 return_ACPI_STATUS(status); 414 return_ACPI_STATUS(status);
321} 415}
322 416
@@ -357,7 +451,7 @@ void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread)
357 451
358 /* Release the mutex, special case for Global Lock */ 452 /* Release the mutex, special case for Global Lock */
359 453
360 if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) { 454 if (obj_desc == acpi_gbl_global_lock_mutex) {
361 455
362 /* Ignore errors */ 456 /* Ignore errors */
363 457
@@ -369,6 +463,7 @@ void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread)
369 /* Mark mutex unowned */ 463 /* Mark mutex unowned */
370 464
371 obj_desc->mutex.owner_thread = NULL; 465 obj_desc->mutex.owner_thread = NULL;
466 obj_desc->mutex.thread_id = 0;
372 467
373 /* Update Thread sync_level (Last mutex is the important one) */ 468 /* Update Thread sync_level (Last mutex is the important one) */
374 469
diff --git a/drivers/acpi/executer/exnames.c b/drivers/acpi/executer/exnames.c
index 308eae52dc05..817e67be3697 100644
--- a/drivers/acpi/executer/exnames.c
+++ b/drivers/acpi/executer/exnames.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c
index 252f10acbbcc..7c3bea575e02 100644
--- a/drivers/acpi/executer/exoparg1.c
+++ b/drivers/acpi/executer/exoparg1.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -121,6 +121,7 @@ acpi_status acpi_ex_opcode_0A_0T_1R(struct acpi_walk_state *walk_state)
121 121
122 if ((ACPI_FAILURE(status)) || walk_state->result_obj) { 122 if ((ACPI_FAILURE(status)) || walk_state->result_obj) {
123 acpi_ut_remove_reference(return_desc); 123 acpi_ut_remove_reference(return_desc);
124 walk_state->result_obj = NULL;
124 } else { 125 } else {
125 /* Save the return value */ 126 /* Save the return value */
126 127
@@ -739,26 +740,38 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
739 value = acpi_gbl_integer_byte_width; 740 value = acpi_gbl_integer_byte_width;
740 break; 741 break;
741 742
742 case ACPI_TYPE_BUFFER:
743 value = temp_desc->buffer.length;
744 break;
745
746 case ACPI_TYPE_STRING: 743 case ACPI_TYPE_STRING:
747 value = temp_desc->string.length; 744 value = temp_desc->string.length;
748 break; 745 break;
749 746
747 case ACPI_TYPE_BUFFER:
748
749 /* Buffer arguments may not be evaluated at this point */
750
751 status = acpi_ds_get_buffer_arguments(temp_desc);
752 value = temp_desc->buffer.length;
753 break;
754
750 case ACPI_TYPE_PACKAGE: 755 case ACPI_TYPE_PACKAGE:
756
757 /* Package arguments may not be evaluated at this point */
758
759 status = acpi_ds_get_package_arguments(temp_desc);
751 value = temp_desc->package.count; 760 value = temp_desc->package.count;
752 break; 761 break;
753 762
754 default: 763 default:
755 ACPI_ERROR((AE_INFO, 764 ACPI_ERROR((AE_INFO,
756 "Operand is not Buf/Int/Str/Pkg - found type %s", 765 "Operand must be Buffer/Integer/String/Package - found type %s",
757 acpi_ut_get_type_name(type))); 766 acpi_ut_get_type_name(type)));
758 status = AE_AML_OPERAND_TYPE; 767 status = AE_AML_OPERAND_TYPE;
759 goto cleanup; 768 goto cleanup;
760 } 769 }
761 770
771 if (ACPI_FAILURE(status)) {
772 goto cleanup;
773 }
774
762 /* 775 /*
763 * Now that we have the size of the object, create a result 776 * Now that we have the size of the object, create a result
764 * object to hold the value 777 * object to hold the value
diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c
index 17e652e65379..8e8bbb6ccebd 100644
--- a/drivers/acpi/executer/exoparg2.c
+++ b/drivers/acpi/executer/exoparg2.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -241,10 +241,6 @@ acpi_status acpi_ex_opcode_2A_2T_1R(struct acpi_walk_state *walk_state)
241 goto cleanup; 241 goto cleanup;
242 } 242 }
243 243
244 /* Return the remainder */
245
246 walk_state->result_obj = return_desc1;
247
248 cleanup: 244 cleanup:
249 /* 245 /*
250 * Since the remainder is not returned indirectly, remove a reference to 246 * Since the remainder is not returned indirectly, remove a reference to
@@ -259,6 +255,12 @@ acpi_status acpi_ex_opcode_2A_2T_1R(struct acpi_walk_state *walk_state)
259 acpi_ut_remove_reference(return_desc1); 255 acpi_ut_remove_reference(return_desc1);
260 } 256 }
261 257
258 /* Save return object (the remainder) on success */
259
260 else {
261 walk_state->result_obj = return_desc1;
262 }
263
262 return_ACPI_STATUS(status); 264 return_ACPI_STATUS(status);
263} 265}
264 266
@@ -490,6 +492,7 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state)
490 492
491 if (ACPI_FAILURE(status)) { 493 if (ACPI_FAILURE(status)) {
492 acpi_ut_remove_reference(return_desc); 494 acpi_ut_remove_reference(return_desc);
495 walk_state->result_obj = NULL;
493 } 496 }
494 497
495 return_ACPI_STATUS(status); 498 return_ACPI_STATUS(status);
@@ -583,8 +586,6 @@ acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state)
583 return_desc->integer.value = ACPI_INTEGER_MAX; 586 return_desc->integer.value = ACPI_INTEGER_MAX;
584 } 587 }
585 588
586 walk_state->result_obj = return_desc;
587
588 cleanup: 589 cleanup:
589 590
590 /* Delete return object on error */ 591 /* Delete return object on error */
@@ -593,5 +594,11 @@ acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state)
593 acpi_ut_remove_reference(return_desc); 594 acpi_ut_remove_reference(return_desc);
594 } 595 }
595 596
597 /* Save return object on success */
598
599 else {
600 walk_state->result_obj = return_desc;
601 }
602
596 return_ACPI_STATUS(status); 603 return_ACPI_STATUS(status);
597} 604}
diff --git a/drivers/acpi/executer/exoparg3.c b/drivers/acpi/executer/exoparg3.c
index 7fe67cf82cee..9cb4197681af 100644
--- a/drivers/acpi/executer/exoparg3.c
+++ b/drivers/acpi/executer/exoparg3.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -260,6 +260,7 @@ acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state)
260 260
261 if (ACPI_FAILURE(status) || walk_state->result_obj) { 261 if (ACPI_FAILURE(status) || walk_state->result_obj) {
262 acpi_ut_remove_reference(return_desc); 262 acpi_ut_remove_reference(return_desc);
263 walk_state->result_obj = NULL;
263 } 264 }
264 265
265 /* Set the return object and exit */ 266 /* Set the return object and exit */
diff --git a/drivers/acpi/executer/exoparg6.c b/drivers/acpi/executer/exoparg6.c
index bd80a9cb3d65..67d48737af53 100644
--- a/drivers/acpi/executer/exoparg6.c
+++ b/drivers/acpi/executer/exoparg6.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -322,8 +322,6 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state)
322 goto cleanup; 322 goto cleanup;
323 } 323 }
324 324
325 walk_state->result_obj = return_desc;
326
327 cleanup: 325 cleanup:
328 326
329 /* Delete return object on error */ 327 /* Delete return object on error */
@@ -332,5 +330,11 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state)
332 acpi_ut_remove_reference(return_desc); 330 acpi_ut_remove_reference(return_desc);
333 } 331 }
334 332
333 /* Save return object on success */
334
335 else {
336 walk_state->result_obj = return_desc;
337 }
338
335 return_ACPI_STATUS(status); 339 return_ACPI_STATUS(status);
336} 340}
diff --git a/drivers/acpi/executer/exprep.c b/drivers/acpi/executer/exprep.c
index efe5d4b461a4..3a2f8cd4c62a 100644
--- a/drivers/acpi/executer/exprep.c
+++ b/drivers/acpi/executer/exprep.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -412,6 +412,7 @@ acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc,
412acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) 412acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
413{ 413{
414 union acpi_operand_object *obj_desc; 414 union acpi_operand_object *obj_desc;
415 union acpi_operand_object *second_desc = NULL;
415 u32 type; 416 u32 type;
416 acpi_status status; 417 acpi_status status;
417 418
@@ -494,6 +495,20 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
494 obj_desc->field.access_byte_width, 495 obj_desc->field.access_byte_width,
495 obj_desc->bank_field.region_obj, 496 obj_desc->bank_field.region_obj,
496 obj_desc->bank_field.bank_obj)); 497 obj_desc->bank_field.bank_obj));
498
499 /*
500 * Remember location in AML stream of the field unit
501 * opcode and operands -- since the bank_value
502 * operands must be evaluated.
503 */
504 second_desc = obj_desc->common.next_object;
505 second_desc->extra.aml_start =
506 ((union acpi_parse_object *)(info->data_register_node))->
507 named.data;
508 second_desc->extra.aml_length =
509 ((union acpi_parse_object *)(info->data_register_node))->
510 named.length;
511
497 break; 512 break;
498 513
499 case ACPI_TYPE_LOCAL_INDEX_FIELD: 514 case ACPI_TYPE_LOCAL_INDEX_FIELD:
diff --git a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c
index 3f51b7e84a17..7cd8bb54fa01 100644
--- a/drivers/acpi/executer/exregion.c
+++ b/drivers/acpi/executer/exregion.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -160,7 +160,7 @@ acpi_ex_system_memory_space_handler(u32 function,
160 if (!mem_info->mapped_logical_address) { 160 if (!mem_info->mapped_logical_address) {
161 ACPI_ERROR((AE_INFO, 161 ACPI_ERROR((AE_INFO,
162 "Could not map memory at %8.8X%8.8X, size %X", 162 "Could not map memory at %8.8X%8.8X, size %X",
163 ACPI_FORMAT_UINT64(address), 163 ACPI_FORMAT_NATIVE_UINT(address),
164 (u32) window_size)); 164 (u32) window_size));
165 mem_info->mapped_length = 0; 165 mem_info->mapped_length = 0;
166 return_ACPI_STATUS(AE_NO_MEMORY); 166 return_ACPI_STATUS(AE_NO_MEMORY);
@@ -182,7 +182,8 @@ acpi_ex_system_memory_space_handler(u32 function,
182 182
183 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 183 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
184 "System-Memory (width %d) R/W %d Address=%8.8X%8.8X\n", 184 "System-Memory (width %d) R/W %d Address=%8.8X%8.8X\n",
185 bit_width, function, ACPI_FORMAT_UINT64(address))); 185 bit_width, function,
186 ACPI_FORMAT_NATIVE_UINT(address)));
186 187
187 /* 188 /*
188 * Perform the memory read or write 189 * Perform the memory read or write
@@ -284,7 +285,8 @@ acpi_ex_system_io_space_handler(u32 function,
284 285
285 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 286 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
286 "System-IO (width %d) R/W %d Address=%8.8X%8.8X\n", 287 "System-IO (width %d) R/W %d Address=%8.8X%8.8X\n",
287 bit_width, function, ACPI_FORMAT_UINT64(address))); 288 bit_width, function,
289 ACPI_FORMAT_NATIVE_UINT(address)));
288 290
289 /* Decode the function parameter */ 291 /* Decode the function parameter */
290 292
diff --git a/drivers/acpi/executer/exresnte.c b/drivers/acpi/executer/exresnte.c
index 2b3a01cc4929..5596f42c9676 100644
--- a/drivers/acpi/executer/exresnte.c
+++ b/drivers/acpi/executer/exresnte.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -116,9 +116,11 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
116 * Several object types require no further processing: 116 * Several object types require no further processing:
117 * 1) Device/Thermal objects don't have a "real" subobject, return the Node 117 * 1) Device/Thermal objects don't have a "real" subobject, return the Node
118 * 2) Method locals and arguments have a pseudo-Node 118 * 2) Method locals and arguments have a pseudo-Node
119 * 3) 10/2007: Added method type to assist with Package construction.
119 */ 120 */
120 if ((entry_type == ACPI_TYPE_DEVICE) || 121 if ((entry_type == ACPI_TYPE_DEVICE) ||
121 (entry_type == ACPI_TYPE_THERMAL) || 122 (entry_type == ACPI_TYPE_THERMAL) ||
123 (entry_type == ACPI_TYPE_METHOD) ||
122 (node->flags & (ANOBJ_METHOD_ARG | ANOBJ_METHOD_LOCAL))) { 124 (node->flags & (ANOBJ_METHOD_ARG | ANOBJ_METHOD_LOCAL))) {
123 return_ACPI_STATUS(AE_OK); 125 return_ACPI_STATUS(AE_OK);
124 } 126 }
@@ -214,7 +216,6 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
214 /* For these objects, just return the object attached to the Node */ 216 /* For these objects, just return the object attached to the Node */
215 217
216 case ACPI_TYPE_MUTEX: 218 case ACPI_TYPE_MUTEX:
217 case ACPI_TYPE_METHOD:
218 case ACPI_TYPE_POWER: 219 case ACPI_TYPE_POWER:
219 case ACPI_TYPE_PROCESSOR: 220 case ACPI_TYPE_PROCESSOR:
220 case ACPI_TYPE_EVENT: 221 case ACPI_TYPE_EVENT:
@@ -238,13 +239,12 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
238 case ACPI_TYPE_LOCAL_REFERENCE: 239 case ACPI_TYPE_LOCAL_REFERENCE:
239 240
240 switch (source_desc->reference.opcode) { 241 switch (source_desc->reference.opcode) {
241 case AML_LOAD_OP: 242 case AML_LOAD_OP: /* This is a ddb_handle */
243 case AML_REF_OF_OP:
244 case AML_INDEX_OP:
242 245
243 /* This is a ddb_handle */
244 /* Return an additional reference to the object */ 246 /* Return an additional reference to the object */
245 247
246 case AML_REF_OF_OP:
247
248 obj_desc = source_desc; 248 obj_desc = source_desc;
249 acpi_ut_add_reference(obj_desc); 249 acpi_ut_add_reference(obj_desc);
250 break; 250 break;
diff --git a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c
index 6c64e55dab0e..b35f7c817acf 100644
--- a/drivers/acpi/executer/exresolv.c
+++ b/drivers/acpi/executer/exresolv.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -140,7 +140,6 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
140{ 140{
141 acpi_status status = AE_OK; 141 acpi_status status = AE_OK;
142 union acpi_operand_object *stack_desc; 142 union acpi_operand_object *stack_desc;
143 void *temp_node;
144 union acpi_operand_object *obj_desc = NULL; 143 union acpi_operand_object *obj_desc = NULL;
145 u16 opcode; 144 u16 opcode;
146 145
@@ -156,23 +155,6 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
156 opcode = stack_desc->reference.opcode; 155 opcode = stack_desc->reference.opcode;
157 156
158 switch (opcode) { 157 switch (opcode) {
159 case AML_NAME_OP:
160
161 /*
162 * Convert name reference to a namespace node
163 * Then, acpi_ex_resolve_node_to_value can be used to get the value
164 */
165 temp_node = stack_desc->reference.object;
166
167 /* Delete the Reference Object */
168
169 acpi_ut_remove_reference(stack_desc);
170
171 /* Return the namespace node */
172
173 (*stack_ptr) = temp_node;
174 break;
175
176 case AML_LOCAL_OP: 158 case AML_LOCAL_OP:
177 case AML_ARG_OP: 159 case AML_ARG_OP:
178 160
@@ -207,15 +189,25 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
207 switch (stack_desc->reference.target_type) { 189 switch (stack_desc->reference.target_type) {
208 case ACPI_TYPE_BUFFER_FIELD: 190 case ACPI_TYPE_BUFFER_FIELD:
209 191
210 /* Just return - leave the Reference on the stack */ 192 /* Just return - do not dereference */
211 break; 193 break;
212 194
213 case ACPI_TYPE_PACKAGE: 195 case ACPI_TYPE_PACKAGE:
214 196
197 /* If method call or copy_object - do not dereference */
198
199 if ((walk_state->opcode ==
200 AML_INT_METHODCALL_OP)
201 || (walk_state->opcode == AML_COPY_OP)) {
202 break;
203 }
204
205 /* Otherwise, dereference the package_index to a package element */
206
215 obj_desc = *stack_desc->reference.where; 207 obj_desc = *stack_desc->reference.where;
216 if (obj_desc) { 208 if (obj_desc) {
217 /* 209 /*
218 * Valid obj descriptor, copy pointer to return value 210 * Valid object descriptor, copy pointer to return value
219 * (i.e., dereference the package index) 211 * (i.e., dereference the package index)
220 * Delete the ref object, increment the returned object 212 * Delete the ref object, increment the returned object
221 */ 213 */
@@ -224,11 +216,11 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
224 *stack_ptr = obj_desc; 216 *stack_ptr = obj_desc;
225 } else { 217 } else {
226 /* 218 /*
227 * A NULL object descriptor means an unitialized element of 219 * A NULL object descriptor means an uninitialized element of
228 * the package, can't dereference it 220 * the package, can't dereference it
229 */ 221 */
230 ACPI_ERROR((AE_INFO, 222 ACPI_ERROR((AE_INFO,
231 "Attempt to deref an Index to NULL pkg element Idx=%p", 223 "Attempt to dereference an Index to NULL package element Idx=%p",
232 stack_desc)); 224 stack_desc));
233 status = AE_AML_UNINITIALIZED_ELEMENT; 225 status = AE_AML_UNINITIALIZED_ELEMENT;
234 } 226 }
@@ -239,7 +231,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
239 /* Invalid reference object */ 231 /* Invalid reference object */
240 232
241 ACPI_ERROR((AE_INFO, 233 ACPI_ERROR((AE_INFO,
242 "Unknown TargetType %X in Index/Reference obj %p", 234 "Unknown TargetType %X in Index/Reference object %p",
243 stack_desc->reference.target_type, 235 stack_desc->reference.target_type,
244 stack_desc)); 236 stack_desc));
245 status = AE_AML_INTERNAL; 237 status = AE_AML_INTERNAL;
@@ -251,7 +243,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
251 case AML_DEBUG_OP: 243 case AML_DEBUG_OP:
252 case AML_LOAD_OP: 244 case AML_LOAD_OP:
253 245
254 /* Just leave the object as-is */ 246 /* Just leave the object as-is, do not dereference */
255 247
256 break; 248 break;
257 249
@@ -390,10 +382,10 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
390 } 382 }
391 383
392 /* 384 /*
393 * For reference objects created via the ref_of or Index operators, 385 * For reference objects created via the ref_of, Index, or Load/load_table
394 * we need to get to the base object (as per the ACPI specification 386 * operators, we need to get to the base object (as per the ACPI
395 * of the object_type and size_of operators). This means traversing 387 * specification of the object_type and size_of operators). This means
396 * the list of possibly many nested references. 388 * traversing the list of possibly many nested references.
397 */ 389 */
398 while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) { 390 while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) {
399 switch (obj_desc->reference.opcode) { 391 switch (obj_desc->reference.opcode) {
@@ -463,6 +455,11 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
463 } 455 }
464 break; 456 break;
465 457
458 case AML_LOAD_OP:
459
460 type = ACPI_TYPE_DDB_HANDLE;
461 goto exit;
462
466 case AML_LOCAL_OP: 463 case AML_LOCAL_OP:
467 case AML_ARG_OP: 464 case AML_ARG_OP:
468 465
diff --git a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c
index 09d897b3f6d5..73e29e566a70 100644
--- a/drivers/acpi/executer/exresop.c
+++ b/drivers/acpi/executer/exresop.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -137,7 +137,6 @@ acpi_ex_resolve_operands(u16 opcode,
137 union acpi_operand_object *obj_desc; 137 union acpi_operand_object *obj_desc;
138 acpi_status status = AE_OK; 138 acpi_status status = AE_OK;
139 u8 object_type; 139 u8 object_type;
140 void *temp_node;
141 u32 arg_types; 140 u32 arg_types;
142 const struct acpi_opcode_info *op_info; 141 const struct acpi_opcode_info *op_info;
143 u32 this_arg_type; 142 u32 this_arg_type;
@@ -239,7 +238,6 @@ acpi_ex_resolve_operands(u16 opcode,
239 238
240 /*lint -fallthrough */ 239 /*lint -fallthrough */
241 240
242 case AML_NAME_OP:
243 case AML_INDEX_OP: 241 case AML_INDEX_OP:
244 case AML_REF_OF_OP: 242 case AML_REF_OF_OP:
245 case AML_ARG_OP: 243 case AML_ARG_OP:
@@ -332,15 +330,6 @@ acpi_ex_resolve_operands(u16 opcode,
332 if (ACPI_FAILURE(status)) { 330 if (ACPI_FAILURE(status)) {
333 return_ACPI_STATUS(status); 331 return_ACPI_STATUS(status);
334 } 332 }
335
336 if (obj_desc->reference.opcode == AML_NAME_OP) {
337
338 /* Convert a named reference to the actual named object */
339
340 temp_node = obj_desc->reference.object;
341 acpi_ut_remove_reference(obj_desc);
342 (*stack_ptr) = temp_node;
343 }
344 goto next_operand; 333 goto next_operand;
345 334
346 case ARGI_DATAREFOBJ: /* Store operator only */ 335 case ARGI_DATAREFOBJ: /* Store operator only */
diff --git a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c
index f4b69a637820..76c875bc3154 100644
--- a/drivers/acpi/executer/exstore.c
+++ b/drivers/acpi/executer/exstore.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -84,8 +84,12 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
84 84
85 ACPI_FUNCTION_TRACE_PTR(ex_do_debug_object, source_desc); 85 ACPI_FUNCTION_TRACE_PTR(ex_do_debug_object, source_desc);
86 86
87 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %*s", 87 /* Print line header as long as we are not in the middle of an object display */
88 level, " ")); 88
89 if (!((level > 0) && index == 0)) {
90 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %*s",
91 level, " "));
92 }
89 93
90 /* Display index for package output only */ 94 /* Display index for package output only */
91 95
@@ -95,12 +99,12 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
95 } 99 }
96 100
97 if (!source_desc) { 101 if (!source_desc) {
98 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "<Null Object>\n")); 102 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[Null Object]\n"));
99 return_VOID; 103 return_VOID;
100 } 104 }
101 105
102 if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) == ACPI_DESC_TYPE_OPERAND) { 106 if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) == ACPI_DESC_TYPE_OPERAND) {
103 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "%s: ", 107 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "%s ",
104 acpi_ut_get_object_type_name 108 acpi_ut_get_object_type_name
105 (source_desc))); 109 (source_desc)));
106 110
@@ -123,6 +127,8 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
123 return_VOID; 127 return_VOID;
124 } 128 }
125 129
130 /* source_desc is of type ACPI_DESC_TYPE_OPERAND */
131
126 switch (ACPI_GET_OBJECT_TYPE(source_desc)) { 132 switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
127 case ACPI_TYPE_INTEGER: 133 case ACPI_TYPE_INTEGER:
128 134
@@ -147,7 +153,7 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
147 (u32) source_desc->buffer.length)); 153 (u32) source_desc->buffer.length));
148 ACPI_DUMP_BUFFER(source_desc->buffer.pointer, 154 ACPI_DUMP_BUFFER(source_desc->buffer.pointer,
149 (source_desc->buffer.length < 155 (source_desc->buffer.length <
150 32) ? source_desc->buffer.length : 32); 156 256) ? source_desc->buffer.length : 256);
151 break; 157 break;
152 158
153 case ACPI_TYPE_STRING: 159 case ACPI_TYPE_STRING:
@@ -160,7 +166,7 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
160 case ACPI_TYPE_PACKAGE: 166 case ACPI_TYPE_PACKAGE:
161 167
162 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, 168 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
163 "[0x%.2X Elements]\n", 169 "[Contains 0x%.2X Elements]\n",
164 source_desc->package.count)); 170 source_desc->package.count));
165 171
166 /* Output the entire contents of the package */ 172 /* Output the entire contents of the package */
@@ -180,12 +186,59 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
180 (source_desc->reference.opcode), 186 (source_desc->reference.opcode),
181 source_desc->reference.offset)); 187 source_desc->reference.offset));
182 } else { 188 } else {
183 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[%s]\n", 189 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[%s]",
184 acpi_ps_get_opcode_name 190 acpi_ps_get_opcode_name
185 (source_desc->reference.opcode))); 191 (source_desc->reference.opcode)));
186 } 192 }
187 193
188 if (source_desc->reference.object) { 194 if (source_desc->reference.opcode == AML_LOAD_OP) { /* Load and load_table */
195 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
196 " Table OwnerId %p\n",
197 source_desc->reference.object));
198 break;
199 }
200
201 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, " "));
202
203 /* Check for valid node first, then valid object */
204
205 if (source_desc->reference.node) {
206 if (ACPI_GET_DESCRIPTOR_TYPE
207 (source_desc->reference.node) !=
208 ACPI_DESC_TYPE_NAMED) {
209 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
210 " %p - Not a valid namespace node\n",
211 source_desc->reference.
212 node));
213 } else {
214 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
215 "Node %p [%4.4s] ",
216 source_desc->reference.
217 node,
218 (source_desc->reference.
219 node)->name.ascii));
220
221 switch ((source_desc->reference.node)->type) {
222
223 /* These types have no attached object */
224
225 case ACPI_TYPE_DEVICE:
226 acpi_os_printf("Device\n");
227 break;
228
229 case ACPI_TYPE_THERMAL:
230 acpi_os_printf("Thermal Zone\n");
231 break;
232
233 default:
234 acpi_ex_do_debug_object((source_desc->
235 reference.
236 node)->object,
237 level + 4, 0);
238 break;
239 }
240 }
241 } else if (source_desc->reference.object) {
189 if (ACPI_GET_DESCRIPTOR_TYPE 242 if (ACPI_GET_DESCRIPTOR_TYPE
190 (source_desc->reference.object) == 243 (source_desc->reference.object) ==
191 ACPI_DESC_TYPE_NAMED) { 244 ACPI_DESC_TYPE_NAMED) {
@@ -198,18 +251,13 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
198 acpi_ex_do_debug_object(source_desc->reference. 251 acpi_ex_do_debug_object(source_desc->reference.
199 object, level + 4, 0); 252 object, level + 4, 0);
200 } 253 }
201 } else if (source_desc->reference.node) {
202 acpi_ex_do_debug_object((source_desc->reference.node)->
203 object, level + 4, 0);
204 } 254 }
205 break; 255 break;
206 256
207 default: 257 default:
208 258
209 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "%p %s\n", 259 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "%p\n",
210 source_desc, 260 source_desc));
211 acpi_ut_get_object_type_name
212 (source_desc)));
213 break; 261 break;
214 } 262 }
215 263
@@ -313,7 +361,6 @@ acpi_ex_store(union acpi_operand_object *source_desc,
313 * 4) Store to the debug object 361 * 4) Store to the debug object
314 */ 362 */
315 switch (ref_desc->reference.opcode) { 363 switch (ref_desc->reference.opcode) {
316 case AML_NAME_OP:
317 case AML_REF_OF_OP: 364 case AML_REF_OF_OP:
318 365
319 /* Storing an object into a Name "container" */ 366 /* Storing an object into a Name "container" */
@@ -415,11 +462,24 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
415 */ 462 */
416 obj_desc = *(index_desc->reference.where); 463 obj_desc = *(index_desc->reference.where);
417 464
418 status = 465 if (ACPI_GET_OBJECT_TYPE(source_desc) ==
419 acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc, 466 ACPI_TYPE_LOCAL_REFERENCE
420 walk_state); 467 && source_desc->reference.opcode == AML_LOAD_OP) {
421 if (ACPI_FAILURE(status)) { 468
422 return_ACPI_STATUS(status); 469 /* This is a DDBHandle, just add a reference to it */
470
471 acpi_ut_add_reference(source_desc);
472 new_desc = source_desc;
473 } else {
474 /* Normal object, copy it */
475
476 status =
477 acpi_ut_copy_iobject_to_iobject(source_desc,
478 &new_desc,
479 walk_state);
480 if (ACPI_FAILURE(status)) {
481 return_ACPI_STATUS(status);
482 }
423 } 483 }
424 484
425 if (obj_desc) { 485 if (obj_desc) {
@@ -571,10 +631,17 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
571 631
572 /* If no implicit conversion, drop into the default case below */ 632 /* If no implicit conversion, drop into the default case below */
573 633
574 if ((!implicit_conversion) || (walk_state->opcode == AML_COPY_OP)) { 634 if ((!implicit_conversion) ||
575 635 ((walk_state->opcode == AML_COPY_OP) &&
576 /* Force execution of default (no implicit conversion) */ 636 (target_type != ACPI_TYPE_LOCAL_REGION_FIELD) &&
577 637 (target_type != ACPI_TYPE_LOCAL_BANK_FIELD) &&
638 (target_type != ACPI_TYPE_LOCAL_INDEX_FIELD))) {
639 /*
640 * Force execution of default (no implicit conversion). Note:
641 * copy_object does not perform an implicit conversion, as per the ACPI
642 * spec -- except in case of region/bank/index fields -- because these
643 * objects must retain their original type permanently.
644 */
578 target_type = ACPI_TYPE_ANY; 645 target_type = ACPI_TYPE_ANY;
579 } 646 }
580 647
diff --git a/drivers/acpi/executer/exstoren.c b/drivers/acpi/executer/exstoren.c
index 1d622c625c64..a6d2168b81f9 100644
--- a/drivers/acpi/executer/exstoren.c
+++ b/drivers/acpi/executer/exstoren.c
@@ -7,7 +7,7 @@
7 *****************************************************************************/ 7 *****************************************************************************/
8 8
9/* 9/*
10 * Copyright (C) 2000 - 2007, R. Byron Moore 10 * Copyright (C) 2000 - 2008, Intel Corp.
11 * All rights reserved. 11 * All rights reserved.
12 * 12 *
13 * Redistribution and use in source and binary forms, with or without 13 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exstorob.c b/drivers/acpi/executer/exstorob.c
index 8233d40178ee..9a75ff09fb0c 100644
--- a/drivers/acpi/executer/exstorob.c
+++ b/drivers/acpi/executer/exstorob.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c
index 9460baff3032..68990f1df371 100644
--- a/drivers/acpi/executer/exsystem.c
+++ b/drivers/acpi/executer/exsystem.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -44,7 +44,6 @@
44 44
45#include <acpi/acpi.h> 45#include <acpi/acpi.h>
46#include <acpi/acinterp.h> 46#include <acpi/acinterp.h>
47#include <acpi/acevents.h>
48 47
49#define _COMPONENT ACPI_EXECUTER 48#define _COMPONENT ACPI_EXECUTER
50ACPI_MODULE_NAME("exsystem") 49ACPI_MODULE_NAME("exsystem")
diff --git a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c
index 6b0aeccbb69b..86c03880b523 100644
--- a/drivers/acpi/executer/exutils.c
+++ b/drivers/acpi/executer/exutils.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -61,7 +61,6 @@
61#include <acpi/acpi.h> 61#include <acpi/acpi.h>
62#include <acpi/acinterp.h> 62#include <acpi/acinterp.h>
63#include <acpi/amlcode.h> 63#include <acpi/amlcode.h>
64#include <acpi/acevents.h>
65 64
66#define _COMPONENT ACPI_EXECUTER 65#define _COMPONENT ACPI_EXECUTER
67ACPI_MODULE_NAME("exutils") 66ACPI_MODULE_NAME("exutils")
@@ -217,9 +216,10 @@ void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc)
217 216
218 /* 217 /*
219 * Object must be a valid number and we must be executing 218 * Object must be a valid number and we must be executing
220 * a control method 219 * a control method. NS node could be there for AML_INT_NAMEPATH_OP.
221 */ 220 */
222 if ((!obj_desc) || 221 if ((!obj_desc) ||
222 (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) ||
223 (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) { 223 (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) {
224 return; 224 return;
225 } 225 }
@@ -240,72 +240,73 @@ void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc)
240 * PARAMETERS: field_flags - Flags with Lock rule: 240 * PARAMETERS: field_flags - Flags with Lock rule:
241 * always_lock or never_lock 241 * always_lock or never_lock
242 * 242 *
243 * RETURN: TRUE/FALSE indicating whether the lock was actually acquired 243 * RETURN: None
244 * 244 *
245 * DESCRIPTION: Obtain the global lock and keep track of this fact via two 245 * DESCRIPTION: Obtain the ACPI hardware Global Lock, only if the field
246 * methods. A global variable keeps the state of the lock, and 246 * flags specifiy that it is to be obtained before field access.
247 * the state is returned to the caller.
248 * 247 *
249 ******************************************************************************/ 248 ******************************************************************************/
250 249
251u8 acpi_ex_acquire_global_lock(u32 field_flags) 250void acpi_ex_acquire_global_lock(u32 field_flags)
252{ 251{
253 u8 locked = FALSE;
254 acpi_status status; 252 acpi_status status;
255 253
256 ACPI_FUNCTION_TRACE(ex_acquire_global_lock); 254 ACPI_FUNCTION_TRACE(ex_acquire_global_lock);
257 255
258 /* Only attempt lock if the always_lock bit is set */ 256 /* Only use the lock if the always_lock bit is set */
257
258 if (!(field_flags & AML_FIELD_LOCK_RULE_MASK)) {
259 return_VOID;
260 }
259 261
260 if (field_flags & AML_FIELD_LOCK_RULE_MASK) { 262 /* Attempt to get the global lock, wait forever */
261 263
262 /* We should attempt to get the lock, wait forever */ 264 status = acpi_ex_acquire_mutex_object(ACPI_WAIT_FOREVER,
265 acpi_gbl_global_lock_mutex,
266 acpi_os_get_thread_id());
263 267
264 status = acpi_ev_acquire_global_lock(ACPI_WAIT_FOREVER); 268 if (ACPI_FAILURE(status)) {
265 if (ACPI_SUCCESS(status)) { 269 ACPI_EXCEPTION((AE_INFO, status,
266 locked = TRUE; 270 "Could not acquire Global Lock"));
267 } else {
268 ACPI_EXCEPTION((AE_INFO, status,
269 "Could not acquire Global Lock"));
270 }
271 } 271 }
272 272
273 return_UINT8(locked); 273 return_VOID;
274} 274}
275 275
276/******************************************************************************* 276/*******************************************************************************
277 * 277 *
278 * FUNCTION: acpi_ex_release_global_lock 278 * FUNCTION: acpi_ex_release_global_lock
279 * 279 *
280 * PARAMETERS: locked_by_me - Return value from corresponding call to 280 * PARAMETERS: field_flags - Flags with Lock rule:
281 * acquire_global_lock. 281 * always_lock or never_lock
282 * 282 *
283 * RETURN: None 283 * RETURN: None
284 * 284 *
285 * DESCRIPTION: Release the global lock if it is locked. 285 * DESCRIPTION: Release the ACPI hardware Global Lock
286 * 286 *
287 ******************************************************************************/ 287 ******************************************************************************/
288 288
289void acpi_ex_release_global_lock(u8 locked_by_me) 289void acpi_ex_release_global_lock(u32 field_flags)
290{ 290{
291 acpi_status status; 291 acpi_status status;
292 292
293 ACPI_FUNCTION_TRACE(ex_release_global_lock); 293 ACPI_FUNCTION_TRACE(ex_release_global_lock);
294 294
295 /* Only attempt unlock if the caller locked it */ 295 /* Only use the lock if the always_lock bit is set */
296 296
297 if (locked_by_me) { 297 if (!(field_flags & AML_FIELD_LOCK_RULE_MASK)) {
298 return_VOID;
299 }
298 300
299 /* OK, now release the lock */ 301 /* Release the global lock */
300 302
301 status = acpi_ev_release_global_lock(); 303 status = acpi_ex_release_mutex_object(acpi_gbl_global_lock_mutex);
302 if (ACPI_FAILURE(status)) { 304 if (ACPI_FAILURE(status)) {
303 305
304 /* Report the error, but there isn't much else we can do */ 306 /* Report the error, but there isn't much else we can do */
305 307
306 ACPI_EXCEPTION((AE_INFO, status, 308 ACPI_EXCEPTION((AE_INFO, status,
307 "Could not release ACPI Global Lock")); 309 "Could not release Global Lock"));
308 }
309 } 310 }
310 311
311 return_VOID; 312 return_VOID;
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index 194077ab9b85..6cf10cbc1eee 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -256,24 +256,23 @@ static int acpi_fan_add(struct acpi_device *device)
256 result = PTR_ERR(cdev); 256 result = PTR_ERR(cdev);
257 goto end; 257 goto end;
258 } 258 }
259 if (cdev) { 259
260 printk(KERN_INFO PREFIX 260 printk(KERN_INFO PREFIX
261 "%s is registered as cooling_device%d\n", 261 "%s is registered as cooling_device%d\n",
262 device->dev.bus_id, cdev->id); 262 device->dev.bus_id, cdev->id);
263 263
264 acpi_driver_data(device) = cdev; 264 acpi_driver_data(device) = cdev;
265 result = sysfs_create_link(&device->dev.kobj, 265 result = sysfs_create_link(&device->dev.kobj,
266 &cdev->device.kobj, 266 &cdev->device.kobj,
267 "thermal_cooling"); 267 "thermal_cooling");
268 if (result) 268 if (result)
269 return result; 269 printk(KERN_ERR PREFIX "Create sysfs link\n");
270 270
271 result = sysfs_create_link(&cdev->device.kobj, 271 result = sysfs_create_link(&cdev->device.kobj,
272 &device->dev.kobj, 272 &device->dev.kobj,
273 "device"); 273 "device");
274 if (result) 274 if (result)
275 return result; 275 printk(KERN_ERR PREFIX "Create sysfs link\n");
276 }
277 276
278 result = acpi_fan_add_fs(device); 277 result = acpi_fan_add_fs(device);
279 if (result) 278 if (result)
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index eda0978b57c6..06f8634fe58b 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -142,6 +142,7 @@ EXPORT_SYMBOL(acpi_get_physical_device);
142 142
143static int acpi_bind_one(struct device *dev, acpi_handle handle) 143static int acpi_bind_one(struct device *dev, acpi_handle handle)
144{ 144{
145 struct acpi_device *acpi_dev;
145 acpi_status status; 146 acpi_status status;
146 147
147 if (dev->archdata.acpi_handle) { 148 if (dev->archdata.acpi_handle) {
@@ -157,6 +158,16 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle)
157 } 158 }
158 dev->archdata.acpi_handle = handle; 159 dev->archdata.acpi_handle = handle;
159 160
161 status = acpi_bus_get_device(handle, &acpi_dev);
162 if (!ACPI_FAILURE(status)) {
163 int ret;
164
165 ret = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj,
166 "firmware_node");
167 ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
168 "physical_node");
169 }
170
160 return 0; 171 return 0;
161} 172}
162 173
@@ -165,8 +176,17 @@ static int acpi_unbind_one(struct device *dev)
165 if (!dev->archdata.acpi_handle) 176 if (!dev->archdata.acpi_handle)
166 return 0; 177 return 0;
167 if (dev == acpi_get_physical_device(dev->archdata.acpi_handle)) { 178 if (dev == acpi_get_physical_device(dev->archdata.acpi_handle)) {
179 struct acpi_device *acpi_dev;
180
168 /* acpi_get_physical_device increase refcnt by one */ 181 /* acpi_get_physical_device increase refcnt by one */
169 put_device(dev); 182 put_device(dev);
183
184 if (!acpi_bus_get_device(dev->archdata.acpi_handle,
185 &acpi_dev)) {
186 sysfs_remove_link(&dev->kobj, "firmware_node");
187 sysfs_remove_link(&acpi_dev->dev.kobj, "physical_node");
188 }
189
170 acpi_detach_data(dev->archdata.acpi_handle, 190 acpi_detach_data(dev->archdata.acpi_handle,
171 acpi_glue_data_handler); 191 acpi_glue_data_handler);
172 dev->archdata.acpi_handle = NULL; 192 dev->archdata.acpi_handle = NULL;
diff --git a/drivers/acpi/hardware/hwacpi.c b/drivers/acpi/hardware/hwacpi.c
index 6031ca13dd2f..816894ea839e 100644
--- a/drivers/acpi/hardware/hwacpi.c
+++ b/drivers/acpi/hardware/hwacpi.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c
index 117a05cadaaa..14bc4f456ae8 100644
--- a/drivers/acpi/hardware/hwgpe.c
+++ b/drivers/acpi/hardware/hwgpe.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c
index 73f9c5fb1ba7..ddf792adcf96 100644
--- a/drivers/acpi/hardware/hwregs.c
+++ b/drivers/acpi/hardware/hwregs.c
@@ -7,7 +7,7 @@
7 ******************************************************************************/ 7 ******************************************************************************/
8 8
9/* 9/*
10 * Copyright (C) 2000 - 2007, R. Byron Moore 10 * Copyright (C) 2000 - 2008, Intel Corp.
11 * All rights reserved. 11 * All rights reserved.
12 * 12 *
13 * Redistribution and use in source and binary forms, with or without 13 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
index 4290e0193097..d9937e05ec6a 100644
--- a/drivers/acpi/hardware/hwsleep.c
+++ b/drivers/acpi/hardware/hwsleep.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -70,9 +70,10 @@ acpi_set_firmware_waking_vector(acpi_physical_address physical_address)
70 70
71 /* Get the FACS */ 71 /* Get the FACS */
72 72
73 status = 73 status = acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS,
74 acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, 74 ACPI_CAST_INDIRECT_PTR(struct
75 (struct acpi_table_header **)&facs); 75 acpi_table_header,
76 &facs));
76 if (ACPI_FAILURE(status)) { 77 if (ACPI_FAILURE(status)) {
77 return_ACPI_STATUS(status); 78 return_ACPI_STATUS(status);
78 } 79 }
@@ -124,9 +125,10 @@ acpi_get_firmware_waking_vector(acpi_physical_address * physical_address)
124 125
125 /* Get the FACS */ 126 /* Get the FACS */
126 127
127 status = 128 status = acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS,
128 acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, 129 ACPI_CAST_INDIRECT_PTR(struct
129 (struct acpi_table_header **)&facs); 130 acpi_table_header,
131 &facs));
130 if (ACPI_FAILURE(status)) { 132 if (ACPI_FAILURE(status)) {
131 return_ACPI_STATUS(status); 133 return_ACPI_STATUS(status);
132 } 134 }
diff --git a/drivers/acpi/hardware/hwtimer.c b/drivers/acpi/hardware/hwtimer.c
index c32eab696acd..b53d575491b9 100644
--- a/drivers/acpi/hardware/hwtimer.c
+++ b/drivers/acpi/hardware/hwtimer.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c
index 57faf598bad8..c39a7f68b889 100644
--- a/drivers/acpi/namespace/nsaccess.c
+++ b/drivers/acpi/namespace/nsaccess.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -208,8 +208,7 @@ acpi_status acpi_ns_root_initialize(void)
208 /* Special case for ACPI Global Lock */ 208 /* Special case for ACPI Global Lock */
209 209
210 if (ACPI_STRCMP(init_val->name, "_GL_") == 0) { 210 if (ACPI_STRCMP(init_val->name, "_GL_") == 0) {
211 acpi_gbl_global_lock_mutex = 211 acpi_gbl_global_lock_mutex = obj_desc;
212 obj_desc->mutex.os_mutex;
213 212
214 /* Create additional counting semaphore for global lock */ 213 /* Create additional counting semaphore for global lock */
215 214
@@ -582,44 +581,68 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
582 return_ACPI_STATUS(status); 581 return_ACPI_STATUS(status);
583 } 582 }
584 583
585 /* 584 /* More segments to follow? */
586 * Sanity typecheck of the target object: 585
587 * 586 if (num_segments > 0) {
588 * If 1) This is the last segment (num_segments == 0) 587 /*
589 * 2) And we are looking for a specific type 588 * If we have an alias to an object that opens a scope (such as a
590 * (Not checking for TYPE_ANY) 589 * device or processor), we need to dereference the alias here so that
591 * 3) Which is not an alias 590 * we can access any children of the original node (via the remaining
592 * 4) Which is not a local type (TYPE_SCOPE) 591 * segments).
593 * 5) And the type of target object is known (not TYPE_ANY) 592 */
594 * 6) And target object does not match what we are looking for 593 if (this_node->type == ACPI_TYPE_LOCAL_ALIAS) {
595 * 594 if (acpi_ns_opens_scope
596 * Then we have a type mismatch. Just warn and ignore it. 595 (((struct acpi_namespace_node *)this_node->
597 */ 596 object)->type)) {
598 if ((num_segments == 0) && 597 this_node =
599 (type_to_check_for != ACPI_TYPE_ANY) && 598 (struct acpi_namespace_node *)
600 (type_to_check_for != ACPI_TYPE_LOCAL_ALIAS) && 599 this_node->object;
601 (type_to_check_for != ACPI_TYPE_LOCAL_METHOD_ALIAS) && 600 }
602 (type_to_check_for != ACPI_TYPE_LOCAL_SCOPE) && 601 }
603 (this_node->type != ACPI_TYPE_ANY) &&
604 (this_node->type != type_to_check_for)) {
605
606 /* Complain about a type mismatch */
607
608 ACPI_WARNING((AE_INFO,
609 "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)",
610 ACPI_CAST_PTR(char, &simple_name),
611 acpi_ut_get_type_name(this_node->type),
612 acpi_ut_get_type_name
613 (type_to_check_for)));
614 } 602 }
615 603
616 /* 604 /* Special handling for the last segment (num_segments == 0) */
617 * If this is the last name segment and we are not looking for a 605
618 * specific type, but the type of found object is known, use that type 606 else {
619 * to see if it opens a scope. 607 /*
620 */ 608 * Sanity typecheck of the target object:
621 if ((num_segments == 0) && (type == ACPI_TYPE_ANY)) { 609 *
622 type = this_node->type; 610 * If 1) This is the last segment (num_segments == 0)
611 * 2) And we are looking for a specific type
612 * (Not checking for TYPE_ANY)
613 * 3) Which is not an alias
614 * 4) Which is not a local type (TYPE_SCOPE)
615 * 5) And the type of target object is known (not TYPE_ANY)
616 * 6) And target object does not match what we are looking for
617 *
618 * Then we have a type mismatch. Just warn and ignore it.
619 */
620 if ((type_to_check_for != ACPI_TYPE_ANY) &&
621 (type_to_check_for != ACPI_TYPE_LOCAL_ALIAS) &&
622 (type_to_check_for != ACPI_TYPE_LOCAL_METHOD_ALIAS)
623 && (type_to_check_for != ACPI_TYPE_LOCAL_SCOPE)
624 && (this_node->type != ACPI_TYPE_ANY)
625 && (this_node->type != type_to_check_for)) {
626
627 /* Complain about a type mismatch */
628
629 ACPI_WARNING((AE_INFO,
630 "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)",
631 ACPI_CAST_PTR(char, &simple_name),
632 acpi_ut_get_type_name(this_node->
633 type),
634 acpi_ut_get_type_name
635 (type_to_check_for)));
636 }
637
638 /*
639 * If this is the last name segment and we are not looking for a
640 * specific type, but the type of found object is known, use that type
641 * to (later) see if it opens a scope.
642 */
643 if (type == ACPI_TYPE_ANY) {
644 type = this_node->type;
645 }
623 } 646 }
624 647
625 /* Point to next name segment and make this node current */ 648 /* Point to next name segment and make this node current */
diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c
index 1d693d8ad2d8..3a1740ac2edc 100644
--- a/drivers/acpi/namespace/nsalloc.c
+++ b/drivers/acpi/namespace/nsalloc.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c
index 1fc4f86676e1..5445751b8a3e 100644
--- a/drivers/acpi/namespace/nsdump.c
+++ b/drivers/acpi/namespace/nsdump.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -249,7 +249,9 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
249 acpi_os_printf("ID %X Len %.4X Addr %p\n", 249 acpi_os_printf("ID %X Len %.4X Addr %p\n",
250 obj_desc->processor.proc_id, 250 obj_desc->processor.proc_id,
251 obj_desc->processor.length, 251 obj_desc->processor.length,
252 (char *)obj_desc->processor.address); 252 ACPI_CAST_PTR(void,
253 obj_desc->processor.
254 address));
253 break; 255 break;
254 256
255 case ACPI_TYPE_DEVICE: 257 case ACPI_TYPE_DEVICE:
@@ -320,9 +322,8 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
320 space_id)); 322 space_id));
321 if (obj_desc->region.flags & AOPOBJ_DATA_VALID) { 323 if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
322 acpi_os_printf(" Addr %8.8X%8.8X Len %.4X\n", 324 acpi_os_printf(" Addr %8.8X%8.8X Len %.4X\n",
323 ACPI_FORMAT_UINT64(obj_desc-> 325 ACPI_FORMAT_NATIVE_UINT
324 region. 326 (obj_desc->region.address),
325 address),
326 obj_desc->region.length); 327 obj_desc->region.length);
327 } else { 328 } else {
328 acpi_os_printf 329 acpi_os_printf
diff --git a/drivers/acpi/namespace/nsdumpdv.c b/drivers/acpi/namespace/nsdumpdv.c
index 5097e167939e..428f50fde11a 100644
--- a/drivers/acpi/namespace/nsdumpdv.c
+++ b/drivers/acpi/namespace/nsdumpdv.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c
index 97b2ac57c16b..14bdfa92bea0 100644
--- a/drivers/acpi/namespace/nseval.c
+++ b/drivers/acpi/namespace/nseval.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c
index 33db2241044e..6d6d930c8e18 100644
--- a/drivers/acpi/namespace/nsinit.c
+++ b/drivers/acpi/namespace/nsinit.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -244,6 +244,10 @@ acpi_ns_init_one_object(acpi_handle obj_handle,
244 info->field_count++; 244 info->field_count++;
245 break; 245 break;
246 246
247 case ACPI_TYPE_LOCAL_BANK_FIELD:
248 info->field_count++;
249 break;
250
247 case ACPI_TYPE_BUFFER: 251 case ACPI_TYPE_BUFFER:
248 info->buffer_count++; 252 info->buffer_count++;
249 break; 253 break;
@@ -287,6 +291,12 @@ acpi_ns_init_one_object(acpi_handle obj_handle,
287 status = acpi_ds_get_buffer_field_arguments(obj_desc); 291 status = acpi_ds_get_buffer_field_arguments(obj_desc);
288 break; 292 break;
289 293
294 case ACPI_TYPE_LOCAL_BANK_FIELD:
295
296 info->field_init++;
297 status = acpi_ds_get_bank_field_arguments(obj_desc);
298 break;
299
290 case ACPI_TYPE_BUFFER: 300 case ACPI_TYPE_BUFFER:
291 301
292 info->buffer_init++; 302 info->buffer_init++;
diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c
index d4f9654fd20f..2c92f6cf5ce1 100644
--- a/drivers/acpi/namespace/nsload.c
+++ b/drivers/acpi/namespace/nsload.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -107,11 +107,11 @@ acpi_ns_load_table(acpi_native_uint table_index,
107 goto unlock; 107 goto unlock;
108 } 108 }
109 109
110 status = acpi_ns_parse_table(table_index, node->child); 110 status = acpi_ns_parse_table(table_index, node);
111 if (ACPI_SUCCESS(status)) { 111 if (ACPI_SUCCESS(status)) {
112 acpi_tb_set_table_loaded_flag(table_index, TRUE); 112 acpi_tb_set_table_loaded_flag(table_index, TRUE);
113 } else { 113 } else {
114 acpi_tb_release_owner_id(table_index); 114 (void)acpi_tb_release_owner_id(table_index);
115 } 115 }
116 116
117 unlock: 117 unlock:
diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c
index cbd94af08cc5..cffef1bcbdbc 100644
--- a/drivers/acpi/namespace/nsnames.c
+++ b/drivers/acpi/namespace/nsnames.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -180,6 +180,12 @@ acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node)
180 next_node = node; 180 next_node = node;
181 181
182 while (next_node && (next_node != acpi_gbl_root_node)) { 182 while (next_node && (next_node != acpi_gbl_root_node)) {
183 if (ACPI_GET_DESCRIPTOR_TYPE(next_node) != ACPI_DESC_TYPE_NAMED) {
184 ACPI_ERROR((AE_INFO,
185 "Invalid NS Node (%p) while traversing path",
186 next_node));
187 return 0;
188 }
183 size += ACPI_PATH_SEGMENT_LENGTH; 189 size += ACPI_PATH_SEGMENT_LENGTH;
184 next_node = acpi_ns_get_parent_node(next_node); 190 next_node = acpi_ns_get_parent_node(next_node);
185 } 191 }
diff --git a/drivers/acpi/namespace/nsobject.c b/drivers/acpi/namespace/nsobject.c
index d9d7377bc6e6..15fe09e24f71 100644
--- a/drivers/acpi/namespace/nsobject.c
+++ b/drivers/acpi/namespace/nsobject.c
@@ -6,7 +6,7 @@
6 ******************************************************************************/ 6 ******************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/namespace/nsparse.c
index e696aa847990..46a79b0103b6 100644
--- a/drivers/acpi/namespace/nsparse.c
+++ b/drivers/acpi/namespace/nsparse.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -64,7 +64,8 @@ ACPI_MODULE_NAME("nsparse")
64 ******************************************************************************/ 64 ******************************************************************************/
65acpi_status 65acpi_status
66acpi_ns_one_complete_parse(acpi_native_uint pass_number, 66acpi_ns_one_complete_parse(acpi_native_uint pass_number,
67 acpi_native_uint table_index) 67 acpi_native_uint table_index,
68 struct acpi_namespace_node * start_node)
68{ 69{
69 union acpi_parse_object *parse_root; 70 union acpi_parse_object *parse_root;
70 acpi_status status; 71 acpi_status status;
@@ -111,14 +112,25 @@ acpi_ns_one_complete_parse(acpi_native_uint pass_number,
111 aml_start = (u8 *) table + sizeof(struct acpi_table_header); 112 aml_start = (u8 *) table + sizeof(struct acpi_table_header);
112 aml_length = table->length - sizeof(struct acpi_table_header); 113 aml_length = table->length - sizeof(struct acpi_table_header);
113 status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL, 114 status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL,
114 aml_start, aml_length, NULL, 115 aml_start, (u32) aml_length,
115 (u8) pass_number); 116 NULL, (u8) pass_number);
116 } 117 }
117 118
118 if (ACPI_FAILURE(status)) { 119 if (ACPI_FAILURE(status)) {
119 acpi_ds_delete_walk_state(walk_state); 120 acpi_ds_delete_walk_state(walk_state);
120 acpi_ps_delete_parse_tree(parse_root); 121 goto cleanup;
121 return_ACPI_STATUS(status); 122 }
123
124 /* start_node is the default location to load the table */
125
126 if (start_node && start_node != acpi_gbl_root_node) {
127 status =
128 acpi_ds_scope_stack_push(start_node, ACPI_TYPE_METHOD,
129 walk_state);
130 if (ACPI_FAILURE(status)) {
131 acpi_ds_delete_walk_state(walk_state);
132 goto cleanup;
133 }
122 } 134 }
123 135
124 /* Parse the AML */ 136 /* Parse the AML */
@@ -127,6 +139,7 @@ acpi_ns_one_complete_parse(acpi_native_uint pass_number,
127 (unsigned)pass_number)); 139 (unsigned)pass_number));
128 status = acpi_ps_parse_aml(walk_state); 140 status = acpi_ps_parse_aml(walk_state);
129 141
142 cleanup:
130 acpi_ps_delete_parse_tree(parse_root); 143 acpi_ps_delete_parse_tree(parse_root);
131 return_ACPI_STATUS(status); 144 return_ACPI_STATUS(status);
132} 145}
@@ -163,7 +176,9 @@ acpi_ns_parse_table(acpi_native_uint table_index,
163 * performs another complete parse of the AML. 176 * performs another complete parse of the AML.
164 */ 177 */
165 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n")); 178 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n"));
166 status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1, table_index); 179 status =
180 acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1, table_index,
181 start_node);
167 if (ACPI_FAILURE(status)) { 182 if (ACPI_FAILURE(status)) {
168 return_ACPI_STATUS(status); 183 return_ACPI_STATUS(status);
169 } 184 }
@@ -178,7 +193,9 @@ acpi_ns_parse_table(acpi_native_uint table_index,
178 * parse objects are all cached. 193 * parse objects are all cached.
179 */ 194 */
180 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n")); 195 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n"));
181 status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2, table_index); 196 status =
197 acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2, table_index,
198 start_node);
182 if (ACPI_FAILURE(status)) { 199 if (ACPI_FAILURE(status)) {
183 return_ACPI_STATUS(status); 200 return_ACPI_STATUS(status);
184 } 201 }
diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c
index e863be665ce8..8399276cba1e 100644
--- a/drivers/acpi/namespace/nssearch.c
+++ b/drivers/acpi/namespace/nssearch.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c
index 90fd059615ff..64c039843ed2 100644
--- a/drivers/acpi/namespace/nsutils.c
+++ b/drivers/acpi/namespace/nsutils.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/namespace/nswalk.c b/drivers/acpi/namespace/nswalk.c
index 280b8357c46c..3c905ce26d7d 100644
--- a/drivers/acpi/namespace/nswalk.c
+++ b/drivers/acpi/namespace/nswalk.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -77,9 +77,7 @@ struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, struct
77 77
78 /* It's really the parent's _scope_ that we want */ 78 /* It's really the parent's _scope_ that we want */
79 79
80 if (parent_node->child) { 80 next_node = parent_node->child;
81 next_node = parent_node->child;
82 }
83 } 81 }
84 82
85 else { 83 else {
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
index b92133faf5b7..a8d549187c84 100644
--- a/drivers/acpi/namespace/nsxfeval.c
+++ b/drivers/acpi/namespace/nsxfeval.c
@@ -6,7 +6,7 @@
6 ******************************************************************************/ 6 ******************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -467,10 +467,13 @@ acpi_ns_get_device_callback(acpi_handle obj_handle,
467 return (AE_CTRL_DEPTH); 467 return (AE_CTRL_DEPTH);
468 } 468 }
469 469
470 if (!(flags & ACPI_STA_DEVICE_PRESENT)) { 470 if (!(flags & ACPI_STA_DEVICE_PRESENT) &&
471 471 !(flags & ACPI_STA_DEVICE_FUNCTIONING)) {
472 /* Don't examine children of the device if not present */ 472 /*
473 473 * Don't examine the children of the device only when the
474 * device is neither present nor functional. See ACPI spec,
475 * description of _STA for more information.
476 */
474 return (AE_CTRL_DEPTH); 477 return (AE_CTRL_DEPTH);
475 } 478 }
476 479
@@ -539,7 +542,7 @@ acpi_ns_get_device_callback(acpi_handle obj_handle,
539 * value is returned to the caller. 542 * value is returned to the caller.
540 * 543 *
541 * This is a wrapper for walk_namespace, but the callback performs 544 * This is a wrapper for walk_namespace, but the callback performs
542 * additional filtering. Please see acpi_get_device_callback. 545 * additional filtering. Please see acpi_ns_get_device_callback.
543 * 546 *
544 ******************************************************************************/ 547 ******************************************************************************/
545 548
diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c
index b489781b22a8..a287ed550f54 100644
--- a/drivers/acpi/namespace/nsxfname.c
+++ b/drivers/acpi/namespace/nsxfname.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/namespace/nsxfobj.c b/drivers/acpi/namespace/nsxfobj.c
index faa375887201..2b375ee80cef 100644
--- a/drivers/acpi/namespace/nsxfobj.c
+++ b/drivers/acpi/namespace/nsxfobj.c
@@ -6,7 +6,7 @@
6 ******************************************************************************/ 6 ******************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index a498a6cc68fe..235a1386888a 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -742,6 +742,7 @@ EXPORT_SYMBOL(acpi_os_execute);
742void acpi_os_wait_events_complete(void *context) 742void acpi_os_wait_events_complete(void *context)
743{ 743{
744 flush_workqueue(kacpid_wq); 744 flush_workqueue(kacpid_wq);
745 flush_workqueue(kacpi_notify_wq);
745} 746}
746 747
747EXPORT_SYMBOL(acpi_os_wait_events_complete); 748EXPORT_SYMBOL(acpi_os_wait_events_complete);
diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c
index c2b9835c890b..f1e8bf65e24e 100644
--- a/drivers/acpi/parser/psargs.c
+++ b/drivers/acpi/parser/psargs.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -230,12 +230,12 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
230 struct acpi_parse_state *parser_state, 230 struct acpi_parse_state *parser_state,
231 union acpi_parse_object *arg, u8 possible_method_call) 231 union acpi_parse_object *arg, u8 possible_method_call)
232{ 232{
233 acpi_status status;
233 char *path; 234 char *path;
234 union acpi_parse_object *name_op; 235 union acpi_parse_object *name_op;
235 acpi_status status;
236 union acpi_operand_object *method_desc; 236 union acpi_operand_object *method_desc;
237 struct acpi_namespace_node *node; 237 struct acpi_namespace_node *node;
238 union acpi_generic_state scope_info; 238 u8 *start = parser_state->aml;
239 239
240 ACPI_FUNCTION_TRACE(ps_get_next_namepath); 240 ACPI_FUNCTION_TRACE(ps_get_next_namepath);
241 241
@@ -249,25 +249,18 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
249 return_ACPI_STATUS(AE_OK); 249 return_ACPI_STATUS(AE_OK);
250 } 250 }
251 251
252 /* Setup search scope info */
253
254 scope_info.scope.node = NULL;
255 node = parser_state->start_node;
256 if (node) {
257 scope_info.scope.node = node;
258 }
259
260 /* 252 /*
261 * Lookup the name in the internal namespace. We don't want to add 253 * Lookup the name in the internal namespace, starting with the current
262 * anything new to the namespace here, however, so we use MODE_EXECUTE. 254 * scope. We don't want to add anything new to the namespace here,
255 * however, so we use MODE_EXECUTE.
263 * Allow searching of the parent tree, but don't open a new scope - 256 * Allow searching of the parent tree, but don't open a new scope -
264 * we just want to lookup the object (must be mode EXECUTE to perform 257 * we just want to lookup the object (must be mode EXECUTE to perform
265 * the upsearch) 258 * the upsearch)
266 */ 259 */
267 status = 260 status = acpi_ns_lookup(walk_state->scope_info, path,
268 acpi_ns_lookup(&scope_info, path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 261 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
269 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, 262 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
270 NULL, &node); 263 NULL, &node);
271 264
272 /* 265 /*
273 * If this name is a control method invocation, we must 266 * If this name is a control method invocation, we must
@@ -275,6 +268,16 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
275 */ 268 */
276 if (ACPI_SUCCESS(status) && 269 if (ACPI_SUCCESS(status) &&
277 possible_method_call && (node->type == ACPI_TYPE_METHOD)) { 270 possible_method_call && (node->type == ACPI_TYPE_METHOD)) {
271 if (walk_state->op->common.aml_opcode == AML_UNLOAD_OP) {
272 /*
273 * acpi_ps_get_next_namestring has increased the AML pointer,
274 * so we need to restore the saved AML pointer for method call.
275 */
276 walk_state->parser_state.aml = start;
277 walk_state->arg_count = 1;
278 acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
279 return_ACPI_STATUS(AE_OK);
280 }
278 281
279 /* This name is actually a control method invocation */ 282 /* This name is actually a control method invocation */
280 283
@@ -686,9 +689,29 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
686 return_ACPI_STATUS(AE_NO_MEMORY); 689 return_ACPI_STATUS(AE_NO_MEMORY);
687 } 690 }
688 691
689 status = 692 /* To support super_name arg of Unload */
690 acpi_ps_get_next_namepath(walk_state, parser_state, 693
691 arg, 0); 694 if (walk_state->op->common.aml_opcode == AML_UNLOAD_OP) {
695 status =
696 acpi_ps_get_next_namepath(walk_state,
697 parser_state, arg,
698 1);
699
700 /*
701 * If the super_name arg of Unload is a method call,
702 * we have restored the AML pointer, just free this Arg
703 */
704 if (arg->common.aml_opcode ==
705 AML_INT_METHODCALL_OP) {
706 acpi_ps_free_op(arg);
707 arg = NULL;
708 }
709 } else {
710 status =
711 acpi_ps_get_next_namepath(walk_state,
712 parser_state, arg,
713 0);
714 }
692 } else { 715 } else {
693 /* Single complex argument, nothing returned */ 716 /* Single complex argument, nothing returned */
694 717
diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/parser/psloop.c
index 773aee82fbb8..c06238e55d98 100644
--- a/drivers/acpi/parser/psloop.c
+++ b/drivers/acpi/parser/psloop.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -182,6 +182,7 @@ acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
182 ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state); 182 ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state);
183 183
184 unnamed_op->common.value.arg = NULL; 184 unnamed_op->common.value.arg = NULL;
185 unnamed_op->common.arg_list_length = 0;
185 unnamed_op->common.aml_opcode = walk_state->opcode; 186 unnamed_op->common.aml_opcode = walk_state->opcode;
186 187
187 /* 188 /*
@@ -241,7 +242,8 @@ acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
241 acpi_ps_append_arg(*op, unnamed_op->common.value.arg); 242 acpi_ps_append_arg(*op, unnamed_op->common.value.arg);
242 acpi_gbl_depth++; 243 acpi_gbl_depth++;
243 244
244 if ((*op)->common.aml_opcode == AML_REGION_OP) { 245 if ((*op)->common.aml_opcode == AML_REGION_OP ||
246 (*op)->common.aml_opcode == AML_DATA_REGION_OP) {
245 /* 247 /*
246 * Defer final parsing of an operation_region body, because we don't 248 * Defer final parsing of an operation_region body, because we don't
247 * have enough info in the first pass to parse it correctly (i.e., 249 * have enough info in the first pass to parse it correctly (i.e.,
@@ -280,6 +282,9 @@ acpi_ps_create_op(struct acpi_walk_state *walk_state,
280 acpi_status status = AE_OK; 282 acpi_status status = AE_OK;
281 union acpi_parse_object *op; 283 union acpi_parse_object *op;
282 union acpi_parse_object *named_op = NULL; 284 union acpi_parse_object *named_op = NULL;
285 union acpi_parse_object *parent_scope;
286 u8 argument_count;
287 const struct acpi_opcode_info *op_info;
283 288
284 ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state); 289 ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state);
285 290
@@ -320,8 +325,32 @@ acpi_ps_create_op(struct acpi_walk_state *walk_state,
320 op->named.length = 0; 325 op->named.length = 0;
321 } 326 }
322 327
323 acpi_ps_append_arg(acpi_ps_get_parent_scope 328 if (walk_state->opcode == AML_BANK_FIELD_OP) {
324 (&(walk_state->parser_state)), op); 329 /*
330 * Backup to beginning of bank_field declaration
331 * body_length is unknown until we parse the body
332 */
333 op->named.data = aml_op_start;
334 op->named.length = 0;
335 }
336
337 parent_scope = acpi_ps_get_parent_scope(&(walk_state->parser_state));
338 acpi_ps_append_arg(parent_scope, op);
339
340 if (parent_scope) {
341 op_info =
342 acpi_ps_get_opcode_info(parent_scope->common.aml_opcode);
343 if (op_info->flags & AML_HAS_TARGET) {
344 argument_count =
345 acpi_ps_get_argument_count(op_info->type);
346 if (parent_scope->common.arg_list_length >
347 argument_count) {
348 op->common.flags |= ACPI_PARSEOP_TARGET;
349 }
350 } else if (parent_scope->common.aml_opcode == AML_INCREMENT_OP) {
351 op->common.flags |= ACPI_PARSEOP_TARGET;
352 }
353 }
325 354
326 if (walk_state->descending_callback != NULL) { 355 if (walk_state->descending_callback != NULL) {
327 /* 356 /*
@@ -603,13 +632,6 @@ acpi_ps_complete_op(struct acpi_walk_state *walk_state,
603 acpi_ps_pop_scope(&(walk_state->parser_state), op, 632 acpi_ps_pop_scope(&(walk_state->parser_state), op,
604 &walk_state->arg_types, 633 &walk_state->arg_types,
605 &walk_state->arg_count); 634 &walk_state->arg_count);
606
607 if ((*op)->common.aml_opcode != AML_WHILE_OP) {
608 status2 = acpi_ds_result_stack_pop(walk_state);
609 if (ACPI_FAILURE(status2)) {
610 return_ACPI_STATUS(status2);
611 }
612 }
613 } 635 }
614 636
615 /* Close this iteration of the While loop */ 637 /* Close this iteration of the While loop */
@@ -640,10 +662,6 @@ acpi_ps_complete_op(struct acpi_walk_state *walk_state,
640 if (ACPI_FAILURE(status2)) { 662 if (ACPI_FAILURE(status2)) {
641 return_ACPI_STATUS(status2); 663 return_ACPI_STATUS(status2);
642 } 664 }
643 status2 = acpi_ds_result_stack_pop(walk_state);
644 if (ACPI_FAILURE(status2)) {
645 return_ACPI_STATUS(status2);
646 }
647 665
648 acpi_ut_delete_generic_state 666 acpi_ut_delete_generic_state
649 (acpi_ut_pop_generic_state 667 (acpi_ut_pop_generic_state
@@ -1005,7 +1023,8 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
1005 acpi_gbl_depth--; 1023 acpi_gbl_depth--;
1006 } 1024 }
1007 1025
1008 if (op->common.aml_opcode == AML_REGION_OP) { 1026 if (op->common.aml_opcode == AML_REGION_OP ||
1027 op->common.aml_opcode == AML_DATA_REGION_OP) {
1009 /* 1028 /*
1010 * Skip parsing of control method or opregion body, 1029 * Skip parsing of control method or opregion body,
1011 * because we don't have enough info in the first pass 1030 * because we don't have enough info in the first pass
@@ -1030,6 +1049,16 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
1030 (u32) (parser_state->aml - op->named.data); 1049 (u32) (parser_state->aml - op->named.data);
1031 } 1050 }
1032 1051
1052 if (op->common.aml_opcode == AML_BANK_FIELD_OP) {
1053 /*
1054 * Backup to beginning of bank_field declaration
1055 *
1056 * body_length is unknown until we parse the body
1057 */
1058 op->named.length =
1059 (u32) (parser_state->aml - op->named.data);
1060 }
1061
1033 /* This op complete, notify the dispatcher */ 1062 /* This op complete, notify the dispatcher */
1034 1063
1035 if (walk_state->ascending_callback != NULL) { 1064 if (walk_state->ascending_callback != NULL) {
diff --git a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c
index 9296e86761d7..f425ab30eae8 100644
--- a/drivers/acpi/parser/psopcode.c
+++ b/drivers/acpi/parser/psopcode.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -49,6 +49,9 @@
49#define _COMPONENT ACPI_PARSER 49#define _COMPONENT ACPI_PARSER
50ACPI_MODULE_NAME("psopcode") 50ACPI_MODULE_NAME("psopcode")
51 51
52static const u8 acpi_gbl_argument_count[] =
53 { 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 6 };
54
52/******************************************************************************* 55/*******************************************************************************
53 * 56 *
54 * NAME: acpi_gbl_aml_op_info 57 * NAME: acpi_gbl_aml_op_info
@@ -59,6 +62,7 @@ ACPI_MODULE_NAME("psopcode")
59 * the operand type. 62 * the operand type.
60 * 63 *
61 ******************************************************************************/ 64 ******************************************************************************/
65
62/* 66/*
63 * Summary of opcode types/flags 67 * Summary of opcode types/flags
64 * 68 *
@@ -176,6 +180,7 @@ ACPI_MODULE_NAME("psopcode")
176 AML_CREATE_QWORD_FIELD_OP 180 AML_CREATE_QWORD_FIELD_OP
177 181
178 ******************************************************************************/ 182 ******************************************************************************/
183
179/* 184/*
180 * Master Opcode information table. A summary of everything we know about each 185 * Master Opcode information table. A summary of everything we know about each
181 * opcode, all in one place. 186 * opcode, all in one place.
@@ -515,9 +520,10 @@ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] = {
515 AML_TYPE_NAMED_FIELD, 520 AML_TYPE_NAMED_FIELD,
516 AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD), 521 AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD),
517/* 5F */ ACPI_OP("BankField", ARGP_BANK_FIELD_OP, ARGI_BANK_FIELD_OP, 522/* 5F */ ACPI_OP("BankField", ARGP_BANK_FIELD_OP, ARGI_BANK_FIELD_OP,
518 ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT, 523 ACPI_TYPE_LOCAL_BANK_FIELD, AML_CLASS_NAMED_OBJECT,
519 AML_TYPE_NAMED_FIELD, 524 AML_TYPE_NAMED_FIELD,
520 AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD), 525 AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD |
526 AML_DEFER),
521 527
522/* Internal opcodes that map to invalid AML opcodes */ 528/* Internal opcodes that map to invalid AML opcodes */
523 529
@@ -619,9 +625,9 @@ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] = {
619 AML_TYPE_EXEC_6A_0T_1R, AML_FLAGS_EXEC_6A_0T_1R), 625 AML_TYPE_EXEC_6A_0T_1R, AML_FLAGS_EXEC_6A_0T_1R),
620/* 7C */ ACPI_OP("DataTableRegion", ARGP_DATA_REGION_OP, 626/* 7C */ ACPI_OP("DataTableRegion", ARGP_DATA_REGION_OP,
621 ARGI_DATA_REGION_OP, ACPI_TYPE_REGION, 627 ARGI_DATA_REGION_OP, ACPI_TYPE_REGION,
622 AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_SIMPLE, 628 AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_COMPLEX,
623 AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | 629 AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE |
624 AML_NSNODE | AML_NAMED), 630 AML_NSNODE | AML_NAMED | AML_DEFER),
625/* 7D */ ACPI_OP("[EvalSubTree]", ARGP_SCOPE_OP, ARGI_SCOPE_OP, 631/* 7D */ ACPI_OP("[EvalSubTree]", ARGP_SCOPE_OP, ARGI_SCOPE_OP,
626 ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT, 632 ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT,
627 AML_TYPE_NAMED_NO_OBJ, 633 AML_TYPE_NAMED_NO_OBJ,
@@ -779,3 +785,25 @@ char *acpi_ps_get_opcode_name(u16 opcode)
779 785
780#endif 786#endif
781} 787}
788
789/*******************************************************************************
790 *
791 * FUNCTION: acpi_ps_get_argument_count
792 *
793 * PARAMETERS: op_type - Type associated with the AML opcode
794 *
795 * RETURN: Argument count
796 *
797 * DESCRIPTION: Obtain the number of expected arguments for an AML opcode
798 *
799 ******************************************************************************/
800
801u8 acpi_ps_get_argument_count(u32 op_type)
802{
803
804 if (op_type <= AML_TYPE_EXEC_6A_0T_1R) {
805 return (acpi_gbl_argument_count[op_type]);
806 }
807
808 return (0);
809}
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c
index 5d63f48e56b5..15e1702e48d6 100644
--- a/drivers/acpi/parser/psparse.c
+++ b/drivers/acpi/parser/psparse.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -205,6 +205,8 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
205 || (op->common.parent->common.aml_opcode == 205 || (op->common.parent->common.aml_opcode ==
206 AML_PACKAGE_OP) 206 AML_PACKAGE_OP)
207 || (op->common.parent->common.aml_opcode == 207 || (op->common.parent->common.aml_opcode ==
208 AML_BANK_FIELD_OP)
209 || (op->common.parent->common.aml_opcode ==
208 AML_VAR_PACKAGE_OP)) { 210 AML_VAR_PACKAGE_OP)) {
209 replacement_op = 211 replacement_op =
210 acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); 212 acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP);
@@ -349,19 +351,13 @@ acpi_ps_next_parse_state(struct acpi_walk_state *walk_state,
349 351
350 parser_state->aml = walk_state->aml_last_while; 352 parser_state->aml = walk_state->aml_last_while;
351 walk_state->control_state->common.value = FALSE; 353 walk_state->control_state->common.value = FALSE;
352 status = acpi_ds_result_stack_pop(walk_state); 354 status = AE_CTRL_BREAK;
353 if (ACPI_SUCCESS(status)) {
354 status = AE_CTRL_BREAK;
355 }
356 break; 355 break;
357 356
358 case AE_CTRL_CONTINUE: 357 case AE_CTRL_CONTINUE:
359 358
360 parser_state->aml = walk_state->aml_last_while; 359 parser_state->aml = walk_state->aml_last_while;
361 status = acpi_ds_result_stack_pop(walk_state); 360 status = AE_CTRL_CONTINUE;
362 if (ACPI_SUCCESS(status)) {
363 status = AE_CTRL_CONTINUE;
364 }
365 break; 361 break;
366 362
367 case AE_CTRL_PENDING: 363 case AE_CTRL_PENDING:
@@ -383,10 +379,7 @@ acpi_ps_next_parse_state(struct acpi_walk_state *walk_state,
383 * Just close out this package 379 * Just close out this package
384 */ 380 */
385 parser_state->aml = acpi_ps_get_next_package_end(parser_state); 381 parser_state->aml = acpi_ps_get_next_package_end(parser_state);
386 status = acpi_ds_result_stack_pop(walk_state); 382 status = AE_CTRL_PENDING;
387 if (ACPI_SUCCESS(status)) {
388 status = AE_CTRL_PENDING;
389 }
390 break; 383 break;
391 384
392 case AE_CTRL_FALSE: 385 case AE_CTRL_FALSE:
@@ -541,7 +534,7 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state)
541 if ((status == AE_ALREADY_EXISTS) && 534 if ((status == AE_ALREADY_EXISTS) &&
542 (!walk_state->method_desc->method.mutex)) { 535 (!walk_state->method_desc->method.mutex)) {
543 ACPI_INFO((AE_INFO, 536 ACPI_INFO((AE_INFO,
544 "Marking method %4.4s as Serialized", 537 "Marking method %4.4s as Serialized because of AE_ALREADY_EXISTS error",
545 walk_state->method_node->name. 538 walk_state->method_node->name.
546 ascii)); 539 ascii));
547 540
@@ -601,6 +594,30 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state)
601 * The object is deleted 594 * The object is deleted
602 */ 595 */
603 if (!previous_walk_state->return_desc) { 596 if (!previous_walk_state->return_desc) {
597 /*
598 * In slack mode execution, if there is no return value
599 * we should implicitly return zero (0) as a default value.
600 */
601 if (acpi_gbl_enable_interpreter_slack &&
602 !previous_walk_state->
603 implicit_return_obj) {
604 previous_walk_state->
605 implicit_return_obj =
606 acpi_ut_create_internal_object
607 (ACPI_TYPE_INTEGER);
608 if (!previous_walk_state->
609 implicit_return_obj) {
610 return_ACPI_STATUS
611 (AE_NO_MEMORY);
612 }
613
614 previous_walk_state->
615 implicit_return_obj->
616 integer.value = 0;
617 }
618
619 /* Restart the calling control method */
620
604 status = 621 status =
605 acpi_ds_restart_control_method 622 acpi_ds_restart_control_method
606 (walk_state, 623 (walk_state,
diff --git a/drivers/acpi/parser/psscope.c b/drivers/acpi/parser/psscope.c
index 77cfa4ed0cfe..ee50e67c9443 100644
--- a/drivers/acpi/parser/psscope.c
+++ b/drivers/acpi/parser/psscope.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/parser/pstree.c b/drivers/acpi/parser/pstree.c
index 966e7ea2a0c4..1dd355ddd182 100644
--- a/drivers/acpi/parser/pstree.c
+++ b/drivers/acpi/parser/pstree.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -171,6 +171,8 @@ acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg)
171 while (arg) { 171 while (arg) {
172 arg->common.parent = op; 172 arg->common.parent = op;
173 arg = arg->common.next; 173 arg = arg->common.next;
174
175 op->common.arg_list_length++;
174 } 176 }
175} 177}
176 178
diff --git a/drivers/acpi/parser/psutils.c b/drivers/acpi/parser/psutils.c
index 8ca52002db55..7cf1f65cd5bb 100644
--- a/drivers/acpi/parser/psutils.c
+++ b/drivers/acpi/parser/psutils.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/parser/pswalk.c b/drivers/acpi/parser/pswalk.c
index 49f9757434e4..8b86ad5a3201 100644
--- a/drivers/acpi/parser/pswalk.c
+++ b/drivers/acpi/parser/pswalk.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c
index 94103bced75e..52581454c47c 100644
--- a/drivers/acpi/parser/psxface.c
+++ b/drivers/acpi/parser/psxface.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 21fc8bf0d31f..81e4f081a4ae 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -122,7 +122,7 @@ acpi_power_get_context(acpi_handle handle,
122 } 122 }
123 123
124 *resource = acpi_driver_data(device); 124 *resource = acpi_driver_data(device);
125 if (!resource) 125 if (!*resource)
126 return -ENODEV; 126 return -ENODEV;
127 127
128 return 0; 128 return 0;
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 5241e3ff5080..386e5aa48834 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -674,22 +674,21 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
674 result = PTR_ERR(pr->cdev); 674 result = PTR_ERR(pr->cdev);
675 goto end; 675 goto end;
676 } 676 }
677 if (pr->cdev) { 677
678 printk(KERN_INFO PREFIX 678 printk(KERN_INFO PREFIX
679 "%s is registered as cooling_device%d\n", 679 "%s is registered as cooling_device%d\n",
680 device->dev.bus_id, pr->cdev->id); 680 device->dev.bus_id, pr->cdev->id);
681 681
682 result = sysfs_create_link(&device->dev.kobj, 682 result = sysfs_create_link(&device->dev.kobj,
683 &pr->cdev->device.kobj, 683 &pr->cdev->device.kobj,
684 "thermal_cooling"); 684 "thermal_cooling");
685 if (result) 685 if (result)
686 return result; 686 printk(KERN_ERR PREFIX "Create sysfs link\n");
687 result = sysfs_create_link(&pr->cdev->device.kobj, 687 result = sysfs_create_link(&pr->cdev->device.kobj,
688 &device->dev.kobj, 688 &device->dev.kobj,
689 "device"); 689 "device");
690 if (result) 690 if (result)
691 return result; 691 printk(KERN_ERR PREFIX "Create sysfs link\n");
692 }
693 692
694 if (pr->flags.throttling) { 693 if (pr->flags.throttling) {
695 printk(KERN_INFO PREFIX "%s [%s] (supports", 694 printk(KERN_INFO PREFIX "%s [%s] (supports",
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 789d4947ed31..2dd2c1f3a01c 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -847,6 +847,7 @@ static int acpi_processor_get_power_info_default(struct acpi_processor *pr)
847 /* all processors need to support C1 */ 847 /* all processors need to support C1 */
848 pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; 848 pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
849 pr->power.states[ACPI_STATE_C1].valid = 1; 849 pr->power.states[ACPI_STATE_C1].valid = 1;
850 pr->power.states[ACPI_STATE_C1].entry_method = ACPI_CSTATE_HALT;
850 } 851 }
851 /* the C0 state only exists as a filler in our array */ 852 /* the C0 state only exists as a filler in our array */
852 pr->power.states[ACPI_STATE_C0].valid = 1; 853 pr->power.states[ACPI_STATE_C0].valid = 1;
@@ -959,6 +960,9 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
959 cx.address); 960 cx.address);
960 } 961 }
961 962
963 if (cx.type == ACPI_STATE_C1) {
964 cx.valid = 1;
965 }
962 966
963 obj = &(element->package.elements[2]); 967 obj = &(element->package.elements[2]);
964 if (obj->type != ACPI_TYPE_INTEGER) 968 if (obj->type != ACPI_TYPE_INTEGER)
@@ -1295,6 +1299,8 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
1295{ 1299{
1296 int result = 0; 1300 int result = 0;
1297 1301
1302 if (boot_option_idle_override)
1303 return 0;
1298 1304
1299 if (!pr) 1305 if (!pr)
1300 return -EINVAL; 1306 return -EINVAL;
@@ -1734,6 +1740,9 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
1734{ 1740{
1735 int ret; 1741 int ret;
1736 1742
1743 if (boot_option_idle_override)
1744 return 0;
1745
1737 if (!pr) 1746 if (!pr)
1738 return -EINVAL; 1747 return -EINVAL;
1739 1748
@@ -1764,6 +1773,8 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
1764 struct proc_dir_entry *entry = NULL; 1773 struct proc_dir_entry *entry = NULL;
1765 unsigned int i; 1774 unsigned int i;
1766 1775
1776 if (boot_option_idle_override)
1777 return 0;
1767 1778
1768 if (!first_run) { 1779 if (!first_run) {
1769 dmi_check_system(processor_power_dmi_table); 1780 dmi_check_system(processor_power_dmi_table);
@@ -1799,7 +1810,7 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
1799 * Note that we use previously set idle handler will be used on 1810 * Note that we use previously set idle handler will be used on
1800 * platforms that only support C1. 1811 * platforms that only support C1.
1801 */ 1812 */
1802 if ((pr->flags.power) && (!boot_option_idle_override)) { 1813 if (pr->flags.power) {
1803#ifdef CONFIG_CPU_IDLE 1814#ifdef CONFIG_CPU_IDLE
1804 acpi_processor_setup_cpuidle(pr); 1815 acpi_processor_setup_cpuidle(pr);
1805 pr->power.dev.cpu = pr->id; 1816 pr->power.dev.cpu = pr->id;
@@ -1835,8 +1846,11 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
1835int acpi_processor_power_exit(struct acpi_processor *pr, 1846int acpi_processor_power_exit(struct acpi_processor *pr,
1836 struct acpi_device *device) 1847 struct acpi_device *device)
1837{ 1848{
1849 if (boot_option_idle_override)
1850 return 0;
1851
1838#ifdef CONFIG_CPU_IDLE 1852#ifdef CONFIG_CPU_IDLE
1839 if ((pr->flags.power) && (!boot_option_idle_override)) 1853 if (pr->flags.power)
1840 cpuidle_unregister_device(&pr->power.dev); 1854 cpuidle_unregister_device(&pr->power.dev);
1841#endif 1855#endif
1842 pr->flags.power_setup_done = 0; 1856 pr->flags.power_setup_done = 0;
diff --git a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c
index 271e61509eeb..7f96332822bf 100644
--- a/drivers/acpi/resources/rsaddr.c
+++ b/drivers/acpi/resources/rsaddr.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c
index 0dd2ce8a3475..8a112d11d491 100644
--- a/drivers/acpi/resources/rscalc.c
+++ b/drivers/acpi/resources/rscalc.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -73,7 +73,7 @@ acpi_rs_stream_option_length(u32 resource_length, u32 minimum_total_length);
73 73
74static u8 acpi_rs_count_set_bits(u16 bit_field) 74static u8 acpi_rs_count_set_bits(u16 bit_field)
75{ 75{
76 u8 bits_set; 76 acpi_native_uint bits_set;
77 77
78 ACPI_FUNCTION_ENTRY(); 78 ACPI_FUNCTION_ENTRY();
79 79
@@ -81,10 +81,10 @@ static u8 acpi_rs_count_set_bits(u16 bit_field)
81 81
82 /* Zero the least significant bit that is set */ 82 /* Zero the least significant bit that is set */
83 83
84 bit_field &= (bit_field - 1); 84 bit_field &= (u16) (bit_field - 1);
85 } 85 }
86 86
87 return (bits_set); 87 return ((u8) bits_set);
88} 88}
89 89
90/******************************************************************************* 90/*******************************************************************************
@@ -211,6 +211,24 @@ acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed)
211 * variable-length fields 211 * variable-length fields
212 */ 212 */
213 switch (resource->type) { 213 switch (resource->type) {
214 case ACPI_RESOURCE_TYPE_IRQ:
215
216 /* Length can be 3 or 2 */
217
218 if (resource->data.irq.descriptor_length == 2) {
219 total_size--;
220 }
221 break;
222
223 case ACPI_RESOURCE_TYPE_START_DEPENDENT:
224
225 /* Length can be 1 or 0 */
226
227 if (resource->data.irq.descriptor_length == 0) {
228 total_size--;
229 }
230 break;
231
214 case ACPI_RESOURCE_TYPE_VENDOR: 232 case ACPI_RESOURCE_TYPE_VENDOR:
215 /* 233 /*
216 * Vendor Defined Resource: 234 * Vendor Defined Resource:
diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c
index 50da494c3ee2..faddaee1bc07 100644
--- a/drivers/acpi/resources/rscreate.c
+++ b/drivers/acpi/resources/rscreate.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c
index 46da116a4030..6bbbb7b8941a 100644
--- a/drivers/acpi/resources/rsdump.c
+++ b/drivers/acpi/resources/rsdump.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -87,8 +87,10 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table);
87 * 87 *
88 ******************************************************************************/ 88 ******************************************************************************/
89 89
90struct acpi_rsdump_info acpi_rs_dump_irq[6] = { 90struct acpi_rsdump_info acpi_rs_dump_irq[7] = {
91 {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_irq), "IRQ", NULL}, 91 {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_irq), "IRQ", NULL},
92 {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(irq.descriptor_length),
93 "Descriptor Length", NULL},
92 {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.triggering), "Triggering", 94 {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.triggering), "Triggering",
93 acpi_gbl_he_decode}, 95 acpi_gbl_he_decode},
94 {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.polarity), "Polarity", 96 {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.polarity), "Polarity",
@@ -115,9 +117,11 @@ struct acpi_rsdump_info acpi_rs_dump_dma[6] = {
115 NULL} 117 NULL}
116}; 118};
117 119
118struct acpi_rsdump_info acpi_rs_dump_start_dpf[3] = { 120struct acpi_rsdump_info acpi_rs_dump_start_dpf[4] = {
119 {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_start_dpf), 121 {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_start_dpf),
120 "Start-Dependent-Functions", NULL}, 122 "Start-Dependent-Functions", NULL},
123 {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(start_dpf.descriptor_length),
124 "Descriptor Length", NULL},
121 {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.compatibility_priority), 125 {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.compatibility_priority),
122 "Compatibility Priority", acpi_gbl_config_decode}, 126 "Compatibility Priority", acpi_gbl_config_decode},
123 {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.performance_robustness), 127 {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.performance_robustness),
diff --git a/drivers/acpi/resources/rsinfo.c b/drivers/acpi/resources/rsinfo.c
index 2c2adb6292c1..3f0a1fedbe0e 100644
--- a/drivers/acpi/resources/rsinfo.c
+++ b/drivers/acpi/resources/rsinfo.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rsio.c b/drivers/acpi/resources/rsio.c
index b297bc3e4419..b66d42e7402e 100644
--- a/drivers/acpi/resources/rsio.c
+++ b/drivers/acpi/resources/rsio.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -185,7 +185,7 @@ struct acpi_rsconvert_info acpi_rs_convert_end_tag[2] = {
185 * 185 *
186 ******************************************************************************/ 186 ******************************************************************************/
187 187
188struct acpi_rsconvert_info acpi_rs_get_start_dpf[5] = { 188struct acpi_rsconvert_info acpi_rs_get_start_dpf[6] = {
189 {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_START_DEPENDENT, 189 {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_START_DEPENDENT,
190 ACPI_RS_SIZE(struct acpi_resource_start_dependent), 190 ACPI_RS_SIZE(struct acpi_resource_start_dependent),
191 ACPI_RSC_TABLE_SIZE(acpi_rs_get_start_dpf)}, 191 ACPI_RSC_TABLE_SIZE(acpi_rs_get_start_dpf)},
@@ -196,6 +196,12 @@ struct acpi_rsconvert_info acpi_rs_get_start_dpf[5] = {
196 ACPI_ACCEPTABLE_CONFIGURATION, 196 ACPI_ACCEPTABLE_CONFIGURATION,
197 2}, 197 2},
198 198
199 /* Get the descriptor length (0 or 1 for Start Dpf descriptor) */
200
201 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.start_dpf.descriptor_length),
202 AML_OFFSET(start_dpf.descriptor_type),
203 0},
204
199 /* All done if there is no flag byte present in the descriptor */ 205 /* All done if there is no flag byte present in the descriptor */
200 206
201 {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 1}, 207 {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 1},
@@ -219,7 +225,9 @@ struct acpi_rsconvert_info acpi_rs_get_start_dpf[5] = {
219 * 225 *
220 ******************************************************************************/ 226 ******************************************************************************/
221 227
222struct acpi_rsconvert_info acpi_rs_set_start_dpf[6] = { 228struct acpi_rsconvert_info acpi_rs_set_start_dpf[10] = {
229 /* Start with a default descriptor of length 1 */
230
223 {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_START_DEPENDENT, 231 {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_START_DEPENDENT,
224 sizeof(struct aml_resource_start_dependent), 232 sizeof(struct aml_resource_start_dependent),
225 ACPI_RSC_TABLE_SIZE(acpi_rs_set_start_dpf)}, 233 ACPI_RSC_TABLE_SIZE(acpi_rs_set_start_dpf)},
@@ -236,6 +244,33 @@ struct acpi_rsconvert_info acpi_rs_set_start_dpf[6] = {
236 AML_OFFSET(start_dpf.flags), 244 AML_OFFSET(start_dpf.flags),
237 2}, 245 2},
238 /* 246 /*
247 * All done if the output descriptor length is required to be 1
248 * (i.e., optimization to 0 bytes cannot be attempted)
249 */
250 {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE,
251 ACPI_RS_OFFSET(data.start_dpf.descriptor_length),
252 1},
253
254 /* Set length to 0 bytes (no flags byte) */
255
256 {ACPI_RSC_LENGTH, 0, 0,
257 sizeof(struct aml_resource_start_dependent_noprio)},
258
259 /*
260 * All done if the output descriptor length is required to be 0.
261 *
262 * TBD: Perhaps we should check for error if input flags are not
263 * compatible with a 0-byte descriptor.
264 */
265 {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE,
266 ACPI_RS_OFFSET(data.start_dpf.descriptor_length),
267 0},
268
269 /* Reset length to 1 byte (descriptor with flags byte) */
270
271 {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_start_dependent)},
272
273 /*
239 * All done if flags byte is necessary -- if either priority value 274 * All done if flags byte is necessary -- if either priority value
240 * is not ACPI_ACCEPTABLE_CONFIGURATION 275 * is not ACPI_ACCEPTABLE_CONFIGURATION
241 */ 276 */
diff --git a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c
index 5657f7b95039..a8805efc0366 100644
--- a/drivers/acpi/resources/rsirq.c
+++ b/drivers/acpi/resources/rsirq.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -52,7 +52,7 @@ ACPI_MODULE_NAME("rsirq")
52 * acpi_rs_get_irq 52 * acpi_rs_get_irq
53 * 53 *
54 ******************************************************************************/ 54 ******************************************************************************/
55struct acpi_rsconvert_info acpi_rs_get_irq[7] = { 55struct acpi_rsconvert_info acpi_rs_get_irq[8] = {
56 {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_IRQ, 56 {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_IRQ,
57 ACPI_RS_SIZE(struct acpi_resource_irq), 57 ACPI_RS_SIZE(struct acpi_resource_irq),
58 ACPI_RSC_TABLE_SIZE(acpi_rs_get_irq)}, 58 ACPI_RSC_TABLE_SIZE(acpi_rs_get_irq)},
@@ -69,6 +69,12 @@ struct acpi_rsconvert_info acpi_rs_get_irq[7] = {
69 ACPI_EDGE_SENSITIVE, 69 ACPI_EDGE_SENSITIVE,
70 1}, 70 1},
71 71
72 /* Get the descriptor length (2 or 3 for IRQ descriptor) */
73
74 {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.irq.descriptor_length),
75 AML_OFFSET(irq.descriptor_type),
76 0},
77
72 /* All done if no flag byte present in descriptor */ 78 /* All done if no flag byte present in descriptor */
73 79
74 {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 3}, 80 {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 3},
@@ -94,7 +100,9 @@ struct acpi_rsconvert_info acpi_rs_get_irq[7] = {
94 * 100 *
95 ******************************************************************************/ 101 ******************************************************************************/
96 102
97struct acpi_rsconvert_info acpi_rs_set_irq[9] = { 103struct acpi_rsconvert_info acpi_rs_set_irq[13] = {
104 /* Start with a default descriptor of length 3 */
105
98 {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_IRQ, 106 {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_IRQ,
99 sizeof(struct aml_resource_irq), 107 sizeof(struct aml_resource_irq),
100 ACPI_RSC_TABLE_SIZE(acpi_rs_set_irq)}, 108 ACPI_RSC_TABLE_SIZE(acpi_rs_set_irq)},
@@ -105,7 +113,7 @@ struct acpi_rsconvert_info acpi_rs_set_irq[9] = {
105 AML_OFFSET(irq.irq_mask), 113 AML_OFFSET(irq.irq_mask),
106 ACPI_RS_OFFSET(data.irq.interrupt_count)}, 114 ACPI_RS_OFFSET(data.irq.interrupt_count)},
107 115
108 /* Set the flags byte by default */ 116 /* Set the flags byte */
109 117
110 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.triggering), 118 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.triggering),
111 AML_OFFSET(irq.flags), 119 AML_OFFSET(irq.flags),
@@ -118,6 +126,33 @@ struct acpi_rsconvert_info acpi_rs_set_irq[9] = {
118 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.sharable), 126 {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.sharable),
119 AML_OFFSET(irq.flags), 127 AML_OFFSET(irq.flags),
120 4}, 128 4},
129
130 /*
131 * All done if the output descriptor length is required to be 3
132 * (i.e., optimization to 2 bytes cannot be attempted)
133 */
134 {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE,
135 ACPI_RS_OFFSET(data.irq.descriptor_length),
136 3},
137
138 /* Set length to 2 bytes (no flags byte) */
139
140 {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq_noflags)},
141
142 /*
143 * All done if the output descriptor length is required to be 2.
144 *
145 * TBD: Perhaps we should check for error if input flags are not
146 * compatible with a 2-byte descriptor.
147 */
148 {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE,
149 ACPI_RS_OFFSET(data.irq.descriptor_length),
150 2},
151
152 /* Reset length to 3 bytes (descriptor with flags byte) */
153
154 {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq)},
155
121 /* 156 /*
122 * Check if the flags byte is necessary. Not needed if the flags are: 157 * Check if the flags byte is necessary. Not needed if the flags are:
123 * ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_HIGH, ACPI_EXCLUSIVE 158 * ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_HIGH, ACPI_EXCLUSIVE
@@ -134,7 +169,7 @@ struct acpi_rsconvert_info acpi_rs_set_irq[9] = {
134 ACPI_RS_OFFSET(data.irq.sharable), 169 ACPI_RS_OFFSET(data.irq.sharable),
135 ACPI_EXCLUSIVE}, 170 ACPI_EXCLUSIVE},
136 171
137 /* irq_no_flags() descriptor can be used */ 172 /* We can optimize to a 2-byte irq_no_flags() descriptor */
138 173
139 {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq_noflags)} 174 {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq_noflags)}
140}; 175};
diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c
index ca21e4660c79..b78c7e797a19 100644
--- a/drivers/acpi/resources/rslist.c
+++ b/drivers/acpi/resources/rslist.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rsmemory.c b/drivers/acpi/resources/rsmemory.c
index 521eab7dd8df..63b21abd90bb 100644
--- a/drivers/acpi/resources/rsmemory.c
+++ b/drivers/acpi/resources/rsmemory.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c
index c7081afa893a..de1ac3881b22 100644
--- a/drivers/acpi/resources/rsmisc.c
+++ b/drivers/acpi/resources/rsmisc.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -497,6 +497,17 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource,
497 } 497 }
498 break; 498 break;
499 499
500 case ACPI_RSC_EXIT_EQ:
501 /*
502 * Control - Exit conversion if equal
503 */
504 if (*ACPI_ADD_PTR(u8, resource,
505 COMPARE_TARGET(info)) ==
506 COMPARE_VALUE(info)) {
507 goto exit;
508 }
509 break;
510
500 default: 511 default:
501 512
502 ACPI_ERROR((AE_INFO, "Invalid conversion opcode")); 513 ACPI_ERROR((AE_INFO, "Invalid conversion opcode"));
diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c
index 11c0bd7b9cfd..befe2302f41b 100644
--- a/drivers/acpi/resources/rsutils.c
+++ b/drivers/acpi/resources/rsutils.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -97,17 +97,17 @@ u8 acpi_rs_decode_bitmask(u16 mask, u8 * list)
97u16 acpi_rs_encode_bitmask(u8 * list, u8 count) 97u16 acpi_rs_encode_bitmask(u8 * list, u8 count)
98{ 98{
99 acpi_native_uint i; 99 acpi_native_uint i;
100 u16 mask; 100 acpi_native_uint mask;
101 101
102 ACPI_FUNCTION_ENTRY(); 102 ACPI_FUNCTION_ENTRY();
103 103
104 /* Encode the list into a single bitmask */ 104 /* Encode the list into a single bitmask */
105 105
106 for (i = 0, mask = 0; i < count; i++) { 106 for (i = 0, mask = 0; i < count; i++) {
107 mask |= (0x0001 << list[i]); 107 mask |= (0x1 << list[i]);
108 } 108 }
109 109
110 return (mask); 110 return ((u16) mask);
111} 111}
112 112
113/******************************************************************************* 113/*******************************************************************************
diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c
index 4c3fd4cdaf73..f59f4c4e034c 100644
--- a/drivers/acpi/resources/rsxface.c
+++ b/drivers/acpi/resources/rsxface.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index e6ce262b5d44..6d85289f1c12 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -677,9 +677,8 @@ acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device,
677 device->wakeup.resources.count = package->package.count - 2; 677 device->wakeup.resources.count = package->package.count - 2;
678 for (i = 0; i < device->wakeup.resources.count; i++) { 678 for (i = 0; i < device->wakeup.resources.count; i++) {
679 element = &(package->package.elements[i + 2]); 679 element = &(package->package.elements[i + 2]);
680 if (element->type != ACPI_TYPE_ANY) { 680 if (element->type != ACPI_TYPE_LOCAL_REFERENCE)
681 return AE_BAD_DATA; 681 return AE_BAD_DATA;
682 }
683 682
684 device->wakeup.resources.handles[i] = element->reference.handle; 683 device->wakeup.resources.handles[i] = element->reference.handle;
685 } 684 }
@@ -692,6 +691,9 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
692 acpi_status status = 0; 691 acpi_status status = 0;
693 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 692 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
694 union acpi_object *package = NULL; 693 union acpi_object *package = NULL;
694 union acpi_object in_arg[3];
695 struct acpi_object_list arg_list = { 3, in_arg };
696 acpi_status psw_status = AE_OK;
695 697
696 struct acpi_device_id button_device_ids[] = { 698 struct acpi_device_id button_device_ids[] = {
697 {"PNP0C0D", 0}, 699 {"PNP0C0D", 0},
@@ -700,7 +702,6 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
700 {"", 0}, 702 {"", 0},
701 }; 703 };
702 704
703
704 /* _PRW */ 705 /* _PRW */
705 status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer); 706 status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer);
706 if (ACPI_FAILURE(status)) { 707 if (ACPI_FAILURE(status)) {
@@ -718,6 +719,45 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
718 kfree(buffer.pointer); 719 kfree(buffer.pointer);
719 720
720 device->wakeup.flags.valid = 1; 721 device->wakeup.flags.valid = 1;
722 /* Call _PSW/_DSW object to disable its ability to wake the sleeping
723 * system for the ACPI device with the _PRW object.
724 * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW.
725 * So it is necessary to call _DSW object first. Only when it is not
726 * present will the _PSW object used.
727 */
728 /*
729 * Three agruments are needed for the _DSW object.
730 * Argument 0: enable/disable the wake capabilities
731 * When _DSW object is called to disable the wake capabilities, maybe
732 * the first argument is filled. The value of the other two agruments
733 * is meaningless.
734 */
735 in_arg[0].type = ACPI_TYPE_INTEGER;
736 in_arg[0].integer.value = 0;
737 in_arg[1].type = ACPI_TYPE_INTEGER;
738 in_arg[1].integer.value = 0;
739 in_arg[2].type = ACPI_TYPE_INTEGER;
740 in_arg[2].integer.value = 0;
741 psw_status = acpi_evaluate_object(device->handle, "_DSW",
742 &arg_list, NULL);
743 if (ACPI_FAILURE(psw_status) && (psw_status != AE_NOT_FOUND))
744 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "error in evaluate _DSW\n"));
745 /*
746 * When the _DSW object is not present, OSPM will call _PSW object.
747 */
748 if (psw_status == AE_NOT_FOUND) {
749 /*
750 * Only one agruments is required for the _PSW object.
751 * agrument 0: enable/disable the wake capabilities
752 */
753 arg_list.count = 1;
754 in_arg[0].integer.value = 0;
755 psw_status = acpi_evaluate_object(device->handle, "_PSW",
756 &arg_list, NULL);
757 if (ACPI_FAILURE(psw_status) && (psw_status != AE_NOT_FOUND))
758 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "error in "
759 "evaluate _PSW\n"));
760 }
721 /* Power button, Lid switch always enable wakeup */ 761 /* Power button, Lid switch always enable wakeup */
722 if (!acpi_match_device_ids(device, button_device_ids)) 762 if (!acpi_match_device_ids(device, button_device_ids))
723 device->wakeup.flags.run_wake = 1; 763 device->wakeup.flags.run_wake = 1;
@@ -882,10 +922,7 @@ static void acpi_device_get_busid(struct acpi_device *device,
882static int 922static int
883acpi_video_bus_match(struct acpi_device *device) 923acpi_video_bus_match(struct acpi_device *device)
884{ 924{
885 acpi_handle h_dummy1; 925 acpi_handle h_dummy;
886 acpi_handle h_dummy2;
887 acpi_handle h_dummy3;
888
889 926
890 if (!device) 927 if (!device)
891 return -EINVAL; 928 return -EINVAL;
@@ -895,18 +932,18 @@ acpi_video_bus_match(struct acpi_device *device)
895 */ 932 */
896 933
897 /* Does this device able to support video switching ? */ 934 /* Does this device able to support video switching ? */
898 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy1)) && 935 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) &&
899 ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy2))) 936 ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy)))
900 return 0; 937 return 0;
901 938
902 /* Does this device able to retrieve a video ROM ? */ 939 /* Does this device able to retrieve a video ROM ? */
903 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy1))) 940 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy)))
904 return 0; 941 return 0;
905 942
906 /* Does this device able to configure which video head to be POSTed ? */ 943 /* Does this device able to configure which video head to be POSTed ? */
907 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy1)) && 944 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy)) &&
908 ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy2)) && 945 ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy)) &&
909 ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy3))) 946 ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy)))
910 return 0; 947 return 0;
911 948
912 return -ENODEV; 949 return -ENODEV;
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index 71183eea7906..c3b0cd88d09f 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -51,7 +51,7 @@ static int acpi_sleep_prepare(u32 acpi_state)
51} 51}
52 52
53#ifdef CONFIG_SUSPEND 53#ifdef CONFIG_SUSPEND
54static struct platform_suspend_ops acpi_pm_ops; 54static struct platform_suspend_ops acpi_suspend_ops;
55 55
56extern void do_suspend_lowlevel(void); 56extern void do_suspend_lowlevel(void);
57 57
@@ -65,11 +65,11 @@ static u32 acpi_suspend_states[] = {
65static int init_8259A_after_S1; 65static int init_8259A_after_S1;
66 66
67/** 67/**
68 * acpi_pm_begin - Set the target system sleep state to the state 68 * acpi_suspend_begin - Set the target system sleep state to the state
69 * associated with given @pm_state, if supported. 69 * associated with given @pm_state, if supported.
70 */ 70 */
71 71
72static int acpi_pm_begin(suspend_state_t pm_state) 72static int acpi_suspend_begin(suspend_state_t pm_state)
73{ 73{
74 u32 acpi_state = acpi_suspend_states[pm_state]; 74 u32 acpi_state = acpi_suspend_states[pm_state];
75 int error = 0; 75 int error = 0;
@@ -85,13 +85,13 @@ static int acpi_pm_begin(suspend_state_t pm_state)
85} 85}
86 86
87/** 87/**
88 * acpi_pm_prepare - Do preliminary suspend work. 88 * acpi_suspend_prepare - Do preliminary suspend work.
89 * 89 *
90 * If necessary, set the firmware waking vector and do arch-specific 90 * If necessary, set the firmware waking vector and do arch-specific
91 * nastiness to get the wakeup code to the waking vector. 91 * nastiness to get the wakeup code to the waking vector.
92 */ 92 */
93 93
94static int acpi_pm_prepare(void) 94static int acpi_suspend_prepare(void)
95{ 95{
96 int error = acpi_sleep_prepare(acpi_target_sleep_state); 96 int error = acpi_sleep_prepare(acpi_target_sleep_state);
97 97
@@ -104,7 +104,7 @@ static int acpi_pm_prepare(void)
104} 104}
105 105
106/** 106/**
107 * acpi_pm_enter - Actually enter a sleep state. 107 * acpi_suspend_enter - Actually enter a sleep state.
108 * @pm_state: ignored 108 * @pm_state: ignored
109 * 109 *
110 * Flush caches and go to sleep. For STR we have to call arch-specific 110 * Flush caches and go to sleep. For STR we have to call arch-specific
@@ -112,7 +112,7 @@ static int acpi_pm_prepare(void)
112 * It's unfortunate, but it works. Please fix if you're feeling frisky. 112 * It's unfortunate, but it works. Please fix if you're feeling frisky.
113 */ 113 */
114 114
115static int acpi_pm_enter(suspend_state_t pm_state) 115static int acpi_suspend_enter(suspend_state_t pm_state)
116{ 116{
117 acpi_status status = AE_OK; 117 acpi_status status = AE_OK;
118 unsigned long flags = 0; 118 unsigned long flags = 0;
@@ -169,13 +169,13 @@ static int acpi_pm_enter(suspend_state_t pm_state)
169} 169}
170 170
171/** 171/**
172 * acpi_pm_finish - Instruct the platform to leave a sleep state. 172 * acpi_suspend_finish - Instruct the platform to leave a sleep state.
173 * 173 *
174 * This is called after we wake back up (or if entering the sleep state 174 * This is called after we wake back up (or if entering the sleep state
175 * failed). 175 * failed).
176 */ 176 */
177 177
178static void acpi_pm_finish(void) 178static void acpi_suspend_finish(void)
179{ 179{
180 u32 acpi_state = acpi_target_sleep_state; 180 u32 acpi_state = acpi_target_sleep_state;
181 181
@@ -196,19 +196,19 @@ static void acpi_pm_finish(void)
196} 196}
197 197
198/** 198/**
199 * acpi_pm_end - Finish up suspend sequence. 199 * acpi_suspend_end - Finish up suspend sequence.
200 */ 200 */
201 201
202static void acpi_pm_end(void) 202static void acpi_suspend_end(void)
203{ 203{
204 /* 204 /*
205 * This is necessary in case acpi_pm_finish() is not called during a 205 * This is necessary in case acpi_suspend_finish() is not called during a
206 * failing transition to a sleep state. 206 * failing transition to a sleep state.
207 */ 207 */
208 acpi_target_sleep_state = ACPI_STATE_S0; 208 acpi_target_sleep_state = ACPI_STATE_S0;
209} 209}
210 210
211static int acpi_pm_state_valid(suspend_state_t pm_state) 211static int acpi_suspend_state_valid(suspend_state_t pm_state)
212{ 212{
213 u32 acpi_state; 213 u32 acpi_state;
214 214
@@ -224,13 +224,13 @@ static int acpi_pm_state_valid(suspend_state_t pm_state)
224 } 224 }
225} 225}
226 226
227static struct platform_suspend_ops acpi_pm_ops = { 227static struct platform_suspend_ops acpi_suspend_ops = {
228 .valid = acpi_pm_state_valid, 228 .valid = acpi_suspend_state_valid,
229 .begin = acpi_pm_begin, 229 .begin = acpi_suspend_begin,
230 .prepare = acpi_pm_prepare, 230 .prepare = acpi_suspend_prepare,
231 .enter = acpi_pm_enter, 231 .enter = acpi_suspend_enter,
232 .finish = acpi_pm_finish, 232 .finish = acpi_suspend_finish,
233 .end = acpi_pm_end, 233 .end = acpi_suspend_end,
234}; 234};
235 235
236/* 236/*
@@ -492,7 +492,7 @@ int __init acpi_sleep_init(void)
492 } 492 }
493 } 493 }
494 494
495 suspend_set_ops(&acpi_pm_ops); 495 suspend_set_ops(&acpi_suspend_ops);
496#endif 496#endif
497 497
498#ifdef CONFIG_HIBERNATION 498#ifdef CONFIG_HIBERNATION
diff --git a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/tables/tbfadt.c
index 002bb33003af..949d4114eb9f 100644
--- a/drivers/acpi/tables/tbfadt.c
+++ b/drivers/acpi/tables/tbfadt.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/tables/tbfind.c b/drivers/acpi/tables/tbfind.c
index 058c064948e1..9ca3afc98c80 100644
--- a/drivers/acpi/tables/tbfind.c
+++ b/drivers/acpi/tables/tbfind.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -70,12 +70,22 @@ acpi_tb_find_table(char *signature,
70{ 70{
71 acpi_native_uint i; 71 acpi_native_uint i;
72 acpi_status status; 72 acpi_status status;
73 struct acpi_table_header header;
73 74
74 ACPI_FUNCTION_TRACE(tb_find_table); 75 ACPI_FUNCTION_TRACE(tb_find_table);
75 76
77 /* Normalize the input strings */
78
79 ACPI_MEMSET(&header, 0, sizeof(struct acpi_table_header));
80 ACPI_STRNCPY(header.signature, signature, ACPI_NAME_SIZE);
81 ACPI_STRNCPY(header.oem_id, oem_id, ACPI_OEM_ID_SIZE);
82 ACPI_STRNCPY(header.oem_table_id, oem_table_id, ACPI_OEM_TABLE_ID_SIZE);
83
84 /* Search for the table */
85
76 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { 86 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
77 if (ACPI_MEMCMP(&(acpi_gbl_root_table_list.tables[i].signature), 87 if (ACPI_MEMCMP(&(acpi_gbl_root_table_list.tables[i].signature),
78 signature, ACPI_NAME_SIZE)) { 88 header.signature, ACPI_NAME_SIZE)) {
79 89
80 /* Not the requested table */ 90 /* Not the requested table */
81 91
@@ -104,20 +114,24 @@ acpi_tb_find_table(char *signature,
104 114
105 if (!ACPI_MEMCMP 115 if (!ACPI_MEMCMP
106 (acpi_gbl_root_table_list.tables[i].pointer->signature, 116 (acpi_gbl_root_table_list.tables[i].pointer->signature,
107 signature, ACPI_NAME_SIZE) && (!oem_id[0] 117 header.signature, ACPI_NAME_SIZE) && (!oem_id[0]
108 || 118 ||
109 !ACPI_MEMCMP 119 !ACPI_MEMCMP
110 (acpi_gbl_root_table_list. 120 (acpi_gbl_root_table_list.
111 tables[i].pointer->oem_id, 121 tables[i].pointer->
112 oem_id, ACPI_OEM_ID_SIZE)) 122 oem_id,
123 header.oem_id,
124 ACPI_OEM_ID_SIZE))
113 && (!oem_table_id[0] 125 && (!oem_table_id[0]
114 || !ACPI_MEMCMP(acpi_gbl_root_table_list.tables[i]. 126 || !ACPI_MEMCMP(acpi_gbl_root_table_list.tables[i].
115 pointer->oem_table_id, oem_table_id, 127 pointer->oem_table_id,
128 header.oem_table_id,
116 ACPI_OEM_TABLE_ID_SIZE))) { 129 ACPI_OEM_TABLE_ID_SIZE))) {
117 *table_index = i; 130 *table_index = i;
118 131
119 ACPI_DEBUG_PRINT((ACPI_DB_TABLES, 132 ACPI_DEBUG_PRINT((ACPI_DB_TABLES,
120 "Found table [%4.4s]\n", signature)); 133 "Found table [%4.4s]\n",
134 header.signature));
121 return_ACPI_STATUS(AE_OK); 135 return_ACPI_STATUS(AE_OK);
122 } 136 }
123 } 137 }
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c
index 3bc0c67a9283..402f93e1ff20 100644
--- a/drivers/acpi/tables/tbinstal.c
+++ b/drivers/acpi/tables/tbinstal.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -125,13 +125,20 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc,
125 125
126 /* The table must be either an SSDT or a PSDT or an OEMx */ 126 /* The table must be either an SSDT or a PSDT or an OEMx */
127 127
128 if ((!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_PSDT)) 128 if (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_PSDT)&&
129 && 129 !ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT)&&
130 (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT)) 130 strncmp(table_desc->pointer->signature, "OEM", 3)) {
131 && (strncmp(table_desc->pointer->signature, "OEM", 3))) { 131 /* Check for a printable name */
132 ACPI_ERROR((AE_INFO, 132 if (acpi_ut_valid_acpi_name(
133 "Table has invalid signature [%4.4s], must be SSDT, PSDT or OEMx", 133 *(u32 *) table_desc->pointer->signature)) {
134 table_desc->pointer->signature)); 134 ACPI_ERROR((AE_INFO, "Table has invalid signature "
135 "[%4.4s], must be SSDT or PSDT",
136 table_desc->pointer->signature));
137 } else {
138 ACPI_ERROR((AE_INFO, "Table has invalid signature "
139 "(0x%8.8X), must be SSDT or PSDT",
140 *(u32 *) table_desc->pointer->signature));
141 }
135 return_ACPI_STATUS(AE_BAD_SIGNATURE); 142 return_ACPI_STATUS(AE_BAD_SIGNATURE);
136 } 143 }
137 144
@@ -162,6 +169,7 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc,
162 169
163 acpi_tb_delete_table(table_desc); 170 acpi_tb_delete_table(table_desc);
164 *table_index = i; 171 *table_index = i;
172 status = AE_ALREADY_EXISTS;
165 goto release; 173 goto release;
166 } 174 }
167 175
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c
index 010f19652f80..bc019b9b6a68 100644
--- a/drivers/acpi/tables/tbutils.c
+++ b/drivers/acpi/tables/tbutils.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -212,7 +212,7 @@ acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length)
212 212
213 if (checksum) { 213 if (checksum) {
214 ACPI_WARNING((AE_INFO, 214 ACPI_WARNING((AE_INFO,
215 "Incorrect checksum in table [%4.4s] - %2.2X, should be %2.2X", 215 "Incorrect checksum in table [%4.4s] - %2.2X, should be %2.2X",
216 table->signature, table->checksum, 216 table->signature, table->checksum,
217 (u8) (table->checksum - checksum))); 217 (u8) (table->checksum - checksum)));
218 218
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c
index a9e3331fee5d..fb57b93c2495 100644
--- a/drivers/acpi/tables/tbxface.c
+++ b/drivers/acpi/tables/tbxface.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2007, R. Byron Moore 9 * Copyright (C) 2000 - 2008, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -635,6 +635,95 @@ acpi_status acpi_load_tables(void)
635ACPI_EXPORT_SYMBOL(acpi_load_tables) 635ACPI_EXPORT_SYMBOL(acpi_load_tables)
636 636
637 637
638/*******************************************************************************
639 *
640 * FUNCTION: acpi_install_table_handler
641 *
642 * PARAMETERS: Handler - Table event handler
643 * Context - Value passed to the handler on each event
644 *
645 * RETURN: Status
646 *
647 * DESCRIPTION: Install table event handler
648 *
649 ******************************************************************************/
650acpi_status
651acpi_install_table_handler(acpi_tbl_handler handler, void *context)
652{
653 acpi_status status;
654
655 ACPI_FUNCTION_TRACE(acpi_install_table_handler);
656
657 if (!handler) {
658 return_ACPI_STATUS(AE_BAD_PARAMETER);
659 }
660
661 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
662 if (ACPI_FAILURE(status)) {
663 return_ACPI_STATUS(status);
664 }
665
666 /* Don't allow more than one handler */
667
668 if (acpi_gbl_table_handler) {
669 status = AE_ALREADY_EXISTS;
670 goto cleanup;
671 }
672
673 /* Install the handler */
674
675 acpi_gbl_table_handler = handler;
676 acpi_gbl_table_handler_context = context;
677
678 cleanup:
679 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
680 return_ACPI_STATUS(status);
681}
682
683ACPI_EXPORT_SYMBOL(acpi_install_table_handler)
684
685/*******************************************************************************
686 *
687 * FUNCTION: acpi_remove_table_handler
688 *
689 * PARAMETERS: Handler - Table event handler that was installed
690 * previously.
691 *
692 * RETURN: Status
693 *
694 * DESCRIPTION: Remove table event handler
695 *
696 ******************************************************************************/
697acpi_status acpi_remove_table_handler(acpi_tbl_handler handler)
698{
699 acpi_status status;
700
701 ACPI_FUNCTION_TRACE(acpi_remove_table_handler);
702
703 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
704 if (ACPI_FAILURE(status)) {
705 return_ACPI_STATUS(status);
706 }
707
708 /* Make sure that the installed handler is the same */
709
710 if (!handler || handler != acpi_gbl_table_handler) {
711 status = AE_BAD_PARAMETER;
712 goto cleanup;
713 }
714
715 /* Remove the handler */
716
717 acpi_gbl_table_handler = NULL;
718
719 cleanup:
720 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
721 return_ACPI_STATUS(status);
722}
723
724ACPI_EXPORT_SYMBOL(acpi_remove_table_handler)
725
726
638static int __init acpi_no_auto_ssdt_setup(char *s) { 727static int __init acpi_no_auto_ssdt_setup(char *s) {
639 728
640 printk(KERN_NOTICE "ACPI: SSDT auto-load disabled\n"); 729 printk(KERN_NOTICE "ACPI: SSDT auto-load disabled\n");
diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c
index 9ecb4b6c1e7d..b8c0dfa084f6 100644
--- a/drivers/acpi/tables/tbxfroot.c
+++ b/drivers/acpi/tables/tbxfroot.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 0815ac3ae3d6..504385b1f211 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -889,10 +889,15 @@ static void acpi_thermal_check(void *data)
889static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf) 889static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf)
890{ 890{
891 struct acpi_thermal *tz = thermal->devdata; 891 struct acpi_thermal *tz = thermal->devdata;
892 int result;
892 893
893 if (!tz) 894 if (!tz)
894 return -EINVAL; 895 return -EINVAL;
895 896
897 result = acpi_thermal_get_temperature(tz);
898 if (result)
899 return result;
900
896 return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(tz->temperature)); 901 return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(tz->temperature));
897} 902}
898 903
@@ -1017,6 +1022,18 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
1017 return -EINVAL; 1022 return -EINVAL;
1018} 1023}
1019 1024
1025static int thermal_get_crit_temp(struct thermal_zone_device *thermal,
1026 unsigned long *temperature) {
1027 struct acpi_thermal *tz = thermal->devdata;
1028
1029 if (tz->trips.critical.flags.valid) {
1030 *temperature = KELVIN_TO_MILLICELSIUS(
1031 tz->trips.critical.temperature);
1032 return 0;
1033 } else
1034 return -EINVAL;
1035}
1036
1020typedef int (*cb)(struct thermal_zone_device *, int, 1037typedef int (*cb)(struct thermal_zone_device *, int,
1021 struct thermal_cooling_device *); 1038 struct thermal_cooling_device *);
1022static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, 1039static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
@@ -1108,6 +1125,7 @@ static struct thermal_zone_device_ops acpi_thermal_zone_ops = {
1108 .set_mode = thermal_set_mode, 1125 .set_mode = thermal_set_mode,
1109 .get_trip_type = thermal_get_trip_type, 1126 .get_trip_type = thermal_get_trip_type,
1110 .get_trip_temp = thermal_get_trip_temp, 1127 .get_trip_temp = thermal_get_trip_temp,
1128 .get_crit_temp = thermal_get_crit_temp,
1111}; 1129};
1112 1130
1113static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) 1131static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
@@ -1128,7 +1146,7 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
1128 1146
1129 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && 1147 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
1130 tz->trips.active[i].flags.valid; i++, trips++); 1148 tz->trips.active[i].flags.valid; i++, trips++);
1131 tz->thermal_zone = thermal_zone_device_register("ACPI thermal zone", 1149 tz->thermal_zone = thermal_zone_device_register("acpitz",
1132 trips, tz, &acpi_thermal_zone_ops); 1150 trips, tz, &acpi_thermal_zone_ops);
1133 if (IS_ERR(tz->thermal_zone)) 1151 if (IS_ERR(tz->thermal_zone))
1134 return -ENODEV; 1152 return -ENODEV;
diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c
index 6e56d5f7c43a..ede084829a70 100644
--- a/drivers/acpi/utilities/utalloc.c
+++ b/drivers/acpi/utilities/utalloc.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -147,7 +147,7 @@ acpi_status acpi_ut_delete_caches(void)
147 147
148 if (acpi_gbl_display_final_mem_stats) { 148 if (acpi_gbl_display_final_mem_stats) {
149 ACPI_STRCPY(buffer, "MEMORY"); 149 ACPI_STRCPY(buffer, "MEMORY");
150 acpi_db_display_statistics(buffer); 150 (void)acpi_db_display_statistics(buffer);
151 } 151 }
152#endif 152#endif
153 153
diff --git a/drivers/acpi/utilities/utcache.c b/drivers/acpi/utilities/utcache.c
index 285a0f531760..245fa80cf600 100644
--- a/drivers/acpi/utilities/utcache.c
+++ b/drivers/acpi/utilities/utcache.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c
index 879eaa10d3ae..655c290aca7b 100644
--- a/drivers/acpi/utilities/utcopy.c
+++ b/drivers/acpi/utilities/utcopy.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -43,6 +43,8 @@
43 43
44#include <acpi/acpi.h> 44#include <acpi/acpi.h>
45#include <acpi/amlcode.h> 45#include <acpi/amlcode.h>
46#include <acpi/acnamesp.h>
47
46 48
47#define _COMPONENT ACPI_UTILITIES 49#define _COMPONENT ACPI_UTILITIES
48ACPI_MODULE_NAME("utcopy") 50ACPI_MODULE_NAME("utcopy")
@@ -172,22 +174,21 @@ acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
172 174
173 case ACPI_TYPE_LOCAL_REFERENCE: 175 case ACPI_TYPE_LOCAL_REFERENCE:
174 176
175 /* 177 /* This is an object reference. */
176 * This is an object reference. Attempt to dereference it. 178
177 */
178 switch (internal_object->reference.opcode) { 179 switch (internal_object->reference.opcode) {
179 case AML_INT_NAMEPATH_OP: 180 case AML_INT_NAMEPATH_OP:
180 181
181 /* For namepath, return the object handle ("reference") */ 182 /* For namepath, return the object handle ("reference") */
182 183
183 default: 184 default:
184 /* 185
185 * Use the object type of "Any" to indicate a reference 186 /* We are referring to the namespace node */
186 * to object containing a handle to an ACPI named object. 187
187 */
188 external_object->type = ACPI_TYPE_ANY;
189 external_object->reference.handle = 188 external_object->reference.handle =
190 internal_object->reference.node; 189 internal_object->reference.node;
190 external_object->reference.actual_type =
191 acpi_ns_get_type(internal_object->reference.node);
191 break; 192 break;
192 } 193 }
193 break; 194 break;
@@ -215,6 +216,11 @@ acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
215 /* 216 /*
216 * There is no corresponding external object type 217 * There is no corresponding external object type
217 */ 218 */
219 ACPI_ERROR((AE_INFO,
220 "Unsupported object type, cannot convert to external object: %s",
221 acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE
222 (internal_object))));
223
218 return_ACPI_STATUS(AE_SUPPORT); 224 return_ACPI_STATUS(AE_SUPPORT);
219 } 225 }
220 226
@@ -455,6 +461,7 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object,
455 case ACPI_TYPE_STRING: 461 case ACPI_TYPE_STRING:
456 case ACPI_TYPE_BUFFER: 462 case ACPI_TYPE_BUFFER:
457 case ACPI_TYPE_INTEGER: 463 case ACPI_TYPE_INTEGER:
464 case ACPI_TYPE_LOCAL_REFERENCE:
458 465
459 internal_object = acpi_ut_create_internal_object((u8) 466 internal_object = acpi_ut_create_internal_object((u8)
460 external_object-> 467 external_object->
@@ -464,9 +471,18 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object,
464 } 471 }
465 break; 472 break;
466 473
474 case ACPI_TYPE_ANY: /* This is the case for a NULL object */
475
476 *ret_internal_object = NULL;
477 return_ACPI_STATUS(AE_OK);
478
467 default: 479 default:
468 /* All other types are not supported */ 480 /* All other types are not supported */
469 481
482 ACPI_ERROR((AE_INFO,
483 "Unsupported object type, cannot convert to internal object: %s",
484 acpi_ut_get_type_name(external_object->type)));
485
470 return_ACPI_STATUS(AE_SUPPORT); 486 return_ACPI_STATUS(AE_SUPPORT);
471 } 487 }
472 488
@@ -502,6 +518,10 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object,
502 external_object->buffer.length); 518 external_object->buffer.length);
503 519
504 internal_object->buffer.length = external_object->buffer.length; 520 internal_object->buffer.length = external_object->buffer.length;
521
522 /* Mark buffer data valid */
523
524 internal_object->buffer.flags |= AOPOBJ_DATA_VALID;
505 break; 525 break;
506 526
507 case ACPI_TYPE_INTEGER: 527 case ACPI_TYPE_INTEGER:
@@ -509,6 +529,15 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object,
509 internal_object->integer.value = external_object->integer.value; 529 internal_object->integer.value = external_object->integer.value;
510 break; 530 break;
511 531
532 case ACPI_TYPE_LOCAL_REFERENCE:
533
534 /* TBD: should validate incoming handle */
535
536 internal_object->reference.opcode = AML_INT_NAMEPATH_OP;
537 internal_object->reference.node =
538 external_object->reference.handle;
539 break;
540
512 default: 541 default:
513 /* Other types can't get here */ 542 /* Other types can't get here */
514 break; 543 break;
@@ -570,13 +599,17 @@ acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,
570 599
571 /* Truncate package and delete it */ 600 /* Truncate package and delete it */
572 601
573 package_object->package.count = i; 602 package_object->package.count = (u32) i;
574 package_elements[i] = NULL; 603 package_elements[i] = NULL;
575 acpi_ut_remove_reference(package_object); 604 acpi_ut_remove_reference(package_object);
576 return_ACPI_STATUS(status); 605 return_ACPI_STATUS(status);
577 } 606 }
578 } 607 }
579 608
609 /* Mark package data valid */
610
611 package_object->package.flags |= AOPOBJ_DATA_VALID;
612
580 *internal_object = package_object; 613 *internal_object = package_object;
581 return_ACPI_STATUS(status); 614 return_ACPI_STATUS(status);
582} 615}
@@ -709,7 +742,15 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
709 /* 742 /*
710 * We copied the reference object, so we now must add a reference 743 * We copied the reference object, so we now must add a reference
711 * to the object pointed to by the reference 744 * to the object pointed to by the reference
745 *
746 * DDBHandle reference (from Load/load_table is a special reference,
747 * it's Reference.Object is the table index, so does not need to
748 * increase the reference count
712 */ 749 */
750 if (source_desc->reference.opcode == AML_LOAD_OP) {
751 break;
752 }
753
713 acpi_ut_add_reference(source_desc->reference.object); 754 acpi_ut_add_reference(source_desc->reference.object);
714 break; 755 break;
715 756
diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c
index 7361204b1eef..f938f465efa4 100644
--- a/drivers/acpi/utilities/utdebug.c
+++ b/drivers/acpi/utilities/utdebug.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -68,9 +68,9 @@ static const char *acpi_ut_trim_function_name(const char *function_name);
68 68
69void acpi_ut_init_stack_ptr_trace(void) 69void acpi_ut_init_stack_ptr_trace(void)
70{ 70{
71 u32 current_sp; 71 acpi_size current_sp;
72 72
73 acpi_gbl_entry_stack_pointer = ACPI_PTR_DIFF(&current_sp, NULL); 73 acpi_gbl_entry_stack_pointer = &current_sp;
74} 74}
75 75
76/******************************************************************************* 76/*******************************************************************************
@@ -89,10 +89,8 @@ void acpi_ut_track_stack_ptr(void)
89{ 89{
90 acpi_size current_sp; 90 acpi_size current_sp;
91 91
92 current_sp = ACPI_PTR_DIFF(&current_sp, NULL); 92 if (&current_sp < acpi_gbl_lowest_stack_pointer) {
93 93 acpi_gbl_lowest_stack_pointer = &current_sp;
94 if (current_sp < acpi_gbl_lowest_stack_pointer) {
95 acpi_gbl_lowest_stack_pointer = current_sp;
96 } 94 }
97 95
98 if (acpi_gbl_nesting_level > acpi_gbl_deepest_nesting) { 96 if (acpi_gbl_nesting_level > acpi_gbl_deepest_nesting) {
@@ -203,6 +201,7 @@ acpi_ut_debug_print(u32 requested_debug_level,
203 201
204 va_start(args, format); 202 va_start(args, format);
205 acpi_os_vprintf(format, args); 203 acpi_os_vprintf(format, args);
204 va_end(args);
206} 205}
207 206
208ACPI_EXPORT_SYMBOL(acpi_ut_debug_print) 207ACPI_EXPORT_SYMBOL(acpi_ut_debug_print)
@@ -240,6 +239,7 @@ acpi_ut_debug_print_raw(u32 requested_debug_level,
240 239
241 va_start(args, format); 240 va_start(args, format);
242 acpi_os_vprintf(format, args); 241 acpi_os_vprintf(format, args);
242 va_end(args);
243} 243}
244 244
245ACPI_EXPORT_SYMBOL(acpi_ut_debug_print_raw) 245ACPI_EXPORT_SYMBOL(acpi_ut_debug_print_raw)
@@ -524,6 +524,11 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display)
524 u32 temp32; 524 u32 temp32;
525 u8 buf_char; 525 u8 buf_char;
526 526
527 if (!buffer) {
528 acpi_os_printf("Null Buffer Pointer in DumpBuffer!\n");
529 return;
530 }
531
527 if ((count < 4) || (count & 0x01)) { 532 if ((count < 4) || (count & 0x01)) {
528 display = DB_BYTE_DISPLAY; 533 display = DB_BYTE_DISPLAY;
529 } 534 }
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
index f777cebdc46d..1fbc35139e84 100644
--- a/drivers/acpi/utilities/utdelete.c
+++ b/drivers/acpi/utilities/utdelete.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -158,7 +158,7 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
158 "***** Mutex %p, OS Mutex %p\n", 158 "***** Mutex %p, OS Mutex %p\n",
159 object, object->mutex.os_mutex)); 159 object, object->mutex.os_mutex));
160 160
161 if (object->mutex.os_mutex == acpi_gbl_global_lock_mutex) { 161 if (object == acpi_gbl_global_lock_mutex) {
162 162
163 /* Global Lock has extra semaphore */ 163 /* Global Lock has extra semaphore */
164 164
@@ -252,6 +252,17 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
252 } 252 }
253 break; 253 break;
254 254
255 case ACPI_TYPE_LOCAL_BANK_FIELD:
256
257 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
258 "***** Bank Field %p\n", object));
259
260 second_desc = acpi_ns_get_secondary_object(object);
261 if (second_desc) {
262 acpi_ut_delete_object_desc(second_desc);
263 }
264 break;
265
255 default: 266 default:
256 break; 267 break;
257 } 268 }
@@ -524,10 +535,12 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
524 535
525 case ACPI_TYPE_LOCAL_REFERENCE: 536 case ACPI_TYPE_LOCAL_REFERENCE:
526 /* 537 /*
527 * The target of an Index (a package, string, or buffer) must track 538 * The target of an Index (a package, string, or buffer) or a named
528 * changes to the ref count of the index. 539 * reference must track changes to the ref count of the index or
540 * target object.
529 */ 541 */
530 if (object->reference.opcode == AML_INDEX_OP) { 542 if ((object->reference.opcode == AML_INDEX_OP) ||
543 (object->reference.opcode == AML_INT_NAMEPATH_OP)) {
531 next_object = object->reference.object; 544 next_object = object->reference.object;
532 } 545 }
533 break; 546 break;
diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c
index 0042b7e78b26..05e61be267d5 100644
--- a/drivers/acpi/utilities/uteval.c
+++ b/drivers/acpi/utilities/uteval.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
index 630c9a2c5b7b..a6e71b801d2d 100644
--- a/drivers/acpi/utilities/utglobal.c
+++ b/drivers/acpi/utilities/utglobal.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -602,6 +602,48 @@ char *acpi_ut_get_mutex_name(u32 mutex_id)
602 602
603 return (acpi_gbl_mutex_names[mutex_id]); 603 return (acpi_gbl_mutex_names[mutex_id]);
604} 604}
605
606/*******************************************************************************
607 *
608 * FUNCTION: acpi_ut_get_notify_name
609 *
610 * PARAMETERS: notify_value - Value from the Notify() request
611 *
612 * RETURN: String corresponding to the Notify Value.
613 *
614 * DESCRIPTION: Translate a Notify Value to a notify namestring.
615 *
616 ******************************************************************************/
617
618/* Names for Notify() values, used for debug output */
619
620static const char *acpi_gbl_notify_value_names[] = {
621 "Bus Check",
622 "Device Check",
623 "Device Wake",
624 "Eject Request",
625 "Device Check Light",
626 "Frequency Mismatch",
627 "Bus Mode Mismatch",
628 "Power Fault",
629 "Capabilities Check",
630 "Device PLD Check",
631 "Reserved",
632 "System Locality Update"
633};
634
635const char *acpi_ut_get_notify_name(u32 notify_value)
636{
637
638 if (notify_value <= ACPI_NOTIFY_MAX) {
639 return (acpi_gbl_notify_value_names[notify_value]);
640 } else if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
641 return ("Reserved");
642 } else { /* Greater or equal to 0x80 */
643
644 return ("**Device Specific**");
645 }
646}
605#endif 647#endif
606 648
607/******************************************************************************* 649/*******************************************************************************
@@ -675,12 +717,13 @@ void acpi_ut_init_globals(void)
675 acpi_gbl_gpe_fadt_blocks[0] = NULL; 717 acpi_gbl_gpe_fadt_blocks[0] = NULL;
676 acpi_gbl_gpe_fadt_blocks[1] = NULL; 718 acpi_gbl_gpe_fadt_blocks[1] = NULL;
677 719
678 /* Global notify handlers */ 720 /* Global handlers */
679 721
680 acpi_gbl_system_notify.handler = NULL; 722 acpi_gbl_system_notify.handler = NULL;
681 acpi_gbl_device_notify.handler = NULL; 723 acpi_gbl_device_notify.handler = NULL;
682 acpi_gbl_exception_handler = NULL; 724 acpi_gbl_exception_handler = NULL;
683 acpi_gbl_init_handler = NULL; 725 acpi_gbl_init_handler = NULL;
726 acpi_gbl_table_handler = NULL;
684 727
685 /* Global Lock support */ 728 /* Global Lock support */
686 729
@@ -722,7 +765,7 @@ void acpi_ut_init_globals(void)
722 acpi_gbl_root_node_struct.flags = ANOBJ_END_OF_PEER_LIST; 765 acpi_gbl_root_node_struct.flags = ANOBJ_END_OF_PEER_LIST;
723 766
724#ifdef ACPI_DEBUG_OUTPUT 767#ifdef ACPI_DEBUG_OUTPUT
725 acpi_gbl_lowest_stack_pointer = ACPI_SIZE_MAX; 768 acpi_gbl_lowest_stack_pointer = ACPI_CAST_PTR(acpi_size, ACPI_SIZE_MAX);
726#endif 769#endif
727 770
728#ifdef ACPI_DBG_TRACK_ALLOCATIONS 771#ifdef ACPI_DBG_TRACK_ALLOCATIONS
diff --git a/drivers/acpi/utilities/utinit.c b/drivers/acpi/utilities/utinit.c
index ad3c0d0a5cf8..cae515fc02d3 100644
--- a/drivers/acpi/utilities/utinit.c
+++ b/drivers/acpi/utilities/utinit.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -125,9 +125,12 @@ void acpi_ut_subsystem_shutdown(void)
125 acpi_gbl_startup_flags = 0; 125 acpi_gbl_startup_flags = 0;
126 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n")); 126 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n"));
127 127
128#ifndef ACPI_ASL_COMPILER
129
128 /* Close the acpi_event Handling */ 130 /* Close the acpi_event Handling */
129 131
130 acpi_ev_terminate(); 132 acpi_ev_terminate();
133#endif
131 134
132 /* Close the Namespace */ 135 /* Close the Namespace */
133 136
diff --git a/drivers/acpi/utilities/utmath.c b/drivers/acpi/utilities/utmath.c
index 0c56a0d20b29..c927324fdd26 100644
--- a/drivers/acpi/utilities/utmath.c
+++ b/drivers/acpi/utilities/utmath.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -276,7 +276,7 @@ acpi_ut_short_divide(acpi_integer in_dividend,
276 *out_quotient = in_dividend / divisor; 276 *out_quotient = in_dividend / divisor;
277 } 277 }
278 if (out_remainder) { 278 if (out_remainder) {
279 *out_remainder = (u32) in_dividend % divisor; 279 *out_remainder = (u32) (in_dividend % divisor);
280 } 280 }
281 281
282 return_ACPI_STATUS(AE_OK); 282 return_ACPI_STATUS(AE_OK);
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
index 2d19f71e9cfa..e4ba7192cd15 100644
--- a/drivers/acpi/utilities/utmisc.c
+++ b/drivers/acpi/utilities/utmisc.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -1033,6 +1033,7 @@ acpi_ut_error(char *module_name, u32 line_number, char *format, ...)
1033 va_start(args, format); 1033 va_start(args, format);
1034 acpi_os_vprintf(format, args); 1034 acpi_os_vprintf(format, args);
1035 acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); 1035 acpi_os_printf(" [%X]\n", ACPI_CA_VERSION);
1036 va_end(args);
1036} 1037}
1037 1038
1038void ACPI_INTERNAL_VAR_XFACE 1039void ACPI_INTERNAL_VAR_XFACE
@@ -1061,6 +1062,8 @@ acpi_ut_warning(char *module_name, u32 line_number, char *format, ...)
1061 va_start(args, format); 1062 va_start(args, format);
1062 acpi_os_vprintf(format, args); 1063 acpi_os_vprintf(format, args);
1063 acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); 1064 acpi_os_printf(" [%X]\n", ACPI_CA_VERSION);
1065 va_end(args);
1066 va_end(args);
1064} 1067}
1065 1068
1066void ACPI_INTERNAL_VAR_XFACE 1069void ACPI_INTERNAL_VAR_XFACE
@@ -1077,4 +1080,5 @@ acpi_ut_info(char *module_name, u32 line_number, char *format, ...)
1077 va_start(args, format); 1080 va_start(args, format);
1078 acpi_os_vprintf(format, args); 1081 acpi_os_vprintf(format, args);
1079 acpi_os_printf("\n"); 1082 acpi_os_printf("\n");
1083 va_end(args);
1080} 1084}
diff --git a/drivers/acpi/utilities/utmutex.c b/drivers/acpi/utilities/utmutex.c
index 4820bc86d1f5..f7d602b1a894 100644
--- a/drivers/acpi/utilities/utmutex.c
+++ b/drivers/acpi/utilities/utmutex.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c
index e08b3fa6639f..e68466de8044 100644
--- a/drivers/acpi/utilities/utobject.c
+++ b/drivers/acpi/utilities/utobject.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -107,6 +107,7 @@ union acpi_operand_object *acpi_ut_create_internal_object_dbg(char *module_name,
107 switch (type) { 107 switch (type) {
108 case ACPI_TYPE_REGION: 108 case ACPI_TYPE_REGION:
109 case ACPI_TYPE_BUFFER_FIELD: 109 case ACPI_TYPE_BUFFER_FIELD:
110 case ACPI_TYPE_LOCAL_BANK_FIELD:
110 111
111 /* These types require a secondary object */ 112 /* These types require a secondary object */
112 113
@@ -469,9 +470,8 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
469 case ACPI_TYPE_PROCESSOR: 470 case ACPI_TYPE_PROCESSOR:
470 case ACPI_TYPE_POWER: 471 case ACPI_TYPE_POWER:
471 472
472 /* 473 /* No extra data for these types */
473 * No extra data for these types 474
474 */
475 break; 475 break;
476 476
477 case ACPI_TYPE_LOCAL_REFERENCE: 477 case ACPI_TYPE_LOCAL_REFERENCE:
diff --git a/drivers/acpi/utilities/utresrc.c b/drivers/acpi/utilities/utresrc.c
index b630ee137ee1..c3e3e1308edc 100644
--- a/drivers/acpi/utilities/utresrc.c
+++ b/drivers/acpi/utilities/utresrc.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/utilities/utstate.c b/drivers/acpi/utilities/utstate.c
index edcaafad0a31..63a6d3d77d88 100644
--- a/drivers/acpi/utilities/utstate.c
+++ b/drivers/acpi/utilities/utstate.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c
index 2d496918b3cd..f8bdadf3c32f 100644
--- a/drivers/acpi/utilities/utxface.c
+++ b/drivers/acpi/utilities/utxface.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -49,6 +49,7 @@
49#define _COMPONENT ACPI_UTILITIES 49#define _COMPONENT ACPI_UTILITIES
50ACPI_MODULE_NAME("utxface") 50ACPI_MODULE_NAME("utxface")
51 51
52#ifndef ACPI_ASL_COMPILER
52/******************************************************************************* 53/*******************************************************************************
53 * 54 *
54 * FUNCTION: acpi_initialize_subsystem 55 * FUNCTION: acpi_initialize_subsystem
@@ -192,24 +193,6 @@ acpi_status acpi_enable_subsystem(u32 flags)
192 } 193 }
193 } 194 }
194 195
195 /*
196 * Complete the GPE initialization for the GPE blocks defined in the FADT
197 * (GPE block 0 and 1).
198 *
199 * Note1: This is where the _PRW methods are executed for the GPEs. These
200 * methods can only be executed after the SCI and Global Lock handlers are
201 * installed and initialized.
202 *
203 * Note2: Currently, there seems to be no need to run the _REG methods
204 * before execution of the _PRW methods and enabling of the GPEs.
205 */
206 if (!(flags & ACPI_NO_EVENT_INIT)) {
207 status = acpi_ev_install_fadt_gpes();
208 if (ACPI_FAILURE(status)) {
209 return (status);
210 }
211 }
212
213 return_ACPI_STATUS(status); 196 return_ACPI_STATUS(status);
214} 197}
215 198
@@ -280,6 +263,23 @@ acpi_status acpi_initialize_objects(u32 flags)
280 } 263 }
281 264
282 /* 265 /*
266 * Complete the GPE initialization for the GPE blocks defined in the FADT
267 * (GPE block 0 and 1).
268 *
269 * Note1: This is where the _PRW methods are executed for the GPEs. These
270 * methods can only be executed after the SCI and Global Lock handlers are
271 * installed and initialized.
272 *
273 * Note2: Currently, there seems to be no need to run the _REG methods
274 * before execution of the _PRW methods and enabling of the GPEs.
275 */
276 if (!(flags & ACPI_NO_EVENT_INIT)) {
277 status = acpi_ev_install_fadt_gpes();
278 if (ACPI_FAILURE(status))
279 return (status);
280 }
281
282 /*
283 * Empty the caches (delete the cached objects) on the assumption that 283 * Empty the caches (delete the cached objects) on the assumption that
284 * the table load filled them up more than they will be at runtime -- 284 * the table load filled them up more than they will be at runtime --
285 * thus wasting non-paged memory. 285 * thus wasting non-paged memory.
@@ -292,6 +292,7 @@ acpi_status acpi_initialize_objects(u32 flags)
292 292
293ACPI_EXPORT_SYMBOL(acpi_initialize_objects) 293ACPI_EXPORT_SYMBOL(acpi_initialize_objects)
294 294
295#endif
295/******************************************************************************* 296/*******************************************************************************
296 * 297 *
297 * FUNCTION: acpi_terminate 298 * FUNCTION: acpi_terminate
@@ -335,6 +336,7 @@ acpi_status acpi_terminate(void)
335} 336}
336 337
337ACPI_EXPORT_SYMBOL(acpi_terminate) 338ACPI_EXPORT_SYMBOL(acpi_terminate)
339#ifndef ACPI_ASL_COMPILER
338#ifdef ACPI_FUTURE_USAGE 340#ifdef ACPI_FUTURE_USAGE
339/******************************************************************************* 341/*******************************************************************************
340 * 342 *
@@ -490,3 +492,4 @@ acpi_status acpi_purge_cached_objects(void)
490} 492}
491 493
492ACPI_EXPORT_SYMBOL(acpi_purge_cached_objects) 494ACPI_EXPORT_SYMBOL(acpi_purge_cached_objects)
495#endif
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
index 44ea60cf21c0..100926143818 100644
--- a/drivers/acpi/utils.c
+++ b/drivers/acpi/utils.c
@@ -398,7 +398,7 @@ acpi_evaluate_reference(acpi_handle handle,
398 398
399 element = &(package->package.elements[i]); 399 element = &(package->package.elements[i]);
400 400
401 if (element->type != ACPI_TYPE_ANY) { 401 if (element->type != ACPI_TYPE_LOCAL_REFERENCE) {
402 status = AE_BAD_DATA; 402 status = AE_BAD_DATA;
403 printk(KERN_ERR PREFIX 403 printk(KERN_ERR PREFIX
404 "Expecting a [Reference] package element, found type %X\n", 404 "Expecting a [Reference] package element, found type %X\n",
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 43b228314a86..f7eb12e55602 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -57,8 +57,6 @@
57#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x88 57#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x88
58#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x89 58#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x89
59 59
60#define ACPI_VIDEO_HEAD_INVALID (~0u - 1)
61#define ACPI_VIDEO_HEAD_END (~0u)
62#define MAX_NAME_LEN 20 60#define MAX_NAME_LEN 20
63 61
64#define ACPI_VIDEO_DISPLAY_CRT 1 62#define ACPI_VIDEO_DISPLAY_CRT 1
@@ -743,21 +741,19 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
743 if (IS_ERR(device->cdev)) 741 if (IS_ERR(device->cdev))
744 return; 742 return;
745 743
746 if (device->cdev) { 744 printk(KERN_INFO PREFIX
747 printk(KERN_INFO PREFIX 745 "%s is registered as cooling_device%d\n",
748 "%s is registered as cooling_device%d\n", 746 device->dev->dev.bus_id, device->cdev->id);
749 device->dev->dev.bus_id, device->cdev->id); 747 result = sysfs_create_link(&device->dev->dev.kobj,
750 result = sysfs_create_link(&device->dev->dev.kobj, 748 &device->cdev->device.kobj,
751 &device->cdev->device.kobj, 749 "thermal_cooling");
752 "thermal_cooling"); 750 if (result)
753 if (result) 751 printk(KERN_ERR PREFIX "Create sysfs link\n");
754 printk(KERN_ERR PREFIX "Create sysfs link\n"); 752 result = sysfs_create_link(&device->cdev->device.kobj,
755 result = sysfs_create_link(&device->cdev->device.kobj, 753 &device->dev->dev.kobj, "device");
756 &device->dev->dev.kobj, 754 if (result)
757 "device"); 755 printk(KERN_ERR PREFIX "Create sysfs link\n");
758 if (result) 756
759 printk(KERN_ERR PREFIX "Create sysfs link\n");
760 }
761 } 757 }
762 if (device->cap._DCS && device->cap._DSS){ 758 if (device->cap._DCS && device->cap._DSS){
763 static int count = 0; 759 static int count = 0;
@@ -1059,30 +1055,25 @@ acpi_video_device_EDID_open_fs(struct inode *inode, struct file *file)
1059 1055
1060static int acpi_video_device_add_fs(struct acpi_device *device) 1056static int acpi_video_device_add_fs(struct acpi_device *device)
1061{ 1057{
1062 struct proc_dir_entry *entry = NULL; 1058 struct proc_dir_entry *entry, *device_dir;
1063 struct acpi_video_device *vid_dev; 1059 struct acpi_video_device *vid_dev;
1064 1060
1065
1066 if (!device)
1067 return -ENODEV;
1068
1069 vid_dev = acpi_driver_data(device); 1061 vid_dev = acpi_driver_data(device);
1070 if (!vid_dev) 1062 if (!vid_dev)
1071 return -ENODEV; 1063 return -ENODEV;
1072 1064
1073 if (!acpi_device_dir(device)) { 1065 device_dir = proc_mkdir(acpi_device_bid(device),
1074 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), 1066 vid_dev->video->dir);
1075 vid_dev->video->dir); 1067 if (!device_dir)
1076 if (!acpi_device_dir(device)) 1068 return -ENOMEM;
1077 return -ENODEV; 1069
1078 acpi_device_dir(device)->owner = THIS_MODULE; 1070 device_dir->owner = THIS_MODULE;
1079 }
1080 1071
1081 /* 'info' [R] */ 1072 /* 'info' [R] */
1082 entry = proc_create_data("info", S_IRUGO, acpi_device_dir(device), 1073 entry = proc_create_data("info", S_IRUGO, acpi_device_dir(device),
1083 &acpi_video_device_info_fops, acpi_driver_data(device)); 1074 &acpi_video_device_info_fops, acpi_driver_data(device));
1084 if (!entry) 1075 if (!entry)
1085 return -ENODEV; 1076 goto err_remove_dir;
1086 1077
1087 /* 'state' [R/W] */ 1078 /* 'state' [R/W] */
1088 acpi_video_device_state_fops.write = acpi_video_device_write_state; 1079 acpi_video_device_state_fops.write = acpi_video_device_write_state;
@@ -1091,7 +1082,7 @@ static int acpi_video_device_add_fs(struct acpi_device *device)
1091 &acpi_video_device_state_fops, 1082 &acpi_video_device_state_fops,
1092 acpi_driver_data(device)); 1083 acpi_driver_data(device));
1093 if (!entry) 1084 if (!entry)
1094 return -ENODEV; 1085 goto err_remove_info;
1095 1086
1096 /* 'brightness' [R/W] */ 1087 /* 'brightness' [R/W] */
1097 acpi_video_device_brightness_fops.write = 1088 acpi_video_device_brightness_fops.write =
@@ -1101,30 +1092,43 @@ static int acpi_video_device_add_fs(struct acpi_device *device)
1101 &acpi_video_device_brightness_fops, 1092 &acpi_video_device_brightness_fops,
1102 acpi_driver_data(device)); 1093 acpi_driver_data(device));
1103 if (!entry) 1094 if (!entry)
1104 return -ENODEV; 1095 goto err_remove_state;
1105 1096
1106 /* 'EDID' [R] */ 1097 /* 'EDID' [R] */
1107 entry = proc_create_data("EDID", S_IRUGO, acpi_device_dir(device), 1098 entry = proc_create_data("EDID", S_IRUGO, acpi_device_dir(device),
1108 &acpi_video_device_EDID_fops, 1099 &acpi_video_device_EDID_fops,
1109 acpi_driver_data(device)); 1100 acpi_driver_data(device));
1110 if (!entry) 1101 if (!entry)
1111 return -ENODEV; 1102 goto err_remove_brightness;
1103
1112 return 0; 1104 return 0;
1105
1106 err_remove_brightness:
1107 remove_proc_entry("brightness", device_dir);
1108 err_remove_state:
1109 remove_proc_entry("state", device_dir);
1110 err_remove_info:
1111 remove_proc_entry("info", device_dir);
1112 err_remove_dir:
1113 remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir);
1114 return -ENOMEM;
1113} 1115}
1114 1116
1115static int acpi_video_device_remove_fs(struct acpi_device *device) 1117static int acpi_video_device_remove_fs(struct acpi_device *device)
1116{ 1118{
1117 struct acpi_video_device *vid_dev; 1119 struct acpi_video_device *vid_dev;
1120 struct proc_dir_entry *device_dir;
1118 1121
1119 vid_dev = acpi_driver_data(device); 1122 vid_dev = acpi_driver_data(device);
1120 if (!vid_dev || !vid_dev->video || !vid_dev->video->dir) 1123 if (!vid_dev || !vid_dev->video || !vid_dev->video->dir)
1121 return -ENODEV; 1124 return -ENODEV;
1122 1125
1123 if (acpi_device_dir(device)) { 1126 device_dir = acpi_device_dir(device);
1124 remove_proc_entry("info", acpi_device_dir(device)); 1127 if (device_dir) {
1125 remove_proc_entry("state", acpi_device_dir(device)); 1128 remove_proc_entry("info", device_dir);
1126 remove_proc_entry("brightness", acpi_device_dir(device)); 1129 remove_proc_entry("state", device_dir);
1127 remove_proc_entry("EDID", acpi_device_dir(device)); 1130 remove_proc_entry("brightness", device_dir);
1131 remove_proc_entry("EDID", device_dir);
1128 remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir); 1132 remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir);
1129 acpi_device_dir(device) = NULL; 1133 acpi_device_dir(device) = NULL;
1130 } 1134 }
@@ -1331,76 +1335,81 @@ acpi_video_bus_write_DOS(struct file *file,
1331 1335
1332static int acpi_video_bus_add_fs(struct acpi_device *device) 1336static int acpi_video_bus_add_fs(struct acpi_device *device)
1333{ 1337{
1334 struct proc_dir_entry *entry = NULL; 1338 struct acpi_video_bus *video = acpi_driver_data(device);
1335 struct acpi_video_bus *video; 1339 struct proc_dir_entry *device_dir;
1340 struct proc_dir_entry *entry;
1336 1341
1342 device_dir = proc_mkdir(acpi_device_bid(device), acpi_video_dir);
1343 if (!device_dir)
1344 return -ENOMEM;
1337 1345
1338 video = acpi_driver_data(device); 1346 device_dir->owner = THIS_MODULE;
1339
1340 if (!acpi_device_dir(device)) {
1341 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
1342 acpi_video_dir);
1343 if (!acpi_device_dir(device))
1344 return -ENODEV;
1345 video->dir = acpi_device_dir(device);
1346 acpi_device_dir(device)->owner = THIS_MODULE;
1347 }
1348 1347
1349 /* 'info' [R] */ 1348 /* 'info' [R] */
1350 entry = proc_create_data("info", S_IRUGO, acpi_device_dir(device), 1349 entry = proc_create_data("info", S_IRUGO, acpi_device_dir(device),
1351 &acpi_video_bus_info_fops, 1350 &acpi_video_bus_info_fops,
1352 acpi_driver_data(device)); 1351 acpi_driver_data(device));
1353 if (!entry) 1352 if (!entry)
1354 return -ENODEV; 1353 goto err_remove_dir;
1355 1354
1356 /* 'ROM' [R] */ 1355 /* 'ROM' [R] */
1357 entry = proc_create_data("ROM", S_IRUGO, acpi_device_dir(device), 1356 entry = proc_create_data("ROM", S_IRUGO, acpi_device_dir(device),
1358 &acpi_video_bus_ROM_fops, 1357 &acpi_video_bus_ROM_fops,
1359 acpi_driver_data(device)); 1358 acpi_driver_data(device));
1360 if (!entry) 1359 if (!entry)
1361 return -ENODEV; 1360 goto err_remove_info;
1362 1361
1363 /* 'POST_info' [R] */ 1362 /* 'POST_info' [R] */
1364 entry = proc_create_data("POST_info", S_IRUGO, acpi_device_dir(device), 1363 entry = proc_create_data("POST_info", S_IRUGO, acpi_device_dir(device),
1365 &acpi_video_bus_POST_info_fops, 1364 &acpi_video_bus_POST_info_fops,
1366 acpi_driver_data(device)); 1365 acpi_driver_data(device));
1367 if (!entry) 1366 if (!entry)
1368 return -ENODEV; 1367 goto err_remove_rom;
1369 1368
1370 /* 'POST' [R/W] */ 1369 /* 'POST' [R/W] */
1371 acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST; 1370 acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST;
1372 entry = proc_create_data("POST", S_IFREG | S_IRUGO | S_IRUSR, 1371 entry = proc_create_data("POST", S_IFREG | S_IRUGO | S_IWUSR,
1373 acpi_device_dir(device), 1372 acpi_device_dir(device),
1374 &acpi_video_bus_POST_fops, 1373 &acpi_video_bus_POST_fops,
1375 acpi_driver_data(device)); 1374 acpi_driver_data(device));
1376 if (!entry) 1375 if (!entry)
1377 return -ENODEV; 1376 goto err_remove_post_info;
1378 1377
1379 /* 'DOS' [R/W] */ 1378 /* 'DOS' [R/W] */
1380 acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS; 1379 acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS;
1381 entry = proc_create_data("DOS", S_IFREG | S_IRUGO | S_IRUSR, 1380 entry = proc_create_data("DOS", S_IFREG | S_IRUGO | S_IWUSR,
1382 acpi_device_dir(device), 1381 acpi_device_dir(device),
1383 &acpi_video_bus_DOS_fops, 1382 &acpi_video_bus_DOS_fops,
1384 acpi_driver_data(device)); 1383 acpi_driver_data(device));
1385 if (!entry) 1384 if (!entry)
1386 return -ENODEV; 1385 goto err_remove_post;
1387 1386
1387 video->dir = acpi_device_dir(device) = device_dir;
1388 return 0; 1388 return 0;
1389
1390 err_remove_post:
1391 remove_proc_entry("POST", device_dir);
1392 err_remove_post_info:
1393 remove_proc_entry("POST_info", device_dir);
1394 err_remove_rom:
1395 remove_proc_entry("ROM", device_dir);
1396 err_remove_info:
1397 remove_proc_entry("info", device_dir);
1398 err_remove_dir:
1399 remove_proc_entry(acpi_device_bid(device), acpi_video_dir);
1400 return -ENOMEM;
1389} 1401}
1390 1402
1391static int acpi_video_bus_remove_fs(struct acpi_device *device) 1403static int acpi_video_bus_remove_fs(struct acpi_device *device)
1392{ 1404{
1393 struct acpi_video_bus *video; 1405 struct proc_dir_entry *device_dir = acpi_device_dir(device);
1394
1395 1406
1396 video = acpi_driver_data(device); 1407 if (device_dir) {
1397 1408 remove_proc_entry("info", device_dir);
1398 if (acpi_device_dir(device)) { 1409 remove_proc_entry("ROM", device_dir);
1399 remove_proc_entry("info", acpi_device_dir(device)); 1410 remove_proc_entry("POST_info", device_dir);
1400 remove_proc_entry("ROM", acpi_device_dir(device)); 1411 remove_proc_entry("POST", device_dir);
1401 remove_proc_entry("POST_info", acpi_device_dir(device)); 1412 remove_proc_entry("DOS", device_dir);
1402 remove_proc_entry("POST", acpi_device_dir(device));
1403 remove_proc_entry("DOS", acpi_device_dir(device));
1404 remove_proc_entry(acpi_device_bid(device), acpi_video_dir); 1413 remove_proc_entry(acpi_device_bid(device), acpi_video_dir);
1405 acpi_device_dir(device) = NULL; 1414 acpi_device_dir(device) = NULL;
1406 } 1415 }
@@ -1416,11 +1425,15 @@ static int acpi_video_bus_remove_fs(struct acpi_device *device)
1416static struct acpi_video_device_attrib* 1425static struct acpi_video_device_attrib*
1417acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id) 1426acpi_video_get_device_attr(struct acpi_video_bus *video, unsigned long device_id)
1418{ 1427{
1419 int count; 1428 struct acpi_video_enumerated_device *ids;
1429 int i;
1430
1431 for (i = 0; i < video->attached_count; i++) {
1432 ids = &video->attached_array[i];
1433 if ((ids->value.int_val & 0xffff) == device_id)
1434 return &ids->value.attrib;
1435 }
1420 1436
1421 for(count = 0; count < video->attached_count; count++)
1422 if((video->attached_array[count].value.int_val & 0xffff) == device_id)
1423 return &(video->attached_array[count].value.attrib);
1424 return NULL; 1437 return NULL;
1425} 1438}
1426 1439
@@ -1547,20 +1560,16 @@ static void
1547acpi_video_device_bind(struct acpi_video_bus *video, 1560acpi_video_device_bind(struct acpi_video_bus *video,
1548 struct acpi_video_device *device) 1561 struct acpi_video_device *device)
1549{ 1562{
1563 struct acpi_video_enumerated_device *ids;
1550 int i; 1564 int i;
1551 1565
1552#define IDS_VAL(i) video->attached_array[i].value.int_val 1566 for (i = 0; i < video->attached_count; i++) {
1553#define IDS_BIND(i) video->attached_array[i].bind_info 1567 ids = &video->attached_array[i];
1554 1568 if (device->device_id == (ids->value.int_val & 0xffff)) {
1555 for (i = 0; IDS_VAL(i) != ACPI_VIDEO_HEAD_INVALID && 1569 ids->bind_info = device;
1556 i < video->attached_count; i++) {
1557 if (device->device_id == (IDS_VAL(i) & 0xffff)) {
1558 IDS_BIND(i) = device;
1559 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "device_bind %d\n", i)); 1570 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "device_bind %d\n", i));
1560 } 1571 }
1561 } 1572 }
1562#undef IDS_VAL
1563#undef IDS_BIND
1564} 1573}
1565 1574
1566/* 1575/*
@@ -1579,7 +1588,7 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
1579 int status; 1588 int status;
1580 int count; 1589 int count;
1581 int i; 1590 int i;
1582 struct acpi_video_enumerated_device *active_device_list; 1591 struct acpi_video_enumerated_device *active_list;
1583 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 1592 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
1584 union acpi_object *dod = NULL; 1593 union acpi_object *dod = NULL;
1585 union acpi_object *obj; 1594 union acpi_object *obj;
@@ -1600,13 +1609,10 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
1600 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d video heads in _DOD\n", 1609 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d video heads in _DOD\n",
1601 dod->package.count)); 1610 dod->package.count));
1602 1611
1603 active_device_list = kmalloc((1 + 1612 active_list = kcalloc(1 + dod->package.count,
1604 dod->package.count) * 1613 sizeof(struct acpi_video_enumerated_device),
1605 sizeof(struct 1614 GFP_KERNEL);
1606 acpi_video_enumerated_device), 1615 if (!active_list) {
1607 GFP_KERNEL);
1608
1609 if (!active_device_list) {
1610 status = -ENOMEM; 1616 status = -ENOMEM;
1611 goto out; 1617 goto out;
1612 } 1618 }
@@ -1616,23 +1622,24 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
1616 obj = &dod->package.elements[i]; 1622 obj = &dod->package.elements[i];
1617 1623
1618 if (obj->type != ACPI_TYPE_INTEGER) { 1624 if (obj->type != ACPI_TYPE_INTEGER) {
1619 printk(KERN_ERR PREFIX "Invalid _DOD data\n"); 1625 printk(KERN_ERR PREFIX
1620 active_device_list[i].value.int_val = 1626 "Invalid _DOD data in element %d\n", i);
1621 ACPI_VIDEO_HEAD_INVALID; 1627 continue;
1622 } 1628 }
1623 active_device_list[i].value.int_val = obj->integer.value; 1629
1624 active_device_list[i].bind_info = NULL; 1630 active_list[count].value.int_val = obj->integer.value;
1631 active_list[count].bind_info = NULL;
1625 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "dod element[%d] = %d\n", i, 1632 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "dod element[%d] = %d\n", i,
1626 (int)obj->integer.value)); 1633 (int)obj->integer.value));
1627 count++; 1634 count++;
1628 } 1635 }
1629 active_device_list[count].value.int_val = ACPI_VIDEO_HEAD_END;
1630 1636
1631 kfree(video->attached_array); 1637 kfree(video->attached_array);
1632 1638
1633 video->attached_array = active_device_list; 1639 video->attached_array = active_list;
1634 video->attached_count = count; 1640 video->attached_count = count;
1635 out: 1641
1642 out:
1636 kfree(buffer.pointer); 1643 kfree(buffer.pointer);
1637 return status; 1644 return status;
1638} 1645}
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 297a48f85446..636af2862308 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -140,6 +140,7 @@ config ACER_WMI
140 depends on EXPERIMENTAL 140 depends on EXPERIMENTAL
141 depends on ACPI 141 depends on ACPI
142 depends on LEDS_CLASS 142 depends on LEDS_CLASS
143 depends on NEW_LEDS
143 depends on BACKLIGHT_CLASS_DEVICE 144 depends on BACKLIGHT_CLASS_DEVICE
144 depends on SERIO_I8042 145 depends on SERIO_I8042
145 select ACPI_WMI 146 select ACPI_WMI
@@ -160,6 +161,7 @@ config ASUS_LAPTOP
160 depends on ACPI 161 depends on ACPI
161 depends on EXPERIMENTAL && !ACPI_ASUS 162 depends on EXPERIMENTAL && !ACPI_ASUS
162 depends on LEDS_CLASS 163 depends on LEDS_CLASS
164 depends on NEW_LEDS
163 depends on BACKLIGHT_CLASS_DEVICE 165 depends on BACKLIGHT_CLASS_DEVICE
164 ---help--- 166 ---help---
165 This is the new Linux driver for Asus laptops. It may also support some 167 This is the new Linux driver for Asus laptops. It may also support some
@@ -241,10 +243,13 @@ config SONYPI_COMPAT
241config THINKPAD_ACPI 243config THINKPAD_ACPI
242 tristate "ThinkPad ACPI Laptop Extras" 244 tristate "ThinkPad ACPI Laptop Extras"
243 depends on X86 && ACPI 245 depends on X86 && ACPI
246 select BACKLIGHT_LCD_SUPPORT
244 select BACKLIGHT_CLASS_DEVICE 247 select BACKLIGHT_CLASS_DEVICE
245 select HWMON 248 select HWMON
246 select NVRAM 249 select NVRAM
247 depends on INPUT 250 select INPUT
251 select NEW_LEDS
252 select LEDS_CLASS
248 ---help--- 253 ---help---
249 This is a driver for the IBM and Lenovo ThinkPad laptops. It adds 254 This is a driver for the IBM and Lenovo ThinkPad laptops. It adds
250 support for Fn-Fx key combinations, Bluetooth control, video 255 support for Fn-Fx key combinations, Bluetooth control, video
@@ -344,6 +349,7 @@ config ATMEL_SSC
344config INTEL_MENLOW 349config INTEL_MENLOW
345 tristate "Thermal Management driver for Intel menlow platform" 350 tristate "Thermal Management driver for Intel menlow platform"
346 depends on ACPI_THERMAL 351 depends on ACPI_THERMAL
352 select THERMAL
347 depends on X86 353 depends on X86
348 ---help--- 354 ---help---
349 ACPI thermal management enhancement driver on 355 ACPI thermal management enhancement driver on
@@ -351,6 +357,19 @@ config INTEL_MENLOW
351 357
352 If unsure, say N. 358 If unsure, say N.
353 359
360config EEEPC_LAPTOP
361 tristate "Eee PC Hotkey Driver (EXPERIMENTAL)"
362 depends on X86
363 depends on ACPI
364 depends on BACKLIGHT_CLASS_DEVICE
365 depends on HWMON
366 depends on EXPERIMENTAL
367 ---help---
368 This driver supports the Fn-Fx keys on Eee PC laptops.
369 It also adds the ability to switch camera/wlan on/off.
370
371 If you have an Eee PC laptop, say Y or M here.
372
354config ENCLOSURE_SERVICES 373config ENCLOSURE_SERVICES
355 tristate "Enclosure Services" 374 tristate "Enclosure Services"
356 default n 375 default n
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 5914da434854..1952875a272e 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -7,7 +7,8 @@ obj-$(CONFIG_IBM_ASM) += ibmasm/
7obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ 7obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/
8obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o 8obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o
9obj-$(CONFIG_ACER_WMI) += acer-wmi.o 9obj-$(CONFIG_ACER_WMI) += acer-wmi.o
10obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o 10obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o
11obj-$(CONFIG_EEEPC_LAPTOP) += eeepc-laptop.o
11obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o 12obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o
12obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o 13obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o
13obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o 14obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o
diff --git a/drivers/misc/eeepc-laptop.c b/drivers/misc/eeepc-laptop.c
new file mode 100644
index 000000000000..6d727609097f
--- /dev/null
+++ b/drivers/misc/eeepc-laptop.c
@@ -0,0 +1,666 @@
1/*
2 * eepc-laptop.c - Asus Eee PC extras
3 *
4 * Based on asus_acpi.c as patched for the Eee PC by Asus:
5 * ftp://ftp.asus.com/pub/ASUS/EeePC/701/ASUS_ACPI_071126.rar
6 * Based on eee.c from eeepc-linux
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#include <linux/kernel.h>
20#include <linux/module.h>
21#include <linux/init.h>
22#include <linux/types.h>
23#include <linux/platform_device.h>
24#include <linux/backlight.h>
25#include <linux/fb.h>
26#include <linux/hwmon.h>
27#include <linux/hwmon-sysfs.h>
28#include <acpi/acpi_drivers.h>
29#include <acpi/acpi_bus.h>
30#include <linux/uaccess.h>
31
32#define EEEPC_LAPTOP_VERSION "0.1"
33
34#define EEEPC_HOTK_NAME "Eee PC Hotkey Driver"
35#define EEEPC_HOTK_FILE "eeepc"
36#define EEEPC_HOTK_CLASS "hotkey"
37#define EEEPC_HOTK_DEVICE_NAME "Hotkey"
38#define EEEPC_HOTK_HID "ASUS010"
39
40#define EEEPC_LOG EEEPC_HOTK_FILE ": "
41#define EEEPC_ERR KERN_ERR EEEPC_LOG
42#define EEEPC_WARNING KERN_WARNING EEEPC_LOG
43#define EEEPC_NOTICE KERN_NOTICE EEEPC_LOG
44#define EEEPC_INFO KERN_INFO EEEPC_LOG
45
46/*
47 * Definitions for Asus EeePC
48 */
49#define NOTIFY_WLAN_ON 0x10
50#define NOTIFY_BRN_MIN 0x20
51#define NOTIFY_BRN_MAX 0x2f
52
53enum {
54 DISABLE_ASL_WLAN = 0x0001,
55 DISABLE_ASL_BLUETOOTH = 0x0002,
56 DISABLE_ASL_IRDA = 0x0004,
57 DISABLE_ASL_CAMERA = 0x0008,
58 DISABLE_ASL_TV = 0x0010,
59 DISABLE_ASL_GPS = 0x0020,
60 DISABLE_ASL_DISPLAYSWITCH = 0x0040,
61 DISABLE_ASL_MODEM = 0x0080,
62 DISABLE_ASL_CARDREADER = 0x0100
63};
64
65enum {
66 CM_ASL_WLAN = 0,
67 CM_ASL_BLUETOOTH,
68 CM_ASL_IRDA,
69 CM_ASL_1394,
70 CM_ASL_CAMERA,
71 CM_ASL_TV,
72 CM_ASL_GPS,
73 CM_ASL_DVDROM,
74 CM_ASL_DISPLAYSWITCH,
75 CM_ASL_PANELBRIGHT,
76 CM_ASL_BIOSFLASH,
77 CM_ASL_ACPIFLASH,
78 CM_ASL_CPUFV,
79 CM_ASL_CPUTEMPERATURE,
80 CM_ASL_FANCPU,
81 CM_ASL_FANCHASSIS,
82 CM_ASL_USBPORT1,
83 CM_ASL_USBPORT2,
84 CM_ASL_USBPORT3,
85 CM_ASL_MODEM,
86 CM_ASL_CARDREADER,
87 CM_ASL_LID
88};
89
90const char *cm_getv[] = {
91 "WLDG", NULL, NULL, NULL,
92 "CAMG", NULL, NULL, NULL,
93 NULL, "PBLG", NULL, NULL,
94 "CFVG", NULL, NULL, NULL,
95 "USBG", NULL, NULL, "MODG",
96 "CRDG", "LIDG"
97};
98
99const char *cm_setv[] = {
100 "WLDS", NULL, NULL, NULL,
101 "CAMS", NULL, NULL, NULL,
102 "SDSP", "PBLS", "HDPS", NULL,
103 "CFVS", NULL, NULL, NULL,
104 "USBG", NULL, NULL, "MODS",
105 "CRDS", NULL
106};
107
108#define EEEPC_EC "\\_SB.PCI0.SBRG.EC0."
109
110#define EEEPC_EC_FAN_PWM EEEPC_EC "SC02" /* Fan PWM duty cycle (%) */
111#define EEEPC_EC_SC02 0x63
112#define EEEPC_EC_FAN_HRPM EEEPC_EC "SC05" /* High byte, fan speed (RPM) */
113#define EEEPC_EC_FAN_LRPM EEEPC_EC "SC06" /* Low byte, fan speed (RPM) */
114#define EEEPC_EC_FAN_CTRL EEEPC_EC "SFB3" /* Byte containing SF25 */
115#define EEEPC_EC_SFB3 0xD3
116
117/*
118 * This is the main structure, we can use it to store useful information
119 * about the hotk device
120 */
121struct eeepc_hotk {
122 struct acpi_device *device; /* the device we are in */
123 acpi_handle handle; /* the handle of the hotk device */
124 u32 cm_supported; /* the control methods supported
125 by this BIOS */
126 uint init_flag; /* Init flags */
127 u16 event_count[128]; /* count for each event */
128};
129
130/* The actual device the driver binds to */
131static struct eeepc_hotk *ehotk;
132
133/* Platform device/driver */
134static struct platform_driver platform_driver = {
135 .driver = {
136 .name = EEEPC_HOTK_FILE,
137 .owner = THIS_MODULE,
138 }
139};
140
141static struct platform_device *platform_device;
142
143/*
144 * The hotkey driver declaration
145 */
146static int eeepc_hotk_add(struct acpi_device *device);
147static int eeepc_hotk_remove(struct acpi_device *device, int type);
148
149static const struct acpi_device_id eeepc_device_ids[] = {
150 {EEEPC_HOTK_HID, 0},
151 {"", 0},
152};
153MODULE_DEVICE_TABLE(acpi, eeepc_device_ids);
154
155static struct acpi_driver eeepc_hotk_driver = {
156 .name = EEEPC_HOTK_NAME,
157 .class = EEEPC_HOTK_CLASS,
158 .ids = eeepc_device_ids,
159 .ops = {
160 .add = eeepc_hotk_add,
161 .remove = eeepc_hotk_remove,
162 },
163};
164
165/* The backlight device /sys/class/backlight */
166static struct backlight_device *eeepc_backlight_device;
167
168/* The hwmon device */
169static struct device *eeepc_hwmon_device;
170
171/*
172 * The backlight class declaration
173 */
174static int read_brightness(struct backlight_device *bd);
175static int update_bl_status(struct backlight_device *bd);
176static struct backlight_ops eeepcbl_ops = {
177 .get_brightness = read_brightness,
178 .update_status = update_bl_status,
179};
180
181MODULE_AUTHOR("Corentin Chary, Eric Cooper");
182MODULE_DESCRIPTION(EEEPC_HOTK_NAME);
183MODULE_LICENSE("GPL");
184
185/*
186 * ACPI Helpers
187 */
188static int write_acpi_int(acpi_handle handle, const char *method, int val,
189 struct acpi_buffer *output)
190{
191 struct acpi_object_list params;
192 union acpi_object in_obj;
193 acpi_status status;
194
195 params.count = 1;
196 params.pointer = &in_obj;
197 in_obj.type = ACPI_TYPE_INTEGER;
198 in_obj.integer.value = val;
199
200 status = acpi_evaluate_object(handle, (char *)method, &params, output);
201 return (status == AE_OK ? 0 : -1);
202}
203
204static int read_acpi_int(acpi_handle handle, const char *method, int *val)
205{
206 acpi_status status;
207 ulong result;
208
209 status = acpi_evaluate_integer(handle, (char *)method, NULL, &result);
210 if (ACPI_FAILURE(status)) {
211 *val = -1;
212 return -1;
213 } else {
214 *val = result;
215 return 0;
216 }
217}
218
219static int set_acpi(int cm, int value)
220{
221 if (ehotk->cm_supported & (0x1 << cm)) {
222 const char *method = cm_setv[cm];
223 if (method == NULL)
224 return -ENODEV;
225 if (write_acpi_int(ehotk->handle, method, value, NULL))
226 printk(EEEPC_WARNING "Error writing %s\n", method);
227 }
228 return 0;
229}
230
231static int get_acpi(int cm)
232{
233 int value = -1;
234 if ((ehotk->cm_supported & (0x1 << cm))) {
235 const char *method = cm_getv[cm];
236 if (method == NULL)
237 return -ENODEV;
238 if (read_acpi_int(ehotk->handle, method, &value))
239 printk(EEEPC_WARNING "Error reading %s\n", method);
240 }
241 return value;
242}
243
244/*
245 * Backlight
246 */
247static int read_brightness(struct backlight_device *bd)
248{
249 return get_acpi(CM_ASL_PANELBRIGHT);
250}
251
252static int set_brightness(struct backlight_device *bd, int value)
253{
254 value = max(0, min(15, value));
255 return set_acpi(CM_ASL_PANELBRIGHT, value);
256}
257
258static int update_bl_status(struct backlight_device *bd)
259{
260 return set_brightness(bd, bd->props.brightness);
261}
262
263/*
264 * Sys helpers
265 */
266static int parse_arg(const char *buf, unsigned long count, int *val)
267{
268 if (!count)
269 return 0;
270 if (sscanf(buf, "%i", val) != 1)
271 return -EINVAL;
272 return count;
273}
274
275static ssize_t store_sys_acpi(int cm, const char *buf, size_t count)
276{
277 int rv, value;
278
279 rv = parse_arg(buf, count, &value);
280 if (rv > 0)
281 set_acpi(cm, value);
282 return rv;
283}
284
285static ssize_t show_sys_acpi(int cm, char *buf)
286{
287 return sprintf(buf, "%d\n", get_acpi(cm));
288}
289
290#define EEEPC_CREATE_DEVICE_ATTR(_name, _cm) \
291 static ssize_t show_##_name(struct device *dev, \
292 struct device_attribute *attr, \
293 char *buf) \
294 { \
295 return show_sys_acpi(_cm, buf); \
296 } \
297 static ssize_t store_##_name(struct device *dev, \
298 struct device_attribute *attr, \
299 const char *buf, size_t count) \
300 { \
301 return store_sys_acpi(_cm, buf, count); \
302 } \
303 static struct device_attribute dev_attr_##_name = { \
304 .attr = { \
305 .name = __stringify(_name), \
306 .mode = 0644 }, \
307 .show = show_##_name, \
308 .store = store_##_name, \
309 }
310
311EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA);
312EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER);
313EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH);
314EEEPC_CREATE_DEVICE_ATTR(wlan, CM_ASL_WLAN);
315
316static struct attribute *platform_attributes[] = {
317 &dev_attr_camera.attr,
318 &dev_attr_cardr.attr,
319 &dev_attr_disp.attr,
320 &dev_attr_wlan.attr,
321 NULL
322};
323
324static struct attribute_group platform_attribute_group = {
325 .attrs = platform_attributes
326};
327
328/*
329 * Hotkey functions
330 */
331static int eeepc_hotk_check(void)
332{
333 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
334 int result;
335
336 result = acpi_bus_get_status(ehotk->device);
337 if (result)
338 return result;
339 if (ehotk->device->status.present) {
340 if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag,
341 &buffer)) {
342 printk(EEEPC_ERR "Hotkey initialization failed\n");
343 return -ENODEV;
344 } else {
345 printk(EEEPC_NOTICE "Hotkey init flags 0x%x\n",
346 ehotk->init_flag);
347 }
348 /* get control methods supported */
349 if (read_acpi_int(ehotk->handle, "CMSG"
350 , &ehotk->cm_supported)) {
351 printk(EEEPC_ERR
352 "Get control methods supported failed\n");
353 return -ENODEV;
354 } else {
355 printk(EEEPC_INFO
356 "Get control methods supported: 0x%x\n",
357 ehotk->cm_supported);
358 }
359 } else {
360 printk(EEEPC_ERR "Hotkey device not present, aborting\n");
361 return -EINVAL;
362 }
363 return 0;
364}
365
366static void notify_wlan(u32 *event)
367{
368 /* if DISABLE_ASL_WLAN is set, the notify code for fn+f2
369 will always be 0x10 */
370 if (ehotk->cm_supported & (0x1 << CM_ASL_WLAN)) {
371 const char *method = cm_getv[CM_ASL_WLAN];
372 int value;
373 if (read_acpi_int(ehotk->handle, method, &value))
374 printk(EEEPC_WARNING "Error reading %s\n",
375 method);
376 else if (value == 1)
377 *event = 0x11;
378 }
379}
380
381static void notify_brn(void)
382{
383 struct backlight_device *bd = eeepc_backlight_device;
384 bd->props.brightness = read_brightness(bd);
385}
386
387static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
388{
389 if (!ehotk)
390 return;
391 if (event == NOTIFY_WLAN_ON && (DISABLE_ASL_WLAN & ehotk->init_flag))
392 notify_wlan(&event);
393 if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX)
394 notify_brn();
395 acpi_bus_generate_proc_event(ehotk->device, event,
396 ehotk->event_count[event % 128]++);
397}
398
399static int eeepc_hotk_add(struct acpi_device *device)
400{
401 acpi_status status = AE_OK;
402 int result;
403
404 if (!device)
405 return -EINVAL;
406 printk(EEEPC_NOTICE EEEPC_HOTK_NAME "\n");
407 ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL);
408 if (!ehotk)
409 return -ENOMEM;
410 ehotk->init_flag = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
411 ehotk->handle = device->handle;
412 strcpy(acpi_device_name(device), EEEPC_HOTK_DEVICE_NAME);
413 strcpy(acpi_device_class(device), EEEPC_HOTK_CLASS);
414 acpi_driver_data(device) = ehotk;
415 ehotk->device = device;
416 result = eeepc_hotk_check();
417 if (result)
418 goto end;
419 status = acpi_install_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY,
420 eeepc_hotk_notify, ehotk);
421 if (ACPI_FAILURE(status))
422 printk(EEEPC_ERR "Error installing notify handler\n");
423 end:
424 if (result) {
425 kfree(ehotk);
426 ehotk = NULL;
427 }
428 return result;
429}
430
431static int eeepc_hotk_remove(struct acpi_device *device, int type)
432{
433 acpi_status status = 0;
434
435 if (!device || !acpi_driver_data(device))
436 return -EINVAL;
437 status = acpi_remove_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY,
438 eeepc_hotk_notify);
439 if (ACPI_FAILURE(status))
440 printk(EEEPC_ERR "Error removing notify handler\n");
441 kfree(ehotk);
442 return 0;
443}
444
445/*
446 * Hwmon
447 */
448static int eeepc_get_fan_pwm(void)
449{
450 int value = 0;
451
452 read_acpi_int(NULL, EEEPC_EC_FAN_PWM, &value);
453 return (value);
454}
455
456static void eeepc_set_fan_pwm(int value)
457{
458 value = SENSORS_LIMIT(value, 0, 100);
459 ec_write(EEEPC_EC_SC02, value);
460}
461
462static int eeepc_get_fan_rpm(void)
463{
464 int high = 0;
465 int low = 0;
466
467 read_acpi_int(NULL, EEEPC_EC_FAN_HRPM, &high);
468 read_acpi_int(NULL, EEEPC_EC_FAN_LRPM, &low);
469 return (high << 8 | low);
470}
471
472static int eeepc_get_fan_ctrl(void)
473{
474 int value = 0;
475
476 read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value);
477 return ((value & 0x02 ? 1 : 0));
478}
479
480static void eeepc_set_fan_ctrl(int manual)
481{
482 int value = 0;
483
484 read_acpi_int(NULL, EEEPC_EC_FAN_CTRL, &value);
485 if (manual)
486 value |= 0x02;
487 else
488 value &= ~0x02;
489 ec_write(EEEPC_EC_SFB3, value);
490}
491
492static ssize_t store_sys_hwmon(void (*set)(int), const char *buf, size_t count)
493{
494 int rv, value;
495
496 rv = parse_arg(buf, count, &value);
497 if (rv > 0)
498 set(value);
499 return rv;
500}
501
502static ssize_t show_sys_hwmon(int (*get)(void), char *buf)
503{
504 return sprintf(buf, "%d\n", get());
505}
506
507#define EEEPC_CREATE_SENSOR_ATTR(_name, _mode, _set, _get) \
508 static ssize_t show_##_name(struct device *dev, \
509 struct device_attribute *attr, \
510 char *buf) \
511 { \
512 return show_sys_hwmon(_set, buf); \
513 } \
514 static ssize_t store_##_name(struct device *dev, \
515 struct device_attribute *attr, \
516 const char *buf, size_t count) \
517 { \
518 return store_sys_hwmon(_get, buf, count); \
519 } \
520 static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);
521
522EEEPC_CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, eeepc_get_fan_rpm, NULL);
523EEEPC_CREATE_SENSOR_ATTR(fan1_pwm, S_IRUGO | S_IWUSR,
524 eeepc_get_fan_pwm, eeepc_set_fan_pwm);
525EEEPC_CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
526 eeepc_get_fan_ctrl, eeepc_set_fan_ctrl);
527
528static struct attribute *hwmon_attributes[] = {
529 &sensor_dev_attr_fan1_pwm.dev_attr.attr,
530 &sensor_dev_attr_fan1_input.dev_attr.attr,
531 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
532 NULL
533};
534
535static struct attribute_group hwmon_attribute_group = {
536 .attrs = hwmon_attributes
537};
538
539/*
540 * exit/init
541 */
542static void eeepc_backlight_exit(void)
543{
544 if (eeepc_backlight_device)
545 backlight_device_unregister(eeepc_backlight_device);
546 eeepc_backlight_device = NULL;
547}
548
549static void eeepc_hwmon_exit(void)
550{
551 struct device *hwmon;
552
553 hwmon = eeepc_hwmon_device;
554 if (!hwmon)
555 return ;
556 hwmon_device_unregister(hwmon);
557 sysfs_remove_group(&hwmon->kobj,
558 &hwmon_attribute_group);
559 eeepc_hwmon_device = NULL;
560}
561
562static void __exit eeepc_laptop_exit(void)
563{
564 eeepc_backlight_exit();
565 eeepc_hwmon_exit();
566 acpi_bus_unregister_driver(&eeepc_hotk_driver);
567 sysfs_remove_group(&platform_device->dev.kobj,
568 &platform_attribute_group);
569 platform_device_unregister(platform_device);
570 platform_driver_unregister(&platform_driver);
571}
572
573static int eeepc_backlight_init(struct device *dev)
574{
575 struct backlight_device *bd;
576
577 bd = backlight_device_register(EEEPC_HOTK_FILE, dev,
578 NULL, &eeepcbl_ops);
579 if (IS_ERR(bd)) {
580 printk(EEEPC_ERR
581 "Could not register eeepc backlight device\n");
582 eeepc_backlight_device = NULL;
583 return PTR_ERR(bd);
584 }
585 eeepc_backlight_device = bd;
586 bd->props.max_brightness = 15;
587 bd->props.brightness = read_brightness(NULL);
588 bd->props.power = FB_BLANK_UNBLANK;
589 backlight_update_status(bd);
590 return 0;
591}
592
593static int eeepc_hwmon_init(struct device *dev)
594{
595 struct device *hwmon;
596 int result;
597
598 hwmon = hwmon_device_register(dev);
599 if (IS_ERR(hwmon)) {
600 printk(EEEPC_ERR
601 "Could not register eeepc hwmon device\n");
602 eeepc_hwmon_device = NULL;
603 return PTR_ERR(hwmon);
604 }
605 eeepc_hwmon_device = hwmon;
606 result = sysfs_create_group(&hwmon->kobj,
607 &hwmon_attribute_group);
608 if (result)
609 eeepc_hwmon_exit();
610 return result;
611}
612
613static int __init eeepc_laptop_init(void)
614{
615 struct device *dev;
616 int result;
617
618 if (acpi_disabled)
619 return -ENODEV;
620 result = acpi_bus_register_driver(&eeepc_hotk_driver);
621 if (result < 0)
622 return result;
623 if (!ehotk) {
624 acpi_bus_unregister_driver(&eeepc_hotk_driver);
625 return -ENODEV;
626 }
627 dev = acpi_get_physical_device(ehotk->device->handle);
628 result = eeepc_backlight_init(dev);
629 if (result)
630 goto fail_backlight;
631 result = eeepc_hwmon_init(dev);
632 if (result)
633 goto fail_hwmon;
634 /* Register platform stuff */
635 result = platform_driver_register(&platform_driver);
636 if (result)
637 goto fail_platform_driver;
638 platform_device = platform_device_alloc(EEEPC_HOTK_FILE, -1);
639 if (!platform_device) {
640 result = -ENOMEM;
641 goto fail_platform_device1;
642 }
643 result = platform_device_add(platform_device);
644 if (result)
645 goto fail_platform_device2;
646 result = sysfs_create_group(&platform_device->dev.kobj,
647 &platform_attribute_group);
648 if (result)
649 goto fail_sysfs;
650 return 0;
651fail_sysfs:
652 platform_device_del(platform_device);
653fail_platform_device2:
654 platform_device_put(platform_device);
655fail_platform_device1:
656 platform_driver_unregister(&platform_driver);
657fail_platform_driver:
658 eeepc_hwmon_exit();
659fail_hwmon:
660 eeepc_backlight_exit();
661fail_backlight:
662 return result;
663}
664
665module_init(eeepc_laptop_init);
666module_exit(eeepc_laptop_exit);
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 6cb781262f94..3f28f6eabdbf 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -21,7 +21,7 @@
21 * 02110-1301, USA. 21 * 02110-1301, USA.
22 */ 22 */
23 23
24#define TPACPI_VERSION "0.19" 24#define TPACPI_VERSION "0.20"
25#define TPACPI_SYSFS_VERSION 0x020200 25#define TPACPI_SYSFS_VERSION 0x020200
26 26
27/* 27/*
@@ -67,6 +67,7 @@
67#include <linux/hwmon.h> 67#include <linux/hwmon.h>
68#include <linux/hwmon-sysfs.h> 68#include <linux/hwmon-sysfs.h>
69#include <linux/input.h> 69#include <linux/input.h>
70#include <linux/leds.h>
70#include <asm/uaccess.h> 71#include <asm/uaccess.h>
71 72
72#include <linux/dmi.h> 73#include <linux/dmi.h>
@@ -85,6 +86,8 @@
85#define TP_CMOS_VOLUME_MUTE 2 86#define TP_CMOS_VOLUME_MUTE 2
86#define TP_CMOS_BRIGHTNESS_UP 4 87#define TP_CMOS_BRIGHTNESS_UP 4
87#define TP_CMOS_BRIGHTNESS_DOWN 5 88#define TP_CMOS_BRIGHTNESS_DOWN 5
89#define TP_CMOS_THINKLIGHT_ON 12
90#define TP_CMOS_THINKLIGHT_OFF 13
88 91
89/* NVRAM Addresses */ 92/* NVRAM Addresses */
90enum tp_nvram_addr { 93enum tp_nvram_addr {
@@ -133,8 +136,12 @@ enum {
133#define TPACPI_PROC_DIR "ibm" 136#define TPACPI_PROC_DIR "ibm"
134#define TPACPI_ACPI_EVENT_PREFIX "ibm" 137#define TPACPI_ACPI_EVENT_PREFIX "ibm"
135#define TPACPI_DRVR_NAME TPACPI_FILE 138#define TPACPI_DRVR_NAME TPACPI_FILE
139#define TPACPI_DRVR_SHORTNAME "tpacpi"
136#define TPACPI_HWMON_DRVR_NAME TPACPI_NAME "_hwmon" 140#define TPACPI_HWMON_DRVR_NAME TPACPI_NAME "_hwmon"
137 141
142#define TPACPI_NVRAM_KTHREAD_NAME "ktpacpi_nvramd"
143#define TPACPI_WORKQUEUE_NAME "ktpacpid"
144
138#define TPACPI_MAX_ACPI_ARGS 3 145#define TPACPI_MAX_ACPI_ARGS 3
139 146
140/* Debugging */ 147/* Debugging */
@@ -225,6 +232,7 @@ static struct {
225 u32 light:1; 232 u32 light:1;
226 u32 light_status:1; 233 u32 light_status:1;
227 u32 bright_16levels:1; 234 u32 bright_16levels:1;
235 u32 bright_acpimode:1;
228 u32 wan:1; 236 u32 wan:1;
229 u32 fan_ctrl_status_undef:1; 237 u32 fan_ctrl_status_undef:1;
230 u32 input_device_registered:1; 238 u32 input_device_registered:1;
@@ -236,6 +244,11 @@ static struct {
236 u32 hotkey_poll_active:1; 244 u32 hotkey_poll_active:1;
237} tp_features; 245} tp_features;
238 246
247static struct {
248 u16 hotkey_mask_ff:1;
249 u16 bright_cmos_ec_unsync:1;
250} tp_warned;
251
239struct thinkpad_id_data { 252struct thinkpad_id_data {
240 unsigned int vendor; /* ThinkPad vendor: 253 unsigned int vendor; /* ThinkPad vendor:
241 * PCI_VENDOR_ID_IBM/PCI_VENDOR_ID_LENOVO */ 254 * PCI_VENDOR_ID_IBM/PCI_VENDOR_ID_LENOVO */
@@ -246,7 +259,8 @@ struct thinkpad_id_data {
246 u16 bios_model; /* Big Endian, TP-1Y = 0x5931, 0 = unknown */ 259 u16 bios_model; /* Big Endian, TP-1Y = 0x5931, 0 = unknown */
247 u16 ec_model; 260 u16 ec_model;
248 261
249 char *model_str; 262 char *model_str; /* ThinkPad T43 */
263 char *nummodel_str; /* 9384A9C for a 9384-A9C model */
250}; 264};
251static struct thinkpad_id_data thinkpad_id; 265static struct thinkpad_id_data thinkpad_id;
252 266
@@ -259,6 +273,16 @@ static enum {
259static int experimental; 273static int experimental;
260static u32 dbg_level; 274static u32 dbg_level;
261 275
276static struct workqueue_struct *tpacpi_wq;
277
278/* Special LED class that can defer work */
279struct tpacpi_led_classdev {
280 struct led_classdev led_classdev;
281 struct work_struct work;
282 enum led_brightness new_brightness;
283 unsigned int led;
284};
285
262/**************************************************************************** 286/****************************************************************************
263 **************************************************************************** 287 ****************************************************************************
264 * 288 *
@@ -807,6 +831,80 @@ static int parse_strtoul(const char *buf,
807 return 0; 831 return 0;
808} 832}
809 833
834static int __init tpacpi_query_bcl_levels(acpi_handle handle)
835{
836 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
837 union acpi_object *obj;
838 int rc;
839
840 if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) {
841 obj = (union acpi_object *)buffer.pointer;
842 if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
843 printk(TPACPI_ERR "Unknown _BCL data, "
844 "please report this to %s\n", TPACPI_MAIL);
845 rc = 0;
846 } else {
847 rc = obj->package.count;
848 }
849 } else {
850 return 0;
851 }
852
853 kfree(buffer.pointer);
854 return rc;
855}
856
857static acpi_status __init tpacpi_acpi_walk_find_bcl(acpi_handle handle,
858 u32 lvl, void *context, void **rv)
859{
860 char name[ACPI_PATH_SEGMENT_LENGTH];
861 struct acpi_buffer buffer = { sizeof(name), &name };
862
863 if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) &&
864 !strncmp("_BCL", name, sizeof(name) - 1)) {
865 BUG_ON(!rv || !*rv);
866 **(int **)rv = tpacpi_query_bcl_levels(handle);
867 return AE_CTRL_TERMINATE;
868 } else {
869 return AE_OK;
870 }
871}
872
873/*
874 * Returns 0 (no ACPI _BCL or _BCL invalid), or size of brightness map
875 */
876static int __init tpacpi_check_std_acpi_brightness_support(void)
877{
878 int status;
879 int bcl_levels = 0;
880 void *bcl_ptr = &bcl_levels;
881
882 if (!vid_handle) {
883 TPACPI_ACPIHANDLE_INIT(vid);
884 }
885 if (!vid_handle)
886 return 0;
887
888 /*
889 * Search for a _BCL method, and execute it. This is safe on all
890 * ThinkPads, and as a side-effect, _BCL will place a Lenovo Vista
891 * BIOS in ACPI backlight control mode. We do NOT have to care
892 * about calling the _BCL method in an enabled video device, any
893 * will do for our purposes.
894 */
895
896 status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3,
897 tpacpi_acpi_walk_find_bcl, NULL,
898 &bcl_ptr);
899
900 if (ACPI_SUCCESS(status) && bcl_levels > 2) {
901 tp_features.bright_acpimode = 1;
902 return (bcl_levels - 2);
903 }
904
905 return 0;
906}
907
810/************************************************************************* 908/*************************************************************************
811 * thinkpad-acpi driver attributes 909 * thinkpad-acpi driver attributes
812 */ 910 */
@@ -909,12 +1007,14 @@ static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm)
909 thinkpad_id.ec_version_str : "unknown"); 1007 thinkpad_id.ec_version_str : "unknown");
910 1008
911 if (thinkpad_id.vendor && thinkpad_id.model_str) 1009 if (thinkpad_id.vendor && thinkpad_id.model_str)
912 printk(TPACPI_INFO "%s %s\n", 1010 printk(TPACPI_INFO "%s %s, model %s\n",
913 (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ? 1011 (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ?
914 "IBM" : ((thinkpad_id.vendor == 1012 "IBM" : ((thinkpad_id.vendor ==
915 PCI_VENDOR_ID_LENOVO) ? 1013 PCI_VENDOR_ID_LENOVO) ?
916 "Lenovo" : "Unknown vendor"), 1014 "Lenovo" : "Unknown vendor"),
917 thinkpad_id.model_str); 1015 thinkpad_id.model_str,
1016 (thinkpad_id.nummodel_str) ?
1017 thinkpad_id.nummodel_str : "unknown");
918 1018
919 return 0; 1019 return 0;
920} 1020}
@@ -1107,6 +1207,19 @@ static int hotkey_mask_set(u32 mask)
1107 int rc = 0; 1207 int rc = 0;
1108 1208
1109 if (tp_features.hotkey_mask) { 1209 if (tp_features.hotkey_mask) {
1210 if (!tp_warned.hotkey_mask_ff &&
1211 (mask == 0xffff || mask == 0xffffff ||
1212 mask == 0xffffffff)) {
1213 tp_warned.hotkey_mask_ff = 1;
1214 printk(TPACPI_NOTICE
1215 "setting the hotkey mask to 0x%08x is likely "
1216 "not the best way to go about it\n", mask);
1217 printk(TPACPI_NOTICE
1218 "please consider using the driver defaults, "
1219 "and refer to up-to-date thinkpad-acpi "
1220 "documentation\n");
1221 }
1222
1110 HOTKEY_CONFIG_CRITICAL_START 1223 HOTKEY_CONFIG_CRITICAL_START
1111 for (i = 0; i < 32; i++) { 1224 for (i = 0; i < 32; i++) {
1112 u32 m = 1 << i; 1225 u32 m = 1 << i;
@@ -1427,8 +1540,7 @@ static void hotkey_poll_setup(int may_warn)
1427 (tpacpi_inputdev->users > 0 || hotkey_report_mode < 2)) { 1540 (tpacpi_inputdev->users > 0 || hotkey_report_mode < 2)) {
1428 if (!tpacpi_hotkey_task) { 1541 if (!tpacpi_hotkey_task) {
1429 tpacpi_hotkey_task = kthread_run(hotkey_kthread, 1542 tpacpi_hotkey_task = kthread_run(hotkey_kthread,
1430 NULL, 1543 NULL, TPACPI_NVRAM_KTHREAD_NAME);
1431 TPACPI_FILE "d");
1432 if (IS_ERR(tpacpi_hotkey_task)) { 1544 if (IS_ERR(tpacpi_hotkey_task)) {
1433 tpacpi_hotkey_task = NULL; 1545 tpacpi_hotkey_task = NULL;
1434 printk(TPACPI_ERR 1546 printk(TPACPI_ERR
@@ -1887,6 +1999,9 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
1887 KEY_UNKNOWN, /* 0x0D: FN+INSERT */ 1999 KEY_UNKNOWN, /* 0x0D: FN+INSERT */
1888 KEY_UNKNOWN, /* 0x0E: FN+DELETE */ 2000 KEY_UNKNOWN, /* 0x0E: FN+DELETE */
1889 2001
2002 /* These either have to go through ACPI video, or
2003 * act like in the IBM ThinkPads, so don't ever
2004 * enable them by default */
1890 KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */ 2005 KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */
1891 KEY_RESERVED, /* 0x10: FN+END (brightness down) */ 2006 KEY_RESERVED, /* 0x10: FN+END (brightness down) */
1892 2007
@@ -2091,6 +2206,32 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
2091 set_bit(SW_TABLET_MODE, tpacpi_inputdev->swbit); 2206 set_bit(SW_TABLET_MODE, tpacpi_inputdev->swbit);
2092 } 2207 }
2093 2208
2209 /* Do not issue duplicate brightness change events to
2210 * userspace */
2211 if (!tp_features.bright_acpimode)
2212 /* update bright_acpimode... */
2213 tpacpi_check_std_acpi_brightness_support();
2214
2215 if (tp_features.bright_acpimode) {
2216 printk(TPACPI_INFO
2217 "This ThinkPad has standard ACPI backlight "
2218 "brightness control, supported by the ACPI "
2219 "video driver\n");
2220 printk(TPACPI_NOTICE
2221 "Disabling thinkpad-acpi brightness events "
2222 "by default...\n");
2223
2224 /* The hotkey_reserved_mask change below is not
2225 * necessary while the keys are at KEY_RESERVED in the
2226 * default map, but better safe than sorry, leave it
2227 * here as a marker of what we have to do, especially
2228 * when we finally become able to set this at runtime
2229 * on response to X.org requests */
2230 hotkey_reserved_mask |=
2231 (1 << TP_ACPI_HOTKEYSCAN_FNHOME)
2232 | (1 << TP_ACPI_HOTKEYSCAN_FNEND);
2233 }
2234
2094 dbg_printk(TPACPI_DBG_INIT, 2235 dbg_printk(TPACPI_DBG_INIT,
2095 "enabling hot key handling\n"); 2236 "enabling hot key handling\n");
2096 res = hotkey_status_set(1); 2237 res = hotkey_status_set(1);
@@ -3110,13 +3251,82 @@ static struct ibm_struct video_driver_data = {
3110TPACPI_HANDLE(lght, root, "\\LGHT"); /* A21e, A2xm/p, T20-22, X20-21 */ 3251TPACPI_HANDLE(lght, root, "\\LGHT"); /* A21e, A2xm/p, T20-22, X20-21 */
3111TPACPI_HANDLE(ledb, ec, "LEDB"); /* G4x */ 3252TPACPI_HANDLE(ledb, ec, "LEDB"); /* G4x */
3112 3253
3254static int light_get_status(void)
3255{
3256 int status = 0;
3257
3258 if (tp_features.light_status) {
3259 if (!acpi_evalf(ec_handle, &status, "KBLT", "d"))
3260 return -EIO;
3261 return (!!status);
3262 }
3263
3264 return -ENXIO;
3265}
3266
3267static int light_set_status(int status)
3268{
3269 int rc;
3270
3271 if (tp_features.light) {
3272 if (cmos_handle) {
3273 rc = acpi_evalf(cmos_handle, NULL, NULL, "vd",
3274 (status)?
3275 TP_CMOS_THINKLIGHT_ON :
3276 TP_CMOS_THINKLIGHT_OFF);
3277 } else {
3278 rc = acpi_evalf(lght_handle, NULL, NULL, "vd",
3279 (status)? 1 : 0);
3280 }
3281 return (rc)? 0 : -EIO;
3282 }
3283
3284 return -ENXIO;
3285}
3286
3287static void light_set_status_worker(struct work_struct *work)
3288{
3289 struct tpacpi_led_classdev *data =
3290 container_of(work, struct tpacpi_led_classdev, work);
3291
3292 if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING))
3293 light_set_status((data->new_brightness != LED_OFF));
3294}
3295
3296static void light_sysfs_set(struct led_classdev *led_cdev,
3297 enum led_brightness brightness)
3298{
3299 struct tpacpi_led_classdev *data =
3300 container_of(led_cdev,
3301 struct tpacpi_led_classdev,
3302 led_classdev);
3303 data->new_brightness = brightness;
3304 queue_work(tpacpi_wq, &data->work);
3305}
3306
3307static enum led_brightness light_sysfs_get(struct led_classdev *led_cdev)
3308{
3309 return (light_get_status() == 1)? LED_FULL : LED_OFF;
3310}
3311
3312static struct tpacpi_led_classdev tpacpi_led_thinklight = {
3313 .led_classdev = {
3314 .name = "tpacpi::thinklight",
3315 .brightness_set = &light_sysfs_set,
3316 .brightness_get = &light_sysfs_get,
3317 }
3318};
3319
3113static int __init light_init(struct ibm_init_struct *iibm) 3320static int __init light_init(struct ibm_init_struct *iibm)
3114{ 3321{
3322 int rc = 0;
3323
3115 vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n"); 3324 vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n");
3116 3325
3117 TPACPI_ACPIHANDLE_INIT(ledb); 3326 TPACPI_ACPIHANDLE_INIT(ledb);
3118 TPACPI_ACPIHANDLE_INIT(lght); 3327 TPACPI_ACPIHANDLE_INIT(lght);
3119 TPACPI_ACPIHANDLE_INIT(cmos); 3328 TPACPI_ACPIHANDLE_INIT(cmos);
3329 INIT_WORK(&tpacpi_led_thinklight.work, light_set_status_worker);
3120 3330
3121 /* light not supported on 570, 600e/x, 770e, 770x, G4x, R30, R31 */ 3331 /* light not supported on 570, 600e/x, 770e, 770x, G4x, R30, R31 */
3122 tp_features.light = (cmos_handle || lght_handle) && !ledb_handle; 3332 tp_features.light = (cmos_handle || lght_handle) && !ledb_handle;
@@ -3130,13 +3340,31 @@ static int __init light_init(struct ibm_init_struct *iibm)
3130 vdbg_printk(TPACPI_DBG_INIT, "light is %s\n", 3340 vdbg_printk(TPACPI_DBG_INIT, "light is %s\n",
3131 str_supported(tp_features.light)); 3341 str_supported(tp_features.light));
3132 3342
3133 return (tp_features.light)? 0 : 1; 3343 if (tp_features.light) {
3344 rc = led_classdev_register(&tpacpi_pdev->dev,
3345 &tpacpi_led_thinklight.led_classdev);
3346 }
3347
3348 if (rc < 0) {
3349 tp_features.light = 0;
3350 tp_features.light_status = 0;
3351 } else {
3352 rc = (tp_features.light)? 0 : 1;
3353 }
3354 return rc;
3355}
3356
3357static void light_exit(void)
3358{
3359 led_classdev_unregister(&tpacpi_led_thinklight.led_classdev);
3360 if (work_pending(&tpacpi_led_thinklight.work))
3361 flush_workqueue(tpacpi_wq);
3134} 3362}
3135 3363
3136static int light_read(char *p) 3364static int light_read(char *p)
3137{ 3365{
3138 int len = 0; 3366 int len = 0;
3139 int status = 0; 3367 int status;
3140 3368
3141 if (!tp_features.light) { 3369 if (!tp_features.light) {
3142 len += sprintf(p + len, "status:\t\tnot supported\n"); 3370 len += sprintf(p + len, "status:\t\tnot supported\n");
@@ -3144,8 +3372,9 @@ static int light_read(char *p)
3144 len += sprintf(p + len, "status:\t\tunknown\n"); 3372 len += sprintf(p + len, "status:\t\tunknown\n");
3145 len += sprintf(p + len, "commands:\ton, off\n"); 3373 len += sprintf(p + len, "commands:\ton, off\n");
3146 } else { 3374 } else {
3147 if (!acpi_evalf(ec_handle, &status, "KBLT", "d")) 3375 status = light_get_status();
3148 return -EIO; 3376 if (status < 0)
3377 return status;
3149 len += sprintf(p + len, "status:\t\t%s\n", onoff(status, 0)); 3378 len += sprintf(p + len, "status:\t\t%s\n", onoff(status, 0));
3150 len += sprintf(p + len, "commands:\ton, off\n"); 3379 len += sprintf(p + len, "commands:\ton, off\n");
3151 } 3380 }
@@ -3155,37 +3384,29 @@ static int light_read(char *p)
3155 3384
3156static int light_write(char *buf) 3385static int light_write(char *buf)
3157{ 3386{
3158 int cmos_cmd, lght_cmd;
3159 char *cmd; 3387 char *cmd;
3160 int success; 3388 int newstatus = 0;
3161 3389
3162 if (!tp_features.light) 3390 if (!tp_features.light)
3163 return -ENODEV; 3391 return -ENODEV;
3164 3392
3165 while ((cmd = next_cmd(&buf))) { 3393 while ((cmd = next_cmd(&buf))) {
3166 if (strlencmp(cmd, "on") == 0) { 3394 if (strlencmp(cmd, "on") == 0) {
3167 cmos_cmd = 0x0c; 3395 newstatus = 1;
3168 lght_cmd = 1;
3169 } else if (strlencmp(cmd, "off") == 0) { 3396 } else if (strlencmp(cmd, "off") == 0) {
3170 cmos_cmd = 0x0d; 3397 newstatus = 0;
3171 lght_cmd = 0;
3172 } else 3398 } else
3173 return -EINVAL; 3399 return -EINVAL;
3174
3175 success = cmos_handle ?
3176 acpi_evalf(cmos_handle, NULL, NULL, "vd", cmos_cmd) :
3177 acpi_evalf(lght_handle, NULL, NULL, "vd", lght_cmd);
3178 if (!success)
3179 return -EIO;
3180 } 3400 }
3181 3401
3182 return 0; 3402 return light_set_status(newstatus);
3183} 3403}
3184 3404
3185static struct ibm_struct light_driver_data = { 3405static struct ibm_struct light_driver_data = {
3186 .name = "light", 3406 .name = "light",
3187 .read = light_read, 3407 .read = light_read,
3188 .write = light_write, 3408 .write = light_write,
3409 .exit = light_exit,
3189}; 3410};
3190 3411
3191/************************************************************************* 3412/*************************************************************************
@@ -3583,6 +3804,12 @@ enum { /* For TPACPI_LED_OLD */
3583 TPACPI_LED_EC_HLMS = 0x0e, /* EC reg to select led to command */ 3804 TPACPI_LED_EC_HLMS = 0x0e, /* EC reg to select led to command */
3584}; 3805};
3585 3806
3807enum led_status_t {
3808 TPACPI_LED_OFF = 0,
3809 TPACPI_LED_ON,
3810 TPACPI_LED_BLINK,
3811};
3812
3586static enum led_access_mode led_supported; 3813static enum led_access_mode led_supported;
3587 3814
3588TPACPI_HANDLE(led, ec, "SLED", /* 570 */ 3815TPACPI_HANDLE(led, ec, "SLED", /* 570 */
@@ -3591,8 +3818,174 @@ TPACPI_HANDLE(led, ec, "SLED", /* 570 */
3591 "LED", /* all others */ 3818 "LED", /* all others */
3592 ); /* R30, R31 */ 3819 ); /* R30, R31 */
3593 3820
3821#define TPACPI_LED_NUMLEDS 8
3822static struct tpacpi_led_classdev *tpacpi_leds;
3823static enum led_status_t tpacpi_led_state_cache[TPACPI_LED_NUMLEDS];
3824static const char const *tpacpi_led_names[TPACPI_LED_NUMLEDS] = {
3825 /* there's a limit of 19 chars + NULL before 2.6.26 */
3826 "tpacpi::power",
3827 "tpacpi:orange:batt",
3828 "tpacpi:green:batt",
3829 "tpacpi::dock_active",
3830 "tpacpi::bay_active",
3831 "tpacpi::dock_batt",
3832 "tpacpi::unknown_led",
3833 "tpacpi::standby",
3834};
3835
3836static int led_get_status(unsigned int led)
3837{
3838 int status;
3839 enum led_status_t led_s;
3840
3841 switch (led_supported) {
3842 case TPACPI_LED_570:
3843 if (!acpi_evalf(ec_handle,
3844 &status, "GLED", "dd", 1 << led))
3845 return -EIO;
3846 led_s = (status == 0)?
3847 TPACPI_LED_OFF :
3848 ((status == 1)?
3849 TPACPI_LED_ON :
3850 TPACPI_LED_BLINK);
3851 tpacpi_led_state_cache[led] = led_s;
3852 return led_s;
3853 default:
3854 return -ENXIO;
3855 }
3856
3857 /* not reached */
3858}
3859
3860static int led_set_status(unsigned int led, enum led_status_t ledstatus)
3861{
3862 /* off, on, blink. Index is led_status_t */
3863 static const int const led_sled_arg1[] = { 0, 1, 3 };
3864 static const int const led_exp_hlbl[] = { 0, 0, 1 }; /* led# * */
3865 static const int const led_exp_hlcl[] = { 0, 1, 1 }; /* led# * */
3866 static const int const led_led_arg1[] = { 0, 0x80, 0xc0 };
3867
3868 int rc = 0;
3869
3870 switch (led_supported) {
3871 case TPACPI_LED_570:
3872 /* 570 */
3873 led = 1 << led;
3874 if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
3875 led, led_sled_arg1[ledstatus]))
3876 rc = -EIO;
3877 break;
3878 case TPACPI_LED_OLD:
3879 /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */
3880 led = 1 << led;
3881 rc = ec_write(TPACPI_LED_EC_HLMS, led);
3882 if (rc >= 0)
3883 rc = ec_write(TPACPI_LED_EC_HLBL,
3884 led * led_exp_hlbl[ledstatus]);
3885 if (rc >= 0)
3886 rc = ec_write(TPACPI_LED_EC_HLCL,
3887 led * led_exp_hlcl[ledstatus]);
3888 break;
3889 case TPACPI_LED_NEW:
3890 /* all others */
3891 if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
3892 led, led_led_arg1[ledstatus]))
3893 rc = -EIO;
3894 break;
3895 default:
3896 rc = -ENXIO;
3897 }
3898
3899 if (!rc)
3900 tpacpi_led_state_cache[led] = ledstatus;
3901
3902 return rc;
3903}
3904
3905static void led_sysfs_set_status(unsigned int led,
3906 enum led_brightness brightness)
3907{
3908 led_set_status(led,
3909 (brightness == LED_OFF) ?
3910 TPACPI_LED_OFF :
3911 (tpacpi_led_state_cache[led] == TPACPI_LED_BLINK) ?
3912 TPACPI_LED_BLINK : TPACPI_LED_ON);
3913}
3914
3915static void led_set_status_worker(struct work_struct *work)
3916{
3917 struct tpacpi_led_classdev *data =
3918 container_of(work, struct tpacpi_led_classdev, work);
3919
3920 if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING))
3921 led_sysfs_set_status(data->led, data->new_brightness);
3922}
3923
3924static void led_sysfs_set(struct led_classdev *led_cdev,
3925 enum led_brightness brightness)
3926{
3927 struct tpacpi_led_classdev *data = container_of(led_cdev,
3928 struct tpacpi_led_classdev, led_classdev);
3929
3930 data->new_brightness = brightness;
3931 queue_work(tpacpi_wq, &data->work);
3932}
3933
3934static int led_sysfs_blink_set(struct led_classdev *led_cdev,
3935 unsigned long *delay_on, unsigned long *delay_off)
3936{
3937 struct tpacpi_led_classdev *data = container_of(led_cdev,
3938 struct tpacpi_led_classdev, led_classdev);
3939
3940 /* Can we choose the flash rate? */
3941 if (*delay_on == 0 && *delay_off == 0) {
3942 /* yes. set them to the hardware blink rate (1 Hz) */
3943 *delay_on = 500; /* ms */
3944 *delay_off = 500; /* ms */
3945 } else if ((*delay_on != 500) || (*delay_off != 500))
3946 return -EINVAL;
3947
3948 data->new_brightness = TPACPI_LED_BLINK;
3949 queue_work(tpacpi_wq, &data->work);
3950
3951 return 0;
3952}
3953
3954static enum led_brightness led_sysfs_get(struct led_classdev *led_cdev)
3955{
3956 int rc;
3957
3958 struct tpacpi_led_classdev *data = container_of(led_cdev,
3959 struct tpacpi_led_classdev, led_classdev);
3960
3961 rc = led_get_status(data->led);
3962
3963 if (rc == TPACPI_LED_OFF || rc < 0)
3964 rc = LED_OFF; /* no error handling in led class :( */
3965 else
3966 rc = LED_FULL;
3967
3968 return rc;
3969}
3970
3971static void led_exit(void)
3972{
3973 unsigned int i;
3974
3975 for (i = 0; i < TPACPI_LED_NUMLEDS; i++) {
3976 if (tpacpi_leds[i].led_classdev.name)
3977 led_classdev_unregister(&tpacpi_leds[i].led_classdev);
3978 }
3979
3980 kfree(tpacpi_leds);
3981 tpacpi_leds = NULL;
3982}
3983
3594static int __init led_init(struct ibm_init_struct *iibm) 3984static int __init led_init(struct ibm_init_struct *iibm)
3595{ 3985{
3986 unsigned int i;
3987 int rc;
3988
3596 vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n"); 3989 vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n");
3597 3990
3598 TPACPI_ACPIHANDLE_INIT(led); 3991 TPACPI_ACPIHANDLE_INIT(led);
@@ -3613,10 +4006,41 @@ static int __init led_init(struct ibm_init_struct *iibm)
3613 vdbg_printk(TPACPI_DBG_INIT, "LED commands are %s, mode %d\n", 4006 vdbg_printk(TPACPI_DBG_INIT, "LED commands are %s, mode %d\n",
3614 str_supported(led_supported), led_supported); 4007 str_supported(led_supported), led_supported);
3615 4008
4009 tpacpi_leds = kzalloc(sizeof(*tpacpi_leds) * TPACPI_LED_NUMLEDS,
4010 GFP_KERNEL);
4011 if (!tpacpi_leds) {
4012 printk(TPACPI_ERR "Out of memory for LED data\n");
4013 return -ENOMEM;
4014 }
4015
4016 for (i = 0; i < TPACPI_LED_NUMLEDS; i++) {
4017 tpacpi_leds[i].led = i;
4018
4019 tpacpi_leds[i].led_classdev.brightness_set = &led_sysfs_set;
4020 tpacpi_leds[i].led_classdev.blink_set = &led_sysfs_blink_set;
4021 if (led_supported == TPACPI_LED_570)
4022 tpacpi_leds[i].led_classdev.brightness_get =
4023 &led_sysfs_get;
4024
4025 tpacpi_leds[i].led_classdev.name = tpacpi_led_names[i];
4026
4027 INIT_WORK(&tpacpi_leds[i].work, led_set_status_worker);
4028
4029 rc = led_classdev_register(&tpacpi_pdev->dev,
4030 &tpacpi_leds[i].led_classdev);
4031 if (rc < 0) {
4032 tpacpi_leds[i].led_classdev.name = NULL;
4033 led_exit();
4034 return rc;
4035 }
4036 }
4037
3616 return (led_supported != TPACPI_LED_NONE)? 0 : 1; 4038 return (led_supported != TPACPI_LED_NONE)? 0 : 1;
3617} 4039}
3618 4040
3619#define led_status(s) ((s) == 0 ? "off" : ((s) == 1 ? "on" : "blinking")) 4041#define str_led_status(s) \
4042 ((s) == TPACPI_LED_OFF ? "off" : \
4043 ((s) == TPACPI_LED_ON ? "on" : "blinking"))
3620 4044
3621static int led_read(char *p) 4045static int led_read(char *p)
3622{ 4046{
@@ -3632,11 +4056,11 @@ static int led_read(char *p)
3632 /* 570 */ 4056 /* 570 */
3633 int i, status; 4057 int i, status;
3634 for (i = 0; i < 8; i++) { 4058 for (i = 0; i < 8; i++) {
3635 if (!acpi_evalf(ec_handle, 4059 status = led_get_status(i);
3636 &status, "GLED", "dd", 1 << i)) 4060 if (status < 0)
3637 return -EIO; 4061 return -EIO;
3638 len += sprintf(p + len, "%d:\t\t%s\n", 4062 len += sprintf(p + len, "%d:\t\t%s\n",
3639 i, led_status(status)); 4063 i, str_led_status(status));
3640 } 4064 }
3641 } 4065 }
3642 4066
@@ -3646,16 +4070,11 @@ static int led_read(char *p)
3646 return len; 4070 return len;
3647} 4071}
3648 4072
3649/* off, on, blink */
3650static const int led_sled_arg1[] = { 0, 1, 3 };
3651static const int led_exp_hlbl[] = { 0, 0, 1 }; /* led# * */
3652static const int led_exp_hlcl[] = { 0, 1, 1 }; /* led# * */
3653static const int led_led_arg1[] = { 0, 0x80, 0xc0 };
3654
3655static int led_write(char *buf) 4073static int led_write(char *buf)
3656{ 4074{
3657 char *cmd; 4075 char *cmd;
3658 int led, ind, ret; 4076 int led, rc;
4077 enum led_status_t s;
3659 4078
3660 if (!led_supported) 4079 if (!led_supported)
3661 return -ENODEV; 4080 return -ENODEV;
@@ -3665,38 +4084,18 @@ static int led_write(char *buf)
3665 return -EINVAL; 4084 return -EINVAL;
3666 4085
3667 if (strstr(cmd, "off")) { 4086 if (strstr(cmd, "off")) {
3668 ind = 0; 4087 s = TPACPI_LED_OFF;
3669 } else if (strstr(cmd, "on")) { 4088 } else if (strstr(cmd, "on")) {
3670 ind = 1; 4089 s = TPACPI_LED_ON;
3671 } else if (strstr(cmd, "blink")) { 4090 } else if (strstr(cmd, "blink")) {
3672 ind = 2; 4091 s = TPACPI_LED_BLINK;
3673 } else
3674 return -EINVAL;
3675
3676 if (led_supported == TPACPI_LED_570) {
3677 /* 570 */
3678 led = 1 << led;
3679 if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
3680 led, led_sled_arg1[ind]))
3681 return -EIO;
3682 } else if (led_supported == TPACPI_LED_OLD) {
3683 /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */
3684 led = 1 << led;
3685 ret = ec_write(TPACPI_LED_EC_HLMS, led);
3686 if (ret >= 0)
3687 ret = ec_write(TPACPI_LED_EC_HLBL,
3688 led * led_exp_hlbl[ind]);
3689 if (ret >= 0)
3690 ret = ec_write(TPACPI_LED_EC_HLCL,
3691 led * led_exp_hlcl[ind]);
3692 if (ret < 0)
3693 return ret;
3694 } else { 4092 } else {
3695 /* all others */ 4093 return -EINVAL;
3696 if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
3697 led, led_led_arg1[ind]))
3698 return -EIO;
3699 } 4094 }
4095
4096 rc = led_set_status(led, s);
4097 if (rc < 0)
4098 return rc;
3700 } 4099 }
3701 4100
3702 return 0; 4101 return 0;
@@ -3706,6 +4105,7 @@ static struct ibm_struct led_driver_data = {
3706 .name = "led", 4105 .name = "led",
3707 .read = led_read, 4106 .read = led_read,
3708 .write = led_write, 4107 .write = led_write,
4108 .exit = led_exit,
3709}; 4109};
3710 4110
3711/************************************************************************* 4111/*************************************************************************
@@ -4170,8 +4570,16 @@ static struct ibm_struct ecdump_driver_data = {
4170 4570
4171#define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen" 4571#define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen"
4172 4572
4573enum {
4574 TP_EC_BACKLIGHT = 0x31,
4575
4576 /* TP_EC_BACKLIGHT bitmasks */
4577 TP_EC_BACKLIGHT_LVLMSK = 0x1F,
4578 TP_EC_BACKLIGHT_CMDMSK = 0xE0,
4579 TP_EC_BACKLIGHT_MAPSW = 0x20,
4580};
4581
4173static struct backlight_device *ibm_backlight_device; 4582static struct backlight_device *ibm_backlight_device;
4174static int brightness_offset = 0x31;
4175static int brightness_mode; 4583static int brightness_mode;
4176static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */ 4584static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */
4177 4585
@@ -4180,16 +4588,24 @@ static struct mutex brightness_mutex;
4180/* 4588/*
4181 * ThinkPads can read brightness from two places: EC 0x31, or 4589 * ThinkPads can read brightness from two places: EC 0x31, or
4182 * CMOS NVRAM byte 0x5E, bits 0-3. 4590 * CMOS NVRAM byte 0x5E, bits 0-3.
4591 *
4592 * EC 0x31 has the following layout
4593 * Bit 7: unknown function
4594 * Bit 6: unknown function
4595 * Bit 5: Z: honour scale changes, NZ: ignore scale changes
4596 * Bit 4: must be set to zero to avoid problems
4597 * Bit 3-0: backlight brightness level
4598 *
4599 * brightness_get_raw returns status data in the EC 0x31 layout
4183 */ 4600 */
4184static int brightness_get(struct backlight_device *bd) 4601static int brightness_get_raw(int *status)
4185{ 4602{
4186 u8 lec = 0, lcmos = 0, level = 0; 4603 u8 lec = 0, lcmos = 0, level = 0;
4187 4604
4188 if (brightness_mode & 1) { 4605 if (brightness_mode & 1) {
4189 if (!acpi_ec_read(brightness_offset, &lec)) 4606 if (!acpi_ec_read(TP_EC_BACKLIGHT, &lec))
4190 return -EIO; 4607 return -EIO;
4191 lec &= (tp_features.bright_16levels)? 0x0f : 0x07; 4608 level = lec & TP_EC_BACKLIGHT_LVLMSK;
4192 level = lec;
4193 }; 4609 };
4194 if (brightness_mode & 2) { 4610 if (brightness_mode & 2) {
4195 lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS) 4611 lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
@@ -4199,16 +4615,27 @@ static int brightness_get(struct backlight_device *bd)
4199 level = lcmos; 4615 level = lcmos;
4200 } 4616 }
4201 4617
4202 if (brightness_mode == 3 && lec != lcmos) { 4618 if (brightness_mode == 3) {
4203 printk(TPACPI_ERR 4619 *status = lec; /* Prefer EC, CMOS is just a backing store */
4204 "CMOS NVRAM (%u) and EC (%u) do not agree " 4620 lec &= TP_EC_BACKLIGHT_LVLMSK;
4205 "on display brightness level\n", 4621 if (lec == lcmos)
4206 (unsigned int) lcmos, 4622 tp_warned.bright_cmos_ec_unsync = 0;
4207 (unsigned int) lec); 4623 else {
4208 return -EIO; 4624 if (!tp_warned.bright_cmos_ec_unsync) {
4625 printk(TPACPI_ERR
4626 "CMOS NVRAM (%u) and EC (%u) do not "
4627 "agree on display brightness level\n",
4628 (unsigned int) lcmos,
4629 (unsigned int) lec);
4630 tp_warned.bright_cmos_ec_unsync = 1;
4631 }
4632 return -EIO;
4633 }
4634 } else {
4635 *status = level;
4209 } 4636 }
4210 4637
4211 return level; 4638 return 0;
4212} 4639}
4213 4640
4214/* May return EINTR which can always be mapped to ERESTARTSYS */ 4641/* May return EINTR which can always be mapped to ERESTARTSYS */
@@ -4216,19 +4643,22 @@ static int brightness_set(int value)
4216{ 4643{
4217 int cmos_cmd, inc, i, res; 4644 int cmos_cmd, inc, i, res;
4218 int current_value; 4645 int current_value;
4646 int command_bits;
4219 4647
4220 if (value > ((tp_features.bright_16levels)? 15 : 7)) 4648 if (value > ((tp_features.bright_16levels)? 15 : 7) ||
4649 value < 0)
4221 return -EINVAL; 4650 return -EINVAL;
4222 4651
4223 res = mutex_lock_interruptible(&brightness_mutex); 4652 res = mutex_lock_interruptible(&brightness_mutex);
4224 if (res < 0) 4653 if (res < 0)
4225 return res; 4654 return res;
4226 4655
4227 current_value = brightness_get(NULL); 4656 res = brightness_get_raw(&current_value);
4228 if (current_value < 0) { 4657 if (res < 0)
4229 res = current_value;
4230 goto errout; 4658 goto errout;
4231 } 4659
4660 command_bits = current_value & TP_EC_BACKLIGHT_CMDMSK;
4661 current_value &= TP_EC_BACKLIGHT_LVLMSK;
4232 4662
4233 cmos_cmd = value > current_value ? 4663 cmos_cmd = value > current_value ?
4234 TP_CMOS_BRIGHTNESS_UP : 4664 TP_CMOS_BRIGHTNESS_UP :
@@ -4243,7 +4673,8 @@ static int brightness_set(int value)
4243 goto errout; 4673 goto errout;
4244 } 4674 }
4245 if ((brightness_mode & 1) && 4675 if ((brightness_mode & 1) &&
4246 !acpi_ec_write(brightness_offset, i + inc)) { 4676 !acpi_ec_write(TP_EC_BACKLIGHT,
4677 (i + inc) | command_bits)) {
4247 res = -EIO; 4678 res = -EIO;
4248 goto errout;; 4679 goto errout;;
4249 } 4680 }
@@ -4266,106 +4697,23 @@ static int brightness_update_status(struct backlight_device *bd)
4266 bd->props.brightness : 0); 4697 bd->props.brightness : 0);
4267} 4698}
4268 4699
4269static struct backlight_ops ibm_backlight_data = { 4700static int brightness_get(struct backlight_device *bd)
4270 .get_brightness = brightness_get,
4271 .update_status = brightness_update_status,
4272};
4273
4274/* --------------------------------------------------------------------- */
4275
4276static int __init tpacpi_query_bcll_levels(acpi_handle handle)
4277{
4278 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
4279 union acpi_object *obj;
4280 int rc;
4281
4282 if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) {
4283 obj = (union acpi_object *)buffer.pointer;
4284 if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
4285 printk(TPACPI_ERR "Unknown BCLL data, "
4286 "please report this to %s\n", TPACPI_MAIL);
4287 rc = 0;
4288 } else {
4289 rc = obj->package.count;
4290 }
4291 } else {
4292 return 0;
4293 }
4294
4295 kfree(buffer.pointer);
4296 return rc;
4297}
4298
4299static acpi_status __init brightness_find_bcll(acpi_handle handle, u32 lvl,
4300 void *context, void **rv)
4301{
4302 char name[ACPI_PATH_SEGMENT_LENGTH];
4303 struct acpi_buffer buffer = { sizeof(name), &name };
4304
4305 if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) &&
4306 !strncmp("BCLL", name, sizeof(name) - 1)) {
4307 if (tpacpi_query_bcll_levels(handle) == 16) {
4308 *rv = handle;
4309 return AE_CTRL_TERMINATE;
4310 } else {
4311 return AE_OK;
4312 }
4313 } else {
4314 return AE_OK;
4315 }
4316}
4317
4318static int __init brightness_check_levels(void)
4319{ 4701{
4320 int status; 4702 int status, res;
4321 void *found_node = NULL;
4322 4703
4323 if (!vid_handle) { 4704 res = brightness_get_raw(&status);
4324 TPACPI_ACPIHANDLE_INIT(vid); 4705 if (res < 0)
4325 } 4706 return 0; /* FIXME: teach backlight about error handling */
4326 if (!vid_handle)
4327 return 0;
4328
4329 /* Search for a BCLL package with 16 levels */
4330 status = acpi_walk_namespace(ACPI_TYPE_PACKAGE, vid_handle, 3,
4331 brightness_find_bcll, NULL,
4332 &found_node);
4333
4334 return (ACPI_SUCCESS(status) && found_node != NULL);
4335}
4336
4337static acpi_status __init brightness_find_bcl(acpi_handle handle, u32 lvl,
4338 void *context, void **rv)
4339{
4340 char name[ACPI_PATH_SEGMENT_LENGTH];
4341 struct acpi_buffer buffer = { sizeof(name), &name };
4342 4707
4343 if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) && 4708 return status & TP_EC_BACKLIGHT_LVLMSK;
4344 !strncmp("_BCL", name, sizeof(name) - 1)) {
4345 *rv = handle;
4346 return AE_CTRL_TERMINATE;
4347 } else {
4348 return AE_OK;
4349 }
4350} 4709}
4351 4710
4352static int __init brightness_check_std_acpi_support(void) 4711static struct backlight_ops ibm_backlight_data = {
4353{ 4712 .get_brightness = brightness_get,
4354 int status; 4713 .update_status = brightness_update_status,
4355 void *found_node = NULL; 4714};
4356
4357 if (!vid_handle) {
4358 TPACPI_ACPIHANDLE_INIT(vid);
4359 }
4360 if (!vid_handle)
4361 return 0;
4362
4363 /* Search for a _BCL method, but don't execute it */
4364 status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3,
4365 brightness_find_bcl, NULL, &found_node);
4366 4715
4367 return (ACPI_SUCCESS(status) && found_node != NULL); 4716/* --------------------------------------------------------------------- */
4368}
4369 4717
4370static int __init brightness_init(struct ibm_init_struct *iibm) 4718static int __init brightness_init(struct ibm_init_struct *iibm)
4371{ 4719{
@@ -4375,13 +4723,19 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
4375 4723
4376 mutex_init(&brightness_mutex); 4724 mutex_init(&brightness_mutex);
4377 4725
4378 if (!brightness_enable) { 4726 /*
4379 dbg_printk(TPACPI_DBG_INIT, 4727 * We always attempt to detect acpi support, so as to switch
4380 "brightness support disabled by " 4728 * Lenovo Vista BIOS to ACPI brightness mode even if we are not
4381 "module parameter\n"); 4729 * going to publish a backlight interface
4382 return 1; 4730 */
4383 } else if (brightness_enable > 1) { 4731 b = tpacpi_check_std_acpi_brightness_support();
4384 if (brightness_check_std_acpi_support()) { 4732 if (b > 0) {
4733 if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) {
4734 printk(TPACPI_NOTICE
4735 "Lenovo BIOS switched to ACPI backlight "
4736 "control mode\n");
4737 }
4738 if (brightness_enable > 1) {
4385 printk(TPACPI_NOTICE 4739 printk(TPACPI_NOTICE
4386 "standard ACPI backlight interface " 4740 "standard ACPI backlight interface "
4387 "available, not loading native one...\n"); 4741 "available, not loading native one...\n");
@@ -4389,6 +4743,22 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
4389 } 4743 }
4390 } 4744 }
4391 4745
4746 if (!brightness_enable) {
4747 dbg_printk(TPACPI_DBG_INIT,
4748 "brightness support disabled by "
4749 "module parameter\n");
4750 return 1;
4751 }
4752
4753 if (b > 16) {
4754 printk(TPACPI_ERR
4755 "Unsupported brightness interface, "
4756 "please contact %s\n", TPACPI_MAIL);
4757 return 1;
4758 }
4759 if (b == 16)
4760 tp_features.bright_16levels = 1;
4761
4392 if (!brightness_mode) { 4762 if (!brightness_mode) {
4393 if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) 4763 if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO)
4394 brightness_mode = 2; 4764 brightness_mode = 2;
@@ -4402,12 +4772,7 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
4402 if (brightness_mode > 3) 4772 if (brightness_mode > 3)
4403 return -EINVAL; 4773 return -EINVAL;
4404 4774
4405 tp_features.bright_16levels = 4775 if (brightness_get_raw(&b) < 0)
4406 thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO &&
4407 brightness_check_levels();
4408
4409 b = brightness_get(NULL);
4410 if (b < 0)
4411 return 1; 4776 return 1;
4412 4777
4413 if (tp_features.bright_16levels) 4778 if (tp_features.bright_16levels)
@@ -4425,7 +4790,7 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
4425 4790
4426 ibm_backlight_device->props.max_brightness = 4791 ibm_backlight_device->props.max_brightness =
4427 (tp_features.bright_16levels)? 15 : 7; 4792 (tp_features.bright_16levels)? 15 : 7;
4428 ibm_backlight_device->props.brightness = b; 4793 ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK;
4429 backlight_update_status(ibm_backlight_device); 4794 backlight_update_status(ibm_backlight_device);
4430 4795
4431 return 0; 4796 return 0;
@@ -5046,11 +5411,11 @@ static void fan_watchdog_reset(void)
5046 if (fan_watchdog_maxinterval > 0 && 5411 if (fan_watchdog_maxinterval > 0 &&
5047 tpacpi_lifecycle != TPACPI_LIFE_EXITING) { 5412 tpacpi_lifecycle != TPACPI_LIFE_EXITING) {
5048 fan_watchdog_active = 1; 5413 fan_watchdog_active = 1;
5049 if (!schedule_delayed_work(&fan_watchdog_task, 5414 if (!queue_delayed_work(tpacpi_wq, &fan_watchdog_task,
5050 msecs_to_jiffies(fan_watchdog_maxinterval 5415 msecs_to_jiffies(fan_watchdog_maxinterval
5051 * 1000))) { 5416 * 1000))) {
5052 printk(TPACPI_ERR 5417 printk(TPACPI_ERR
5053 "failed to schedule the fan watchdog, " 5418 "failed to queue the fan watchdog, "
5054 "watchdog will not trigger\n"); 5419 "watchdog will not trigger\n");
5055 } 5420 }
5056 } else 5421 } else
@@ -5420,7 +5785,7 @@ static void fan_exit(void)
5420 &driver_attr_fan_watchdog); 5785 &driver_attr_fan_watchdog);
5421 5786
5422 cancel_delayed_work(&fan_watchdog_task); 5787 cancel_delayed_work(&fan_watchdog_task);
5423 flush_scheduled_work(); 5788 flush_workqueue(tpacpi_wq);
5424} 5789}
5425 5790
5426static int fan_read(char *p) 5791static int fan_read(char *p)
@@ -5826,10 +6191,13 @@ static void __init get_thinkpad_model_data(struct thinkpad_id_data *tp)
5826 6191
5827 tp->model_str = kstrdup(dmi_get_system_info(DMI_PRODUCT_VERSION), 6192 tp->model_str = kstrdup(dmi_get_system_info(DMI_PRODUCT_VERSION),
5828 GFP_KERNEL); 6193 GFP_KERNEL);
5829 if (strnicmp(tp->model_str, "ThinkPad", 8) != 0) { 6194 if (tp->model_str && strnicmp(tp->model_str, "ThinkPad", 8) != 0) {
5830 kfree(tp->model_str); 6195 kfree(tp->model_str);
5831 tp->model_str = NULL; 6196 tp->model_str = NULL;
5832 } 6197 }
6198
6199 tp->nummodel_str = kstrdup(dmi_get_system_info(DMI_PRODUCT_NAME),
6200 GFP_KERNEL);
5833} 6201}
5834 6202
5835static int __init probe_for_thinkpad(void) 6203static int __init probe_for_thinkpad(void)
@@ -6071,6 +6439,9 @@ static void thinkpad_acpi_module_exit(void)
6071 if (proc_dir) 6439 if (proc_dir)
6072 remove_proc_entry(TPACPI_PROC_DIR, acpi_root_dir); 6440 remove_proc_entry(TPACPI_PROC_DIR, acpi_root_dir);
6073 6441
6442 if (tpacpi_wq)
6443 destroy_workqueue(tpacpi_wq);
6444
6074 kfree(thinkpad_id.bios_version_str); 6445 kfree(thinkpad_id.bios_version_str);
6075 kfree(thinkpad_id.ec_version_str); 6446 kfree(thinkpad_id.ec_version_str);
6076 kfree(thinkpad_id.model_str); 6447 kfree(thinkpad_id.model_str);
@@ -6101,6 +6472,12 @@ static int __init thinkpad_acpi_module_init(void)
6101 TPACPI_ACPIHANDLE_INIT(ecrd); 6472 TPACPI_ACPIHANDLE_INIT(ecrd);
6102 TPACPI_ACPIHANDLE_INIT(ecwr); 6473 TPACPI_ACPIHANDLE_INIT(ecwr);
6103 6474
6475 tpacpi_wq = create_singlethread_workqueue(TPACPI_WORKQUEUE_NAME);
6476 if (!tpacpi_wq) {
6477 thinkpad_acpi_module_exit();
6478 return -ENOMEM;
6479 }
6480
6104 proc_dir = proc_mkdir(TPACPI_PROC_DIR, acpi_root_dir); 6481 proc_dir = proc_mkdir(TPACPI_PROC_DIR, acpi_root_dir);
6105 if (!proc_dir) { 6482 if (!proc_dir) {
6106 printk(TPACPI_ERR 6483 printk(TPACPI_ERR
@@ -6223,6 +6600,8 @@ static int __init thinkpad_acpi_module_init(void)
6223/* Please remove this in year 2009 */ 6600/* Please remove this in year 2009 */
6224MODULE_ALIAS("ibm_acpi"); 6601MODULE_ALIAS("ibm_acpi");
6225 6602
6603MODULE_ALIAS(TPACPI_DRVR_SHORTNAME);
6604
6226/* 6605/*
6227 * DMI matching for module autoloading 6606 * DMI matching for module autoloading
6228 * 6607 *
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h
index 31a633f65547..4fe7c58f57e9 100644
--- a/drivers/pnp/base.h
+++ b/drivers/pnp/base.h
@@ -1,12 +1,78 @@
1extern spinlock_t pnp_lock; 1extern spinlock_t pnp_lock;
2void *pnp_alloc(long size); 2void *pnp_alloc(long size);
3
4int pnp_register_protocol(struct pnp_protocol *protocol);
5void pnp_unregister_protocol(struct pnp_protocol *protocol);
6
7#define PNP_EISA_ID_MASK 0x7fffffff
8void pnp_eisa_id_to_string(u32 id, char *str);
9struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *, int id, char *pnpid);
10struct pnp_card *pnp_alloc_card(struct pnp_protocol *, int id, char *pnpid);
11
12int pnp_add_device(struct pnp_dev *dev);
13struct pnp_id *pnp_add_id(struct pnp_dev *dev, char *id);
3int pnp_interface_attach_device(struct pnp_dev *dev); 14int pnp_interface_attach_device(struct pnp_dev *dev);
15
16int pnp_add_card(struct pnp_card *card);
17struct pnp_id *pnp_add_card_id(struct pnp_card *card, char *id);
18void pnp_remove_card(struct pnp_card *card);
19int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev);
20void pnp_remove_card_device(struct pnp_dev *dev);
21
22struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev);
23struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev,
24 int priority);
25int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option,
26 struct pnp_irq *data);
27int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option,
28 struct pnp_dma *data);
29int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option,
30 struct pnp_port *data);
31int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option,
32 struct pnp_mem *data);
33void pnp_init_resources(struct pnp_dev *dev);
34
4void pnp_fixup_device(struct pnp_dev *dev); 35void pnp_fixup_device(struct pnp_dev *dev);
5void pnp_free_option(struct pnp_option *option); 36void pnp_free_option(struct pnp_option *option);
6int __pnp_add_device(struct pnp_dev *dev); 37int __pnp_add_device(struct pnp_dev *dev);
7void __pnp_remove_device(struct pnp_dev *dev); 38void __pnp_remove_device(struct pnp_dev *dev);
8 39
9int pnp_check_port(struct pnp_dev * dev, int idx); 40int pnp_check_port(struct pnp_dev *dev, struct resource *res);
10int pnp_check_mem(struct pnp_dev * dev, int idx); 41int pnp_check_mem(struct pnp_dev *dev, struct resource *res);
11int pnp_check_irq(struct pnp_dev * dev, int idx); 42int pnp_check_irq(struct pnp_dev *dev, struct resource *res);
12int pnp_check_dma(struct pnp_dev * dev, int idx); 43int pnp_check_dma(struct pnp_dev *dev, struct resource *res);
44
45void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc);
46
47void pnp_init_resource(struct resource *res);
48
49struct pnp_resource *pnp_get_pnp_resource(struct pnp_dev *dev,
50 unsigned int type, unsigned int num);
51
52#define PNP_MAX_PORT 40
53#define PNP_MAX_MEM 24
54#define PNP_MAX_IRQ 2
55#define PNP_MAX_DMA 2
56
57struct pnp_resource {
58 struct resource res;
59 unsigned int index; /* ISAPNP config register index */
60};
61
62struct pnp_resource_table {
63 struct pnp_resource port[PNP_MAX_PORT];
64 struct pnp_resource mem[PNP_MAX_MEM];
65 struct pnp_resource dma[PNP_MAX_DMA];
66 struct pnp_resource irq[PNP_MAX_IRQ];
67};
68
69struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
70 int flags);
71struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma,
72 int flags);
73struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev,
74 resource_size_t start,
75 resource_size_t end, int flags);
76struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
77 resource_size_t start,
78 resource_size_t end, int flags);
diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c
index da1c9909eb44..a762a4176736 100644
--- a/drivers/pnp/card.c
+++ b/drivers/pnp/card.c
@@ -5,6 +5,7 @@
5 */ 5 */
6 6
7#include <linux/module.h> 7#include <linux/module.h>
8#include <linux/ctype.h>
8#include <linux/slab.h> 9#include <linux/slab.h>
9#include <linux/pnp.h> 10#include <linux/pnp.h>
10#include "base.h" 11#include "base.h"
@@ -100,19 +101,33 @@ static int card_probe(struct pnp_card *card, struct pnp_card_driver *drv)
100 * @id: pointer to a pnp_id structure 101 * @id: pointer to a pnp_id structure
101 * @card: pointer to the desired card 102 * @card: pointer to the desired card
102 */ 103 */
103int pnp_add_card_id(struct pnp_id *id, struct pnp_card *card) 104struct pnp_id *pnp_add_card_id(struct pnp_card *card, char *id)
104{ 105{
105 struct pnp_id *ptr; 106 struct pnp_id *dev_id, *ptr;
106 107
107 id->next = NULL; 108 dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
109 if (!dev_id)
110 return NULL;
111
112 dev_id->id[0] = id[0];
113 dev_id->id[1] = id[1];
114 dev_id->id[2] = id[2];
115 dev_id->id[3] = tolower(id[3]);
116 dev_id->id[4] = tolower(id[4]);
117 dev_id->id[5] = tolower(id[5]);
118 dev_id->id[6] = tolower(id[6]);
119 dev_id->id[7] = '\0';
120
121 dev_id->next = NULL;
108 ptr = card->id; 122 ptr = card->id;
109 while (ptr && ptr->next) 123 while (ptr && ptr->next)
110 ptr = ptr->next; 124 ptr = ptr->next;
111 if (ptr) 125 if (ptr)
112 ptr->next = id; 126 ptr->next = dev_id;
113 else 127 else
114 card->id = id; 128 card->id = dev_id;
115 return 0; 129
130 return dev_id;
116} 131}
117 132
118static void pnp_free_card_ids(struct pnp_card *card) 133static void pnp_free_card_ids(struct pnp_card *card)
@@ -136,6 +151,31 @@ static void pnp_release_card(struct device *dmdev)
136 kfree(card); 151 kfree(card);
137} 152}
138 153
154struct pnp_card *pnp_alloc_card(struct pnp_protocol *protocol, int id, char *pnpid)
155{
156 struct pnp_card *card;
157 struct pnp_id *dev_id;
158
159 card = kzalloc(sizeof(struct pnp_card), GFP_KERNEL);
160 if (!card)
161 return NULL;
162
163 card->protocol = protocol;
164 card->number = id;
165
166 card->dev.parent = &card->protocol->dev;
167 sprintf(card->dev.bus_id, "%02x:%02x", card->protocol->number,
168 card->number);
169
170 dev_id = pnp_add_card_id(card, pnpid);
171 if (!dev_id) {
172 kfree(card);
173 return NULL;
174 }
175
176 return card;
177}
178
139static ssize_t pnp_show_card_name(struct device *dmdev, 179static ssize_t pnp_show_card_name(struct device *dmdev,
140 struct device_attribute *attr, char *buf) 180 struct device_attribute *attr, char *buf)
141{ 181{
@@ -191,9 +231,6 @@ int pnp_add_card(struct pnp_card *card)
191 int error; 231 int error;
192 struct list_head *pos, *temp; 232 struct list_head *pos, *temp;
193 233
194 sprintf(card->dev.bus_id, "%02x:%02x", card->protocol->number,
195 card->number);
196 card->dev.parent = &card->protocol->dev;
197 card->dev.bus = NULL; 234 card->dev.bus = NULL;
198 card->dev.release = &pnp_release_card; 235 card->dev.release = &pnp_release_card;
199 error = device_register(&card->dev); 236 error = device_register(&card->dev);
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
index 7d366ca672d3..20771b7d4482 100644
--- a/drivers/pnp/core.c
+++ b/drivers/pnp/core.c
@@ -106,18 +106,53 @@ static void pnp_release_device(struct device *dmdev)
106 pnp_free_option(dev->independent); 106 pnp_free_option(dev->independent);
107 pnp_free_option(dev->dependent); 107 pnp_free_option(dev->dependent);
108 pnp_free_ids(dev); 108 pnp_free_ids(dev);
109 kfree(dev->res);
109 kfree(dev); 110 kfree(dev);
110} 111}
111 112
112int __pnp_add_device(struct pnp_dev *dev) 113struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, char *pnpid)
113{ 114{
114 int ret; 115 struct pnp_dev *dev;
116 struct pnp_id *dev_id;
115 117
116 pnp_fixup_device(dev); 118 dev = kzalloc(sizeof(struct pnp_dev), GFP_KERNEL);
119 if (!dev)
120 return NULL;
121
122 dev->res = kzalloc(sizeof(struct pnp_resource_table), GFP_KERNEL);
123 if (!dev->res) {
124 kfree(dev);
125 return NULL;
126 }
127
128 dev->protocol = protocol;
129 dev->number = id;
130 dev->dma_mask = DMA_24BIT_MASK;
131
132 dev->dev.parent = &dev->protocol->dev;
117 dev->dev.bus = &pnp_bus_type; 133 dev->dev.bus = &pnp_bus_type;
118 dev->dev.dma_mask = &dev->dma_mask; 134 dev->dev.dma_mask = &dev->dma_mask;
119 dev->dma_mask = dev->dev.coherent_dma_mask = DMA_24BIT_MASK; 135 dev->dev.coherent_dma_mask = dev->dma_mask;
120 dev->dev.release = &pnp_release_device; 136 dev->dev.release = &pnp_release_device;
137
138 sprintf(dev->dev.bus_id, "%02x:%02x", dev->protocol->number,
139 dev->number);
140
141 dev_id = pnp_add_id(dev, pnpid);
142 if (!dev_id) {
143 kfree(dev->res);
144 kfree(dev);
145 return NULL;
146 }
147
148 return dev;
149}
150
151int __pnp_add_device(struct pnp_dev *dev)
152{
153 int ret;
154
155 pnp_fixup_device(dev);
121 dev->status = PNP_READY; 156 dev->status = PNP_READY;
122 spin_lock(&pnp_lock); 157 spin_lock(&pnp_lock);
123 list_add_tail(&dev->global_list, &pnp_global); 158 list_add_tail(&dev->global_list, &pnp_global);
@@ -145,9 +180,6 @@ int pnp_add_device(struct pnp_dev *dev)
145 if (dev->card) 180 if (dev->card)
146 return -EINVAL; 181 return -EINVAL;
147 182
148 dev->dev.parent = &dev->protocol->dev;
149 sprintf(dev->dev.bus_id, "%02x:%02x", dev->protocol->number,
150 dev->number);
151 ret = __pnp_add_device(dev); 183 ret = __pnp_add_device(dev);
152 if (ret) 184 if (ret)
153 return ret; 185 return ret;
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c
index e85cbf116db1..d3f869ee1d92 100644
--- a/drivers/pnp/driver.c
+++ b/drivers/pnp/driver.c
@@ -226,22 +226,36 @@ void pnp_unregister_driver(struct pnp_driver *drv)
226 226
227/** 227/**
228 * pnp_add_id - adds an EISA id to the specified device 228 * pnp_add_id - adds an EISA id to the specified device
229 * @id: pointer to a pnp_id structure
230 * @dev: pointer to the desired device 229 * @dev: pointer to the desired device
230 * @id: pointer to an EISA id string
231 */ 231 */
232int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev) 232struct pnp_id *pnp_add_id(struct pnp_dev *dev, char *id)
233{ 233{
234 struct pnp_id *ptr; 234 struct pnp_id *dev_id, *ptr;
235 235
236 id->next = NULL; 236 dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
237 if (!dev_id)
238 return NULL;
239
240 dev_id->id[0] = id[0];
241 dev_id->id[1] = id[1];
242 dev_id->id[2] = id[2];
243 dev_id->id[3] = tolower(id[3]);
244 dev_id->id[4] = tolower(id[4]);
245 dev_id->id[5] = tolower(id[5]);
246 dev_id->id[6] = tolower(id[6]);
247 dev_id->id[7] = '\0';
248
249 dev_id->next = NULL;
237 ptr = dev->id; 250 ptr = dev->id;
238 while (ptr && ptr->next) 251 while (ptr && ptr->next)
239 ptr = ptr->next; 252 ptr = ptr->next;
240 if (ptr) 253 if (ptr)
241 ptr->next = id; 254 ptr->next = dev_id;
242 else 255 else
243 dev->id = id; 256 dev->id = dev_id;
244 return 0; 257
258 return dev_id;
245} 259}
246 260
247EXPORT_SYMBOL(pnp_register_driver); 261EXPORT_SYMBOL(pnp_register_driver);
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c
index 982658477a58..5d9301de1778 100644
--- a/drivers/pnp/interface.c
+++ b/drivers/pnp/interface.c
@@ -248,6 +248,7 @@ static ssize_t pnp_show_current_resources(struct device *dmdev,
248 char *buf) 248 char *buf)
249{ 249{
250 struct pnp_dev *dev = to_pnp_dev(dmdev); 250 struct pnp_dev *dev = to_pnp_dev(dmdev);
251 struct resource *res;
251 int i, ret; 252 int i, ret;
252 pnp_info_buffer_t *buffer; 253 pnp_info_buffer_t *buffer;
253 254
@@ -267,50 +268,46 @@ static ssize_t pnp_show_current_resources(struct device *dmdev,
267 else 268 else
268 pnp_printf(buffer, "disabled\n"); 269 pnp_printf(buffer, "disabled\n");
269 270
270 for (i = 0; i < PNP_MAX_PORT; i++) { 271 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) {
271 if (pnp_port_valid(dev, i)) { 272 if (pnp_resource_valid(res)) {
272 pnp_printf(buffer, "io"); 273 pnp_printf(buffer, "io");
273 if (pnp_port_flags(dev, i) & IORESOURCE_DISABLED) 274 if (res->flags & IORESOURCE_DISABLED)
274 pnp_printf(buffer, " disabled\n"); 275 pnp_printf(buffer, " disabled\n");
275 else 276 else
276 pnp_printf(buffer, " 0x%llx-0x%llx\n", 277 pnp_printf(buffer, " 0x%llx-0x%llx\n",
277 (unsigned long long) 278 (unsigned long long) res->start,
278 pnp_port_start(dev, i), 279 (unsigned long long) res->end);
279 (unsigned long long)pnp_port_end(dev,
280 i));
281 } 280 }
282 } 281 }
283 for (i = 0; i < PNP_MAX_MEM; i++) { 282 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
284 if (pnp_mem_valid(dev, i)) { 283 if (pnp_resource_valid(res)) {
285 pnp_printf(buffer, "mem"); 284 pnp_printf(buffer, "mem");
286 if (pnp_mem_flags(dev, i) & IORESOURCE_DISABLED) 285 if (res->flags & IORESOURCE_DISABLED)
287 pnp_printf(buffer, " disabled\n"); 286 pnp_printf(buffer, " disabled\n");
288 else 287 else
289 pnp_printf(buffer, " 0x%llx-0x%llx\n", 288 pnp_printf(buffer, " 0x%llx-0x%llx\n",
290 (unsigned long long) 289 (unsigned long long) res->start,
291 pnp_mem_start(dev, i), 290 (unsigned long long) res->end);
292 (unsigned long long)pnp_mem_end(dev,
293 i));
294 } 291 }
295 } 292 }
296 for (i = 0; i < PNP_MAX_IRQ; i++) { 293 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IRQ, i)); i++) {
297 if (pnp_irq_valid(dev, i)) { 294 if (pnp_resource_valid(res)) {
298 pnp_printf(buffer, "irq"); 295 pnp_printf(buffer, "irq");
299 if (pnp_irq_flags(dev, i) & IORESOURCE_DISABLED) 296 if (res->flags & IORESOURCE_DISABLED)
300 pnp_printf(buffer, " disabled\n"); 297 pnp_printf(buffer, " disabled\n");
301 else 298 else
302 pnp_printf(buffer, " %lld\n", 299 pnp_printf(buffer, " %lld\n",
303 (unsigned long long)pnp_irq(dev, i)); 300 (unsigned long long) res->start);
304 } 301 }
305 } 302 }
306 for (i = 0; i < PNP_MAX_DMA; i++) { 303 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_DMA, i)); i++) {
307 if (pnp_dma_valid(dev, i)) { 304 if (pnp_resource_valid(res)) {
308 pnp_printf(buffer, "dma"); 305 pnp_printf(buffer, "dma");
309 if (pnp_dma_flags(dev, i) & IORESOURCE_DISABLED) 306 if (res->flags & IORESOURCE_DISABLED)
310 pnp_printf(buffer, " disabled\n"); 307 pnp_printf(buffer, " disabled\n");
311 else 308 else
312 pnp_printf(buffer, " %lld\n", 309 pnp_printf(buffer, " %lld\n",
313 (unsigned long long)pnp_dma(dev, i)); 310 (unsigned long long) res->start);
314 } 311 }
315 } 312 }
316 ret = (buffer->curr - buf); 313 ret = (buffer->curr - buf);
@@ -323,8 +320,10 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
323 const char *ubuf, size_t count) 320 const char *ubuf, size_t count)
324{ 321{
325 struct pnp_dev *dev = to_pnp_dev(dmdev); 322 struct pnp_dev *dev = to_pnp_dev(dmdev);
323 struct pnp_resource *pnp_res;
326 char *buf = (void *)ubuf; 324 char *buf = (void *)ubuf;
327 int retval = 0; 325 int retval = 0;
326 resource_size_t start, end;
328 327
329 if (dev->status & PNP_ATTACHED) { 328 if (dev->status & PNP_ATTACHED) {
330 retval = -EBUSY; 329 retval = -EBUSY;
@@ -351,20 +350,20 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
351 if (!strnicmp(buf, "auto", 4)) { 350 if (!strnicmp(buf, "auto", 4)) {
352 if (dev->active) 351 if (dev->active)
353 goto done; 352 goto done;
354 pnp_init_resource_table(&dev->res); 353 pnp_init_resources(dev);
355 retval = pnp_auto_config_dev(dev); 354 retval = pnp_auto_config_dev(dev);
356 goto done; 355 goto done;
357 } 356 }
358 if (!strnicmp(buf, "clear", 5)) { 357 if (!strnicmp(buf, "clear", 5)) {
359 if (dev->active) 358 if (dev->active)
360 goto done; 359 goto done;
361 pnp_init_resource_table(&dev->res); 360 pnp_init_resources(dev);
362 goto done; 361 goto done;
363 } 362 }
364 if (!strnicmp(buf, "get", 3)) { 363 if (!strnicmp(buf, "get", 3)) {
365 mutex_lock(&pnp_res_mutex); 364 mutex_lock(&pnp_res_mutex);
366 if (pnp_can_read(dev)) 365 if (pnp_can_read(dev))
367 dev->protocol->get(dev, &dev->res); 366 dev->protocol->get(dev);
368 mutex_unlock(&pnp_res_mutex); 367 mutex_unlock(&pnp_res_mutex);
369 goto done; 368 goto done;
370 } 369 }
@@ -373,7 +372,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
373 if (dev->active) 372 if (dev->active)
374 goto done; 373 goto done;
375 buf += 3; 374 buf += 3;
376 pnp_init_resource_table(&dev->res); 375 pnp_init_resources(dev);
377 mutex_lock(&pnp_res_mutex); 376 mutex_lock(&pnp_res_mutex);
378 while (1) { 377 while (1) {
379 while (isspace(*buf)) 378 while (isspace(*buf))
@@ -382,76 +381,60 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
382 buf += 2; 381 buf += 2;
383 while (isspace(*buf)) 382 while (isspace(*buf))
384 ++buf; 383 ++buf;
385 dev->res.port_resource[nport].start = 384 start = simple_strtoul(buf, &buf, 0);
386 simple_strtoul(buf, &buf, 0);
387 while (isspace(*buf)) 385 while (isspace(*buf))
388 ++buf; 386 ++buf;
389 if (*buf == '-') { 387 if (*buf == '-') {
390 buf += 1; 388 buf += 1;
391 while (isspace(*buf)) 389 while (isspace(*buf))
392 ++buf; 390 ++buf;
393 dev->res.port_resource[nport].end = 391 end = simple_strtoul(buf, &buf, 0);
394 simple_strtoul(buf, &buf, 0);
395 } else 392 } else
396 dev->res.port_resource[nport].end = 393 end = start;
397 dev->res.port_resource[nport].start; 394 pnp_res = pnp_add_io_resource(dev, start, end,
398 dev->res.port_resource[nport].flags = 395 0);
399 IORESOURCE_IO; 396 if (pnp_res)
400 nport++; 397 pnp_res->index = nport++;
401 if (nport >= PNP_MAX_PORT)
402 break;
403 continue; 398 continue;
404 } 399 }
405 if (!strnicmp(buf, "mem", 3)) { 400 if (!strnicmp(buf, "mem", 3)) {
406 buf += 3; 401 buf += 3;
407 while (isspace(*buf)) 402 while (isspace(*buf))
408 ++buf; 403 ++buf;
409 dev->res.mem_resource[nmem].start = 404 start = simple_strtoul(buf, &buf, 0);
410 simple_strtoul(buf, &buf, 0);
411 while (isspace(*buf)) 405 while (isspace(*buf))
412 ++buf; 406 ++buf;
413 if (*buf == '-') { 407 if (*buf == '-') {
414 buf += 1; 408 buf += 1;
415 while (isspace(*buf)) 409 while (isspace(*buf))
416 ++buf; 410 ++buf;
417 dev->res.mem_resource[nmem].end = 411 end = simple_strtoul(buf, &buf, 0);
418 simple_strtoul(buf, &buf, 0);
419 } else 412 } else
420 dev->res.mem_resource[nmem].end = 413 end = start;
421 dev->res.mem_resource[nmem].start; 414 pnp_res = pnp_add_mem_resource(dev, start, end,
422 dev->res.mem_resource[nmem].flags = 415 0);
423 IORESOURCE_MEM; 416 if (pnp_res)
424 nmem++; 417 pnp_res->index = nmem++;
425 if (nmem >= PNP_MAX_MEM)
426 break;
427 continue; 418 continue;
428 } 419 }
429 if (!strnicmp(buf, "irq", 3)) { 420 if (!strnicmp(buf, "irq", 3)) {
430 buf += 3; 421 buf += 3;
431 while (isspace(*buf)) 422 while (isspace(*buf))
432 ++buf; 423 ++buf;
433 dev->res.irq_resource[nirq].start = 424 start = simple_strtoul(buf, &buf, 0);
434 dev->res.irq_resource[nirq].end = 425 pnp_res = pnp_add_irq_resource(dev, start, 0);
435 simple_strtoul(buf, &buf, 0); 426 if (pnp_res)
436 dev->res.irq_resource[nirq].flags = 427 nirq++;
437 IORESOURCE_IRQ;
438 nirq++;
439 if (nirq >= PNP_MAX_IRQ)
440 break;
441 continue; 428 continue;
442 } 429 }
443 if (!strnicmp(buf, "dma", 3)) { 430 if (!strnicmp(buf, "dma", 3)) {
444 buf += 3; 431 buf += 3;
445 while (isspace(*buf)) 432 while (isspace(*buf))
446 ++buf; 433 ++buf;
447 dev->res.dma_resource[ndma].start = 434 start = simple_strtoul(buf, &buf, 0);
448 dev->res.dma_resource[ndma].end = 435 pnp_res = pnp_add_dma_resource(dev, start, 0);
449 simple_strtoul(buf, &buf, 0); 436 if (pnp_res)
450 dev->res.dma_resource[ndma].flags = 437 pnp_res->index = ndma++;
451 IORESOURCE_DMA;
452 ndma++;
453 if (ndma >= PNP_MAX_DMA)
454 break;
455 continue; 438 continue;
456 } 439 }
457 break; 440 break;
diff --git a/drivers/pnp/isapnp/Makefile b/drivers/pnp/isapnp/Makefile
index cac18bbfb817..3e38f06f8d78 100644
--- a/drivers/pnp/isapnp/Makefile
+++ b/drivers/pnp/isapnp/Makefile
@@ -5,3 +5,7 @@
5isapnp-proc-$(CONFIG_PROC_FS) = proc.o 5isapnp-proc-$(CONFIG_PROC_FS) = proc.o
6 6
7obj-y := core.o compat.o $(isapnp-proc-y) 7obj-y := core.o compat.o $(isapnp-proc-y)
8
9ifeq ($(CONFIG_PNP_DEBUG),y)
10EXTRA_CFLAGS += -DDEBUG
11endif
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index 257f5d827d83..f1bccdbdeb08 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -44,6 +44,8 @@
44#include <linux/mutex.h> 44#include <linux/mutex.h>
45#include <asm/io.h> 45#include <asm/io.h>
46 46
47#include "../base.h"
48
47#if 0 49#if 0
48#define ISAPNP_REGION_OK 50#define ISAPNP_REGION_OK
49#endif 51#endif
@@ -88,6 +90,14 @@ MODULE_LICENSE("GPL");
88#define _LTAG_MEM32RANGE 0x85 90#define _LTAG_MEM32RANGE 0x85
89#define _LTAG_FIXEDMEM32RANGE 0x86 91#define _LTAG_FIXEDMEM32RANGE 0x86
90 92
93/* Logical device control and configuration registers */
94
95#define ISAPNP_CFG_ACTIVATE 0x30 /* byte */
96#define ISAPNP_CFG_MEM 0x40 /* 4 * dword */
97#define ISAPNP_CFG_PORT 0x60 /* 8 * word */
98#define ISAPNP_CFG_IRQ 0x70 /* 2 * word */
99#define ISAPNP_CFG_DMA 0x74 /* 2 * byte */
100
91/* 101/*
92 * Sizes of ISAPNP logical device configuration register sets. 102 * Sizes of ISAPNP logical device configuration register sets.
93 * See PNP-ISA-v1.0a.pdf, Appendix A. 103 * See PNP-ISA-v1.0a.pdf, Appendix A.
@@ -388,28 +398,6 @@ static void __init isapnp_skip_bytes(int count)
388} 398}
389 399
390/* 400/*
391 * Parse EISA id.
392 */
393static void isapnp_parse_id(struct pnp_dev *dev, unsigned short vendor,
394 unsigned short device)
395{
396 struct pnp_id *id;
397
398 if (!dev)
399 return;
400 id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
401 if (!id)
402 return;
403 sprintf(id->id, "%c%c%c%x%x%x%x",
404 'A' + ((vendor >> 2) & 0x3f) - 1,
405 'A' + (((vendor & 3) << 3) | ((vendor >> 13) & 7)) - 1,
406 'A' + ((vendor >> 8) & 0x1f) - 1,
407 (device >> 4) & 0x0f,
408 device & 0x0f, (device >> 12) & 0x0f, (device >> 8) & 0x0f);
409 pnp_add_id(id, dev);
410}
411
412/*
413 * Parse logical device tag. 401 * Parse logical device tag.
414 */ 402 */
415static struct pnp_dev *__init isapnp_parse_device(struct pnp_card *card, 403static struct pnp_dev *__init isapnp_parse_device(struct pnp_card *card,
@@ -417,30 +405,31 @@ static struct pnp_dev *__init isapnp_parse_device(struct pnp_card *card,
417{ 405{
418 unsigned char tmp[6]; 406 unsigned char tmp[6];
419 struct pnp_dev *dev; 407 struct pnp_dev *dev;
408 u32 eisa_id;
409 char id[8];
420 410
421 isapnp_peek(tmp, size); 411 isapnp_peek(tmp, size);
422 dev = kzalloc(sizeof(struct pnp_dev), GFP_KERNEL); 412 eisa_id = tmp[0] | tmp[1] << 8 | tmp[2] << 16 | tmp[3] << 24;
413 pnp_eisa_id_to_string(eisa_id, id);
414
415 dev = pnp_alloc_dev(&isapnp_protocol, number, id);
423 if (!dev) 416 if (!dev)
424 return NULL; 417 return NULL;
425 dev->number = number; 418
426 isapnp_parse_id(dev, (tmp[1] << 8) | tmp[0], (tmp[3] << 8) | tmp[2]);
427 dev->regs = tmp[4];
428 dev->card = card; 419 dev->card = card;
429 if (size > 5)
430 dev->regs |= tmp[5] << 8;
431 dev->protocol = &isapnp_protocol;
432 dev->capabilities |= PNP_CONFIGURABLE; 420 dev->capabilities |= PNP_CONFIGURABLE;
433 dev->capabilities |= PNP_READ; 421 dev->capabilities |= PNP_READ;
434 dev->capabilities |= PNP_WRITE; 422 dev->capabilities |= PNP_WRITE;
435 dev->capabilities |= PNP_DISABLE; 423 dev->capabilities |= PNP_DISABLE;
436 pnp_init_resource_table(&dev->res); 424 pnp_init_resources(dev);
437 return dev; 425 return dev;
438} 426}
439 427
440/* 428/*
441 * Add IRQ resource to resources list. 429 * Add IRQ resource to resources list.
442 */ 430 */
443static void __init isapnp_parse_irq_resource(struct pnp_option *option, 431static void __init isapnp_parse_irq_resource(struct pnp_dev *dev,
432 struct pnp_option *option,
444 int size) 433 int size)
445{ 434{
446 unsigned char tmp[3]; 435 unsigned char tmp[3];
@@ -457,13 +446,14 @@ static void __init isapnp_parse_irq_resource(struct pnp_option *option,
457 irq->flags = tmp[2]; 446 irq->flags = tmp[2];
458 else 447 else
459 irq->flags = IORESOURCE_IRQ_HIGHEDGE; 448 irq->flags = IORESOURCE_IRQ_HIGHEDGE;
460 pnp_register_irq_resource(option, irq); 449 pnp_register_irq_resource(dev, option, irq);
461} 450}
462 451
463/* 452/*
464 * Add DMA resource to resources list. 453 * Add DMA resource to resources list.
465 */ 454 */
466static void __init isapnp_parse_dma_resource(struct pnp_option *option, 455static void __init isapnp_parse_dma_resource(struct pnp_dev *dev,
456 struct pnp_option *option,
467 int size) 457 int size)
468{ 458{
469 unsigned char tmp[2]; 459 unsigned char tmp[2];
@@ -475,13 +465,14 @@ static void __init isapnp_parse_dma_resource(struct pnp_option *option,
475 return; 465 return;
476 dma->map = tmp[0]; 466 dma->map = tmp[0];
477 dma->flags = tmp[1]; 467 dma->flags = tmp[1];
478 pnp_register_dma_resource(option, dma); 468 pnp_register_dma_resource(dev, option, dma);
479} 469}
480 470
481/* 471/*
482 * Add port resource to resources list. 472 * Add port resource to resources list.
483 */ 473 */
484static void __init isapnp_parse_port_resource(struct pnp_option *option, 474static void __init isapnp_parse_port_resource(struct pnp_dev *dev,
475 struct pnp_option *option,
485 int size) 476 int size)
486{ 477{
487 unsigned char tmp[7]; 478 unsigned char tmp[7];
@@ -496,13 +487,14 @@ static void __init isapnp_parse_port_resource(struct pnp_option *option,
496 port->align = tmp[5]; 487 port->align = tmp[5];
497 port->size = tmp[6]; 488 port->size = tmp[6];
498 port->flags = tmp[0] ? PNP_PORT_FLAG_16BITADDR : 0; 489 port->flags = tmp[0] ? PNP_PORT_FLAG_16BITADDR : 0;
499 pnp_register_port_resource(option, port); 490 pnp_register_port_resource(dev, option, port);
500} 491}
501 492
502/* 493/*
503 * Add fixed port resource to resources list. 494 * Add fixed port resource to resources list.
504 */ 495 */
505static void __init isapnp_parse_fixed_port_resource(struct pnp_option *option, 496static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev,
497 struct pnp_option *option,
506 int size) 498 int size)
507{ 499{
508 unsigned char tmp[3]; 500 unsigned char tmp[3];
@@ -516,13 +508,14 @@ static void __init isapnp_parse_fixed_port_resource(struct pnp_option *option,
516 port->size = tmp[2]; 508 port->size = tmp[2];
517 port->align = 0; 509 port->align = 0;
518 port->flags = PNP_PORT_FLAG_FIXED; 510 port->flags = PNP_PORT_FLAG_FIXED;
519 pnp_register_port_resource(option, port); 511 pnp_register_port_resource(dev, option, port);
520} 512}
521 513
522/* 514/*
523 * Add memory resource to resources list. 515 * Add memory resource to resources list.
524 */ 516 */
525static void __init isapnp_parse_mem_resource(struct pnp_option *option, 517static void __init isapnp_parse_mem_resource(struct pnp_dev *dev,
518 struct pnp_option *option,
526 int size) 519 int size)
527{ 520{
528 unsigned char tmp[9]; 521 unsigned char tmp[9];
@@ -537,13 +530,14 @@ static void __init isapnp_parse_mem_resource(struct pnp_option *option,
537 mem->align = (tmp[6] << 8) | tmp[5]; 530 mem->align = (tmp[6] << 8) | tmp[5];
538 mem->size = ((tmp[8] << 8) | tmp[7]) << 8; 531 mem->size = ((tmp[8] << 8) | tmp[7]) << 8;
539 mem->flags = tmp[0]; 532 mem->flags = tmp[0];
540 pnp_register_mem_resource(option, mem); 533 pnp_register_mem_resource(dev, option, mem);
541} 534}
542 535
543/* 536/*
544 * Add 32-bit memory resource to resources list. 537 * Add 32-bit memory resource to resources list.
545 */ 538 */
546static void __init isapnp_parse_mem32_resource(struct pnp_option *option, 539static void __init isapnp_parse_mem32_resource(struct pnp_dev *dev,
540 struct pnp_option *option,
547 int size) 541 int size)
548{ 542{
549 unsigned char tmp[17]; 543 unsigned char tmp[17];
@@ -560,13 +554,14 @@ static void __init isapnp_parse_mem32_resource(struct pnp_option *option,
560 mem->size = 554 mem->size =
561 (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13]; 555 (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13];
562 mem->flags = tmp[0]; 556 mem->flags = tmp[0];
563 pnp_register_mem_resource(option, mem); 557 pnp_register_mem_resource(dev, option, mem);
564} 558}
565 559
566/* 560/*
567 * Add 32-bit fixed memory resource to resources list. 561 * Add 32-bit fixed memory resource to resources list.
568 */ 562 */
569static void __init isapnp_parse_fixed_mem32_resource(struct pnp_option *option, 563static void __init isapnp_parse_fixed_mem32_resource(struct pnp_dev *dev,
564 struct pnp_option *option,
570 int size) 565 int size)
571{ 566{
572 unsigned char tmp[9]; 567 unsigned char tmp[9];
@@ -581,7 +576,7 @@ static void __init isapnp_parse_fixed_mem32_resource(struct pnp_option *option,
581 mem->size = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5]; 576 mem->size = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
582 mem->align = 0; 577 mem->align = 0;
583 mem->flags = tmp[0]; 578 mem->flags = tmp[0];
584 pnp_register_mem_resource(option, mem); 579 pnp_register_mem_resource(dev, option, mem);
585} 580}
586 581
587/* 582/*
@@ -613,6 +608,8 @@ static int __init isapnp_create_device(struct pnp_card *card,
613 unsigned char type, tmp[17]; 608 unsigned char type, tmp[17];
614 struct pnp_option *option; 609 struct pnp_option *option;
615 struct pnp_dev *dev; 610 struct pnp_dev *dev;
611 u32 eisa_id;
612 char id[8];
616 613
617 if ((dev = isapnp_parse_device(card, size, number++)) == NULL) 614 if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
618 return 1; 615 return 1;
@@ -652,8 +649,10 @@ static int __init isapnp_create_device(struct pnp_card *card,
652 case _STAG_COMPATDEVID: 649 case _STAG_COMPATDEVID:
653 if (size == 4 && compat < DEVICE_COUNT_COMPATIBLE) { 650 if (size == 4 && compat < DEVICE_COUNT_COMPATIBLE) {
654 isapnp_peek(tmp, 4); 651 isapnp_peek(tmp, 4);
655 isapnp_parse_id(dev, (tmp[1] << 8) | tmp[0], 652 eisa_id = tmp[0] | tmp[1] << 8 |
656 (tmp[3] << 8) | tmp[2]); 653 tmp[2] << 16 | tmp[3] << 24;
654 pnp_eisa_id_to_string(eisa_id, id);
655 pnp_add_id(dev, id);
657 compat++; 656 compat++;
658 size = 0; 657 size = 0;
659 } 658 }
@@ -661,13 +660,13 @@ static int __init isapnp_create_device(struct pnp_card *card,
661 case _STAG_IRQ: 660 case _STAG_IRQ:
662 if (size < 2 || size > 3) 661 if (size < 2 || size > 3)
663 goto __skip; 662 goto __skip;
664 isapnp_parse_irq_resource(option, size); 663 isapnp_parse_irq_resource(dev, option, size);
665 size = 0; 664 size = 0;
666 break; 665 break;
667 case _STAG_DMA: 666 case _STAG_DMA:
668 if (size != 2) 667 if (size != 2)
669 goto __skip; 668 goto __skip;
670 isapnp_parse_dma_resource(option, size); 669 isapnp_parse_dma_resource(dev, option, size);
671 size = 0; 670 size = 0;
672 break; 671 break;
673 case _STAG_STARTDEP: 672 case _STAG_STARTDEP:
@@ -687,17 +686,18 @@ static int __init isapnp_create_device(struct pnp_card *card,
687 if (size != 0) 686 if (size != 0)
688 goto __skip; 687 goto __skip;
689 priority = 0; 688 priority = 0;
689 dev_dbg(&dev->dev, "end dependent options\n");
690 break; 690 break;
691 case _STAG_IOPORT: 691 case _STAG_IOPORT:
692 if (size != 7) 692 if (size != 7)
693 goto __skip; 693 goto __skip;
694 isapnp_parse_port_resource(option, size); 694 isapnp_parse_port_resource(dev, option, size);
695 size = 0; 695 size = 0;
696 break; 696 break;
697 case _STAG_FIXEDIO: 697 case _STAG_FIXEDIO:
698 if (size != 3) 698 if (size != 3)
699 goto __skip; 699 goto __skip;
700 isapnp_parse_fixed_port_resource(option, size); 700 isapnp_parse_fixed_port_resource(dev, option, size);
701 size = 0; 701 size = 0;
702 break; 702 break;
703 case _STAG_VENDOR: 703 case _STAG_VENDOR:
@@ -705,7 +705,7 @@ static int __init isapnp_create_device(struct pnp_card *card,
705 case _LTAG_MEMRANGE: 705 case _LTAG_MEMRANGE:
706 if (size != 9) 706 if (size != 9)
707 goto __skip; 707 goto __skip;
708 isapnp_parse_mem_resource(option, size); 708 isapnp_parse_mem_resource(dev, option, size);
709 size = 0; 709 size = 0;
710 break; 710 break;
711 case _LTAG_ANSISTR: 711 case _LTAG_ANSISTR:
@@ -720,13 +720,13 @@ static int __init isapnp_create_device(struct pnp_card *card,
720 case _LTAG_MEM32RANGE: 720 case _LTAG_MEM32RANGE:
721 if (size != 17) 721 if (size != 17)
722 goto __skip; 722 goto __skip;
723 isapnp_parse_mem32_resource(option, size); 723 isapnp_parse_mem32_resource(dev, option, size);
724 size = 0; 724 size = 0;
725 break; 725 break;
726 case _LTAG_FIXEDMEM32RANGE: 726 case _LTAG_FIXEDMEM32RANGE:
727 if (size != 9) 727 if (size != 9)
728 goto __skip; 728 goto __skip;
729 isapnp_parse_fixed_mem32_resource(option, size); 729 isapnp_parse_fixed_mem32_resource(dev, option, size);
730 size = 0; 730 size = 0;
731 break; 731 break;
732 case _STAG_END: 732 case _STAG_END:
@@ -734,9 +734,8 @@ static int __init isapnp_create_device(struct pnp_card *card,
734 isapnp_skip_bytes(size); 734 isapnp_skip_bytes(size);
735 return 1; 735 return 1;
736 default: 736 default:
737 printk(KERN_ERR 737 dev_err(&dev->dev, "unknown tag %#x (card %i), "
738 "isapnp: unexpected or unknown tag type 0x%x for logical device %i (device %i), ignored\n", 738 "ignored\n", type, card->number);
739 type, dev->number, card->number);
740 } 739 }
741__skip: 740__skip:
742 if (size > 0) 741 if (size > 0)
@@ -789,9 +788,8 @@ static void __init isapnp_parse_resource_map(struct pnp_card *card)
789 isapnp_skip_bytes(size); 788 isapnp_skip_bytes(size);
790 return; 789 return;
791 default: 790 default:
792 printk(KERN_ERR 791 dev_err(&card->dev, "unknown tag %#x, ignored\n",
793 "isapnp: unexpected or unknown tag type 0x%x for device %i, ignored\n", 792 type);
794 type, card->number);
795 } 793 }
796__skip: 794__skip:
797 if (size > 0) 795 if (size > 0)
@@ -822,25 +820,6 @@ static unsigned char __init isapnp_checksum(unsigned char *data)
822} 820}
823 821
824/* 822/*
825 * Parse EISA id for ISA PnP card.
826 */
827static void isapnp_parse_card_id(struct pnp_card *card, unsigned short vendor,
828 unsigned short device)
829{
830 struct pnp_id *id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
831
832 if (!id)
833 return;
834 sprintf(id->id, "%c%c%c%x%x%x%x",
835 'A' + ((vendor >> 2) & 0x3f) - 1,
836 'A' + (((vendor & 3) << 3) | ((vendor >> 13) & 7)) - 1,
837 'A' + ((vendor >> 8) & 0x1f) - 1,
838 (device >> 4) & 0x0f,
839 device & 0x0f, (device >> 12) & 0x0f, (device >> 8) & 0x0f);
840 pnp_add_card_id(id, card);
841}
842
843/*
844 * Build device list for all present ISA PnP devices. 823 * Build device list for all present ISA PnP devices.
845 */ 824 */
846static int __init isapnp_build_device_list(void) 825static int __init isapnp_build_device_list(void)
@@ -848,6 +827,8 @@ static int __init isapnp_build_device_list(void)
848 int csn; 827 int csn;
849 unsigned char header[9], checksum; 828 unsigned char header[9], checksum;
850 struct pnp_card *card; 829 struct pnp_card *card;
830 u32 eisa_id;
831 char id[8];
851 832
852 isapnp_wait(); 833 isapnp_wait();
853 isapnp_key(); 834 isapnp_key();
@@ -855,32 +836,30 @@ static int __init isapnp_build_device_list(void)
855 isapnp_wake(csn); 836 isapnp_wake(csn);
856 isapnp_peek(header, 9); 837 isapnp_peek(header, 9);
857 checksum = isapnp_checksum(header); 838 checksum = isapnp_checksum(header);
839 eisa_id = header[0] | header[1] << 8 |
840 header[2] << 16 | header[3] << 24;
841 pnp_eisa_id_to_string(eisa_id, id);
842 card = pnp_alloc_card(&isapnp_protocol, csn, id);
843 if (!card)
844 continue;
845
858#if 0 846#if 0
859 printk(KERN_DEBUG 847 dev_info(&card->dev,
860 "vendor: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", 848 "vendor: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
861 header[0], header[1], header[2], header[3], header[4], 849 header[0], header[1], header[2], header[3], header[4],
862 header[5], header[6], header[7], header[8]); 850 header[5], header[6], header[7], header[8]);
863 printk(KERN_DEBUG "checksum = 0x%x\n", checksum); 851 dev_info(&card->dev, "checksum = %#x\n", checksum);
864#endif 852#endif
865 if ((card =
866 kzalloc(sizeof(struct pnp_card), GFP_KERNEL)) == NULL)
867 continue;
868
869 card->number = csn;
870 INIT_LIST_HEAD(&card->devices); 853 INIT_LIST_HEAD(&card->devices);
871 isapnp_parse_card_id(card, (header[1] << 8) | header[0],
872 (header[3] << 8) | header[2]);
873 card->serial = 854 card->serial =
874 (header[7] << 24) | (header[6] << 16) | (header[5] << 8) | 855 (header[7] << 24) | (header[6] << 16) | (header[5] << 8) |
875 header[4]; 856 header[4];
876 isapnp_checksum_value = 0x00; 857 isapnp_checksum_value = 0x00;
877 isapnp_parse_resource_map(card); 858 isapnp_parse_resource_map(card);
878 if (isapnp_checksum_value != 0x00) 859 if (isapnp_checksum_value != 0x00)
879 printk(KERN_ERR 860 dev_err(&card->dev, "invalid checksum %#x\n",
880 "isapnp: checksum for device %i is not valid (0x%x)\n", 861 isapnp_checksum_value);
881 csn, isapnp_checksum_value);
882 card->checksum = isapnp_checksum_value; 862 card->checksum = isapnp_checksum_value;
883 card->protocol = &isapnp_protocol;
884 863
885 pnp_add_card(card); 864 pnp_add_card(card);
886 } 865 }
@@ -947,100 +926,117 @@ EXPORT_SYMBOL(isapnp_cfg_begin);
947EXPORT_SYMBOL(isapnp_cfg_end); 926EXPORT_SYMBOL(isapnp_cfg_end);
948EXPORT_SYMBOL(isapnp_write_byte); 927EXPORT_SYMBOL(isapnp_write_byte);
949 928
950static int isapnp_read_resources(struct pnp_dev *dev, 929static int isapnp_get_resources(struct pnp_dev *dev)
951 struct pnp_resource_table *res)
952{ 930{
953 int tmp, ret; 931 struct pnp_resource *pnp_res;
932 int i, ret;
954 933
934 dev_dbg(&dev->dev, "get resources\n");
935 pnp_init_resources(dev);
936 isapnp_cfg_begin(dev->card->number, dev->number);
955 dev->active = isapnp_read_byte(ISAPNP_CFG_ACTIVATE); 937 dev->active = isapnp_read_byte(ISAPNP_CFG_ACTIVATE);
956 if (dev->active) { 938 if (!dev->active)
957 for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) { 939 goto __end;
958 ret = isapnp_read_word(ISAPNP_CFG_PORT + (tmp << 1)); 940
959 if (!ret) 941 for (i = 0; i < ISAPNP_MAX_PORT; i++) {
960 continue; 942 ret = isapnp_read_word(ISAPNP_CFG_PORT + (i << 1));
961 res->port_resource[tmp].start = ret; 943 if (ret) {
962 res->port_resource[tmp].flags = IORESOURCE_IO; 944 pnp_res = pnp_add_io_resource(dev, ret, ret, 0);
945 if (pnp_res)
946 pnp_res->index = i;
963 } 947 }
964 for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) { 948 }
965 ret = 949 for (i = 0; i < ISAPNP_MAX_MEM; i++) {
966 isapnp_read_word(ISAPNP_CFG_MEM + (tmp << 3)) << 8; 950 ret = isapnp_read_word(ISAPNP_CFG_MEM + (i << 3)) << 8;
967 if (!ret) 951 if (ret) {
968 continue; 952 pnp_res = pnp_add_mem_resource(dev, ret, ret, 0);
969 res->mem_resource[tmp].start = ret; 953 if (pnp_res)
970 res->mem_resource[tmp].flags = IORESOURCE_MEM; 954 pnp_res->index = i;
971 } 955 }
972 for (tmp = 0; tmp < ISAPNP_MAX_IRQ; tmp++) { 956 }
973 ret = 957 for (i = 0; i < ISAPNP_MAX_IRQ; i++) {
974 (isapnp_read_word(ISAPNP_CFG_IRQ + (tmp << 1)) >> 958 ret = isapnp_read_word(ISAPNP_CFG_IRQ + (i << 1)) >> 8;
975 8); 959 if (ret) {
976 if (!ret) 960 pnp_res = pnp_add_irq_resource(dev, ret, 0);
977 continue; 961 if (pnp_res)
978 res->irq_resource[tmp].start = 962 pnp_res->index = i;
979 res->irq_resource[tmp].end = ret;
980 res->irq_resource[tmp].flags = IORESOURCE_IRQ;
981 } 963 }
982 for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) { 964 }
983 ret = isapnp_read_byte(ISAPNP_CFG_DMA + tmp); 965 for (i = 0; i < ISAPNP_MAX_DMA; i++) {
984 if (ret == 4) 966 ret = isapnp_read_byte(ISAPNP_CFG_DMA + i);
985 continue; 967 if (ret != 4) {
986 res->dma_resource[tmp].start = 968 pnp_res = pnp_add_dma_resource(dev, ret, 0);
987 res->dma_resource[tmp].end = ret; 969 if (pnp_res)
988 res->dma_resource[tmp].flags = IORESOURCE_DMA; 970 pnp_res->index = i;
989 } 971 }
990 } 972 }
991 return 0;
992}
993
994static int isapnp_get_resources(struct pnp_dev *dev,
995 struct pnp_resource_table *res)
996{
997 int ret;
998 973
999 pnp_init_resource_table(res); 974__end:
1000 isapnp_cfg_begin(dev->card->number, dev->number);
1001 ret = isapnp_read_resources(dev, res);
1002 isapnp_cfg_end(); 975 isapnp_cfg_end();
1003 return ret; 976 return 0;
1004} 977}
1005 978
1006static int isapnp_set_resources(struct pnp_dev *dev, 979static int isapnp_set_resources(struct pnp_dev *dev)
1007 struct pnp_resource_table *res)
1008{ 980{
1009 int tmp; 981 struct pnp_resource *pnp_res;
982 struct resource *res;
983 int tmp, index;
1010 984
985 dev_dbg(&dev->dev, "set resources\n");
1011 isapnp_cfg_begin(dev->card->number, dev->number); 986 isapnp_cfg_begin(dev->card->number, dev->number);
1012 dev->active = 1; 987 dev->active = 1;
1013 for (tmp = 0; 988 for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) {
1014 tmp < ISAPNP_MAX_PORT 989 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, tmp);
1015 && (res->port_resource[tmp]. 990 if (!pnp_res)
1016 flags & (IORESOURCE_IO | IORESOURCE_UNSET)) == IORESOURCE_IO; 991 continue;
1017 tmp++) 992 res = &pnp_res->res;
1018 isapnp_write_word(ISAPNP_CFG_PORT + (tmp << 1), 993 if (pnp_resource_valid(res)) {
1019 res->port_resource[tmp].start); 994 index = pnp_res->index;
1020 for (tmp = 0; 995 dev_dbg(&dev->dev, " set io %d to %#llx\n",
1021 tmp < ISAPNP_MAX_IRQ 996 index, (unsigned long long) res->start);
1022 && (res->irq_resource[tmp]. 997 isapnp_write_word(ISAPNP_CFG_PORT + (index << 1),
1023 flags & (IORESOURCE_IRQ | IORESOURCE_UNSET)) == IORESOURCE_IRQ; 998 res->start);
1024 tmp++) { 999 }
1025 int irq = res->irq_resource[tmp].start; 1000 }
1026 if (irq == 2) 1001 for (tmp = 0; tmp < ISAPNP_MAX_IRQ; tmp++) {
1027 irq = 9; 1002 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, tmp);
1028 isapnp_write_byte(ISAPNP_CFG_IRQ + (tmp << 1), irq); 1003 if (!pnp_res)
1004 continue;
1005 res = &pnp_res->res;
1006 if (pnp_resource_valid(res)) {
1007 int irq = res->start;
1008 if (irq == 2)
1009 irq = 9;
1010 index = pnp_res->index;
1011 dev_dbg(&dev->dev, " set irq %d to %d\n", index, irq);
1012 isapnp_write_byte(ISAPNP_CFG_IRQ + (index << 1), irq);
1013 }
1014 }
1015 for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) {
1016 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, tmp);
1017 if (!pnp_res)
1018 continue;
1019 res = &pnp_res->res;
1020 if (pnp_resource_valid(res)) {
1021 index = pnp_res->index;
1022 dev_dbg(&dev->dev, " set dma %d to %lld\n",
1023 index, (unsigned long long) res->start);
1024 isapnp_write_byte(ISAPNP_CFG_DMA + index, res->start);
1025 }
1026 }
1027 for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) {
1028 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_MEM, tmp);
1029 if (!pnp_res)
1030 continue;
1031 res = &pnp_res->res;
1032 if (pnp_resource_valid(res)) {
1033 index = pnp_res->index;
1034 dev_dbg(&dev->dev, " set mem %d to %#llx\n",
1035 index, (unsigned long long) res->start);
1036 isapnp_write_word(ISAPNP_CFG_MEM + (index << 3),
1037 (res->start >> 8) & 0xffff);
1038 }
1029 } 1039 }
1030 for (tmp = 0;
1031 tmp < ISAPNP_MAX_DMA
1032 && (res->dma_resource[tmp].
1033 flags & (IORESOURCE_DMA | IORESOURCE_UNSET)) == IORESOURCE_DMA;
1034 tmp++)
1035 isapnp_write_byte(ISAPNP_CFG_DMA + tmp,
1036 res->dma_resource[tmp].start);
1037 for (tmp = 0;
1038 tmp < ISAPNP_MAX_MEM
1039 && (res->mem_resource[tmp].
1040 flags & (IORESOURCE_MEM | IORESOURCE_UNSET)) == IORESOURCE_MEM;
1041 tmp++)
1042 isapnp_write_word(ISAPNP_CFG_MEM + (tmp << 3),
1043 (res->mem_resource[tmp].start >> 8) & 0xffff);
1044 /* FIXME: We aren't handling 32bit mems properly here */ 1040 /* FIXME: We aren't handling 32bit mems properly here */
1045 isapnp_activate(dev->number); 1041 isapnp_activate(dev->number);
1046 isapnp_cfg_end(); 1042 isapnp_cfg_end();
@@ -1138,13 +1134,13 @@ static int __init isapnp_init(void)
1138 protocol_for_each_card(&isapnp_protocol, card) { 1134 protocol_for_each_card(&isapnp_protocol, card) {
1139 cards++; 1135 cards++;
1140 if (isapnp_verbose) { 1136 if (isapnp_verbose) {
1141 printk(KERN_INFO "isapnp: Card '%s'\n", 1137 dev_info(&card->dev, "card '%s'\n",
1142 card->name[0] ? card->name : "Unknown"); 1138 card->name[0] ? card->name : "unknown");
1143 if (isapnp_verbose < 2) 1139 if (isapnp_verbose < 2)
1144 continue; 1140 continue;
1145 card_for_each_dev(card, dev) { 1141 card_for_each_dev(card, dev) {
1146 printk(KERN_INFO "isapnp: Device '%s'\n", 1142 dev_info(&card->dev, "device '%s'\n",
1147 dev->name[0] ? dev->name : "Unknown"); 1143 dev->name[0] ? dev->name : "unknown");
1148 } 1144 }
1149 } 1145 }
1150 } 1146 }
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index c28caf272c11..bea0914ff947 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -19,100 +19,118 @@ DEFINE_MUTEX(pnp_res_mutex);
19 19
20static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) 20static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
21{ 21{
22 resource_size_t *start, *end; 22 struct pnp_resource *pnp_res;
23 unsigned long *flags; 23 struct resource *res;
24 24
25 if (idx >= PNP_MAX_PORT) { 25 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, idx);
26 if (!pnp_res) {
26 dev_err(&dev->dev, "too many I/O port resources\n"); 27 dev_err(&dev->dev, "too many I/O port resources\n");
27 /* pretend we were successful so at least the manager won't try again */ 28 /* pretend we were successful so at least the manager won't try again */
28 return 1; 29 return 1;
29 } 30 }
30 31
32 res = &pnp_res->res;
33
31 /* check if this resource has been manually set, if so skip */ 34 /* check if this resource has been manually set, if so skip */
32 if (!(dev->res.port_resource[idx].flags & IORESOURCE_AUTO)) 35 if (!(res->flags & IORESOURCE_AUTO)) {
36 dev_dbg(&dev->dev, " io %d already set to %#llx-%#llx "
37 "flags %#lx\n", idx, (unsigned long long) res->start,
38 (unsigned long long) res->end, res->flags);
33 return 1; 39 return 1;
34 40 }
35 start = &dev->res.port_resource[idx].start;
36 end = &dev->res.port_resource[idx].end;
37 flags = &dev->res.port_resource[idx].flags;
38 41
39 /* set the initial values */ 42 /* set the initial values */
40 *flags |= rule->flags | IORESOURCE_IO; 43 pnp_res->index = idx;
41 *flags &= ~IORESOURCE_UNSET; 44 res->flags |= rule->flags | IORESOURCE_IO;
45 res->flags &= ~IORESOURCE_UNSET;
42 46
43 if (!rule->size) { 47 if (!rule->size) {
44 *flags |= IORESOURCE_DISABLED; 48 res->flags |= IORESOURCE_DISABLED;
49 dev_dbg(&dev->dev, " io %d disabled\n", idx);
45 return 1; /* skip disabled resource requests */ 50 return 1; /* skip disabled resource requests */
46 } 51 }
47 52
48 *start = rule->min; 53 res->start = rule->min;
49 *end = *start + rule->size - 1; 54 res->end = res->start + rule->size - 1;
50 55
51 /* run through until pnp_check_port is happy */ 56 /* run through until pnp_check_port is happy */
52 while (!pnp_check_port(dev, idx)) { 57 while (!pnp_check_port(dev, res)) {
53 *start += rule->align; 58 res->start += rule->align;
54 *end = *start + rule->size - 1; 59 res->end = res->start + rule->size - 1;
55 if (*start > rule->max || !rule->align) 60 if (res->start > rule->max || !rule->align) {
61 dev_dbg(&dev->dev, " couldn't assign io %d\n", idx);
56 return 0; 62 return 0;
63 }
57 } 64 }
65 dev_dbg(&dev->dev, " assign io %d %#llx-%#llx\n", idx,
66 (unsigned long long) res->start, (unsigned long long) res->end);
58 return 1; 67 return 1;
59} 68}
60 69
61static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) 70static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
62{ 71{
63 resource_size_t *start, *end; 72 struct pnp_resource *pnp_res;
64 unsigned long *flags; 73 struct resource *res;
65 74
66 if (idx >= PNP_MAX_MEM) { 75 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_MEM, idx);
76 if (!pnp_res) {
67 dev_err(&dev->dev, "too many memory resources\n"); 77 dev_err(&dev->dev, "too many memory resources\n");
68 /* pretend we were successful so at least the manager won't try again */ 78 /* pretend we were successful so at least the manager won't try again */
69 return 1; 79 return 1;
70 } 80 }
71 81
82 res = &pnp_res->res;
83
72 /* check if this resource has been manually set, if so skip */ 84 /* check if this resource has been manually set, if so skip */
73 if (!(dev->res.mem_resource[idx].flags & IORESOURCE_AUTO)) 85 if (!(res->flags & IORESOURCE_AUTO)) {
86 dev_dbg(&dev->dev, " mem %d already set to %#llx-%#llx "
87 "flags %#lx\n", idx, (unsigned long long) res->start,
88 (unsigned long long) res->end, res->flags);
74 return 1; 89 return 1;
75 90 }
76 start = &dev->res.mem_resource[idx].start;
77 end = &dev->res.mem_resource[idx].end;
78 flags = &dev->res.mem_resource[idx].flags;
79 91
80 /* set the initial values */ 92 /* set the initial values */
81 *flags |= rule->flags | IORESOURCE_MEM; 93 pnp_res->index = idx;
82 *flags &= ~IORESOURCE_UNSET; 94 res->flags |= rule->flags | IORESOURCE_MEM;
95 res->flags &= ~IORESOURCE_UNSET;
83 96
84 /* convert pnp flags to standard Linux flags */ 97 /* convert pnp flags to standard Linux flags */
85 if (!(rule->flags & IORESOURCE_MEM_WRITEABLE)) 98 if (!(rule->flags & IORESOURCE_MEM_WRITEABLE))
86 *flags |= IORESOURCE_READONLY; 99 res->flags |= IORESOURCE_READONLY;
87 if (rule->flags & IORESOURCE_MEM_CACHEABLE) 100 if (rule->flags & IORESOURCE_MEM_CACHEABLE)
88 *flags |= IORESOURCE_CACHEABLE; 101 res->flags |= IORESOURCE_CACHEABLE;
89 if (rule->flags & IORESOURCE_MEM_RANGELENGTH) 102 if (rule->flags & IORESOURCE_MEM_RANGELENGTH)
90 *flags |= IORESOURCE_RANGELENGTH; 103 res->flags |= IORESOURCE_RANGELENGTH;
91 if (rule->flags & IORESOURCE_MEM_SHADOWABLE) 104 if (rule->flags & IORESOURCE_MEM_SHADOWABLE)
92 *flags |= IORESOURCE_SHADOWABLE; 105 res->flags |= IORESOURCE_SHADOWABLE;
93 106
94 if (!rule->size) { 107 if (!rule->size) {
95 *flags |= IORESOURCE_DISABLED; 108 res->flags |= IORESOURCE_DISABLED;
109 dev_dbg(&dev->dev, " mem %d disabled\n", idx);
96 return 1; /* skip disabled resource requests */ 110 return 1; /* skip disabled resource requests */
97 } 111 }
98 112
99 *start = rule->min; 113 res->start = rule->min;
100 *end = *start + rule->size - 1; 114 res->end = res->start + rule->size - 1;
101 115
102 /* run through until pnp_check_mem is happy */ 116 /* run through until pnp_check_mem is happy */
103 while (!pnp_check_mem(dev, idx)) { 117 while (!pnp_check_mem(dev, res)) {
104 *start += rule->align; 118 res->start += rule->align;
105 *end = *start + rule->size - 1; 119 res->end = res->start + rule->size - 1;
106 if (*start > rule->max || !rule->align) 120 if (res->start > rule->max || !rule->align) {
121 dev_dbg(&dev->dev, " couldn't assign mem %d\n", idx);
107 return 0; 122 return 0;
123 }
108 } 124 }
125 dev_dbg(&dev->dev, " assign mem %d %#llx-%#llx\n", idx,
126 (unsigned long long) res->start, (unsigned long long) res->end);
109 return 1; 127 return 1;
110} 128}
111 129
112static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) 130static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
113{ 131{
114 resource_size_t *start, *end; 132 struct pnp_resource *pnp_res;
115 unsigned long *flags; 133 struct resource *res;
116 int i; 134 int i;
117 135
118 /* IRQ priority: this table is good for i386 */ 136 /* IRQ priority: this table is good for i386 */
@@ -120,49 +138,59 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
120 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2 138 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2
121 }; 139 };
122 140
123 if (idx >= PNP_MAX_IRQ) { 141 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, idx);
142 if (!pnp_res) {
124 dev_err(&dev->dev, "too many IRQ resources\n"); 143 dev_err(&dev->dev, "too many IRQ resources\n");
125 /* pretend we were successful so at least the manager won't try again */ 144 /* pretend we were successful so at least the manager won't try again */
126 return 1; 145 return 1;
127 } 146 }
128 147
148 res = &pnp_res->res;
149
129 /* check if this resource has been manually set, if so skip */ 150 /* check if this resource has been manually set, if so skip */
130 if (!(dev->res.irq_resource[idx].flags & IORESOURCE_AUTO)) 151 if (!(res->flags & IORESOURCE_AUTO)) {
152 dev_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n",
153 idx, (int) res->start, res->flags);
131 return 1; 154 return 1;
132 155 }
133 start = &dev->res.irq_resource[idx].start;
134 end = &dev->res.irq_resource[idx].end;
135 flags = &dev->res.irq_resource[idx].flags;
136 156
137 /* set the initial values */ 157 /* set the initial values */
138 *flags |= rule->flags | IORESOURCE_IRQ; 158 pnp_res->index = idx;
139 *flags &= ~IORESOURCE_UNSET; 159 res->flags |= rule->flags | IORESOURCE_IRQ;
160 res->flags &= ~IORESOURCE_UNSET;
140 161
141 if (bitmap_empty(rule->map, PNP_IRQ_NR)) { 162 if (bitmap_empty(rule->map, PNP_IRQ_NR)) {
142 *flags |= IORESOURCE_DISABLED; 163 res->flags |= IORESOURCE_DISABLED;
164 dev_dbg(&dev->dev, " irq %d disabled\n", idx);
143 return 1; /* skip disabled resource requests */ 165 return 1; /* skip disabled resource requests */
144 } 166 }
145 167
146 /* TBD: need check for >16 IRQ */ 168 /* TBD: need check for >16 IRQ */
147 *start = find_next_bit(rule->map, PNP_IRQ_NR, 16); 169 res->start = find_next_bit(rule->map, PNP_IRQ_NR, 16);
148 if (*start < PNP_IRQ_NR) { 170 if (res->start < PNP_IRQ_NR) {
149 *end = *start; 171 res->end = res->start;
172 dev_dbg(&dev->dev, " assign irq %d %d\n", idx,
173 (int) res->start);
150 return 1; 174 return 1;
151 } 175 }
152 for (i = 0; i < 16; i++) { 176 for (i = 0; i < 16; i++) {
153 if (test_bit(xtab[i], rule->map)) { 177 if (test_bit(xtab[i], rule->map)) {
154 *start = *end = xtab[i]; 178 res->start = res->end = xtab[i];
155 if (pnp_check_irq(dev, idx)) 179 if (pnp_check_irq(dev, res)) {
180 dev_dbg(&dev->dev, " assign irq %d %d\n", idx,
181 (int) res->start);
156 return 1; 182 return 1;
183 }
157 } 184 }
158 } 185 }
186 dev_dbg(&dev->dev, " couldn't assign irq %d\n", idx);
159 return 0; 187 return 0;
160} 188}
161 189
162static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) 190static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
163{ 191{
164 resource_size_t *start, *end; 192 struct pnp_resource *pnp_res;
165 unsigned long *flags; 193 struct resource *res;
166 int i; 194 int i;
167 195
168 /* DMA priority: this table is good for i386 */ 196 /* DMA priority: this table is good for i386 */
@@ -170,71 +198,89 @@ static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
170 1, 3, 5, 6, 7, 0, 2, 4 198 1, 3, 5, 6, 7, 0, 2, 4
171 }; 199 };
172 200
173 if (idx >= PNP_MAX_DMA) { 201 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, idx);
202 if (!pnp_res) {
174 dev_err(&dev->dev, "too many DMA resources\n"); 203 dev_err(&dev->dev, "too many DMA resources\n");
175 return; 204 return;
176 } 205 }
177 206
207 res = &pnp_res->res;
208
178 /* check if this resource has been manually set, if so skip */ 209 /* check if this resource has been manually set, if so skip */
179 if (!(dev->res.dma_resource[idx].flags & IORESOURCE_AUTO)) 210 if (!(res->flags & IORESOURCE_AUTO)) {
211 dev_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n",
212 idx, (int) res->start, res->flags);
180 return; 213 return;
181 214 }
182 start = &dev->res.dma_resource[idx].start;
183 end = &dev->res.dma_resource[idx].end;
184 flags = &dev->res.dma_resource[idx].flags;
185 215
186 /* set the initial values */ 216 /* set the initial values */
187 *flags |= rule->flags | IORESOURCE_DMA; 217 pnp_res->index = idx;
188 *flags &= ~IORESOURCE_UNSET; 218 res->flags |= rule->flags | IORESOURCE_DMA;
219 res->flags &= ~IORESOURCE_UNSET;
189 220
190 for (i = 0; i < 8; i++) { 221 for (i = 0; i < 8; i++) {
191 if (rule->map & (1 << xtab[i])) { 222 if (rule->map & (1 << xtab[i])) {
192 *start = *end = xtab[i]; 223 res->start = res->end = xtab[i];
193 if (pnp_check_dma(dev, idx)) 224 if (pnp_check_dma(dev, res)) {
225 dev_dbg(&dev->dev, " assign dma %d %d\n", idx,
226 (int) res->start);
194 return; 227 return;
228 }
195 } 229 }
196 } 230 }
197#ifdef MAX_DMA_CHANNELS 231#ifdef MAX_DMA_CHANNELS
198 *start = *end = MAX_DMA_CHANNELS; 232 res->start = res->end = MAX_DMA_CHANNELS;
199#endif 233#endif
200 *flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED; 234 res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED;
235 dev_dbg(&dev->dev, " disable dma %d\n", idx);
236}
237
238void pnp_init_resource(struct resource *res)
239{
240 unsigned long type;
241
242 type = res->flags & (IORESOURCE_IO | IORESOURCE_MEM |
243 IORESOURCE_IRQ | IORESOURCE_DMA);
244
245 res->name = NULL;
246 res->flags = type | IORESOURCE_AUTO | IORESOURCE_UNSET;
247 if (type == IORESOURCE_IRQ || type == IORESOURCE_DMA) {
248 res->start = -1;
249 res->end = -1;
250 } else {
251 res->start = 0;
252 res->end = 0;
253 }
201} 254}
202 255
203/** 256/**
204 * pnp_init_resources - Resets a resource table to default values. 257 * pnp_init_resources - Resets a resource table to default values.
205 * @table: pointer to the desired resource table 258 * @table: pointer to the desired resource table
206 */ 259 */
207void pnp_init_resource_table(struct pnp_resource_table *table) 260void pnp_init_resources(struct pnp_dev *dev)
208{ 261{
262 struct resource *res;
209 int idx; 263 int idx;
210 264
211 for (idx = 0; idx < PNP_MAX_IRQ; idx++) { 265 for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
212 table->irq_resource[idx].name = NULL; 266 res = &dev->res->irq[idx].res;
213 table->irq_resource[idx].start = -1; 267 res->flags = IORESOURCE_IRQ;
214 table->irq_resource[idx].end = -1; 268 pnp_init_resource(res);
215 table->irq_resource[idx].flags =
216 IORESOURCE_IRQ | IORESOURCE_AUTO | IORESOURCE_UNSET;
217 } 269 }
218 for (idx = 0; idx < PNP_MAX_DMA; idx++) { 270 for (idx = 0; idx < PNP_MAX_DMA; idx++) {
219 table->dma_resource[idx].name = NULL; 271 res = &dev->res->dma[idx].res;
220 table->dma_resource[idx].start = -1; 272 res->flags = IORESOURCE_DMA;
221 table->dma_resource[idx].end = -1; 273 pnp_init_resource(res);
222 table->dma_resource[idx].flags =
223 IORESOURCE_DMA | IORESOURCE_AUTO | IORESOURCE_UNSET;
224 } 274 }
225 for (idx = 0; idx < PNP_MAX_PORT; idx++) { 275 for (idx = 0; idx < PNP_MAX_PORT; idx++) {
226 table->port_resource[idx].name = NULL; 276 res = &dev->res->port[idx].res;
227 table->port_resource[idx].start = 0; 277 res->flags = IORESOURCE_IO;
228 table->port_resource[idx].end = 0; 278 pnp_init_resource(res);
229 table->port_resource[idx].flags =
230 IORESOURCE_IO | IORESOURCE_AUTO | IORESOURCE_UNSET;
231 } 279 }
232 for (idx = 0; idx < PNP_MAX_MEM; idx++) { 280 for (idx = 0; idx < PNP_MAX_MEM; idx++) {
233 table->mem_resource[idx].name = NULL; 281 res = &dev->res->mem[idx].res;
234 table->mem_resource[idx].start = 0; 282 res->flags = IORESOURCE_MEM;
235 table->mem_resource[idx].end = 0; 283 pnp_init_resource(res);
236 table->mem_resource[idx].flags =
237 IORESOURCE_MEM | IORESOURCE_AUTO | IORESOURCE_UNSET;
238 } 284 }
239} 285}
240 286
@@ -242,41 +288,38 @@ void pnp_init_resource_table(struct pnp_resource_table *table)
242 * pnp_clean_resources - clears resources that were not manually set 288 * pnp_clean_resources - clears resources that were not manually set
243 * @res: the resources to clean 289 * @res: the resources to clean
244 */ 290 */
245static void pnp_clean_resource_table(struct pnp_resource_table *res) 291static void pnp_clean_resource_table(struct pnp_dev *dev)
246{ 292{
293 struct resource *res;
247 int idx; 294 int idx;
248 295
249 for (idx = 0; idx < PNP_MAX_IRQ; idx++) { 296 for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
250 if (!(res->irq_resource[idx].flags & IORESOURCE_AUTO)) 297 res = &dev->res->irq[idx].res;
251 continue; 298 if (res->flags & IORESOURCE_AUTO) {
252 res->irq_resource[idx].start = -1; 299 res->flags = IORESOURCE_IRQ;
253 res->irq_resource[idx].end = -1; 300 pnp_init_resource(res);
254 res->irq_resource[idx].flags = 301 }
255 IORESOURCE_IRQ | IORESOURCE_AUTO | IORESOURCE_UNSET;
256 } 302 }
257 for (idx = 0; idx < PNP_MAX_DMA; idx++) { 303 for (idx = 0; idx < PNP_MAX_DMA; idx++) {
258 if (!(res->dma_resource[idx].flags & IORESOURCE_AUTO)) 304 res = &dev->res->dma[idx].res;
259 continue; 305 if (res->flags & IORESOURCE_AUTO) {
260 res->dma_resource[idx].start = -1; 306 res->flags = IORESOURCE_DMA;
261 res->dma_resource[idx].end = -1; 307 pnp_init_resource(res);
262 res->dma_resource[idx].flags = 308 }
263 IORESOURCE_DMA | IORESOURCE_AUTO | IORESOURCE_UNSET;
264 } 309 }
265 for (idx = 0; idx < PNP_MAX_PORT; idx++) { 310 for (idx = 0; idx < PNP_MAX_PORT; idx++) {
266 if (!(res->port_resource[idx].flags & IORESOURCE_AUTO)) 311 res = &dev->res->port[idx].res;
267 continue; 312 if (res->flags & IORESOURCE_AUTO) {
268 res->port_resource[idx].start = 0; 313 res->flags = IORESOURCE_IO;
269 res->port_resource[idx].end = 0; 314 pnp_init_resource(res);
270 res->port_resource[idx].flags = 315 }
271 IORESOURCE_IO | IORESOURCE_AUTO | IORESOURCE_UNSET;
272 } 316 }
273 for (idx = 0; idx < PNP_MAX_MEM; idx++) { 317 for (idx = 0; idx < PNP_MAX_MEM; idx++) {
274 if (!(res->mem_resource[idx].flags & IORESOURCE_AUTO)) 318 res = &dev->res->mem[idx].res;
275 continue; 319 if (res->flags & IORESOURCE_AUTO) {
276 res->mem_resource[idx].start = 0; 320 res->flags = IORESOURCE_MEM;
277 res->mem_resource[idx].end = 0; 321 pnp_init_resource(res);
278 res->mem_resource[idx].flags = 322 }
279 IORESOURCE_MEM | IORESOURCE_AUTO | IORESOURCE_UNSET;
280 } 323 }
281} 324}
282 325
@@ -298,9 +341,11 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
298 if (!pnp_can_configure(dev)) 341 if (!pnp_can_configure(dev))
299 return -ENODEV; 342 return -ENODEV;
300 343
344 dbg_pnp_show_resources(dev, "before pnp_assign_resources");
301 mutex_lock(&pnp_res_mutex); 345 mutex_lock(&pnp_res_mutex);
302 pnp_clean_resource_table(&dev->res); /* start with a fresh slate */ 346 pnp_clean_resource_table(dev);
303 if (dev->independent) { 347 if (dev->independent) {
348 dev_dbg(&dev->dev, "assigning independent options\n");
304 port = dev->independent->port; 349 port = dev->independent->port;
305 mem = dev->independent->mem; 350 mem = dev->independent->mem;
306 irq = dev->independent->irq; 351 irq = dev->independent->irq;
@@ -333,6 +378,8 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
333 if (depnum) { 378 if (depnum) {
334 struct pnp_option *dep; 379 struct pnp_option *dep;
335 int i; 380 int i;
381
382 dev_dbg(&dev->dev, "assigning dependent option %d\n", depnum);
336 for (i = 1, dep = dev->dependent; i < depnum; 383 for (i = 1, dep = dev->dependent; i < depnum;
337 i++, dep = dep->next) 384 i++, dep = dep->next)
338 if (!dep) 385 if (!dep)
@@ -368,68 +415,17 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
368 goto fail; 415 goto fail;
369 416
370 mutex_unlock(&pnp_res_mutex); 417 mutex_unlock(&pnp_res_mutex);
418 dbg_pnp_show_resources(dev, "after pnp_assign_resources");
371 return 1; 419 return 1;
372 420
373fail: 421fail:
374 pnp_clean_resource_table(&dev->res); 422 pnp_clean_resource_table(dev);
375 mutex_unlock(&pnp_res_mutex); 423 mutex_unlock(&pnp_res_mutex);
424 dbg_pnp_show_resources(dev, "after pnp_assign_resources (failed)");
376 return 0; 425 return 0;
377} 426}
378 427
379/** 428/**
380 * pnp_manual_config_dev - Disables Auto Config and Manually sets the resource table
381 * @dev: pointer to the desired device
382 * @res: pointer to the new resource config
383 * @mode: 0 or PNP_CONFIG_FORCE
384 *
385 * This function can be used by drivers that want to manually set thier resources.
386 */
387int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res,
388 int mode)
389{
390 int i;
391 struct pnp_resource_table *bak;
392
393 if (!pnp_can_configure(dev))
394 return -ENODEV;
395 bak = pnp_alloc(sizeof(struct pnp_resource_table));
396 if (!bak)
397 return -ENOMEM;
398 *bak = dev->res;
399
400 mutex_lock(&pnp_res_mutex);
401 dev->res = *res;
402 if (!(mode & PNP_CONFIG_FORCE)) {
403 for (i = 0; i < PNP_MAX_PORT; i++) {
404 if (!pnp_check_port(dev, i))
405 goto fail;
406 }
407 for (i = 0; i < PNP_MAX_MEM; i++) {
408 if (!pnp_check_mem(dev, i))
409 goto fail;
410 }
411 for (i = 0; i < PNP_MAX_IRQ; i++) {
412 if (!pnp_check_irq(dev, i))
413 goto fail;
414 }
415 for (i = 0; i < PNP_MAX_DMA; i++) {
416 if (!pnp_check_dma(dev, i))
417 goto fail;
418 }
419 }
420 mutex_unlock(&pnp_res_mutex);
421
422 kfree(bak);
423 return 0;
424
425fail:
426 dev->res = *bak;
427 mutex_unlock(&pnp_res_mutex);
428 kfree(bak);
429 return -EINVAL;
430}
431
432/**
433 * pnp_auto_config_dev - automatically assigns resources to a device 429 * pnp_auto_config_dev - automatically assigns resources to a device
434 * @dev: pointer to the desired device 430 * @dev: pointer to the desired device
435 */ 431 */
@@ -473,7 +469,8 @@ int pnp_start_dev(struct pnp_dev *dev)
473 return -EINVAL; 469 return -EINVAL;
474 } 470 }
475 471
476 if (dev->protocol->set(dev, &dev->res) < 0) { 472 dbg_pnp_show_resources(dev, "pnp_start_dev");
473 if (dev->protocol->set(dev) < 0) {
477 dev_err(&dev->dev, "activation failed\n"); 474 dev_err(&dev->dev, "activation failed\n");
478 return -EIO; 475 return -EIO;
479 } 476 }
@@ -549,30 +546,13 @@ int pnp_disable_dev(struct pnp_dev *dev)
549 546
550 /* release the resources so that other devices can use them */ 547 /* release the resources so that other devices can use them */
551 mutex_lock(&pnp_res_mutex); 548 mutex_lock(&pnp_res_mutex);
552 pnp_clean_resource_table(&dev->res); 549 pnp_clean_resource_table(dev);
553 mutex_unlock(&pnp_res_mutex); 550 mutex_unlock(&pnp_res_mutex);
554 551
555 return 0; 552 return 0;
556} 553}
557 554
558/**
559 * pnp_resource_change - change one resource
560 * @resource: pointer to resource to be changed
561 * @start: start of region
562 * @size: size of region
563 */
564void pnp_resource_change(struct resource *resource, resource_size_t start,
565 resource_size_t size)
566{
567 resource->flags &= ~(IORESOURCE_AUTO | IORESOURCE_UNSET);
568 resource->start = start;
569 resource->end = start + size - 1;
570}
571
572EXPORT_SYMBOL(pnp_manual_config_dev);
573EXPORT_SYMBOL(pnp_start_dev); 555EXPORT_SYMBOL(pnp_start_dev);
574EXPORT_SYMBOL(pnp_stop_dev); 556EXPORT_SYMBOL(pnp_stop_dev);
575EXPORT_SYMBOL(pnp_activate_dev); 557EXPORT_SYMBOL(pnp_activate_dev);
576EXPORT_SYMBOL(pnp_disable_dev); 558EXPORT_SYMBOL(pnp_disable_dev);
577EXPORT_SYMBOL(pnp_resource_change);
578EXPORT_SYMBOL(pnp_init_resource_table);
diff --git a/drivers/pnp/pnpacpi/Makefile b/drivers/pnp/pnpacpi/Makefile
index 905326fcca85..2d7a1e6908be 100644
--- a/drivers/pnp/pnpacpi/Makefile
+++ b/drivers/pnp/pnpacpi/Makefile
@@ -3,3 +3,7 @@
3# 3#
4 4
5obj-y := core.o rsparser.o 5obj-y := core.o rsparser.o
6
7ifeq ($(CONFIG_PNP_DEBUG),y)
8EXTRA_CFLAGS += -DDEBUG
9endif
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index c283a9a70d83..50902773beaf 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -25,6 +25,7 @@
25#include <acpi/acpi_bus.h> 25#include <acpi/acpi_bus.h>
26#include <acpi/actypes.h> 26#include <acpi/actypes.h>
27 27
28#include "../base.h"
28#include "pnpacpi.h" 29#include "pnpacpi.h"
29 30
30static int num = 0; 31static int num = 0;
@@ -44,7 +45,7 @@ static struct acpi_device_id excluded_id_list[] __initdata = {
44 {"", 0}, 45 {"", 0},
45}; 46};
46 47
47static inline int is_exclusive_device(struct acpi_device *dev) 48static inline int __init is_exclusive_device(struct acpi_device *dev)
48{ 49{
49 return (!acpi_match_device_ids(dev, excluded_id_list)); 50 return (!acpi_match_device_ids(dev, excluded_id_list));
50} 51}
@@ -72,40 +73,24 @@ static int __init ispnpidacpi(char *id)
72 return 1; 73 return 1;
73} 74}
74 75
75static void __init pnpidacpi_to_pnpid(char *id, char *str) 76static int pnpacpi_get_resources(struct pnp_dev *dev)
76{ 77{
77 str[0] = id[0]; 78 dev_dbg(&dev->dev, "get resources\n");
78 str[1] = id[1]; 79 return pnpacpi_parse_allocated_resource(dev);
79 str[2] = id[2];
80 str[3] = tolower(id[3]);
81 str[4] = tolower(id[4]);
82 str[5] = tolower(id[5]);
83 str[6] = tolower(id[6]);
84 str[7] = '\0';
85} 80}
86 81
87static int pnpacpi_get_resources(struct pnp_dev *dev, 82static int pnpacpi_set_resources(struct pnp_dev *dev)
88 struct pnp_resource_table *res)
89{
90 acpi_status status;
91
92 status = pnpacpi_parse_allocated_resource((acpi_handle) dev->data,
93 &dev->res);
94 return ACPI_FAILURE(status) ? -ENODEV : 0;
95}
96
97static int pnpacpi_set_resources(struct pnp_dev *dev,
98 struct pnp_resource_table *res)
99{ 83{
100 acpi_handle handle = dev->data; 84 acpi_handle handle = dev->data;
101 struct acpi_buffer buffer; 85 struct acpi_buffer buffer;
102 int ret = 0; 86 int ret;
103 acpi_status status; 87 acpi_status status;
104 88
105 ret = pnpacpi_build_resource_template(handle, &buffer); 89 dev_dbg(&dev->dev, "set resources\n");
90 ret = pnpacpi_build_resource_template(dev, &buffer);
106 if (ret) 91 if (ret)
107 return ret; 92 return ret;
108 ret = pnpacpi_encode_resources(res, &buffer); 93 ret = pnpacpi_encode_resources(dev, &buffer);
109 if (ret) { 94 if (ret) {
110 kfree(buffer.pointer); 95 kfree(buffer.pointer);
111 return ret; 96 return ret;
@@ -163,7 +148,6 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
163{ 148{
164 acpi_handle temp = NULL; 149 acpi_handle temp = NULL;
165 acpi_status status; 150 acpi_status status;
166 struct pnp_id *dev_id;
167 struct pnp_dev *dev; 151 struct pnp_dev *dev;
168 152
169 status = acpi_get_handle(device->handle, "_CRS", &temp); 153 status = acpi_get_handle(device->handle, "_CRS", &temp);
@@ -171,11 +155,10 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
171 is_exclusive_device(device)) 155 is_exclusive_device(device))
172 return 0; 156 return 0;
173 157
174 dev = kzalloc(sizeof(struct pnp_dev), GFP_KERNEL); 158 dev = pnp_alloc_dev(&pnpacpi_protocol, num, acpi_device_hid(device));
175 if (!dev) { 159 if (!dev)
176 pnp_err("Out of memory");
177 return -ENOMEM; 160 return -ENOMEM;
178 } 161
179 dev->data = device->handle; 162 dev->data = device->handle;
180 /* .enabled means the device can decode the resources */ 163 /* .enabled means the device can decode the resources */
181 dev->active = device->status.enabled; 164 dev->active = device->status.enabled;
@@ -191,44 +174,17 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
191 if (ACPI_SUCCESS(status)) 174 if (ACPI_SUCCESS(status))
192 dev->capabilities |= PNP_DISABLE; 175 dev->capabilities |= PNP_DISABLE;
193 176
194 dev->protocol = &pnpacpi_protocol;
195
196 if (strlen(acpi_device_name(device))) 177 if (strlen(acpi_device_name(device)))
197 strncpy(dev->name, acpi_device_name(device), sizeof(dev->name)); 178 strncpy(dev->name, acpi_device_name(device), sizeof(dev->name));
198 else 179 else
199 strncpy(dev->name, acpi_device_bid(device), sizeof(dev->name)); 180 strncpy(dev->name, acpi_device_bid(device), sizeof(dev->name));
200 181
201 dev->number = num; 182 if (dev->active)
202 183 pnpacpi_parse_allocated_resource(dev);
203 /* set the initial values for the PnP device */
204 dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
205 if (!dev_id)
206 goto err;
207 pnpidacpi_to_pnpid(acpi_device_hid(device), dev_id->id);
208 pnp_add_id(dev_id, dev);
209
210 if (dev->active) {
211 /* parse allocated resource */
212 status = pnpacpi_parse_allocated_resource(device->handle,
213 &dev->res);
214 if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
215 pnp_err("PnPACPI: METHOD_NAME__CRS failure for %s",
216 dev_id->id);
217 goto err1;
218 }
219 }
220 184
221 if (dev->capabilities & PNP_CONFIGURABLE) { 185 if (dev->capabilities & PNP_CONFIGURABLE)
222 status = pnpacpi_parse_resource_option_data(device->handle, 186 pnpacpi_parse_resource_option_data(dev);
223 dev);
224 if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
225 pnp_err("PnPACPI: METHOD_NAME__PRS failure for %s",
226 dev_id->id);
227 goto err1;
228 }
229 }
230 187
231 /* parse compatible ids */
232 if (device->flags.compatible_ids) { 188 if (device->flags.compatible_ids) {
233 struct acpi_compatible_id_list *cid_list = device->pnp.cid_list; 189 struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
234 int i; 190 int i;
@@ -236,27 +192,17 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
236 for (i = 0; i < cid_list->count; i++) { 192 for (i = 0; i < cid_list->count; i++) {
237 if (!ispnpidacpi(cid_list->id[i].value)) 193 if (!ispnpidacpi(cid_list->id[i].value))
238 continue; 194 continue;
239 dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL); 195 pnp_add_id(dev, cid_list->id[i].value);
240 if (!dev_id)
241 continue;
242
243 pnpidacpi_to_pnpid(cid_list->id[i].value, dev_id->id);
244 pnp_add_id(dev_id, dev);
245 } 196 }
246 } 197 }
247 198
248 /* clear out the damaged flags */ 199 /* clear out the damaged flags */
249 if (!dev->active) 200 if (!dev->active)
250 pnp_init_resource_table(&dev->res); 201 pnp_init_resources(dev);
251 pnp_add_device(dev); 202 pnp_add_device(dev);
252 num++; 203 num++;
253 204
254 return AE_OK; 205 return AE_OK;
255err1:
256 kfree(dev_id);
257err:
258 kfree(dev);
259 return -EINVAL;
260} 206}
261 207
262static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle, 208static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle,
diff --git a/drivers/pnp/pnpacpi/pnpacpi.h b/drivers/pnp/pnpacpi/pnpacpi.h
index f28e2ed66fa3..3e60225b0227 100644
--- a/drivers/pnp/pnpacpi/pnpacpi.h
+++ b/drivers/pnp/pnpacpi/pnpacpi.h
@@ -5,8 +5,8 @@
5#include <linux/acpi.h> 5#include <linux/acpi.h>
6#include <linux/pnp.h> 6#include <linux/pnp.h>
7 7
8acpi_status pnpacpi_parse_allocated_resource(acpi_handle, struct pnp_resource_table*); 8int pnpacpi_parse_allocated_resource(struct pnp_dev *);
9acpi_status pnpacpi_parse_resource_option_data(acpi_handle, struct pnp_dev*); 9int pnpacpi_parse_resource_option_data(struct pnp_dev *);
10int pnpacpi_encode_resources(struct pnp_resource_table *, struct acpi_buffer *); 10int pnpacpi_encode_resources(struct pnp_dev *, struct acpi_buffer *);
11int pnpacpi_build_resource_template(acpi_handle, struct acpi_buffer*); 11int pnpacpi_build_resource_template(struct pnp_dev *, struct acpi_buffer *);
12#endif 12#endif
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 98cbc9f18eed..0201c8adfda7 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -21,6 +21,8 @@
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/acpi.h> 22#include <linux/acpi.h>
23#include <linux/pci.h> 23#include <linux/pci.h>
24#include <linux/pnp.h>
25#include "../base.h"
24#include "pnpacpi.h" 26#include "pnpacpi.h"
25 27
26#ifdef CONFIG_IA64 28#ifdef CONFIG_IA64
@@ -32,19 +34,26 @@
32/* 34/*
33 * Allocated Resources 35 * Allocated Resources
34 */ 36 */
35static int irq_flags(int triggering, int polarity) 37static int irq_flags(int triggering, int polarity, int shareable)
36{ 38{
39 int flags;
40
37 if (triggering == ACPI_LEVEL_SENSITIVE) { 41 if (triggering == ACPI_LEVEL_SENSITIVE) {
38 if (polarity == ACPI_ACTIVE_LOW) 42 if (polarity == ACPI_ACTIVE_LOW)
39 return IORESOURCE_IRQ_LOWLEVEL; 43 flags = IORESOURCE_IRQ_LOWLEVEL;
40 else 44 else
41 return IORESOURCE_IRQ_HIGHLEVEL; 45 flags = IORESOURCE_IRQ_HIGHLEVEL;
42 } else { 46 } else {
43 if (polarity == ACPI_ACTIVE_LOW) 47 if (polarity == ACPI_ACTIVE_LOW)
44 return IORESOURCE_IRQ_LOWEDGE; 48 flags = IORESOURCE_IRQ_LOWEDGE;
45 else 49 else
46 return IORESOURCE_IRQ_HIGHEDGE; 50 flags = IORESOURCE_IRQ_HIGHEDGE;
47 } 51 }
52
53 if (shareable)
54 flags |= IORESOURCE_IRQ_SHAREABLE;
55
56 return flags;
48} 57}
49 58
50static void decode_irq_flags(int flag, int *triggering, int *polarity) 59static void decode_irq_flags(int flag, int *triggering, int *polarity)
@@ -69,29 +78,16 @@ static void decode_irq_flags(int flag, int *triggering, int *polarity)
69 } 78 }
70} 79}
71 80
72static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res, 81static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev,
73 u32 gsi, int triggering, 82 u32 gsi, int triggering,
74 int polarity, int shareable) 83 int polarity, int shareable)
75{ 84{
76 int i = 0; 85 int irq, flags;
77 int irq;
78 int p, t; 86 int p, t;
79 static unsigned char warned;
80 87
81 if (!valid_IRQ(gsi)) 88 if (!valid_IRQ(gsi))
82 return; 89 return;
83 90
84 while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) &&
85 i < PNP_MAX_IRQ)
86 i++;
87 if (i >= PNP_MAX_IRQ) {
88 if (!warned) {
89 printk(KERN_WARNING "pnpacpi: exceeded the max number"
90 " of IRQ resources: %d\n", PNP_MAX_IRQ);
91 warned = 1;
92 }
93 return;
94 }
95 /* 91 /*
96 * in IO-APIC mode, use overrided attribute. Two reasons: 92 * in IO-APIC mode, use overrided attribute. Two reasons:
97 * 1. BIOS bug in DSDT 93 * 1. BIOS bug in DSDT
@@ -102,27 +98,21 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res,
102 p = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; 98 p = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
103 99
104 if (triggering != t || polarity != p) { 100 if (triggering != t || polarity != p) {
105 pnp_warn("IRQ %d override to %s, %s", 101 dev_warn(&dev->dev, "IRQ %d override to %s, %s\n",
106 gsi, t ? "edge":"level", p ? "low":"high"); 102 gsi, t ? "edge":"level", p ? "low":"high");
107 triggering = t; 103 triggering = t;
108 polarity = p; 104 polarity = p;
109 } 105 }
110 } 106 }
111 107
112 res->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag 108 flags = irq_flags(triggering, polarity, shareable);
113 res->irq_resource[i].flags |= irq_flags(triggering, polarity);
114 irq = acpi_register_gsi(gsi, triggering, polarity); 109 irq = acpi_register_gsi(gsi, triggering, polarity);
115 if (irq < 0) { 110 if (irq >= 0)
116 res->irq_resource[i].flags |= IORESOURCE_DISABLED; 111 pcibios_penalize_isa_irq(irq, 1);
117 return; 112 else
118 } 113 flags |= IORESOURCE_DISABLED;
119
120 if (shareable)
121 res->irq_resource[i].flags |= IORESOURCE_IRQ_SHAREABLE;
122 114
123 res->irq_resource[i].start = irq; 115 pnp_add_irq_resource(dev, irq, flags);
124 res->irq_resource[i].end = irq;
125 pcibios_penalize_isa_irq(irq, 1);
126} 116}
127 117
128static int dma_flags(int type, int bus_master, int transfer) 118static int dma_flags(int type, int bus_master, int transfer)
@@ -168,88 +158,36 @@ static int dma_flags(int type, int bus_master, int transfer)
168 return flags; 158 return flags;
169} 159}
170 160
171static void pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res, 161static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start,
172 u32 dma, int type, 162 u64 len, int io_decode)
173 int bus_master, int transfer)
174{ 163{
175 int i = 0; 164 int flags = 0;
176 static unsigned char warned; 165 u64 end = start + len - 1;
177
178 while (i < PNP_MAX_DMA &&
179 !(res->dma_resource[i].flags & IORESOURCE_UNSET))
180 i++;
181 if (i < PNP_MAX_DMA) {
182 res->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag
183 res->dma_resource[i].flags |=
184 dma_flags(type, bus_master, transfer);
185 if (dma == -1) {
186 res->dma_resource[i].flags |= IORESOURCE_DISABLED;
187 return;
188 }
189 res->dma_resource[i].start = dma;
190 res->dma_resource[i].end = dma;
191 } else if (!warned) {
192 printk(KERN_WARNING "pnpacpi: exceeded the max number of DMA "
193 "resources: %d \n", PNP_MAX_DMA);
194 warned = 1;
195 }
196}
197 166
198static void pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res, 167 if (io_decode == ACPI_DECODE_16)
199 u64 io, u64 len, int io_decode) 168 flags |= PNP_PORT_FLAG_16BITADDR;
200{ 169 if (len == 0 || end >= 0x10003)
201 int i = 0; 170 flags |= IORESOURCE_DISABLED;
202 static unsigned char warned;
203 171
204 while (!(res->port_resource[i].flags & IORESOURCE_UNSET) && 172 pnp_add_io_resource(dev, start, end, flags);
205 i < PNP_MAX_PORT)
206 i++;
207 if (i < PNP_MAX_PORT) {
208 res->port_resource[i].flags = IORESOURCE_IO; // Also clears _UNSET flag
209 if (io_decode == ACPI_DECODE_16)
210 res->port_resource[i].flags |= PNP_PORT_FLAG_16BITADDR;
211 if (len <= 0 || (io + len - 1) >= 0x10003) {
212 res->port_resource[i].flags |= IORESOURCE_DISABLED;
213 return;
214 }
215 res->port_resource[i].start = io;
216 res->port_resource[i].end = io + len - 1;
217 } else if (!warned) {
218 printk(KERN_WARNING "pnpacpi: exceeded the max number of IO "
219 "resources: %d \n", PNP_MAX_PORT);
220 warned = 1;
221 }
222} 173}
223 174
224static void pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res, 175static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev,
225 u64 mem, u64 len, 176 u64 start, u64 len,
226 int write_protect) 177 int write_protect)
227{ 178{
228 int i = 0; 179 int flags = 0;
229 static unsigned char warned; 180 u64 end = start + len - 1;
230 181
231 while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) && 182 if (len == 0)
232 (i < PNP_MAX_MEM)) 183 flags |= IORESOURCE_DISABLED;
233 i++; 184 if (write_protect == ACPI_READ_WRITE_MEMORY)
234 if (i < PNP_MAX_MEM) { 185 flags |= IORESOURCE_MEM_WRITEABLE;
235 res->mem_resource[i].flags = IORESOURCE_MEM; // Also clears _UNSET flag 186
236 if (len <= 0) { 187 pnp_add_mem_resource(dev, start, end, flags);
237 res->mem_resource[i].flags |= IORESOURCE_DISABLED;
238 return;
239 }
240 if (write_protect == ACPI_READ_WRITE_MEMORY)
241 res->mem_resource[i].flags |= IORESOURCE_MEM_WRITEABLE;
242
243 res->mem_resource[i].start = mem;
244 res->mem_resource[i].end = mem + len - 1;
245 } else if (!warned) {
246 printk(KERN_WARNING "pnpacpi: exceeded the max number of mem "
247 "resources: %d\n", PNP_MAX_MEM);
248 warned = 1;
249 }
250} 188}
251 189
252static void pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res_table, 190static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,
253 struct acpi_resource *res) 191 struct acpi_resource *res)
254{ 192{
255 struct acpi_resource_address64 addr, *p = &addr; 193 struct acpi_resource_address64 addr, *p = &addr;
@@ -257,7 +195,7 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res
257 195
258 status = acpi_resource_to_address64(res, p); 196 status = acpi_resource_to_address64(res, p);
259 if (!ACPI_SUCCESS(status)) { 197 if (!ACPI_SUCCESS(status)) {
260 pnp_warn("PnPACPI: failed to convert resource type %d", 198 dev_warn(&dev->dev, "failed to convert resource type %d\n",
261 res->type); 199 res->type);
262 return; 200 return;
263 } 201 }
@@ -266,11 +204,11 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res
266 return; 204 return;
267 205
268 if (p->resource_type == ACPI_MEMORY_RANGE) 206 if (p->resource_type == ACPI_MEMORY_RANGE)
269 pnpacpi_parse_allocated_memresource(res_table, 207 pnpacpi_parse_allocated_memresource(dev,
270 p->minimum, p->address_length, 208 p->minimum, p->address_length,
271 p->info.mem.write_protect); 209 p->info.mem.write_protect);
272 else if (p->resource_type == ACPI_IO_RANGE) 210 else if (p->resource_type == ACPI_IO_RANGE)
273 pnpacpi_parse_allocated_ioresource(res_table, 211 pnpacpi_parse_allocated_ioresource(dev,
274 p->minimum, p->address_length, 212 p->minimum, p->address_length,
275 p->granularity == 0xfff ? ACPI_DECODE_10 : 213 p->granularity == 0xfff ? ACPI_DECODE_10 :
276 ACPI_DECODE_16); 214 ACPI_DECODE_16);
@@ -279,8 +217,16 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res
279static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, 217static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
280 void *data) 218 void *data)
281{ 219{
282 struct pnp_resource_table *res_table = data; 220 struct pnp_dev *dev = data;
283 int i; 221 struct acpi_resource_irq *irq;
222 struct acpi_resource_dma *dma;
223 struct acpi_resource_io *io;
224 struct acpi_resource_fixed_io *fixed_io;
225 struct acpi_resource_memory24 *memory24;
226 struct acpi_resource_memory32 *memory32;
227 struct acpi_resource_fixed_memory32 *fixed_memory32;
228 struct acpi_resource_extended_irq *extended_irq;
229 int i, flags;
284 230
285 switch (res->type) { 231 switch (res->type) {
286 case ACPI_RESOURCE_TYPE_IRQ: 232 case ACPI_RESOURCE_TYPE_IRQ:
@@ -288,29 +234,33 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
288 * Per spec, only one interrupt per descriptor is allowed in 234 * Per spec, only one interrupt per descriptor is allowed in
289 * _CRS, but some firmware violates this, so parse them all. 235 * _CRS, but some firmware violates this, so parse them all.
290 */ 236 */
291 for (i = 0; i < res->data.irq.interrupt_count; i++) { 237 irq = &res->data.irq;
292 pnpacpi_parse_allocated_irqresource(res_table, 238 for (i = 0; i < irq->interrupt_count; i++) {
293 res->data.irq.interrupts[i], 239 pnpacpi_parse_allocated_irqresource(dev,
294 res->data.irq.triggering, 240 irq->interrupts[i],
295 res->data.irq.polarity, 241 irq->triggering,
296 res->data.irq.sharable); 242 irq->polarity,
243 irq->sharable);
297 } 244 }
298 break; 245 break;
299 246
300 case ACPI_RESOURCE_TYPE_DMA: 247 case ACPI_RESOURCE_TYPE_DMA:
301 if (res->data.dma.channel_count > 0) 248 dma = &res->data.dma;
302 pnpacpi_parse_allocated_dmaresource(res_table, 249 if (dma->channel_count > 0) {
303 res->data.dma.channels[0], 250 flags = dma_flags(dma->type, dma->bus_master,
304 res->data.dma.type, 251 dma->transfer);
305 res->data.dma.bus_master, 252 if (dma->channels[0] == (u8) -1)
306 res->data.dma.transfer); 253 flags |= IORESOURCE_DISABLED;
254 pnp_add_dma_resource(dev, dma->channels[0], flags);
255 }
307 break; 256 break;
308 257
309 case ACPI_RESOURCE_TYPE_IO: 258 case ACPI_RESOURCE_TYPE_IO:
310 pnpacpi_parse_allocated_ioresource(res_table, 259 io = &res->data.io;
311 res->data.io.minimum, 260 pnpacpi_parse_allocated_ioresource(dev,
312 res->data.io.address_length, 261 io->minimum,
313 res->data.io.io_decode); 262 io->address_length,
263 io->io_decode);
314 break; 264 break;
315 265
316 case ACPI_RESOURCE_TYPE_START_DEPENDENT: 266 case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -318,9 +268,10 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
318 break; 268 break;
319 269
320 case ACPI_RESOURCE_TYPE_FIXED_IO: 270 case ACPI_RESOURCE_TYPE_FIXED_IO:
321 pnpacpi_parse_allocated_ioresource(res_table, 271 fixed_io = &res->data.fixed_io;
322 res->data.fixed_io.address, 272 pnpacpi_parse_allocated_ioresource(dev,
323 res->data.fixed_io.address_length, 273 fixed_io->address,
274 fixed_io->address_length,
324 ACPI_DECODE_10); 275 ACPI_DECODE_10);
325 break; 276 break;
326 277
@@ -331,27 +282,30 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
331 break; 282 break;
332 283
333 case ACPI_RESOURCE_TYPE_MEMORY24: 284 case ACPI_RESOURCE_TYPE_MEMORY24:
334 pnpacpi_parse_allocated_memresource(res_table, 285 memory24 = &res->data.memory24;
335 res->data.memory24.minimum, 286 pnpacpi_parse_allocated_memresource(dev,
336 res->data.memory24.address_length, 287 memory24->minimum,
337 res->data.memory24.write_protect); 288 memory24->address_length,
289 memory24->write_protect);
338 break; 290 break;
339 case ACPI_RESOURCE_TYPE_MEMORY32: 291 case ACPI_RESOURCE_TYPE_MEMORY32:
340 pnpacpi_parse_allocated_memresource(res_table, 292 memory32 = &res->data.memory32;
341 res->data.memory32.minimum, 293 pnpacpi_parse_allocated_memresource(dev,
342 res->data.memory32.address_length, 294 memory32->minimum,
343 res->data.memory32.write_protect); 295 memory32->address_length,
296 memory32->write_protect);
344 break; 297 break;
345 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: 298 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
346 pnpacpi_parse_allocated_memresource(res_table, 299 fixed_memory32 = &res->data.fixed_memory32;
347 res->data.fixed_memory32.address, 300 pnpacpi_parse_allocated_memresource(dev,
348 res->data.fixed_memory32.address_length, 301 fixed_memory32->address,
349 res->data.fixed_memory32.write_protect); 302 fixed_memory32->address_length,
303 fixed_memory32->write_protect);
350 break; 304 break;
351 case ACPI_RESOURCE_TYPE_ADDRESS16: 305 case ACPI_RESOURCE_TYPE_ADDRESS16:
352 case ACPI_RESOURCE_TYPE_ADDRESS32: 306 case ACPI_RESOURCE_TYPE_ADDRESS32:
353 case ACPI_RESOURCE_TYPE_ADDRESS64: 307 case ACPI_RESOURCE_TYPE_ADDRESS64:
354 pnpacpi_parse_allocated_address_space(res_table, res); 308 pnpacpi_parse_allocated_address_space(dev, res);
355 break; 309 break;
356 310
357 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: 311 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
@@ -360,15 +314,16 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
360 break; 314 break;
361 315
362 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 316 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
363 if (res->data.extended_irq.producer_consumer == ACPI_PRODUCER) 317 extended_irq = &res->data.extended_irq;
318 if (extended_irq->producer_consumer == ACPI_PRODUCER)
364 return AE_OK; 319 return AE_OK;
365 320
366 for (i = 0; i < res->data.extended_irq.interrupt_count; i++) { 321 for (i = 0; i < extended_irq->interrupt_count; i++) {
367 pnpacpi_parse_allocated_irqresource(res_table, 322 pnpacpi_parse_allocated_irqresource(dev,
368 res->data.extended_irq.interrupts[i], 323 extended_irq->interrupts[i],
369 res->data.extended_irq.triggering, 324 extended_irq->triggering,
370 res->data.extended_irq.polarity, 325 extended_irq->polarity,
371 res->data.extended_irq.sharable); 326 extended_irq->sharable);
372 } 327 }
373 break; 328 break;
374 329
@@ -376,24 +331,36 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
376 break; 331 break;
377 332
378 default: 333 default:
379 pnp_warn("PnPACPI: unknown resource type %d", res->type); 334 dev_warn(&dev->dev, "unknown resource type %d in _CRS\n",
335 res->type);
380 return AE_ERROR; 336 return AE_ERROR;
381 } 337 }
382 338
383 return AE_OK; 339 return AE_OK;
384} 340}
385 341
386acpi_status pnpacpi_parse_allocated_resource(acpi_handle handle, 342int pnpacpi_parse_allocated_resource(struct pnp_dev *dev)
387 struct pnp_resource_table * res)
388{ 343{
389 /* Blank the resource table values */ 344 acpi_handle handle = dev->data;
390 pnp_init_resource_table(res); 345 acpi_status status;
346
347 dev_dbg(&dev->dev, "parse allocated resources\n");
391 348
392 return acpi_walk_resources(handle, METHOD_NAME__CRS, 349 pnp_init_resources(dev);
393 pnpacpi_allocated_resource, res); 350
351 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
352 pnpacpi_allocated_resource, dev);
353
354 if (ACPI_FAILURE(status)) {
355 if (status != AE_NOT_FOUND)
356 dev_err(&dev->dev, "can't evaluate _CRS: %d", status);
357 return -EPERM;
358 }
359 return 0;
394} 360}
395 361
396static __init void pnpacpi_parse_dma_option(struct pnp_option *option, 362static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev,
363 struct pnp_option *option,
397 struct acpi_resource_dma *p) 364 struct acpi_resource_dma *p)
398{ 365{
399 int i; 366 int i;
@@ -410,10 +377,11 @@ static __init void pnpacpi_parse_dma_option(struct pnp_option *option,
410 377
411 dma->flags = dma_flags(p->type, p->bus_master, p->transfer); 378 dma->flags = dma_flags(p->type, p->bus_master, p->transfer);
412 379
413 pnp_register_dma_resource(option, dma); 380 pnp_register_dma_resource(dev, option, dma);
414} 381}
415 382
416static __init void pnpacpi_parse_irq_option(struct pnp_option *option, 383static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev,
384 struct pnp_option *option,
417 struct acpi_resource_irq *p) 385 struct acpi_resource_irq *p)
418{ 386{
419 int i; 387 int i;
@@ -428,12 +396,13 @@ static __init void pnpacpi_parse_irq_option(struct pnp_option *option,
428 for (i = 0; i < p->interrupt_count; i++) 396 for (i = 0; i < p->interrupt_count; i++)
429 if (p->interrupts[i]) 397 if (p->interrupts[i])
430 __set_bit(p->interrupts[i], irq->map); 398 __set_bit(p->interrupts[i], irq->map);
431 irq->flags = irq_flags(p->triggering, p->polarity); 399 irq->flags = irq_flags(p->triggering, p->polarity, p->sharable);
432 400
433 pnp_register_irq_resource(option, irq); 401 pnp_register_irq_resource(dev, option, irq);
434} 402}
435 403
436static __init void pnpacpi_parse_ext_irq_option(struct pnp_option *option, 404static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev,
405 struct pnp_option *option,
437 struct acpi_resource_extended_irq *p) 406 struct acpi_resource_extended_irq *p)
438{ 407{
439 int i; 408 int i;
@@ -448,12 +417,13 @@ static __init void pnpacpi_parse_ext_irq_option(struct pnp_option *option,
448 for (i = 0; i < p->interrupt_count; i++) 417 for (i = 0; i < p->interrupt_count; i++)
449 if (p->interrupts[i]) 418 if (p->interrupts[i])
450 __set_bit(p->interrupts[i], irq->map); 419 __set_bit(p->interrupts[i], irq->map);
451 irq->flags = irq_flags(p->triggering, p->polarity); 420 irq->flags = irq_flags(p->triggering, p->polarity, p->sharable);
452 421
453 pnp_register_irq_resource(option, irq); 422 pnp_register_irq_resource(dev, option, irq);
454} 423}
455 424
456static __init void pnpacpi_parse_port_option(struct pnp_option *option, 425static __init void pnpacpi_parse_port_option(struct pnp_dev *dev,
426 struct pnp_option *option,
457 struct acpi_resource_io *io) 427 struct acpi_resource_io *io)
458{ 428{
459 struct pnp_port *port; 429 struct pnp_port *port;
@@ -469,10 +439,11 @@ static __init void pnpacpi_parse_port_option(struct pnp_option *option,
469 port->size = io->address_length; 439 port->size = io->address_length;
470 port->flags = ACPI_DECODE_16 == io->io_decode ? 440 port->flags = ACPI_DECODE_16 == io->io_decode ?
471 PNP_PORT_FLAG_16BITADDR : 0; 441 PNP_PORT_FLAG_16BITADDR : 0;
472 pnp_register_port_resource(option, port); 442 pnp_register_port_resource(dev, option, port);
473} 443}
474 444
475static __init void pnpacpi_parse_fixed_port_option(struct pnp_option *option, 445static __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev,
446 struct pnp_option *option,
476 struct acpi_resource_fixed_io *io) 447 struct acpi_resource_fixed_io *io)
477{ 448{
478 struct pnp_port *port; 449 struct pnp_port *port;
@@ -486,10 +457,11 @@ static __init void pnpacpi_parse_fixed_port_option(struct pnp_option *option,
486 port->size = io->address_length; 457 port->size = io->address_length;
487 port->align = 0; 458 port->align = 0;
488 port->flags = PNP_PORT_FLAG_FIXED; 459 port->flags = PNP_PORT_FLAG_FIXED;
489 pnp_register_port_resource(option, port); 460 pnp_register_port_resource(dev, option, port);
490} 461}
491 462
492static __init void pnpacpi_parse_mem24_option(struct pnp_option *option, 463static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev,
464 struct pnp_option *option,
493 struct acpi_resource_memory24 *p) 465 struct acpi_resource_memory24 *p)
494{ 466{
495 struct pnp_mem *mem; 467 struct pnp_mem *mem;
@@ -507,10 +479,11 @@ static __init void pnpacpi_parse_mem24_option(struct pnp_option *option,
507 mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ? 479 mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
508 IORESOURCE_MEM_WRITEABLE : 0; 480 IORESOURCE_MEM_WRITEABLE : 0;
509 481
510 pnp_register_mem_resource(option, mem); 482 pnp_register_mem_resource(dev, option, mem);
511} 483}
512 484
513static __init void pnpacpi_parse_mem32_option(struct pnp_option *option, 485static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev,
486 struct pnp_option *option,
514 struct acpi_resource_memory32 *p) 487 struct acpi_resource_memory32 *p)
515{ 488{
516 struct pnp_mem *mem; 489 struct pnp_mem *mem;
@@ -528,10 +501,11 @@ static __init void pnpacpi_parse_mem32_option(struct pnp_option *option,
528 mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ? 501 mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
529 IORESOURCE_MEM_WRITEABLE : 0; 502 IORESOURCE_MEM_WRITEABLE : 0;
530 503
531 pnp_register_mem_resource(option, mem); 504 pnp_register_mem_resource(dev, option, mem);
532} 505}
533 506
534static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option, 507static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev,
508 struct pnp_option *option,
535 struct acpi_resource_fixed_memory32 *p) 509 struct acpi_resource_fixed_memory32 *p)
536{ 510{
537 struct pnp_mem *mem; 511 struct pnp_mem *mem;
@@ -548,10 +522,11 @@ static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option,
548 mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ? 522 mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
549 IORESOURCE_MEM_WRITEABLE : 0; 523 IORESOURCE_MEM_WRITEABLE : 0;
550 524
551 pnp_register_mem_resource(option, mem); 525 pnp_register_mem_resource(dev, option, mem);
552} 526}
553 527
554static __init void pnpacpi_parse_address_option(struct pnp_option *option, 528static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
529 struct pnp_option *option,
555 struct acpi_resource *r) 530 struct acpi_resource *r)
556{ 531{
557 struct acpi_resource_address64 addr, *p = &addr; 532 struct acpi_resource_address64 addr, *p = &addr;
@@ -579,7 +554,7 @@ static __init void pnpacpi_parse_address_option(struct pnp_option *option,
579 mem->flags = (p->info.mem.write_protect == 554 mem->flags = (p->info.mem.write_protect ==
580 ACPI_READ_WRITE_MEMORY) ? IORESOURCE_MEM_WRITEABLE 555 ACPI_READ_WRITE_MEMORY) ? IORESOURCE_MEM_WRITEABLE
581 : 0; 556 : 0;
582 pnp_register_mem_resource(option, mem); 557 pnp_register_mem_resource(dev, option, mem);
583 } else if (p->resource_type == ACPI_IO_RANGE) { 558 } else if (p->resource_type == ACPI_IO_RANGE) {
584 port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL); 559 port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
585 if (!port) 560 if (!port)
@@ -588,7 +563,7 @@ static __init void pnpacpi_parse_address_option(struct pnp_option *option,
588 port->size = p->address_length; 563 port->size = p->address_length;
589 port->align = 0; 564 port->align = 0;
590 port->flags = PNP_PORT_FLAG_FIXED; 565 port->flags = PNP_PORT_FLAG_FIXED;
591 pnp_register_port_resource(option, port); 566 pnp_register_port_resource(dev, option, port);
592 } 567 }
593} 568}
594 569
@@ -608,11 +583,11 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
608 583
609 switch (res->type) { 584 switch (res->type) {
610 case ACPI_RESOURCE_TYPE_IRQ: 585 case ACPI_RESOURCE_TYPE_IRQ:
611 pnpacpi_parse_irq_option(option, &res->data.irq); 586 pnpacpi_parse_irq_option(dev, option, &res->data.irq);
612 break; 587 break;
613 588
614 case ACPI_RESOURCE_TYPE_DMA: 589 case ACPI_RESOURCE_TYPE_DMA:
615 pnpacpi_parse_dma_option(option, &res->data.dma); 590 pnpacpi_parse_dma_option(dev, option, &res->data.dma);
616 break; 591 break;
617 592
618 case ACPI_RESOURCE_TYPE_START_DEPENDENT: 593 case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -642,19 +617,22 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
642 case ACPI_RESOURCE_TYPE_END_DEPENDENT: 617 case ACPI_RESOURCE_TYPE_END_DEPENDENT:
643 /*only one EndDependentFn is allowed */ 618 /*only one EndDependentFn is allowed */
644 if (!parse_data->option_independent) { 619 if (!parse_data->option_independent) {
645 pnp_warn("PnPACPI: more than one EndDependentFn"); 620 dev_warn(&dev->dev, "more than one EndDependentFn "
621 "in _PRS\n");
646 return AE_ERROR; 622 return AE_ERROR;
647 } 623 }
648 parse_data->option = parse_data->option_independent; 624 parse_data->option = parse_data->option_independent;
649 parse_data->option_independent = NULL; 625 parse_data->option_independent = NULL;
626 dev_dbg(&dev->dev, "end dependent options\n");
650 break; 627 break;
651 628
652 case ACPI_RESOURCE_TYPE_IO: 629 case ACPI_RESOURCE_TYPE_IO:
653 pnpacpi_parse_port_option(option, &res->data.io); 630 pnpacpi_parse_port_option(dev, option, &res->data.io);
654 break; 631 break;
655 632
656 case ACPI_RESOURCE_TYPE_FIXED_IO: 633 case ACPI_RESOURCE_TYPE_FIXED_IO:
657 pnpacpi_parse_fixed_port_option(option, &res->data.fixed_io); 634 pnpacpi_parse_fixed_port_option(dev, option,
635 &res->data.fixed_io);
658 break; 636 break;
659 637
660 case ACPI_RESOURCE_TYPE_VENDOR: 638 case ACPI_RESOURCE_TYPE_VENDOR:
@@ -662,57 +640,67 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
662 break; 640 break;
663 641
664 case ACPI_RESOURCE_TYPE_MEMORY24: 642 case ACPI_RESOURCE_TYPE_MEMORY24:
665 pnpacpi_parse_mem24_option(option, &res->data.memory24); 643 pnpacpi_parse_mem24_option(dev, option, &res->data.memory24);
666 break; 644 break;
667 645
668 case ACPI_RESOURCE_TYPE_MEMORY32: 646 case ACPI_RESOURCE_TYPE_MEMORY32:
669 pnpacpi_parse_mem32_option(option, &res->data.memory32); 647 pnpacpi_parse_mem32_option(dev, option, &res->data.memory32);
670 break; 648 break;
671 649
672 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: 650 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
673 pnpacpi_parse_fixed_mem32_option(option, 651 pnpacpi_parse_fixed_mem32_option(dev, option,
674 &res->data.fixed_memory32); 652 &res->data.fixed_memory32);
675 break; 653 break;
676 654
677 case ACPI_RESOURCE_TYPE_ADDRESS16: 655 case ACPI_RESOURCE_TYPE_ADDRESS16:
678 case ACPI_RESOURCE_TYPE_ADDRESS32: 656 case ACPI_RESOURCE_TYPE_ADDRESS32:
679 case ACPI_RESOURCE_TYPE_ADDRESS64: 657 case ACPI_RESOURCE_TYPE_ADDRESS64:
680 pnpacpi_parse_address_option(option, res); 658 pnpacpi_parse_address_option(dev, option, res);
681 break; 659 break;
682 660
683 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: 661 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
684 break; 662 break;
685 663
686 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 664 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
687 pnpacpi_parse_ext_irq_option(option, &res->data.extended_irq); 665 pnpacpi_parse_ext_irq_option(dev, option,
666 &res->data.extended_irq);
688 break; 667 break;
689 668
690 case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: 669 case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
691 break; 670 break;
692 671
693 default: 672 default:
694 pnp_warn("PnPACPI: unknown resource type %d", res->type); 673 dev_warn(&dev->dev, "unknown resource type %d in _PRS\n",
674 res->type);
695 return AE_ERROR; 675 return AE_ERROR;
696 } 676 }
697 677
698 return AE_OK; 678 return AE_OK;
699} 679}
700 680
701acpi_status __init pnpacpi_parse_resource_option_data(acpi_handle handle, 681int __init pnpacpi_parse_resource_option_data(struct pnp_dev *dev)
702 struct pnp_dev *dev)
703{ 682{
683 acpi_handle handle = dev->data;
704 acpi_status status; 684 acpi_status status;
705 struct acpipnp_parse_option_s parse_data; 685 struct acpipnp_parse_option_s parse_data;
706 686
687 dev_dbg(&dev->dev, "parse resource options\n");
688
707 parse_data.option = pnp_register_independent_option(dev); 689 parse_data.option = pnp_register_independent_option(dev);
708 if (!parse_data.option) 690 if (!parse_data.option)
709 return AE_ERROR; 691 return -ENOMEM;
692
710 parse_data.option_independent = parse_data.option; 693 parse_data.option_independent = parse_data.option;
711 parse_data.dev = dev; 694 parse_data.dev = dev;
712 status = acpi_walk_resources(handle, METHOD_NAME__PRS, 695 status = acpi_walk_resources(handle, METHOD_NAME__PRS,
713 pnpacpi_option_resource, &parse_data); 696 pnpacpi_option_resource, &parse_data);
714 697
715 return status; 698 if (ACPI_FAILURE(status)) {
699 if (status != AE_NOT_FOUND)
700 dev_err(&dev->dev, "can't evaluate _PRS: %d", status);
701 return -EPERM;
702 }
703 return 0;
716} 704}
717 705
718static int pnpacpi_supported_resource(struct acpi_resource *res) 706static int pnpacpi_supported_resource(struct acpi_resource *res)
@@ -760,9 +748,10 @@ static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data)
760 return AE_OK; 748 return AE_OK;
761} 749}
762 750
763int pnpacpi_build_resource_template(acpi_handle handle, 751int pnpacpi_build_resource_template(struct pnp_dev *dev,
764 struct acpi_buffer *buffer) 752 struct acpi_buffer *buffer)
765{ 753{
754 acpi_handle handle = dev->data;
766 struct acpi_resource *resource; 755 struct acpi_resource *resource;
767 int res_cnt = 0; 756 int res_cnt = 0;
768 acpi_status status; 757 acpi_status status;
@@ -770,7 +759,7 @@ int pnpacpi_build_resource_template(acpi_handle handle,
770 status = acpi_walk_resources(handle, METHOD_NAME__CRS, 759 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
771 pnpacpi_count_resources, &res_cnt); 760 pnpacpi_count_resources, &res_cnt);
772 if (ACPI_FAILURE(status)) { 761 if (ACPI_FAILURE(status)) {
773 pnp_err("Evaluate _CRS failed"); 762 dev_err(&dev->dev, "can't evaluate _CRS: %d\n", status);
774 return -EINVAL; 763 return -EINVAL;
775 } 764 }
776 if (!res_cnt) 765 if (!res_cnt)
@@ -779,13 +768,13 @@ int pnpacpi_build_resource_template(acpi_handle handle,
779 buffer->pointer = kzalloc(buffer->length - 1, GFP_KERNEL); 768 buffer->pointer = kzalloc(buffer->length - 1, GFP_KERNEL);
780 if (!buffer->pointer) 769 if (!buffer->pointer)
781 return -ENOMEM; 770 return -ENOMEM;
782 pnp_dbg("Res cnt %d", res_cnt); 771
783 resource = (struct acpi_resource *)buffer->pointer; 772 resource = (struct acpi_resource *)buffer->pointer;
784 status = acpi_walk_resources(handle, METHOD_NAME__CRS, 773 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
785 pnpacpi_type_resources, &resource); 774 pnpacpi_type_resources, &resource);
786 if (ACPI_FAILURE(status)) { 775 if (ACPI_FAILURE(status)) {
787 kfree(buffer->pointer); 776 kfree(buffer->pointer);
788 pnp_err("Evaluate _CRS failed"); 777 dev_err(&dev->dev, "can't evaluate _CRS: %d\n", status);
789 return -EINVAL; 778 return -EINVAL;
790 } 779 }
791 /* resource will pointer the end resource now */ 780 /* resource will pointer the end resource now */
@@ -794,129 +783,184 @@ int pnpacpi_build_resource_template(acpi_handle handle,
794 return 0; 783 return 0;
795} 784}
796 785
797static void pnpacpi_encode_irq(struct acpi_resource *resource, 786static void pnpacpi_encode_irq(struct pnp_dev *dev,
787 struct acpi_resource *resource,
798 struct resource *p) 788 struct resource *p)
799{ 789{
790 struct acpi_resource_irq *irq = &resource->data.irq;
800 int triggering, polarity; 791 int triggering, polarity;
801 792
802 decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity); 793 decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity);
803 resource->data.irq.triggering = triggering; 794 irq->triggering = triggering;
804 resource->data.irq.polarity = polarity; 795 irq->polarity = polarity;
805 if (triggering == ACPI_EDGE_SENSITIVE) 796 if (triggering == ACPI_EDGE_SENSITIVE)
806 resource->data.irq.sharable = ACPI_EXCLUSIVE; 797 irq->sharable = ACPI_EXCLUSIVE;
807 else 798 else
808 resource->data.irq.sharable = ACPI_SHARED; 799 irq->sharable = ACPI_SHARED;
809 resource->data.irq.interrupt_count = 1; 800 irq->interrupt_count = 1;
810 resource->data.irq.interrupts[0] = p->start; 801 irq->interrupts[0] = p->start;
802
803 dev_dbg(&dev->dev, " encode irq %d %s %s %s\n", (int) p->start,
804 triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge",
805 polarity == ACPI_ACTIVE_LOW ? "low" : "high",
806 irq->sharable == ACPI_SHARED ? "shared" : "exclusive");
811} 807}
812 808
813static void pnpacpi_encode_ext_irq(struct acpi_resource *resource, 809static void pnpacpi_encode_ext_irq(struct pnp_dev *dev,
810 struct acpi_resource *resource,
814 struct resource *p) 811 struct resource *p)
815{ 812{
813 struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq;
816 int triggering, polarity; 814 int triggering, polarity;
817 815
818 decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity); 816 decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity);
819 resource->data.extended_irq.producer_consumer = ACPI_CONSUMER; 817 extended_irq->producer_consumer = ACPI_CONSUMER;
820 resource->data.extended_irq.triggering = triggering; 818 extended_irq->triggering = triggering;
821 resource->data.extended_irq.polarity = polarity; 819 extended_irq->polarity = polarity;
822 if (triggering == ACPI_EDGE_SENSITIVE) 820 if (triggering == ACPI_EDGE_SENSITIVE)
823 resource->data.irq.sharable = ACPI_EXCLUSIVE; 821 extended_irq->sharable = ACPI_EXCLUSIVE;
824 else 822 else
825 resource->data.irq.sharable = ACPI_SHARED; 823 extended_irq->sharable = ACPI_SHARED;
826 resource->data.extended_irq.interrupt_count = 1; 824 extended_irq->interrupt_count = 1;
827 resource->data.extended_irq.interrupts[0] = p->start; 825 extended_irq->interrupts[0] = p->start;
826
827 dev_dbg(&dev->dev, " encode irq %d %s %s %s\n", (int) p->start,
828 triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge",
829 polarity == ACPI_ACTIVE_LOW ? "low" : "high",
830 extended_irq->sharable == ACPI_SHARED ? "shared" : "exclusive");
828} 831}
829 832
830static void pnpacpi_encode_dma(struct acpi_resource *resource, 833static void pnpacpi_encode_dma(struct pnp_dev *dev,
834 struct acpi_resource *resource,
831 struct resource *p) 835 struct resource *p)
832{ 836{
837 struct acpi_resource_dma *dma = &resource->data.dma;
838
833 /* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */ 839 /* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */
834 switch (p->flags & IORESOURCE_DMA_SPEED_MASK) { 840 switch (p->flags & IORESOURCE_DMA_SPEED_MASK) {
835 case IORESOURCE_DMA_TYPEA: 841 case IORESOURCE_DMA_TYPEA:
836 resource->data.dma.type = ACPI_TYPE_A; 842 dma->type = ACPI_TYPE_A;
837 break; 843 break;
838 case IORESOURCE_DMA_TYPEB: 844 case IORESOURCE_DMA_TYPEB:
839 resource->data.dma.type = ACPI_TYPE_B; 845 dma->type = ACPI_TYPE_B;
840 break; 846 break;
841 case IORESOURCE_DMA_TYPEF: 847 case IORESOURCE_DMA_TYPEF:
842 resource->data.dma.type = ACPI_TYPE_F; 848 dma->type = ACPI_TYPE_F;
843 break; 849 break;
844 default: 850 default:
845 resource->data.dma.type = ACPI_COMPATIBILITY; 851 dma->type = ACPI_COMPATIBILITY;
846 } 852 }
847 853
848 switch (p->flags & IORESOURCE_DMA_TYPE_MASK) { 854 switch (p->flags & IORESOURCE_DMA_TYPE_MASK) {
849 case IORESOURCE_DMA_8BIT: 855 case IORESOURCE_DMA_8BIT:
850 resource->data.dma.transfer = ACPI_TRANSFER_8; 856 dma->transfer = ACPI_TRANSFER_8;
851 break; 857 break;
852 case IORESOURCE_DMA_8AND16BIT: 858 case IORESOURCE_DMA_8AND16BIT:
853 resource->data.dma.transfer = ACPI_TRANSFER_8_16; 859 dma->transfer = ACPI_TRANSFER_8_16;
854 break; 860 break;
855 default: 861 default:
856 resource->data.dma.transfer = ACPI_TRANSFER_16; 862 dma->transfer = ACPI_TRANSFER_16;
857 } 863 }
858 864
859 resource->data.dma.bus_master = !!(p->flags & IORESOURCE_DMA_MASTER); 865 dma->bus_master = !!(p->flags & IORESOURCE_DMA_MASTER);
860 resource->data.dma.channel_count = 1; 866 dma->channel_count = 1;
861 resource->data.dma.channels[0] = p->start; 867 dma->channels[0] = p->start;
868
869 dev_dbg(&dev->dev, " encode dma %d "
870 "type %#x transfer %#x master %d\n",
871 (int) p->start, dma->type, dma->transfer, dma->bus_master);
862} 872}
863 873
864static void pnpacpi_encode_io(struct acpi_resource *resource, 874static void pnpacpi_encode_io(struct pnp_dev *dev,
875 struct acpi_resource *resource,
865 struct resource *p) 876 struct resource *p)
866{ 877{
878 struct acpi_resource_io *io = &resource->data.io;
879
867 /* Note: pnp_assign_port will copy pnp_port->flags into p->flags */ 880 /* Note: pnp_assign_port will copy pnp_port->flags into p->flags */
868 resource->data.io.io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR) ? 881 io->io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR) ?
869 ACPI_DECODE_16 : ACPI_DECODE_10; 882 ACPI_DECODE_16 : ACPI_DECODE_10;
870 resource->data.io.minimum = p->start; 883 io->minimum = p->start;
871 resource->data.io.maximum = p->end; 884 io->maximum = p->end;
872 resource->data.io.alignment = 0; /* Correct? */ 885 io->alignment = 0; /* Correct? */
873 resource->data.io.address_length = p->end - p->start + 1; 886 io->address_length = p->end - p->start + 1;
887
888 dev_dbg(&dev->dev, " encode io %#llx-%#llx decode %#x\n",
889 (unsigned long long) p->start, (unsigned long long) p->end,
890 io->io_decode);
874} 891}
875 892
876static void pnpacpi_encode_fixed_io(struct acpi_resource *resource, 893static void pnpacpi_encode_fixed_io(struct pnp_dev *dev,
894 struct acpi_resource *resource,
877 struct resource *p) 895 struct resource *p)
878{ 896{
879 resource->data.fixed_io.address = p->start; 897 struct acpi_resource_fixed_io *fixed_io = &resource->data.fixed_io;
880 resource->data.fixed_io.address_length = p->end - p->start + 1; 898
899 fixed_io->address = p->start;
900 fixed_io->address_length = p->end - p->start + 1;
901
902 dev_dbg(&dev->dev, " encode fixed_io %#llx-%#llx\n",
903 (unsigned long long) p->start, (unsigned long long) p->end);
881} 904}
882 905
883static void pnpacpi_encode_mem24(struct acpi_resource *resource, 906static void pnpacpi_encode_mem24(struct pnp_dev *dev,
907 struct acpi_resource *resource,
884 struct resource *p) 908 struct resource *p)
885{ 909{
910 struct acpi_resource_memory24 *memory24 = &resource->data.memory24;
911
886 /* Note: pnp_assign_mem will copy pnp_mem->flags into p->flags */ 912 /* Note: pnp_assign_mem will copy pnp_mem->flags into p->flags */
887 resource->data.memory24.write_protect = 913 memory24->write_protect =
888 (p->flags & IORESOURCE_MEM_WRITEABLE) ? 914 (p->flags & IORESOURCE_MEM_WRITEABLE) ?
889 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; 915 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
890 resource->data.memory24.minimum = p->start; 916 memory24->minimum = p->start;
891 resource->data.memory24.maximum = p->end; 917 memory24->maximum = p->end;
892 resource->data.memory24.alignment = 0; 918 memory24->alignment = 0;
893 resource->data.memory24.address_length = p->end - p->start + 1; 919 memory24->address_length = p->end - p->start + 1;
920
921 dev_dbg(&dev->dev, " encode mem24 %#llx-%#llx write_protect %#x\n",
922 (unsigned long long) p->start, (unsigned long long) p->end,
923 memory24->write_protect);
894} 924}
895 925
896static void pnpacpi_encode_mem32(struct acpi_resource *resource, 926static void pnpacpi_encode_mem32(struct pnp_dev *dev,
927 struct acpi_resource *resource,
897 struct resource *p) 928 struct resource *p)
898{ 929{
899 resource->data.memory32.write_protect = 930 struct acpi_resource_memory32 *memory32 = &resource->data.memory32;
931
932 memory32->write_protect =
900 (p->flags & IORESOURCE_MEM_WRITEABLE) ? 933 (p->flags & IORESOURCE_MEM_WRITEABLE) ?
901 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; 934 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
902 resource->data.memory32.minimum = p->start; 935 memory32->minimum = p->start;
903 resource->data.memory32.maximum = p->end; 936 memory32->maximum = p->end;
904 resource->data.memory32.alignment = 0; 937 memory32->alignment = 0;
905 resource->data.memory32.address_length = p->end - p->start + 1; 938 memory32->address_length = p->end - p->start + 1;
939
940 dev_dbg(&dev->dev, " encode mem32 %#llx-%#llx write_protect %#x\n",
941 (unsigned long long) p->start, (unsigned long long) p->end,
942 memory32->write_protect);
906} 943}
907 944
908static void pnpacpi_encode_fixed_mem32(struct acpi_resource *resource, 945static void pnpacpi_encode_fixed_mem32(struct pnp_dev *dev,
946 struct acpi_resource *resource,
909 struct resource *p) 947 struct resource *p)
910{ 948{
911 resource->data.fixed_memory32.write_protect = 949 struct acpi_resource_fixed_memory32 *fixed_memory32 = &resource->data.fixed_memory32;
950
951 fixed_memory32->write_protect =
912 (p->flags & IORESOURCE_MEM_WRITEABLE) ? 952 (p->flags & IORESOURCE_MEM_WRITEABLE) ?
913 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; 953 ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
914 resource->data.fixed_memory32.address = p->start; 954 fixed_memory32->address = p->start;
915 resource->data.fixed_memory32.address_length = p->end - p->start + 1; 955 fixed_memory32->address_length = p->end - p->start + 1;
956
957 dev_dbg(&dev->dev, " encode fixed_mem32 %#llx-%#llx "
958 "write_protect %#x\n",
959 (unsigned long long) p->start, (unsigned long long) p->end,
960 fixed_memory32->write_protect);
916} 961}
917 962
918int pnpacpi_encode_resources(struct pnp_resource_table *res_table, 963int pnpacpi_encode_resources(struct pnp_dev *dev, struct acpi_buffer *buffer)
919 struct acpi_buffer *buffer)
920{ 964{
921 int i = 0; 965 int i = 0;
922 /* pnpacpi_build_resource_template allocates extra mem */ 966 /* pnpacpi_build_resource_template allocates extra mem */
@@ -924,58 +968,48 @@ int pnpacpi_encode_resources(struct pnp_resource_table *res_table,
924 struct acpi_resource *resource = buffer->pointer; 968 struct acpi_resource *resource = buffer->pointer;
925 int port = 0, irq = 0, dma = 0, mem = 0; 969 int port = 0, irq = 0, dma = 0, mem = 0;
926 970
927 pnp_dbg("res cnt %d", res_cnt); 971 dev_dbg(&dev->dev, "encode %d resources\n", res_cnt);
928 while (i < res_cnt) { 972 while (i < res_cnt) {
929 switch (resource->type) { 973 switch (resource->type) {
930 case ACPI_RESOURCE_TYPE_IRQ: 974 case ACPI_RESOURCE_TYPE_IRQ:
931 pnp_dbg("Encode irq"); 975 pnpacpi_encode_irq(dev, resource,
932 pnpacpi_encode_irq(resource, 976 pnp_get_resource(dev, IORESOURCE_IRQ, irq));
933 &res_table->irq_resource[irq]);
934 irq++; 977 irq++;
935 break; 978 break;
936 979
937 case ACPI_RESOURCE_TYPE_DMA: 980 case ACPI_RESOURCE_TYPE_DMA:
938 pnp_dbg("Encode dma"); 981 pnpacpi_encode_dma(dev, resource,
939 pnpacpi_encode_dma(resource, 982 pnp_get_resource(dev, IORESOURCE_DMA, dma));
940 &res_table->dma_resource[dma]);
941 dma++; 983 dma++;
942 break; 984 break;
943 case ACPI_RESOURCE_TYPE_IO: 985 case ACPI_RESOURCE_TYPE_IO:
944 pnp_dbg("Encode io"); 986 pnpacpi_encode_io(dev, resource,
945 pnpacpi_encode_io(resource, 987 pnp_get_resource(dev, IORESOURCE_IO, port));
946 &res_table->port_resource[port]);
947 port++; 988 port++;
948 break; 989 break;
949 case ACPI_RESOURCE_TYPE_FIXED_IO: 990 case ACPI_RESOURCE_TYPE_FIXED_IO:
950 pnp_dbg("Encode fixed io"); 991 pnpacpi_encode_fixed_io(dev, resource,
951 pnpacpi_encode_fixed_io(resource, 992 pnp_get_resource(dev, IORESOURCE_IO, port));
952 &res_table->
953 port_resource[port]);
954 port++; 993 port++;
955 break; 994 break;
956 case ACPI_RESOURCE_TYPE_MEMORY24: 995 case ACPI_RESOURCE_TYPE_MEMORY24:
957 pnp_dbg("Encode mem24"); 996 pnpacpi_encode_mem24(dev, resource,
958 pnpacpi_encode_mem24(resource, 997 pnp_get_resource(dev, IORESOURCE_MEM, mem));
959 &res_table->mem_resource[mem]);
960 mem++; 998 mem++;
961 break; 999 break;
962 case ACPI_RESOURCE_TYPE_MEMORY32: 1000 case ACPI_RESOURCE_TYPE_MEMORY32:
963 pnp_dbg("Encode mem32"); 1001 pnpacpi_encode_mem32(dev, resource,
964 pnpacpi_encode_mem32(resource, 1002 pnp_get_resource(dev, IORESOURCE_MEM, mem));
965 &res_table->mem_resource[mem]);
966 mem++; 1003 mem++;
967 break; 1004 break;
968 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: 1005 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
969 pnp_dbg("Encode fixed mem32"); 1006 pnpacpi_encode_fixed_mem32(dev, resource,
970 pnpacpi_encode_fixed_mem32(resource, 1007 pnp_get_resource(dev, IORESOURCE_MEM, mem));
971 &res_table->
972 mem_resource[mem]);
973 mem++; 1008 mem++;
974 break; 1009 break;
975 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: 1010 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
976 pnp_dbg("Encode ext irq"); 1011 pnpacpi_encode_ext_irq(dev, resource,
977 pnpacpi_encode_ext_irq(resource, 1012 pnp_get_resource(dev, IORESOURCE_IRQ, irq));
978 &res_table->irq_resource[irq]);
979 irq++; 1013 irq++;
980 break; 1014 break;
981 case ACPI_RESOURCE_TYPE_START_DEPENDENT: 1015 case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -988,7 +1022,8 @@ int pnpacpi_encode_resources(struct pnp_resource_table *res_table,
988 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: 1022 case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
989 case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: 1023 case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
990 default: /* other type */ 1024 default: /* other type */
991 pnp_warn("unknown resource type %d", resource->type); 1025 dev_warn(&dev->dev, "can't encode unknown resource "
1026 "type %d\n", resource->type);
992 return -EINVAL; 1027 return -EINVAL;
993 } 1028 }
994 resource++; 1029 resource++;
diff --git a/drivers/pnp/pnpbios/Makefile b/drivers/pnp/pnpbios/Makefile
index 3cd3ed760605..310e2b3a7710 100644
--- a/drivers/pnp/pnpbios/Makefile
+++ b/drivers/pnp/pnpbios/Makefile
@@ -5,3 +5,7 @@
5pnpbios-proc-$(CONFIG_PNPBIOS_PROC_FS) = proc.o 5pnpbios-proc-$(CONFIG_PNPBIOS_PROC_FS) = proc.o
6 6
7obj-y := core.o bioscalls.o rsparser.o $(pnpbios-proc-y) 7obj-y := core.o bioscalls.o rsparser.o $(pnpbios-proc-y)
8
9ifeq ($(CONFIG_PNP_DEBUG),y)
10EXTRA_CFLAGS += -DDEBUG
11endif
diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c
index a8364d815222..7ff824496b39 100644
--- a/drivers/pnp/pnpbios/bioscalls.c
+++ b/drivers/pnp/pnpbios/bioscalls.c
@@ -7,7 +7,6 @@
7#include <linux/init.h> 7#include <linux/init.h>
8#include <linux/linkage.h> 8#include <linux/linkage.h>
9#include <linux/kernel.h> 9#include <linux/kernel.h>
10#include <linux/pnpbios.h>
11#include <linux/device.h> 10#include <linux/device.h>
12#include <linux/pnp.h> 11#include <linux/pnp.h>
13#include <linux/mm.h> 12#include <linux/mm.h>
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
index a8a51500e1e9..19a4be1a9a31 100644
--- a/drivers/pnp/pnpbios/core.c
+++ b/drivers/pnp/pnpbios/core.c
@@ -50,7 +50,6 @@
50#include <linux/init.h> 50#include <linux/init.h>
51#include <linux/linkage.h> 51#include <linux/linkage.h>
52#include <linux/kernel.h> 52#include <linux/kernel.h>
53#include <linux/pnpbios.h>
54#include <linux/device.h> 53#include <linux/device.h>
55#include <linux/pnp.h> 54#include <linux/pnp.h>
56#include <linux/mm.h> 55#include <linux/mm.h>
@@ -69,6 +68,7 @@
69#include <asm/system.h> 68#include <asm/system.h>
70#include <asm/byteorder.h> 69#include <asm/byteorder.h>
71 70
71#include "../base.h"
72#include "pnpbios.h" 72#include "pnpbios.h"
73 73
74/* 74/*
@@ -203,8 +203,7 @@ static int pnp_dock_thread(void *unused)
203 203
204#endif /* CONFIG_HOTPLUG */ 204#endif /* CONFIG_HOTPLUG */
205 205
206static int pnpbios_get_resources(struct pnp_dev *dev, 206static int pnpbios_get_resources(struct pnp_dev *dev)
207 struct pnp_resource_table *res)
208{ 207{
209 u8 nodenum = dev->number; 208 u8 nodenum = dev->number;
210 struct pnp_bios_node *node; 209 struct pnp_bios_node *node;
@@ -212,6 +211,7 @@ static int pnpbios_get_resources(struct pnp_dev *dev,
212 if (!pnpbios_is_dynamic(dev)) 211 if (!pnpbios_is_dynamic(dev))
213 return -EPERM; 212 return -EPERM;
214 213
214 dev_dbg(&dev->dev, "get resources\n");
215 node = kzalloc(node_info.max_node_size, GFP_KERNEL); 215 node = kzalloc(node_info.max_node_size, GFP_KERNEL);
216 if (!node) 216 if (!node)
217 return -1; 217 return -1;
@@ -219,14 +219,13 @@ static int pnpbios_get_resources(struct pnp_dev *dev,
219 kfree(node); 219 kfree(node);
220 return -ENODEV; 220 return -ENODEV;
221 } 221 }
222 pnpbios_read_resources_from_node(res, node); 222 pnpbios_read_resources_from_node(dev, node);
223 dev->active = pnp_is_active(dev); 223 dev->active = pnp_is_active(dev);
224 kfree(node); 224 kfree(node);
225 return 0; 225 return 0;
226} 226}
227 227
228static int pnpbios_set_resources(struct pnp_dev *dev, 228static int pnpbios_set_resources(struct pnp_dev *dev)
229 struct pnp_resource_table *res)
230{ 229{
231 u8 nodenum = dev->number; 230 u8 nodenum = dev->number;
232 struct pnp_bios_node *node; 231 struct pnp_bios_node *node;
@@ -235,6 +234,7 @@ static int pnpbios_set_resources(struct pnp_dev *dev,
235 if (!pnpbios_is_dynamic(dev)) 234 if (!pnpbios_is_dynamic(dev))
236 return -EPERM; 235 return -EPERM;
237 236
237 dev_dbg(&dev->dev, "set resources\n");
238 node = kzalloc(node_info.max_node_size, GFP_KERNEL); 238 node = kzalloc(node_info.max_node_size, GFP_KERNEL);
239 if (!node) 239 if (!node)
240 return -1; 240 return -1;
@@ -242,7 +242,7 @@ static int pnpbios_set_resources(struct pnp_dev *dev,
242 kfree(node); 242 kfree(node);
243 return -ENODEV; 243 return -ENODEV;
244 } 244 }
245 if (pnpbios_write_resources_to_node(res, node) < 0) { 245 if (pnpbios_write_resources_to_node(dev, node) < 0) {
246 kfree(node); 246 kfree(node);
247 return -1; 247 return -1;
248 } 248 }
@@ -317,7 +317,6 @@ static int __init insert_device(struct pnp_bios_node *node)
317{ 317{
318 struct list_head *pos; 318 struct list_head *pos;
319 struct pnp_dev *dev; 319 struct pnp_dev *dev;
320 struct pnp_id *dev_id;
321 char id[8]; 320 char id[8];
322 321
323 /* check if the device is already added */ 322 /* check if the device is already added */
@@ -327,20 +326,11 @@ static int __init insert_device(struct pnp_bios_node *node)
327 return -1; 326 return -1;
328 } 327 }
329 328
330 dev = kzalloc(sizeof(struct pnp_dev), GFP_KERNEL); 329 pnp_eisa_id_to_string(node->eisa_id & PNP_EISA_ID_MASK, id);
330 dev = pnp_alloc_dev(&pnpbios_protocol, node->handle, id);
331 if (!dev) 331 if (!dev)
332 return -1; 332 return -1;
333 333
334 dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
335 if (!dev_id) {
336 kfree(dev);
337 return -1;
338 }
339
340 dev->number = node->handle;
341 pnpid32_to_pnpid(node->eisa_id, id);
342 memcpy(dev_id->id, id, 7);
343 pnp_add_id(dev_id, dev);
344 pnpbios_parse_data_stream(dev, node); 334 pnpbios_parse_data_stream(dev, node);
345 dev->active = pnp_is_active(dev); 335 dev->active = pnp_is_active(dev);
346 dev->flags = node->flags; 336 dev->flags = node->flags;
@@ -353,11 +343,10 @@ static int __init insert_device(struct pnp_bios_node *node)
353 dev->capabilities |= PNP_WRITE; 343 dev->capabilities |= PNP_WRITE;
354 if (dev->flags & PNPBIOS_REMOVABLE) 344 if (dev->flags & PNPBIOS_REMOVABLE)
355 dev->capabilities |= PNP_REMOVABLE; 345 dev->capabilities |= PNP_REMOVABLE;
356 dev->protocol = &pnpbios_protocol;
357 346
358 /* clear out the damaged flags */ 347 /* clear out the damaged flags */
359 if (!dev->active) 348 if (!dev->active)
360 pnp_init_resource_table(&dev->res); 349 pnp_init_resources(dev);
361 350
362 pnp_add_device(dev); 351 pnp_add_device(dev);
363 pnpbios_interface_attach_device(node); 352 pnpbios_interface_attach_device(node);
diff --git a/drivers/pnp/pnpbios/pnpbios.h b/drivers/pnp/pnpbios/pnpbios.h
index d8cb2fd1f127..b09cf6dc2075 100644
--- a/drivers/pnp/pnpbios/pnpbios.h
+++ b/drivers/pnp/pnpbios/pnpbios.h
@@ -2,6 +2,142 @@
2 * pnpbios.h - contains local definitions 2 * pnpbios.h - contains local definitions
3 */ 3 */
4 4
5/*
6 * Include file for the interface to a PnP BIOS
7 *
8 * Original BIOS code (C) 1998 Christian Schmidt (chr.schmidt@tu-bs.de)
9 * PnP handler parts (c) 1998 Tom Lees <tom@lpsg.demon.co.uk>
10 * Minor reorganizations by David Hinds <dahinds@users.sourceforge.net>
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2, or (at your option) any
15 * later version.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26
27/*
28 * Return codes
29 */
30#define PNP_SUCCESS 0x00
31#define PNP_NOT_SET_STATICALLY 0x7f
32#define PNP_UNKNOWN_FUNCTION 0x81
33#define PNP_FUNCTION_NOT_SUPPORTED 0x82
34#define PNP_INVALID_HANDLE 0x83
35#define PNP_BAD_PARAMETER 0x84
36#define PNP_SET_FAILED 0x85
37#define PNP_EVENTS_NOT_PENDING 0x86
38#define PNP_SYSTEM_NOT_DOCKED 0x87
39#define PNP_NO_ISA_PNP_CARDS 0x88
40#define PNP_UNABLE_TO_DETERMINE_DOCK_CAPABILITIES 0x89
41#define PNP_CONFIG_CHANGE_FAILED_NO_BATTERY 0x8a
42#define PNP_CONFIG_CHANGE_FAILED_RESOURCE_CONFLICT 0x8b
43#define PNP_BUFFER_TOO_SMALL 0x8c
44#define PNP_USE_ESCD_SUPPORT 0x8d
45#define PNP_MESSAGE_NOT_SUPPORTED 0x8e
46#define PNP_HARDWARE_ERROR 0x8f
47
48#define ESCD_SUCCESS 0x00
49#define ESCD_IO_ERROR_READING 0x55
50#define ESCD_INVALID 0x56
51#define ESCD_BUFFER_TOO_SMALL 0x59
52#define ESCD_NVRAM_TOO_SMALL 0x5a
53#define ESCD_FUNCTION_NOT_SUPPORTED 0x81
54
55/*
56 * Events that can be received by "get event"
57 */
58#define PNPEV_ABOUT_TO_CHANGE_CONFIG 0x0001
59#define PNPEV_DOCK_CHANGED 0x0002
60#define PNPEV_SYSTEM_DEVICE_CHANGED 0x0003
61#define PNPEV_CONFIG_CHANGED_FAILED 0x0004
62#define PNPEV_UNKNOWN_SYSTEM_EVENT 0xffff
63/* 0x8000 through 0xfffe are OEM defined */
64
65/*
66 * Messages that should be sent through "send message"
67 */
68#define PNPMSG_OK 0x00
69#define PNPMSG_ABORT 0x01
70#define PNPMSG_UNDOCK_DEFAULT_ACTION 0x40
71#define PNPMSG_POWER_OFF 0x41
72#define PNPMSG_PNP_OS_ACTIVE 0x42
73#define PNPMSG_PNP_OS_INACTIVE 0x43
74
75/*
76 * Plug and Play BIOS flags
77 */
78#define PNPBIOS_NO_DISABLE 0x0001
79#define PNPBIOS_NO_CONFIG 0x0002
80#define PNPBIOS_OUTPUT 0x0004
81#define PNPBIOS_INPUT 0x0008
82#define PNPBIOS_BOOTABLE 0x0010
83#define PNPBIOS_DOCK 0x0020
84#define PNPBIOS_REMOVABLE 0x0040
85#define pnpbios_is_static(x) (((x)->flags & 0x0100) == 0x0000)
86#define pnpbios_is_dynamic(x) ((x)->flags & 0x0080)
87
88/*
89 * Function Parameters
90 */
91#define PNPMODE_STATIC 1
92#define PNPMODE_DYNAMIC 0
93
94/* 0x8000 through 0xffff are OEM defined */
95
96#pragma pack(1)
97struct pnp_dev_node_info {
98 __u16 no_nodes;
99 __u16 max_node_size;
100};
101struct pnp_docking_station_info {
102 __u32 location_id;
103 __u32 serial;
104 __u16 capabilities;
105};
106struct pnp_isa_config_struc {
107 __u8 revision;
108 __u8 no_csns;
109 __u16 isa_rd_data_port;
110 __u16 reserved;
111};
112struct escd_info_struc {
113 __u16 min_escd_write_size;
114 __u16 escd_size;
115 __u32 nv_storage_base;
116};
117struct pnp_bios_node {
118 __u16 size;
119 __u8 handle;
120 __u32 eisa_id;
121 __u8 type_code[3];
122 __u16 flags;
123 __u8 data[0];
124};
125#pragma pack()
126
127/* non-exported */
128extern struct pnp_dev_node_info node_info;
129
130extern int pnp_bios_dev_node_info(struct pnp_dev_node_info *data);
131extern int pnp_bios_get_dev_node(u8 *nodenum, char config,
132 struct pnp_bios_node *data);
133extern int pnp_bios_set_dev_node(u8 nodenum, char config,
134 struct pnp_bios_node *data);
135extern int pnp_bios_get_stat_res(char *info);
136extern int pnp_bios_isapnp_config(struct pnp_isa_config_struc *data);
137extern int pnp_bios_escd_info(struct escd_info_struc *data);
138extern int pnp_bios_read_escd(char *data, u32 nvram_base);
139extern int pnp_bios_dock_station_info(struct pnp_docking_station_info *data);
140
5#pragma pack(1) 141#pragma pack(1)
6union pnp_bios_install_struct { 142union pnp_bios_install_struct {
7 struct { 143 struct {
@@ -28,8 +164,8 @@ extern int pnp_bios_present(void);
28extern int pnpbios_dont_use_current_config; 164extern int pnpbios_dont_use_current_config;
29 165
30extern int pnpbios_parse_data_stream(struct pnp_dev *dev, struct pnp_bios_node * node); 166extern int pnpbios_parse_data_stream(struct pnp_dev *dev, struct pnp_bios_node * node);
31extern int pnpbios_read_resources_from_node(struct pnp_resource_table *res, struct pnp_bios_node * node); 167extern int pnpbios_read_resources_from_node(struct pnp_dev *dev, struct pnp_bios_node *node);
32extern int pnpbios_write_resources_to_node(struct pnp_resource_table *res, struct pnp_bios_node * node); 168extern int pnpbios_write_resources_to_node(struct pnp_dev *dev, struct pnp_bios_node *node);
33extern void pnpid32_to_pnpid(u32 id, char *str); 169extern void pnpid32_to_pnpid(u32 id, char *str);
34 170
35extern void pnpbios_print_status(const char * module, u16 status); 171extern void pnpbios_print_status(const char * module, u16 status);
diff --git a/drivers/pnp/pnpbios/proc.c b/drivers/pnp/pnpbios/proc.c
index 46d506f66259..b35d921bac6e 100644
--- a/drivers/pnp/pnpbios/proc.c
+++ b/drivers/pnp/pnpbios/proc.c
@@ -23,7 +23,7 @@
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/types.h> 24#include <linux/types.h>
25#include <linux/proc_fs.h> 25#include <linux/proc_fs.h>
26#include <linux/pnpbios.h> 26#include <linux/pnp.h>
27#include <linux/init.h> 27#include <linux/init.h>
28 28
29#include <asm/uaccess.h> 29#include <asm/uaccess.h>
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
index caade3531416..2e2c457a0fea 100644
--- a/drivers/pnp/pnpbios/rsparser.c
+++ b/drivers/pnp/pnpbios/rsparser.c
@@ -4,7 +4,6 @@
4 4
5#include <linux/ctype.h> 5#include <linux/ctype.h>
6#include <linux/pnp.h> 6#include <linux/pnp.h>
7#include <linux/pnpbios.h>
8#include <linux/string.h> 7#include <linux/string.h>
9#include <linux/slab.h> 8#include <linux/slab.h>
10 9
@@ -16,6 +15,7 @@ inline void pcibios_penalize_isa_irq(int irq, int active)
16} 15}
17#endif /* CONFIG_PCI */ 16#endif /* CONFIG_PCI */
18 17
18#include "../base.h"
19#include "pnpbios.h" 19#include "pnpbios.h"
20 20
21/* standard resource tags */ 21/* standard resource tags */
@@ -53,97 +53,43 @@ inline void pcibios_penalize_isa_irq(int irq, int active)
53 * Allocated Resources 53 * Allocated Resources
54 */ 54 */
55 55
56static void pnpbios_parse_allocated_irqresource(struct pnp_resource_table *res, 56static void pnpbios_parse_allocated_ioresource(struct pnp_dev *dev,
57 int irq) 57 int start, int len)
58{ 58{
59 int i = 0; 59 int flags = 0;
60 60 int end = start + len - 1;
61 while (!(res->irq_resource[i].flags & IORESOURCE_UNSET)
62 && i < PNP_MAX_IRQ)
63 i++;
64 if (i < PNP_MAX_IRQ) {
65 res->irq_resource[i].flags = IORESOURCE_IRQ; // Also clears _UNSET flag
66 if (irq == -1) {
67 res->irq_resource[i].flags |= IORESOURCE_DISABLED;
68 return;
69 }
70 res->irq_resource[i].start =
71 res->irq_resource[i].end = (unsigned long)irq;
72 pcibios_penalize_isa_irq(irq, 1);
73 }
74}
75 61
76static void pnpbios_parse_allocated_dmaresource(struct pnp_resource_table *res, 62 if (len <= 0 || end >= 0x10003)
77 int dma) 63 flags |= IORESOURCE_DISABLED;
78{
79 int i = 0;
80
81 while (i < PNP_MAX_DMA &&
82 !(res->dma_resource[i].flags & IORESOURCE_UNSET))
83 i++;
84 if (i < PNP_MAX_DMA) {
85 res->dma_resource[i].flags = IORESOURCE_DMA; // Also clears _UNSET flag
86 if (dma == -1) {
87 res->dma_resource[i].flags |= IORESOURCE_DISABLED;
88 return;
89 }
90 res->dma_resource[i].start =
91 res->dma_resource[i].end = (unsigned long)dma;
92 }
93}
94 64
95static void pnpbios_parse_allocated_ioresource(struct pnp_resource_table *res, 65 pnp_add_io_resource(dev, start, end, flags);
96 int io, int len)
97{
98 int i = 0;
99
100 while (!(res->port_resource[i].flags & IORESOURCE_UNSET)
101 && i < PNP_MAX_PORT)
102 i++;
103 if (i < PNP_MAX_PORT) {
104 res->port_resource[i].flags = IORESOURCE_IO; // Also clears _UNSET flag
105 if (len <= 0 || (io + len - 1) >= 0x10003) {
106 res->port_resource[i].flags |= IORESOURCE_DISABLED;
107 return;
108 }
109 res->port_resource[i].start = (unsigned long)io;
110 res->port_resource[i].end = (unsigned long)(io + len - 1);
111 }
112} 66}
113 67
114static void pnpbios_parse_allocated_memresource(struct pnp_resource_table *res, 68static void pnpbios_parse_allocated_memresource(struct pnp_dev *dev,
115 int mem, int len) 69 int start, int len)
116{ 70{
117 int i = 0; 71 int flags = 0;
118 72 int end = start + len - 1;
119 while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) 73
120 && i < PNP_MAX_MEM) 74 if (len <= 0)
121 i++; 75 flags |= IORESOURCE_DISABLED;
122 if (i < PNP_MAX_MEM) { 76
123 res->mem_resource[i].flags = IORESOURCE_MEM; // Also clears _UNSET flag 77 pnp_add_mem_resource(dev, start, end, flags);
124 if (len <= 0) {
125 res->mem_resource[i].flags |= IORESOURCE_DISABLED;
126 return;
127 }
128 res->mem_resource[i].start = (unsigned long)mem;
129 res->mem_resource[i].end = (unsigned long)(mem + len - 1);
130 }
131} 78}
132 79
133static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p, 80static unsigned char *pnpbios_parse_allocated_resource_data(struct pnp_dev *dev,
134 unsigned char *end, 81 unsigned char *p,
135 struct 82 unsigned char *end)
136 pnp_resource_table
137 *res)
138{ 83{
139 unsigned int len, tag; 84 unsigned int len, tag;
140 int io, size, mask, i; 85 int io, size, mask, i, flags;
141 86
142 if (!p) 87 if (!p)
143 return NULL; 88 return NULL;
144 89
145 /* Blank the resource table values */ 90 dev_dbg(&dev->dev, "parse allocated resources\n");
146 pnp_init_resource_table(res); 91
92 pnp_init_resources(dev);
147 93
148 while ((char *)p < (char *)end) { 94 while ((char *)p < (char *)end) {
149 95
@@ -163,7 +109,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
163 goto len_err; 109 goto len_err;
164 io = *(short *)&p[4]; 110 io = *(short *)&p[4];
165 size = *(short *)&p[10]; 111 size = *(short *)&p[10];
166 pnpbios_parse_allocated_memresource(res, io, size); 112 pnpbios_parse_allocated_memresource(dev, io, size);
167 break; 113 break;
168 114
169 case LARGE_TAG_ANSISTR: 115 case LARGE_TAG_ANSISTR:
@@ -179,7 +125,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
179 goto len_err; 125 goto len_err;
180 io = *(int *)&p[4]; 126 io = *(int *)&p[4];
181 size = *(int *)&p[16]; 127 size = *(int *)&p[16];
182 pnpbios_parse_allocated_memresource(res, io, size); 128 pnpbios_parse_allocated_memresource(dev, io, size);
183 break; 129 break;
184 130
185 case LARGE_TAG_FIXEDMEM32: 131 case LARGE_TAG_FIXEDMEM32:
@@ -187,29 +133,37 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
187 goto len_err; 133 goto len_err;
188 io = *(int *)&p[4]; 134 io = *(int *)&p[4];
189 size = *(int *)&p[8]; 135 size = *(int *)&p[8];
190 pnpbios_parse_allocated_memresource(res, io, size); 136 pnpbios_parse_allocated_memresource(dev, io, size);
191 break; 137 break;
192 138
193 case SMALL_TAG_IRQ: 139 case SMALL_TAG_IRQ:
194 if (len < 2 || len > 3) 140 if (len < 2 || len > 3)
195 goto len_err; 141 goto len_err;
142 flags = 0;
196 io = -1; 143 io = -1;
197 mask = p[1] + p[2] * 256; 144 mask = p[1] + p[2] * 256;
198 for (i = 0; i < 16; i++, mask = mask >> 1) 145 for (i = 0; i < 16; i++, mask = mask >> 1)
199 if (mask & 0x01) 146 if (mask & 0x01)
200 io = i; 147 io = i;
201 pnpbios_parse_allocated_irqresource(res, io); 148 if (io != -1)
149 pcibios_penalize_isa_irq(io, 1);
150 else
151 flags = IORESOURCE_DISABLED;
152 pnp_add_irq_resource(dev, io, flags);
202 break; 153 break;
203 154
204 case SMALL_TAG_DMA: 155 case SMALL_TAG_DMA:
205 if (len != 2) 156 if (len != 2)
206 goto len_err; 157 goto len_err;
158 flags = 0;
207 io = -1; 159 io = -1;
208 mask = p[1]; 160 mask = p[1];
209 for (i = 0; i < 8; i++, mask = mask >> 1) 161 for (i = 0; i < 8; i++, mask = mask >> 1)
210 if (mask & 0x01) 162 if (mask & 0x01)
211 io = i; 163 io = i;
212 pnpbios_parse_allocated_dmaresource(res, io); 164 if (io == -1)
165 flags = IORESOURCE_DISABLED;
166 pnp_add_dma_resource(dev, io, flags);
213 break; 167 break;
214 168
215 case SMALL_TAG_PORT: 169 case SMALL_TAG_PORT:
@@ -217,7 +171,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
217 goto len_err; 171 goto len_err;
218 io = p[2] + p[3] * 256; 172 io = p[2] + p[3] * 256;
219 size = p[7]; 173 size = p[7];
220 pnpbios_parse_allocated_ioresource(res, io, size); 174 pnpbios_parse_allocated_ioresource(dev, io, size);
221 break; 175 break;
222 176
223 case SMALL_TAG_VENDOR: 177 case SMALL_TAG_VENDOR:
@@ -229,7 +183,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
229 goto len_err; 183 goto len_err;
230 io = p[1] + p[2] * 256; 184 io = p[1] + p[2] * 256;
231 size = p[3]; 185 size = p[3];
232 pnpbios_parse_allocated_ioresource(res, io, size); 186 pnpbios_parse_allocated_ioresource(dev, io, size);
233 break; 187 break;
234 188
235 case SMALL_TAG_END: 189 case SMALL_TAG_END:
@@ -239,9 +193,8 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p,
239 193
240 default: /* an unkown tag */ 194 default: /* an unkown tag */
241len_err: 195len_err:
242 printk(KERN_ERR 196 dev_err(&dev->dev, "unknown tag %#x length %d\n",
243 "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", 197 tag, len);
244 tag, len);
245 break; 198 break;
246 } 199 }
247 200
@@ -252,8 +205,7 @@ len_err:
252 p += len + 1; 205 p += len + 1;
253 } 206 }
254 207
255 printk(KERN_ERR 208 dev_err(&dev->dev, "no end tag in resource structure\n");
256 "PnPBIOS: Resource structure does not contain an end tag.\n");
257 209
258 return NULL; 210 return NULL;
259} 211}
@@ -262,7 +214,8 @@ len_err:
262 * Resource Configuration Options 214 * Resource Configuration Options
263 */ 215 */
264 216
265static __init void pnpbios_parse_mem_option(unsigned char *p, int size, 217static __init void pnpbios_parse_mem_option(struct pnp_dev *dev,
218 unsigned char *p, int size,
266 struct pnp_option *option) 219 struct pnp_option *option)
267{ 220{
268 struct pnp_mem *mem; 221 struct pnp_mem *mem;
@@ -275,10 +228,11 @@ static __init void pnpbios_parse_mem_option(unsigned char *p, int size,
275 mem->align = (p[9] << 8) | p[8]; 228 mem->align = (p[9] << 8) | p[8];
276 mem->size = ((p[11] << 8) | p[10]) << 8; 229 mem->size = ((p[11] << 8) | p[10]) << 8;
277 mem->flags = p[3]; 230 mem->flags = p[3];
278 pnp_register_mem_resource(option, mem); 231 pnp_register_mem_resource(dev, option, mem);
279} 232}
280 233
281static __init void pnpbios_parse_mem32_option(unsigned char *p, int size, 234static __init void pnpbios_parse_mem32_option(struct pnp_dev *dev,
235 unsigned char *p, int size,
282 struct pnp_option *option) 236 struct pnp_option *option)
283{ 237{
284 struct pnp_mem *mem; 238 struct pnp_mem *mem;
@@ -291,10 +245,11 @@ static __init void pnpbios_parse_mem32_option(unsigned char *p, int size,
291 mem->align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12]; 245 mem->align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12];
292 mem->size = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16]; 246 mem->size = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16];
293 mem->flags = p[3]; 247 mem->flags = p[3];
294 pnp_register_mem_resource(option, mem); 248 pnp_register_mem_resource(dev, option, mem);
295} 249}
296 250
297static __init void pnpbios_parse_fixed_mem32_option(unsigned char *p, int size, 251static __init void pnpbios_parse_fixed_mem32_option(struct pnp_dev *dev,
252 unsigned char *p, int size,
298 struct pnp_option *option) 253 struct pnp_option *option)
299{ 254{
300 struct pnp_mem *mem; 255 struct pnp_mem *mem;
@@ -306,11 +261,12 @@ static __init void pnpbios_parse_fixed_mem32_option(unsigned char *p, int size,
306 mem->size = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8]; 261 mem->size = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
307 mem->align = 0; 262 mem->align = 0;
308 mem->flags = p[3]; 263 mem->flags = p[3];
309 pnp_register_mem_resource(option, mem); 264 pnp_register_mem_resource(dev, option, mem);
310} 265}
311 266
312static __init void pnpbios_parse_irq_option(unsigned char *p, int size, 267static __init void pnpbios_parse_irq_option(struct pnp_dev *dev,
313 struct pnp_option *option) 268 unsigned char *p, int size,
269 struct pnp_option *option)
314{ 270{
315 struct pnp_irq *irq; 271 struct pnp_irq *irq;
316 unsigned long bits; 272 unsigned long bits;
@@ -324,11 +280,12 @@ static __init void pnpbios_parse_irq_option(unsigned char *p, int size,
324 irq->flags = p[3]; 280 irq->flags = p[3];
325 else 281 else
326 irq->flags = IORESOURCE_IRQ_HIGHEDGE; 282 irq->flags = IORESOURCE_IRQ_HIGHEDGE;
327 pnp_register_irq_resource(option, irq); 283 pnp_register_irq_resource(dev, option, irq);
328} 284}
329 285
330static __init void pnpbios_parse_dma_option(unsigned char *p, int size, 286static __init void pnpbios_parse_dma_option(struct pnp_dev *dev,
331 struct pnp_option *option) 287 unsigned char *p, int size,
288 struct pnp_option *option)
332{ 289{
333 struct pnp_dma *dma; 290 struct pnp_dma *dma;
334 291
@@ -337,10 +294,11 @@ static __init void pnpbios_parse_dma_option(unsigned char *p, int size,
337 return; 294 return;
338 dma->map = p[1]; 295 dma->map = p[1];
339 dma->flags = p[2]; 296 dma->flags = p[2];
340 pnp_register_dma_resource(option, dma); 297 pnp_register_dma_resource(dev, option, dma);
341} 298}
342 299
343static __init void pnpbios_parse_port_option(unsigned char *p, int size, 300static __init void pnpbios_parse_port_option(struct pnp_dev *dev,
301 unsigned char *p, int size,
344 struct pnp_option *option) 302 struct pnp_option *option)
345{ 303{
346 struct pnp_port *port; 304 struct pnp_port *port;
@@ -353,10 +311,11 @@ static __init void pnpbios_parse_port_option(unsigned char *p, int size,
353 port->align = p[6]; 311 port->align = p[6];
354 port->size = p[7]; 312 port->size = p[7];
355 port->flags = p[1] ? PNP_PORT_FLAG_16BITADDR : 0; 313 port->flags = p[1] ? PNP_PORT_FLAG_16BITADDR : 0;
356 pnp_register_port_resource(option, port); 314 pnp_register_port_resource(dev, option, port);
357} 315}
358 316
359static __init void pnpbios_parse_fixed_port_option(unsigned char *p, int size, 317static __init void pnpbios_parse_fixed_port_option(struct pnp_dev *dev,
318 unsigned char *p, int size,
360 struct pnp_option *option) 319 struct pnp_option *option)
361{ 320{
362 struct pnp_port *port; 321 struct pnp_port *port;
@@ -368,7 +327,7 @@ static __init void pnpbios_parse_fixed_port_option(unsigned char *p, int size,
368 port->size = p[3]; 327 port->size = p[3];
369 port->align = 0; 328 port->align = 0;
370 port->flags = PNP_PORT_FLAG_FIXED; 329 port->flags = PNP_PORT_FLAG_FIXED;
371 pnp_register_port_resource(option, port); 330 pnp_register_port_resource(dev, option, port);
372} 331}
373 332
374static __init unsigned char * 333static __init unsigned char *
@@ -382,6 +341,8 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
382 if (!p) 341 if (!p)
383 return NULL; 342 return NULL;
384 343
344 dev_dbg(&dev->dev, "parse resource options\n");
345
385 option_independent = option = pnp_register_independent_option(dev); 346 option_independent = option = pnp_register_independent_option(dev);
386 if (!option) 347 if (!option)
387 return NULL; 348 return NULL;
@@ -402,37 +363,37 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
402 case LARGE_TAG_MEM: 363 case LARGE_TAG_MEM:
403 if (len != 9) 364 if (len != 9)
404 goto len_err; 365 goto len_err;
405 pnpbios_parse_mem_option(p, len, option); 366 pnpbios_parse_mem_option(dev, p, len, option);
406 break; 367 break;
407 368
408 case LARGE_TAG_MEM32: 369 case LARGE_TAG_MEM32:
409 if (len != 17) 370 if (len != 17)
410 goto len_err; 371 goto len_err;
411 pnpbios_parse_mem32_option(p, len, option); 372 pnpbios_parse_mem32_option(dev, p, len, option);
412 break; 373 break;
413 374
414 case LARGE_TAG_FIXEDMEM32: 375 case LARGE_TAG_FIXEDMEM32:
415 if (len != 9) 376 if (len != 9)
416 goto len_err; 377 goto len_err;
417 pnpbios_parse_fixed_mem32_option(p, len, option); 378 pnpbios_parse_fixed_mem32_option(dev, p, len, option);
418 break; 379 break;
419 380
420 case SMALL_TAG_IRQ: 381 case SMALL_TAG_IRQ:
421 if (len < 2 || len > 3) 382 if (len < 2 || len > 3)
422 goto len_err; 383 goto len_err;
423 pnpbios_parse_irq_option(p, len, option); 384 pnpbios_parse_irq_option(dev, p, len, option);
424 break; 385 break;
425 386
426 case SMALL_TAG_DMA: 387 case SMALL_TAG_DMA:
427 if (len != 2) 388 if (len != 2)
428 goto len_err; 389 goto len_err;
429 pnpbios_parse_dma_option(p, len, option); 390 pnpbios_parse_dma_option(dev, p, len, option);
430 break; 391 break;
431 392
432 case SMALL_TAG_PORT: 393 case SMALL_TAG_PORT:
433 if (len != 7) 394 if (len != 7)
434 goto len_err; 395 goto len_err;
435 pnpbios_parse_port_option(p, len, option); 396 pnpbios_parse_port_option(dev, p, len, option);
436 break; 397 break;
437 398
438 case SMALL_TAG_VENDOR: 399 case SMALL_TAG_VENDOR:
@@ -442,7 +403,7 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
442 case SMALL_TAG_FIXEDPORT: 403 case SMALL_TAG_FIXEDPORT:
443 if (len != 3) 404 if (len != 3)
444 goto len_err; 405 goto len_err;
445 pnpbios_parse_fixed_port_option(p, len, option); 406 pnpbios_parse_fixed_port_option(dev, p, len, option);
446 break; 407 break;
447 408
448 case SMALL_TAG_STARTDEP: 409 case SMALL_TAG_STARTDEP:
@@ -460,9 +421,10 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
460 if (len != 0) 421 if (len != 0)
461 goto len_err; 422 goto len_err;
462 if (option_independent == option) 423 if (option_independent == option)
463 printk(KERN_WARNING 424 dev_warn(&dev->dev, "missing "
464 "PnPBIOS: Missing SMALL_TAG_STARTDEP tag\n"); 425 "SMALL_TAG_STARTDEP tag\n");
465 option = option_independent; 426 option = option_independent;
427 dev_dbg(&dev->dev, "end dependent options\n");
466 break; 428 break;
467 429
468 case SMALL_TAG_END: 430 case SMALL_TAG_END:
@@ -470,9 +432,8 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
470 432
471 default: /* an unkown tag */ 433 default: /* an unkown tag */
472len_err: 434len_err:
473 printk(KERN_ERR 435 dev_err(&dev->dev, "unknown tag %#x length %d\n",
474 "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", 436 tag, len);
475 tag, len);
476 break; 437 break;
477 } 438 }
478 439
@@ -483,8 +444,7 @@ len_err:
483 p += len + 1; 444 p += len + 1;
484 } 445 }
485 446
486 printk(KERN_ERR 447 dev_err(&dev->dev, "no end tag in resource structure\n");
487 "PnPBIOS: Resource structure does not contain an end tag.\n");
488 448
489 return NULL; 449 return NULL;
490} 450}
@@ -493,32 +453,12 @@ len_err:
493 * Compatible Device IDs 453 * Compatible Device IDs
494 */ 454 */
495 455
496#define HEX(id,a) hex[((id)>>a) & 15]
497#define CHAR(id,a) (0x40 + (((id)>>a) & 31))
498
499void pnpid32_to_pnpid(u32 id, char *str)
500{
501 const char *hex = "0123456789abcdef";
502
503 id = be32_to_cpu(id);
504 str[0] = CHAR(id, 26);
505 str[1] = CHAR(id, 21);
506 str[2] = CHAR(id, 16);
507 str[3] = HEX(id, 12);
508 str[4] = HEX(id, 8);
509 str[5] = HEX(id, 4);
510 str[6] = HEX(id, 0);
511 str[7] = '\0';
512}
513
514#undef CHAR
515#undef HEX
516
517static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p, 456static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p,
518 unsigned char *end, 457 unsigned char *end,
519 struct pnp_dev *dev) 458 struct pnp_dev *dev)
520{ 459{
521 int len, tag; 460 int len, tag;
461 u32 eisa_id;
522 char id[8]; 462 char id[8];
523 struct pnp_id *dev_id; 463 struct pnp_id *dev_id;
524 464
@@ -548,13 +488,11 @@ static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p,
548 case SMALL_TAG_COMPATDEVID: /* compatible ID */ 488 case SMALL_TAG_COMPATDEVID: /* compatible ID */
549 if (len != 4) 489 if (len != 4)
550 goto len_err; 490 goto len_err;
551 dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL); 491 eisa_id = p[1] | p[2] << 8 | p[3] << 16 | p[4] << 24;
492 pnp_eisa_id_to_string(eisa_id & PNP_EISA_ID_MASK, id);
493 dev_id = pnp_add_id(dev, id);
552 if (!dev_id) 494 if (!dev_id)
553 return NULL; 495 return NULL;
554 pnpid32_to_pnpid(p[1] | p[2] << 8 | p[3] << 16 | p[4] <<
555 24, id);
556 memcpy(&dev_id->id, id, 7);
557 pnp_add_id(dev_id, dev);
558 break; 496 break;
559 497
560 case SMALL_TAG_END: 498 case SMALL_TAG_END:
@@ -564,9 +502,8 @@ static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p,
564 502
565 default: /* an unkown tag */ 503 default: /* an unkown tag */
566len_err: 504len_err:
567 printk(KERN_ERR 505 dev_err(&dev->dev, "unknown tag %#x length %d\n",
568 "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", 506 tag, len);
569 tag, len);
570 break; 507 break;
571 } 508 }
572 509
@@ -577,8 +514,7 @@ len_err:
577 p += len + 1; 514 p += len + 1;
578 } 515 }
579 516
580 printk(KERN_ERR 517 dev_err(&dev->dev, "no end tag in resource structure\n");
581 "PnPBIOS: Resource structure does not contain an end tag.\n");
582 518
583 return NULL; 519 return NULL;
584} 520}
@@ -587,7 +523,8 @@ len_err:
587 * Allocated Resource Encoding 523 * Allocated Resource Encoding
588 */ 524 */
589 525
590static void pnpbios_encode_mem(unsigned char *p, struct resource *res) 526static void pnpbios_encode_mem(struct pnp_dev *dev, unsigned char *p,
527 struct resource *res)
591{ 528{
592 unsigned long base = res->start; 529 unsigned long base = res->start;
593 unsigned long len = res->end - res->start + 1; 530 unsigned long len = res->end - res->start + 1;
@@ -598,9 +535,13 @@ static void pnpbios_encode_mem(unsigned char *p, struct resource *res)
598 p[7] = ((base >> 8) >> 8) & 0xff; 535 p[7] = ((base >> 8) >> 8) & 0xff;
599 p[10] = (len >> 8) & 0xff; 536 p[10] = (len >> 8) & 0xff;
600 p[11] = ((len >> 8) >> 8) & 0xff; 537 p[11] = ((len >> 8) >> 8) & 0xff;
538
539 dev_dbg(&dev->dev, " encode mem %#llx-%#llx\n",
540 (unsigned long long) res->start, (unsigned long long) res->end);
601} 541}
602 542
603static void pnpbios_encode_mem32(unsigned char *p, struct resource *res) 543static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p,
544 struct resource *res)
604{ 545{
605 unsigned long base = res->start; 546 unsigned long base = res->start;
606 unsigned long len = res->end - res->start + 1; 547 unsigned long len = res->end - res->start + 1;
@@ -617,9 +558,13 @@ static void pnpbios_encode_mem32(unsigned char *p, struct resource *res)
617 p[17] = (len >> 8) & 0xff; 558 p[17] = (len >> 8) & 0xff;
618 p[18] = (len >> 16) & 0xff; 559 p[18] = (len >> 16) & 0xff;
619 p[19] = (len >> 24) & 0xff; 560 p[19] = (len >> 24) & 0xff;
561
562 dev_dbg(&dev->dev, " encode mem32 %#llx-%#llx\n",
563 (unsigned long long) res->start, (unsigned long long) res->end);
620} 564}
621 565
622static void pnpbios_encode_fixed_mem32(unsigned char *p, struct resource *res) 566static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p,
567 struct resource *res)
623{ 568{
624 unsigned long base = res->start; 569 unsigned long base = res->start;
625 unsigned long len = res->end - res->start + 1; 570 unsigned long len = res->end - res->start + 1;
@@ -632,26 +577,36 @@ static void pnpbios_encode_fixed_mem32(unsigned char *p, struct resource *res)
632 p[9] = (len >> 8) & 0xff; 577 p[9] = (len >> 8) & 0xff;
633 p[10] = (len >> 16) & 0xff; 578 p[10] = (len >> 16) & 0xff;
634 p[11] = (len >> 24) & 0xff; 579 p[11] = (len >> 24) & 0xff;
580
581 dev_dbg(&dev->dev, " encode fixed_mem32 %#llx-%#llx\n",
582 (unsigned long long) res->start, (unsigned long long) res->end);
635} 583}
636 584
637static void pnpbios_encode_irq(unsigned char *p, struct resource *res) 585static void pnpbios_encode_irq(struct pnp_dev *dev, unsigned char *p,
586 struct resource *res)
638{ 587{
639 unsigned long map = 0; 588 unsigned long map = 0;
640 589
641 map = 1 << res->start; 590 map = 1 << res->start;
642 p[1] = map & 0xff; 591 p[1] = map & 0xff;
643 p[2] = (map >> 8) & 0xff; 592 p[2] = (map >> 8) & 0xff;
593
594 dev_dbg(&dev->dev, " encode irq %d\n", res->start);
644} 595}
645 596
646static void pnpbios_encode_dma(unsigned char *p, struct resource *res) 597static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p,
598 struct resource *res)
647{ 599{
648 unsigned long map = 0; 600 unsigned long map = 0;
649 601
650 map = 1 << res->start; 602 map = 1 << res->start;
651 p[1] = map & 0xff; 603 p[1] = map & 0xff;
604
605 dev_dbg(&dev->dev, " encode dma %d\n", res->start);
652} 606}
653 607
654static void pnpbios_encode_port(unsigned char *p, struct resource *res) 608static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p,
609 struct resource *res)
655{ 610{
656 unsigned long base = res->start; 611 unsigned long base = res->start;
657 unsigned long len = res->end - res->start + 1; 612 unsigned long len = res->end - res->start + 1;
@@ -661,9 +616,13 @@ static void pnpbios_encode_port(unsigned char *p, struct resource *res)
661 p[4] = base & 0xff; 616 p[4] = base & 0xff;
662 p[5] = (base >> 8) & 0xff; 617 p[5] = (base >> 8) & 0xff;
663 p[7] = len & 0xff; 618 p[7] = len & 0xff;
619
620 dev_dbg(&dev->dev, " encode io %#llx-%#llx\n",
621 (unsigned long long) res->start, (unsigned long long) res->end);
664} 622}
665 623
666static void pnpbios_encode_fixed_port(unsigned char *p, struct resource *res) 624static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p,
625 struct resource *res)
667{ 626{
668 unsigned long base = res->start; 627 unsigned long base = res->start;
669 unsigned long len = res->end - res->start + 1; 628 unsigned long len = res->end - res->start + 1;
@@ -671,13 +630,15 @@ static void pnpbios_encode_fixed_port(unsigned char *p, struct resource *res)
671 p[1] = base & 0xff; 630 p[1] = base & 0xff;
672 p[2] = (base >> 8) & 0xff; 631 p[2] = (base >> 8) & 0xff;
673 p[3] = len & 0xff; 632 p[3] = len & 0xff;
633
634 dev_dbg(&dev->dev, " encode fixed_io %#llx-%#llx\n",
635 (unsigned long long) res->start, (unsigned long long) res->end);
674} 636}
675 637
676static unsigned char *pnpbios_encode_allocated_resource_data(unsigned char *p, 638static unsigned char *pnpbios_encode_allocated_resource_data(struct pnp_dev
677 unsigned char *end, 639 *dev,
678 struct 640 unsigned char *p,
679 pnp_resource_table 641 unsigned char *end)
680 *res)
681{ 642{
682 unsigned int len, tag; 643 unsigned int len, tag;
683 int port = 0, irq = 0, dma = 0, mem = 0; 644 int port = 0, irq = 0, dma = 0, mem = 0;
@@ -701,42 +662,48 @@ static unsigned char *pnpbios_encode_allocated_resource_data(unsigned char *p,
701 case LARGE_TAG_MEM: 662 case LARGE_TAG_MEM:
702 if (len != 9) 663 if (len != 9)
703 goto len_err; 664 goto len_err;
704 pnpbios_encode_mem(p, &res->mem_resource[mem]); 665 pnpbios_encode_mem(dev, p,
666 pnp_get_resource(dev, IORESOURCE_MEM, mem));
705 mem++; 667 mem++;
706 break; 668 break;
707 669
708 case LARGE_TAG_MEM32: 670 case LARGE_TAG_MEM32:
709 if (len != 17) 671 if (len != 17)
710 goto len_err; 672 goto len_err;
711 pnpbios_encode_mem32(p, &res->mem_resource[mem]); 673 pnpbios_encode_mem32(dev, p,
674 pnp_get_resource(dev, IORESOURCE_MEM, mem));
712 mem++; 675 mem++;
713 break; 676 break;
714 677
715 case LARGE_TAG_FIXEDMEM32: 678 case LARGE_TAG_FIXEDMEM32:
716 if (len != 9) 679 if (len != 9)
717 goto len_err; 680 goto len_err;
718 pnpbios_encode_fixed_mem32(p, &res->mem_resource[mem]); 681 pnpbios_encode_fixed_mem32(dev, p,
682 pnp_get_resource(dev, IORESOURCE_MEM, mem));
719 mem++; 683 mem++;
720 break; 684 break;
721 685
722 case SMALL_TAG_IRQ: 686 case SMALL_TAG_IRQ:
723 if (len < 2 || len > 3) 687 if (len < 2 || len > 3)
724 goto len_err; 688 goto len_err;
725 pnpbios_encode_irq(p, &res->irq_resource[irq]); 689 pnpbios_encode_irq(dev, p,
690 pnp_get_resource(dev, IORESOURCE_IRQ, irq));
726 irq++; 691 irq++;
727 break; 692 break;
728 693
729 case SMALL_TAG_DMA: 694 case SMALL_TAG_DMA:
730 if (len != 2) 695 if (len != 2)
731 goto len_err; 696 goto len_err;
732 pnpbios_encode_dma(p, &res->dma_resource[dma]); 697 pnpbios_encode_dma(dev, p,
698 pnp_get_resource(dev, IORESOURCE_DMA, dma));
733 dma++; 699 dma++;
734 break; 700 break;
735 701
736 case SMALL_TAG_PORT: 702 case SMALL_TAG_PORT:
737 if (len != 7) 703 if (len != 7)
738 goto len_err; 704 goto len_err;
739 pnpbios_encode_port(p, &res->port_resource[port]); 705 pnpbios_encode_port(dev, p,
706 pnp_get_resource(dev, IORESOURCE_IO, port));
740 port++; 707 port++;
741 break; 708 break;
742 709
@@ -747,7 +714,8 @@ static unsigned char *pnpbios_encode_allocated_resource_data(unsigned char *p,
747 case SMALL_TAG_FIXEDPORT: 714 case SMALL_TAG_FIXEDPORT:
748 if (len != 3) 715 if (len != 3)
749 goto len_err; 716 goto len_err;
750 pnpbios_encode_fixed_port(p, &res->port_resource[port]); 717 pnpbios_encode_fixed_port(dev, p,
718 pnp_get_resource(dev, IORESOURCE_IO, port));
751 port++; 719 port++;
752 break; 720 break;
753 721
@@ -758,9 +726,8 @@ static unsigned char *pnpbios_encode_allocated_resource_data(unsigned char *p,
758 726
759 default: /* an unkown tag */ 727 default: /* an unkown tag */
760len_err: 728len_err:
761 printk(KERN_ERR 729 dev_err(&dev->dev, "unknown tag %#x length %d\n",
762 "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", 730 tag, len);
763 tag, len);
764 break; 731 break;
765 } 732 }
766 733
@@ -771,8 +738,7 @@ len_err:
771 p += len + 1; 738 p += len + 1;
772 } 739 }
773 740
774 printk(KERN_ERR 741 dev_err(&dev->dev, "no end tag in resource structure\n");
775 "PnPBIOS: Resource structure does not contain an end tag.\n");
776 742
777 return NULL; 743 return NULL;
778} 744}
@@ -787,7 +753,7 @@ int __init pnpbios_parse_data_stream(struct pnp_dev *dev,
787 unsigned char *p = (char *)node->data; 753 unsigned char *p = (char *)node->data;
788 unsigned char *end = (char *)(node->data + node->size); 754 unsigned char *end = (char *)(node->data + node->size);
789 755
790 p = pnpbios_parse_allocated_resource_data(p, end, &dev->res); 756 p = pnpbios_parse_allocated_resource_data(dev, p, end);
791 if (!p) 757 if (!p)
792 return -EIO; 758 return -EIO;
793 p = pnpbios_parse_resource_option_data(p, end, dev); 759 p = pnpbios_parse_resource_option_data(p, end, dev);
@@ -799,25 +765,25 @@ int __init pnpbios_parse_data_stream(struct pnp_dev *dev,
799 return 0; 765 return 0;
800} 766}
801 767
802int pnpbios_read_resources_from_node(struct pnp_resource_table *res, 768int pnpbios_read_resources_from_node(struct pnp_dev *dev,
803 struct pnp_bios_node *node) 769 struct pnp_bios_node *node)
804{ 770{
805 unsigned char *p = (char *)node->data; 771 unsigned char *p = (char *)node->data;
806 unsigned char *end = (char *)(node->data + node->size); 772 unsigned char *end = (char *)(node->data + node->size);
807 773
808 p = pnpbios_parse_allocated_resource_data(p, end, res); 774 p = pnpbios_parse_allocated_resource_data(dev, p, end);
809 if (!p) 775 if (!p)
810 return -EIO; 776 return -EIO;
811 return 0; 777 return 0;
812} 778}
813 779
814int pnpbios_write_resources_to_node(struct pnp_resource_table *res, 780int pnpbios_write_resources_to_node(struct pnp_dev *dev,
815 struct pnp_bios_node *node) 781 struct pnp_bios_node *node)
816{ 782{
817 unsigned char *p = (char *)node->data; 783 unsigned char *p = (char *)node->data;
818 unsigned char *end = (char *)(node->data + node->size); 784 unsigned char *end = (char *)(node->data + node->size);
819 785
820 p = pnpbios_encode_allocated_resource_data(p, end, res); 786 p = pnpbios_encode_allocated_resource_data(dev, p, end);
821 if (!p) 787 if (!p)
822 return -EIO; 788 return -EIO;
823 return 0; 789 return 0;
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
index e4daf4635c48..d049a2279fea 100644
--- a/drivers/pnp/quirks.c
+++ b/drivers/pnp/quirks.c
@@ -117,6 +117,7 @@ static void quirk_sb16audio_resources(struct pnp_dev *dev)
117static void quirk_system_pci_resources(struct pnp_dev *dev) 117static void quirk_system_pci_resources(struct pnp_dev *dev)
118{ 118{
119 struct pci_dev *pdev = NULL; 119 struct pci_dev *pdev = NULL;
120 struct resource *res;
120 resource_size_t pnp_start, pnp_end, pci_start, pci_end; 121 resource_size_t pnp_start, pnp_end, pci_start, pci_end;
121 int i, j; 122 int i, j;
122 123
@@ -137,13 +138,15 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
137 138
138 pci_start = pci_resource_start(pdev, i); 139 pci_start = pci_resource_start(pdev, i);
139 pci_end = pci_resource_end(pdev, i); 140 pci_end = pci_resource_end(pdev, i);
140 for (j = 0; j < PNP_MAX_MEM; j++) { 141 for (j = 0;
141 if (!pnp_mem_valid(dev, j) || 142 (res = pnp_get_resource(dev, IORESOURCE_MEM, j));
142 pnp_mem_len(dev, j) == 0) 143 j++) {
144 if (res->flags & IORESOURCE_UNSET ||
145 (res->start == 0 && res->end == 0))
143 continue; 146 continue;
144 147
145 pnp_start = pnp_mem_start(dev, j); 148 pnp_start = res->start;
146 pnp_end = pnp_mem_end(dev, j); 149 pnp_end = res->end;
147 150
148 /* 151 /*
149 * If the PNP region doesn't overlap the PCI 152 * If the PNP region doesn't overlap the PCI
@@ -176,7 +179,7 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
176 pci_name(pdev), i, 179 pci_name(pdev), i,
177 (unsigned long long) pci_start, 180 (unsigned long long) pci_start,
178 (unsigned long long) pci_end); 181 (unsigned long long) pci_end);
179 pnp_mem_flags(dev, j) = 0; 182 res->flags = 0;
180 } 183 }
181 } 184 }
182 } 185 }
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index e50ebcffb962..2041620d5682 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -53,6 +53,8 @@ struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev)
53 if (dev->independent) 53 if (dev->independent)
54 dev_err(&dev->dev, "independent resource already registered\n"); 54 dev_err(&dev->dev, "independent resource already registered\n");
55 dev->independent = option; 55 dev->independent = option;
56
57 dev_dbg(&dev->dev, "new independent option\n");
56 return option; 58 return option;
57} 59}
58 60
@@ -70,12 +72,18 @@ struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev,
70 parent->next = option; 72 parent->next = option;
71 } else 73 } else
72 dev->dependent = option; 74 dev->dependent = option;
75
76 dev_dbg(&dev->dev, "new dependent option (priority %#x)\n", priority);
73 return option; 77 return option;
74} 78}
75 79
76int pnp_register_irq_resource(struct pnp_option *option, struct pnp_irq *data) 80int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option,
81 struct pnp_irq *data)
77{ 82{
78 struct pnp_irq *ptr; 83 struct pnp_irq *ptr;
84#ifdef DEBUG
85 char buf[PNP_IRQ_NR]; /* hex-encoded, so this is overkill but safe */
86#endif
79 87
80 ptr = option->irq; 88 ptr = option->irq;
81 while (ptr && ptr->next) 89 while (ptr && ptr->next)
@@ -94,10 +102,17 @@ int pnp_register_irq_resource(struct pnp_option *option, struct pnp_irq *data)
94 pcibios_penalize_isa_irq(i, 0); 102 pcibios_penalize_isa_irq(i, 0);
95 } 103 }
96#endif 104#endif
105
106#ifdef DEBUG
107 bitmap_scnprintf(buf, sizeof(buf), data->map, PNP_IRQ_NR);
108 dev_dbg(&dev->dev, " irq bitmask %s flags %#x\n", buf,
109 data->flags);
110#endif
97 return 0; 111 return 0;
98} 112}
99 113
100int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data) 114int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option,
115 struct pnp_dma *data)
101{ 116{
102 struct pnp_dma *ptr; 117 struct pnp_dma *ptr;
103 118
@@ -109,10 +124,13 @@ int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data)
109 else 124 else
110 option->dma = data; 125 option->dma = data;
111 126
127 dev_dbg(&dev->dev, " dma bitmask %#x flags %#x\n", data->map,
128 data->flags);
112 return 0; 129 return 0;
113} 130}
114 131
115int pnp_register_port_resource(struct pnp_option *option, struct pnp_port *data) 132int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option,
133 struct pnp_port *data)
116{ 134{
117 struct pnp_port *ptr; 135 struct pnp_port *ptr;
118 136
@@ -124,10 +142,14 @@ int pnp_register_port_resource(struct pnp_option *option, struct pnp_port *data)
124 else 142 else
125 option->port = data; 143 option->port = data;
126 144
145 dev_dbg(&dev->dev, " io "
146 "min %#x max %#x align %d size %d flags %#x\n",
147 data->min, data->max, data->align, data->size, data->flags);
127 return 0; 148 return 0;
128} 149}
129 150
130int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data) 151int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option,
152 struct pnp_mem *data)
131{ 153{
132 struct pnp_mem *ptr; 154 struct pnp_mem *ptr;
133 155
@@ -138,6 +160,10 @@ int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data)
138 ptr->next = data; 160 ptr->next = data;
139 else 161 else
140 option->mem = data; 162 option->mem = data;
163
164 dev_dbg(&dev->dev, " mem "
165 "min %#x max %#x align %d size %d flags %#x\n",
166 data->min, data->max, data->align, data->size, data->flags);
141 return 0; 167 return 0;
142} 168}
143 169
@@ -213,17 +239,18 @@ void pnp_free_option(struct pnp_option *option)
213#define cannot_compare(flags) \ 239#define cannot_compare(flags) \
214((flags) & (IORESOURCE_UNSET | IORESOURCE_DISABLED)) 240((flags) & (IORESOURCE_UNSET | IORESOURCE_DISABLED))
215 241
216int pnp_check_port(struct pnp_dev *dev, int idx) 242int pnp_check_port(struct pnp_dev *dev, struct resource *res)
217{ 243{
218 int tmp; 244 int i;
219 struct pnp_dev *tdev; 245 struct pnp_dev *tdev;
246 struct resource *tres;
220 resource_size_t *port, *end, *tport, *tend; 247 resource_size_t *port, *end, *tport, *tend;
221 248
222 port = &dev->res.port_resource[idx].start; 249 port = &res->start;
223 end = &dev->res.port_resource[idx].end; 250 end = &res->end;
224 251
225 /* if the resource doesn't exist, don't complain about it */ 252 /* if the resource doesn't exist, don't complain about it */
226 if (cannot_compare(dev->res.port_resource[idx].flags)) 253 if (cannot_compare(res->flags))
227 return 1; 254 return 1;
228 255
229 /* check if the resource is already in use, skip if the 256 /* check if the resource is already in use, skip if the
@@ -234,18 +261,18 @@ int pnp_check_port(struct pnp_dev *dev, int idx)
234 } 261 }
235 262
236 /* check if the resource is reserved */ 263 /* check if the resource is reserved */
237 for (tmp = 0; tmp < 8; tmp++) { 264 for (i = 0; i < 8; i++) {
238 int rport = pnp_reserve_io[tmp << 1]; 265 int rport = pnp_reserve_io[i << 1];
239 int rend = pnp_reserve_io[(tmp << 1) + 1] + rport - 1; 266 int rend = pnp_reserve_io[(i << 1) + 1] + rport - 1;
240 if (ranged_conflict(port, end, &rport, &rend)) 267 if (ranged_conflict(port, end, &rport, &rend))
241 return 0; 268 return 0;
242 } 269 }
243 270
244 /* check for internal conflicts */ 271 /* check for internal conflicts */
245 for (tmp = 0; tmp < PNP_MAX_PORT && tmp != idx; tmp++) { 272 for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) {
246 if (dev->res.port_resource[tmp].flags & IORESOURCE_IO) { 273 if (tres != res && tres->flags & IORESOURCE_IO) {
247 tport = &dev->res.port_resource[tmp].start; 274 tport = &tres->start;
248 tend = &dev->res.port_resource[tmp].end; 275 tend = &tres->end;
249 if (ranged_conflict(port, end, tport, tend)) 276 if (ranged_conflict(port, end, tport, tend))
250 return 0; 277 return 0;
251 } 278 }
@@ -255,13 +282,14 @@ int pnp_check_port(struct pnp_dev *dev, int idx)
255 pnp_for_each_dev(tdev) { 282 pnp_for_each_dev(tdev) {
256 if (tdev == dev) 283 if (tdev == dev)
257 continue; 284 continue;
258 for (tmp = 0; tmp < PNP_MAX_PORT; tmp++) { 285 for (i = 0;
259 if (tdev->res.port_resource[tmp].flags & IORESOURCE_IO) { 286 (tres = pnp_get_resource(tdev, IORESOURCE_IO, i));
260 if (cannot_compare 287 i++) {
261 (tdev->res.port_resource[tmp].flags)) 288 if (tres->flags & IORESOURCE_IO) {
289 if (cannot_compare(tres->flags))
262 continue; 290 continue;
263 tport = &tdev->res.port_resource[tmp].start; 291 tport = &tres->start;
264 tend = &tdev->res.port_resource[tmp].end; 292 tend = &tres->end;
265 if (ranged_conflict(port, end, tport, tend)) 293 if (ranged_conflict(port, end, tport, tend))
266 return 0; 294 return 0;
267 } 295 }
@@ -271,17 +299,18 @@ int pnp_check_port(struct pnp_dev *dev, int idx)
271 return 1; 299 return 1;
272} 300}
273 301
274int pnp_check_mem(struct pnp_dev *dev, int idx) 302int pnp_check_mem(struct pnp_dev *dev, struct resource *res)
275{ 303{
276 int tmp; 304 int i;
277 struct pnp_dev *tdev; 305 struct pnp_dev *tdev;
306 struct resource *tres;
278 resource_size_t *addr, *end, *taddr, *tend; 307 resource_size_t *addr, *end, *taddr, *tend;
279 308
280 addr = &dev->res.mem_resource[idx].start; 309 addr = &res->start;
281 end = &dev->res.mem_resource[idx].end; 310 end = &res->end;
282 311
283 /* if the resource doesn't exist, don't complain about it */ 312 /* if the resource doesn't exist, don't complain about it */
284 if (cannot_compare(dev->res.mem_resource[idx].flags)) 313 if (cannot_compare(res->flags))
285 return 1; 314 return 1;
286 315
287 /* check if the resource is already in use, skip if the 316 /* check if the resource is already in use, skip if the
@@ -292,18 +321,18 @@ int pnp_check_mem(struct pnp_dev *dev, int idx)
292 } 321 }
293 322
294 /* check if the resource is reserved */ 323 /* check if the resource is reserved */
295 for (tmp = 0; tmp < 8; tmp++) { 324 for (i = 0; i < 8; i++) {
296 int raddr = pnp_reserve_mem[tmp << 1]; 325 int raddr = pnp_reserve_mem[i << 1];
297 int rend = pnp_reserve_mem[(tmp << 1) + 1] + raddr - 1; 326 int rend = pnp_reserve_mem[(i << 1) + 1] + raddr - 1;
298 if (ranged_conflict(addr, end, &raddr, &rend)) 327 if (ranged_conflict(addr, end, &raddr, &rend))
299 return 0; 328 return 0;
300 } 329 }
301 330
302 /* check for internal conflicts */ 331 /* check for internal conflicts */
303 for (tmp = 0; tmp < PNP_MAX_MEM && tmp != idx; tmp++) { 332 for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
304 if (dev->res.mem_resource[tmp].flags & IORESOURCE_MEM) { 333 if (tres != res && tres->flags & IORESOURCE_MEM) {
305 taddr = &dev->res.mem_resource[tmp].start; 334 taddr = &tres->start;
306 tend = &dev->res.mem_resource[tmp].end; 335 tend = &tres->end;
307 if (ranged_conflict(addr, end, taddr, tend)) 336 if (ranged_conflict(addr, end, taddr, tend))
308 return 0; 337 return 0;
309 } 338 }
@@ -313,13 +342,14 @@ int pnp_check_mem(struct pnp_dev *dev, int idx)
313 pnp_for_each_dev(tdev) { 342 pnp_for_each_dev(tdev) {
314 if (tdev == dev) 343 if (tdev == dev)
315 continue; 344 continue;
316 for (tmp = 0; tmp < PNP_MAX_MEM; tmp++) { 345 for (i = 0;
317 if (tdev->res.mem_resource[tmp].flags & IORESOURCE_MEM) { 346 (tres = pnp_get_resource(tdev, IORESOURCE_MEM, i));
318 if (cannot_compare 347 i++) {
319 (tdev->res.mem_resource[tmp].flags)) 348 if (tres->flags & IORESOURCE_MEM) {
349 if (cannot_compare(tres->flags))
320 continue; 350 continue;
321 taddr = &tdev->res.mem_resource[tmp].start; 351 taddr = &tres->start;
322 tend = &tdev->res.mem_resource[tmp].end; 352 tend = &tres->end;
323 if (ranged_conflict(addr, end, taddr, tend)) 353 if (ranged_conflict(addr, end, taddr, tend))
324 return 0; 354 return 0;
325 } 355 }
@@ -334,14 +364,17 @@ static irqreturn_t pnp_test_handler(int irq, void *dev_id)
334 return IRQ_HANDLED; 364 return IRQ_HANDLED;
335} 365}
336 366
337int pnp_check_irq(struct pnp_dev *dev, int idx) 367int pnp_check_irq(struct pnp_dev *dev, struct resource *res)
338{ 368{
339 int tmp; 369 int i;
340 struct pnp_dev *tdev; 370 struct pnp_dev *tdev;
341 resource_size_t *irq = &dev->res.irq_resource[idx].start; 371 struct resource *tres;
372 resource_size_t *irq;
373
374 irq = &res->start;
342 375
343 /* if the resource doesn't exist, don't complain about it */ 376 /* if the resource doesn't exist, don't complain about it */
344 if (cannot_compare(dev->res.irq_resource[idx].flags)) 377 if (cannot_compare(res->flags))
345 return 1; 378 return 1;
346 379
347 /* check if the resource is valid */ 380 /* check if the resource is valid */
@@ -349,15 +382,15 @@ int pnp_check_irq(struct pnp_dev *dev, int idx)
349 return 0; 382 return 0;
350 383
351 /* check if the resource is reserved */ 384 /* check if the resource is reserved */
352 for (tmp = 0; tmp < 16; tmp++) { 385 for (i = 0; i < 16; i++) {
353 if (pnp_reserve_irq[tmp] == *irq) 386 if (pnp_reserve_irq[i] == *irq)
354 return 0; 387 return 0;
355 } 388 }
356 389
357 /* check for internal conflicts */ 390 /* check for internal conflicts */
358 for (tmp = 0; tmp < PNP_MAX_IRQ && tmp != idx; tmp++) { 391 for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_IRQ, i)); i++) {
359 if (dev->res.irq_resource[tmp].flags & IORESOURCE_IRQ) { 392 if (tres != res && tres->flags & IORESOURCE_IRQ) {
360 if (dev->res.irq_resource[tmp].start == *irq) 393 if (tres->start == *irq)
361 return 0; 394 return 0;
362 } 395 }
363 } 396 }
@@ -388,12 +421,13 @@ int pnp_check_irq(struct pnp_dev *dev, int idx)
388 pnp_for_each_dev(tdev) { 421 pnp_for_each_dev(tdev) {
389 if (tdev == dev) 422 if (tdev == dev)
390 continue; 423 continue;
391 for (tmp = 0; tmp < PNP_MAX_IRQ; tmp++) { 424 for (i = 0;
392 if (tdev->res.irq_resource[tmp].flags & IORESOURCE_IRQ) { 425 (tres = pnp_get_resource(tdev, IORESOURCE_IRQ, i));
393 if (cannot_compare 426 i++) {
394 (tdev->res.irq_resource[tmp].flags)) 427 if (tres->flags & IORESOURCE_IRQ) {
428 if (cannot_compare(tres->flags))
395 continue; 429 continue;
396 if ((tdev->res.irq_resource[tmp].start == *irq)) 430 if (tres->start == *irq)
397 return 0; 431 return 0;
398 } 432 }
399 } 433 }
@@ -402,15 +436,18 @@ int pnp_check_irq(struct pnp_dev *dev, int idx)
402 return 1; 436 return 1;
403} 437}
404 438
405int pnp_check_dma(struct pnp_dev *dev, int idx) 439int pnp_check_dma(struct pnp_dev *dev, struct resource *res)
406{ 440{
407#ifndef CONFIG_IA64 441#ifndef CONFIG_IA64
408 int tmp; 442 int i;
409 struct pnp_dev *tdev; 443 struct pnp_dev *tdev;
410 resource_size_t *dma = &dev->res.dma_resource[idx].start; 444 struct resource *tres;
445 resource_size_t *dma;
446
447 dma = &res->start;
411 448
412 /* if the resource doesn't exist, don't complain about it */ 449 /* if the resource doesn't exist, don't complain about it */
413 if (cannot_compare(dev->res.dma_resource[idx].flags)) 450 if (cannot_compare(res->flags))
414 return 1; 451 return 1;
415 452
416 /* check if the resource is valid */ 453 /* check if the resource is valid */
@@ -418,15 +455,15 @@ int pnp_check_dma(struct pnp_dev *dev, int idx)
418 return 0; 455 return 0;
419 456
420 /* check if the resource is reserved */ 457 /* check if the resource is reserved */
421 for (tmp = 0; tmp < 8; tmp++) { 458 for (i = 0; i < 8; i++) {
422 if (pnp_reserve_dma[tmp] == *dma) 459 if (pnp_reserve_dma[i] == *dma)
423 return 0; 460 return 0;
424 } 461 }
425 462
426 /* check for internal conflicts */ 463 /* check for internal conflicts */
427 for (tmp = 0; tmp < PNP_MAX_DMA && tmp != idx; tmp++) { 464 for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_DMA, i)); i++) {
428 if (dev->res.dma_resource[tmp].flags & IORESOURCE_DMA) { 465 if (tres != res && tres->flags & IORESOURCE_DMA) {
429 if (dev->res.dma_resource[tmp].start == *dma) 466 if (tres->start == *dma)
430 return 0; 467 return 0;
431 } 468 }
432 } 469 }
@@ -443,12 +480,13 @@ int pnp_check_dma(struct pnp_dev *dev, int idx)
443 pnp_for_each_dev(tdev) { 480 pnp_for_each_dev(tdev) {
444 if (tdev == dev) 481 if (tdev == dev)
445 continue; 482 continue;
446 for (tmp = 0; tmp < PNP_MAX_DMA; tmp++) { 483 for (i = 0;
447 if (tdev->res.dma_resource[tmp].flags & IORESOURCE_DMA) { 484 (tres = pnp_get_resource(tdev, IORESOURCE_DMA, i));
448 if (cannot_compare 485 i++) {
449 (tdev->res.dma_resource[tmp].flags)) 486 if (tres->flags & IORESOURCE_DMA) {
487 if (cannot_compare(tres->flags))
450 continue; 488 continue;
451 if ((tdev->res.dma_resource[tmp].start == *dma)) 489 if (tres->start == *dma)
452 return 0; 490 return 0;
453 } 491 }
454 } 492 }
@@ -461,6 +499,193 @@ int pnp_check_dma(struct pnp_dev *dev, int idx)
461#endif 499#endif
462} 500}
463 501
502struct pnp_resource *pnp_get_pnp_resource(struct pnp_dev *dev,
503 unsigned int type, unsigned int num)
504{
505 struct pnp_resource_table *res = dev->res;
506
507 switch (type) {
508 case IORESOURCE_IO:
509 if (num >= PNP_MAX_PORT)
510 return NULL;
511 return &res->port[num];
512 case IORESOURCE_MEM:
513 if (num >= PNP_MAX_MEM)
514 return NULL;
515 return &res->mem[num];
516 case IORESOURCE_IRQ:
517 if (num >= PNP_MAX_IRQ)
518 return NULL;
519 return &res->irq[num];
520 case IORESOURCE_DMA:
521 if (num >= PNP_MAX_DMA)
522 return NULL;
523 return &res->dma[num];
524 }
525 return NULL;
526}
527
528struct resource *pnp_get_resource(struct pnp_dev *dev,
529 unsigned int type, unsigned int num)
530{
531 struct pnp_resource *pnp_res;
532
533 pnp_res = pnp_get_pnp_resource(dev, type, num);
534 if (pnp_res)
535 return &pnp_res->res;
536
537 return NULL;
538}
539EXPORT_SYMBOL(pnp_get_resource);
540
541static struct pnp_resource *pnp_new_resource(struct pnp_dev *dev, int type)
542{
543 struct pnp_resource *pnp_res;
544 int i;
545
546 switch (type) {
547 case IORESOURCE_IO:
548 for (i = 0; i < PNP_MAX_PORT; i++) {
549 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, i);
550 if (pnp_res && !pnp_resource_valid(&pnp_res->res))
551 return pnp_res;
552 }
553 break;
554 case IORESOURCE_MEM:
555 for (i = 0; i < PNP_MAX_MEM; i++) {
556 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_MEM, i);
557 if (pnp_res && !pnp_resource_valid(&pnp_res->res))
558 return pnp_res;
559 }
560 break;
561 case IORESOURCE_IRQ:
562 for (i = 0; i < PNP_MAX_IRQ; i++) {
563 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, i);
564 if (pnp_res && !pnp_resource_valid(&pnp_res->res))
565 return pnp_res;
566 }
567 break;
568 case IORESOURCE_DMA:
569 for (i = 0; i < PNP_MAX_DMA; i++) {
570 pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, i);
571 if (pnp_res && !pnp_resource_valid(&pnp_res->res))
572 return pnp_res;
573 }
574 break;
575 }
576 return NULL;
577}
578
579struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
580 int flags)
581{
582 struct pnp_resource *pnp_res;
583 struct resource *res;
584 static unsigned char warned;
585
586 pnp_res = pnp_new_resource(dev, IORESOURCE_IRQ);
587 if (!pnp_res) {
588 if (!warned) {
589 dev_err(&dev->dev, "can't add resource for IRQ %d\n",
590 irq);
591 warned = 1;
592 }
593 return NULL;
594 }
595
596 res = &pnp_res->res;
597 res->flags = IORESOURCE_IRQ | flags;
598 res->start = irq;
599 res->end = irq;
600
601 dev_dbg(&dev->dev, " add irq %d flags %#x\n", irq, flags);
602 return pnp_res;
603}
604
605struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma,
606 int flags)
607{
608 struct pnp_resource *pnp_res;
609 struct resource *res;
610 static unsigned char warned;
611
612 pnp_res = pnp_new_resource(dev, IORESOURCE_DMA);
613 if (!pnp_res) {
614 if (!warned) {
615 dev_err(&dev->dev, "can't add resource for DMA %d\n",
616 dma);
617 warned = 1;
618 }
619 return NULL;
620 }
621
622 res = &pnp_res->res;
623 res->flags = IORESOURCE_DMA | flags;
624 res->start = dma;
625 res->end = dma;
626
627 dev_dbg(&dev->dev, " add dma %d flags %#x\n", dma, flags);
628 return pnp_res;
629}
630
631struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev,
632 resource_size_t start,
633 resource_size_t end, int flags)
634{
635 struct pnp_resource *pnp_res;
636 struct resource *res;
637 static unsigned char warned;
638
639 pnp_res = pnp_new_resource(dev, IORESOURCE_IO);
640 if (!pnp_res) {
641 if (!warned) {
642 dev_err(&dev->dev, "can't add resource for IO "
643 "%#llx-%#llx\n",(unsigned long long) start,
644 (unsigned long long) end);
645 warned = 1;
646 }
647 return NULL;
648 }
649
650 res = &pnp_res->res;
651 res->flags = IORESOURCE_IO | flags;
652 res->start = start;
653 res->end = end;
654
655 dev_dbg(&dev->dev, " add io %#llx-%#llx flags %#x\n",
656 (unsigned long long) start, (unsigned long long) end, flags);
657 return pnp_res;
658}
659
660struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
661 resource_size_t start,
662 resource_size_t end, int flags)
663{
664 struct pnp_resource *pnp_res;
665 struct resource *res;
666 static unsigned char warned;
667
668 pnp_res = pnp_new_resource(dev, IORESOURCE_MEM);
669 if (!pnp_res) {
670 if (!warned) {
671 dev_err(&dev->dev, "can't add resource for MEM "
672 "%#llx-%#llx\n",(unsigned long long) start,
673 (unsigned long long) end);
674 warned = 1;
675 }
676 return NULL;
677 }
678
679 res = &pnp_res->res;
680 res->flags = IORESOURCE_MEM | flags;
681 res->start = start;
682 res->end = end;
683
684 dev_dbg(&dev->dev, " add mem %#llx-%#llx flags %#x\n",
685 (unsigned long long) start, (unsigned long long) end, flags);
686 return pnp_res;
687}
688
464/* format is: pnp_reserve_irq=irq1[,irq2] .... */ 689/* format is: pnp_reserve_irq=irq1[,irq2] .... */
465static int __init pnp_setup_reserve_irq(char *str) 690static int __init pnp_setup_reserve_irq(char *str)
466{ 691{
diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c
index 13c608f5fb30..3eba85ed729c 100644
--- a/drivers/pnp/support.c
+++ b/drivers/pnp/support.c
@@ -25,3 +25,66 @@ int pnp_is_active(struct pnp_dev *dev)
25} 25}
26 26
27EXPORT_SYMBOL(pnp_is_active); 27EXPORT_SYMBOL(pnp_is_active);
28
29/*
30 * Functionally similar to acpi_ex_eisa_id_to_string(), but that's
31 * buried in the ACPI CA, and we can't depend on it being present.
32 */
33void pnp_eisa_id_to_string(u32 id, char *str)
34{
35 id = be32_to_cpu(id);
36
37 /*
38 * According to the specs, the first three characters are five-bit
39 * compressed ASCII, and the left-over high order bit should be zero.
40 * However, the Linux ISAPNP code historically used six bits for the
41 * first character, and there seem to be IDs that depend on that,
42 * e.g., "nEC8241" in the Linux 8250_pnp serial driver and the
43 * FreeBSD sys/pc98/cbus/sio_cbus.c driver.
44 */
45 str[0] = 'A' + ((id >> 26) & 0x3f) - 1;
46 str[1] = 'A' + ((id >> 21) & 0x1f) - 1;
47 str[2] = 'A' + ((id >> 16) & 0x1f) - 1;
48 str[3] = hex_asc((id >> 12) & 0xf);
49 str[4] = hex_asc((id >> 8) & 0xf);
50 str[5] = hex_asc((id >> 4) & 0xf);
51 str[6] = hex_asc((id >> 0) & 0xf);
52 str[7] = '\0';
53}
54
55void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc)
56{
57#ifdef DEBUG
58 struct resource *res;
59 int i;
60
61 dev_dbg(&dev->dev, "current resources: %s\n", desc);
62
63 for (i = 0; i < PNP_MAX_IRQ; i++) {
64 res = pnp_get_resource(dev, IORESOURCE_IRQ, i);
65 if (res && !(res->flags & IORESOURCE_UNSET))
66 dev_dbg(&dev->dev, " irq %lld flags %#lx\n",
67 (unsigned long long) res->start, res->flags);
68 }
69 for (i = 0; i < PNP_MAX_DMA; i++) {
70 res = pnp_get_resource(dev, IORESOURCE_DMA, i);
71 if (res && !(res->flags & IORESOURCE_UNSET))
72 dev_dbg(&dev->dev, " dma %lld flags %#lx\n",
73 (unsigned long long) res->start, res->flags);
74 }
75 for (i = 0; i < PNP_MAX_PORT; i++) {
76 res = pnp_get_resource(dev, IORESOURCE_IO, i);
77 if (res && !(res->flags & IORESOURCE_UNSET))
78 dev_dbg(&dev->dev, " io %#llx-%#llx flags %#lx\n",
79 (unsigned long long) res->start,
80 (unsigned long long) res->end, res->flags);
81 }
82 for (i = 0; i < PNP_MAX_MEM; i++) {
83 res = pnp_get_resource(dev, IORESOURCE_MEM, i);
84 if (res && !(res->flags & IORESOURCE_UNSET))
85 dev_dbg(&dev->dev, " mem %#llx-%#llx flags %#lx\n",
86 (unsigned long long) res->start,
87 (unsigned long long) res->end, res->flags);
88 }
89#endif
90}
diff --git a/drivers/pnp/system.c b/drivers/pnp/system.c
index 55c4563986b3..9c2496dbeee4 100644
--- a/drivers/pnp/system.c
+++ b/drivers/pnp/system.c
@@ -56,14 +56,15 @@ static void reserve_range(struct pnp_dev *dev, resource_size_t start,
56 56
57static void reserve_resources_of_dev(struct pnp_dev *dev) 57static void reserve_resources_of_dev(struct pnp_dev *dev)
58{ 58{
59 struct resource *res;
59 int i; 60 int i;
60 61
61 for (i = 0; i < PNP_MAX_PORT; i++) { 62 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) {
62 if (!pnp_port_valid(dev, i)) 63 if (res->flags & IORESOURCE_UNSET)
63 continue; 64 continue;
64 if (pnp_port_start(dev, i) == 0) 65 if (res->start == 0)
65 continue; /* disabled */ 66 continue; /* disabled */
66 if (pnp_port_start(dev, i) < 0x100) 67 if (res->start < 0x100)
67 /* 68 /*
68 * Below 0x100 is only standard PC hardware 69 * Below 0x100 is only standard PC hardware
69 * (pics, kbd, timer, dma, ...) 70 * (pics, kbd, timer, dma, ...)
@@ -73,19 +74,17 @@ static void reserve_resources_of_dev(struct pnp_dev *dev)
73 * So, do nothing 74 * So, do nothing
74 */ 75 */
75 continue; 76 continue;
76 if (pnp_port_end(dev, i) < pnp_port_start(dev, i)) 77 if (res->end < res->start)
77 continue; /* invalid */ 78 continue; /* invalid */
78 79
79 reserve_range(dev, pnp_port_start(dev, i), 80 reserve_range(dev, res->start, res->end, 1);
80 pnp_port_end(dev, i), 1);
81 } 81 }
82 82
83 for (i = 0; i < PNP_MAX_MEM; i++) { 83 for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
84 if (!pnp_mem_valid(dev, i)) 84 if (res->flags & IORESOURCE_UNSET)
85 continue; 85 continue;
86 86
87 reserve_range(dev, pnp_mem_start(dev, i), 87 reserve_range(dev, res->start, res->end, 0);
88 pnp_mem_end(dev, i), 0);
89 } 88 }
90} 89}
91 90
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index dcdc142a3441..d060a06ce05b 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -854,11 +854,12 @@ cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
854 * don't define the IRQ. It should always be safe to 854 * don't define the IRQ. It should always be safe to
855 * hardcode it in these cases 855 * hardcode it in these cases
856 */ 856 */
857 return cmos_do_probe(&pnp->dev, &pnp->res.port_resource[0], 8); 857 return cmos_do_probe(&pnp->dev,
858 pnp_get_resource(pnp, IORESOURCE_IO, 0), 8);
858 else 859 else
859 return cmos_do_probe(&pnp->dev, 860 return cmos_do_probe(&pnp->dev,
860 &pnp->res.port_resource[0], 861 pnp_get_resource(pnp, IORESOURCE_IO, 0),
861 pnp->res.irq_resource[0].start); 862 pnp_irq(pnp, 0));
862} 863}
863 864
864static void __exit cmos_pnp_remove(struct pnp_dev *pnp) 865static void __exit cmos_pnp_remove(struct pnp_dev *pnp)
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 17e71d56f31e..4b628526df09 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -3,7 +3,7 @@
3# 3#
4 4
5menuconfig THERMAL 5menuconfig THERMAL
6 bool "Generic Thermal sysfs driver" 6 tristate "Generic Thermal sysfs driver"
7 help 7 help
8 Generic Thermal Sysfs driver offers a generic mechanism for 8 Generic Thermal Sysfs driver offers a generic mechanism for
9 thermal management. Usually it's made up of one or more thermal 9 thermal management. Usually it's made up of one or more thermal
@@ -11,4 +11,4 @@ menuconfig THERMAL
11 Each thermal zone contains its own temperature, trip points, 11 Each thermal zone contains its own temperature, trip points,
12 cooling devices. 12 cooling devices.
13 All platforms with ACPI thermal support can use this driver. 13 All platforms with ACPI thermal support can use this driver.
14 If you want this support, you should say Y here. 14 If you want this support, you should say Y or M here.
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 8ef1232de376..31108a01c22e 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -2,4 +2,4 @@
2# Makefile for sensor chip drivers. 2# Makefile for sensor chip drivers.
3# 3#
4 4
5obj-$(CONFIG_THERMAL) += thermal.o 5obj-$(CONFIG_THERMAL) += thermal_sys.o
diff --git a/drivers/thermal/thermal.c b/drivers/thermal/thermal_sys.c
index 7f79bbf652d7..6098787341f3 100644
--- a/drivers/thermal/thermal.c
+++ b/drivers/thermal/thermal_sys.c
@@ -31,7 +31,7 @@
31#include <linux/thermal.h> 31#include <linux/thermal.h>
32#include <linux/spinlock.h> 32#include <linux/spinlock.h>
33 33
34MODULE_AUTHOR("Zhang Rui") 34MODULE_AUTHOR("Zhang Rui");
35MODULE_DESCRIPTION("Generic thermal management sysfs support"); 35MODULE_DESCRIPTION("Generic thermal management sysfs support");
36MODULE_LICENSE("GPL"); 36MODULE_LICENSE("GPL");
37 37
@@ -295,6 +295,164 @@ thermal_cooling_device_trip_point_show(struct device *dev,
295 295
296/* Device management */ 296/* Device management */
297 297
298#if defined(CONFIG_HWMON) || \
299 (defined(CONFIG_HWMON_MODULE) && defined(CONFIG_THERMAL_MODULE))
300/* hwmon sys I/F */
301#include <linux/hwmon.h>
302static LIST_HEAD(thermal_hwmon_list);
303
304static ssize_t
305name_show(struct device *dev, struct device_attribute *attr, char *buf)
306{
307 struct thermal_hwmon_device *hwmon = dev->driver_data;
308 return sprintf(buf, "%s\n", hwmon->type);
309}
310static DEVICE_ATTR(name, 0444, name_show, NULL);
311
312static ssize_t
313temp_input_show(struct device *dev, struct device_attribute *attr, char *buf)
314{
315 struct thermal_hwmon_attr *hwmon_attr
316 = container_of(attr, struct thermal_hwmon_attr, attr);
317 struct thermal_zone_device *tz
318 = container_of(hwmon_attr, struct thermal_zone_device,
319 temp_input);
320
321 return tz->ops->get_temp(tz, buf);
322}
323
324static ssize_t
325temp_crit_show(struct device *dev, struct device_attribute *attr,
326 char *buf)
327{
328 struct thermal_hwmon_attr *hwmon_attr
329 = container_of(attr, struct thermal_hwmon_attr, attr);
330 struct thermal_zone_device *tz
331 = container_of(hwmon_attr, struct thermal_zone_device,
332 temp_crit);
333
334 return tz->ops->get_trip_temp(tz, 0, buf);
335}
336
337
338static int
339thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
340{
341 struct thermal_hwmon_device *hwmon;
342 int new_hwmon_device = 1;
343 int result;
344
345 mutex_lock(&thermal_list_lock);
346 list_for_each_entry(hwmon, &thermal_hwmon_list, node)
347 if (!strcmp(hwmon->type, tz->type)) {
348 new_hwmon_device = 0;
349 mutex_unlock(&thermal_list_lock);
350 goto register_sys_interface;
351 }
352 mutex_unlock(&thermal_list_lock);
353
354 hwmon = kzalloc(sizeof(struct thermal_hwmon_device), GFP_KERNEL);
355 if (!hwmon)
356 return -ENOMEM;
357
358 INIT_LIST_HEAD(&hwmon->tz_list);
359 strlcpy(hwmon->type, tz->type, THERMAL_NAME_LENGTH);
360 hwmon->device = hwmon_device_register(NULL);
361 if (IS_ERR(hwmon->device)) {
362 result = PTR_ERR(hwmon->device);
363 goto free_mem;
364 }
365 hwmon->device->driver_data = hwmon;
366 result = device_create_file(hwmon->device, &dev_attr_name);
367 if (result)
368 goto unregister_hwmon_device;
369
370 register_sys_interface:
371 tz->hwmon = hwmon;
372 hwmon->count++;
373
374 snprintf(tz->temp_input.name, THERMAL_NAME_LENGTH,
375 "temp%d_input", hwmon->count);
376 tz->temp_input.attr.attr.name = tz->temp_input.name;
377 tz->temp_input.attr.attr.mode = 0444;
378 tz->temp_input.attr.show = temp_input_show;
379 result = device_create_file(hwmon->device, &tz->temp_input.attr);
380 if (result)
381 goto unregister_hwmon_device;
382
383 if (tz->ops->get_crit_temp) {
384 unsigned long temperature;
385 if (!tz->ops->get_crit_temp(tz, &temperature)) {
386 snprintf(tz->temp_crit.name, THERMAL_NAME_LENGTH,
387 "temp%d_crit", hwmon->count);
388 tz->temp_crit.attr.attr.name = tz->temp_crit.name;
389 tz->temp_crit.attr.attr.mode = 0444;
390 tz->temp_crit.attr.show = temp_crit_show;
391 result = device_create_file(hwmon->device,
392 &tz->temp_crit.attr);
393 if (result)
394 goto unregister_hwmon_device;
395 }
396 }
397
398 mutex_lock(&thermal_list_lock);
399 if (new_hwmon_device)
400 list_add_tail(&hwmon->node, &thermal_hwmon_list);
401 list_add_tail(&tz->hwmon_node, &hwmon->tz_list);
402 mutex_unlock(&thermal_list_lock);
403
404 return 0;
405
406 unregister_hwmon_device:
407 device_remove_file(hwmon->device, &tz->temp_crit.attr);
408 device_remove_file(hwmon->device, &tz->temp_input.attr);
409 if (new_hwmon_device) {
410 device_remove_file(hwmon->device, &dev_attr_name);
411 hwmon_device_unregister(hwmon->device);
412 }
413 free_mem:
414 if (new_hwmon_device)
415 kfree(hwmon);
416
417 return result;
418}
419
420static void
421thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
422{
423 struct thermal_hwmon_device *hwmon = tz->hwmon;
424
425 tz->hwmon = NULL;
426 device_remove_file(hwmon->device, &tz->temp_input.attr);
427 device_remove_file(hwmon->device, &tz->temp_crit.attr);
428
429 mutex_lock(&thermal_list_lock);
430 list_del(&tz->hwmon_node);
431 if (!list_empty(&hwmon->tz_list)) {
432 mutex_unlock(&thermal_list_lock);
433 return;
434 }
435 list_del(&hwmon->node);
436 mutex_unlock(&thermal_list_lock);
437
438 device_remove_file(hwmon->device, &dev_attr_name);
439 hwmon_device_unregister(hwmon->device);
440 kfree(hwmon);
441}
442#else
443static int
444thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
445{
446 return 0;
447}
448
449static void
450thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
451{
452}
453#endif
454
455
298/** 456/**
299 * thermal_zone_bind_cooling_device - bind a cooling device to a thermal zone 457 * thermal_zone_bind_cooling_device - bind a cooling device to a thermal zone
300 * @tz: thermal zone device 458 * @tz: thermal zone device
@@ -642,6 +800,10 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
642 goto unregister; 800 goto unregister;
643 } 801 }
644 802
803 result = thermal_add_hwmon_sysfs(tz);
804 if (result)
805 goto unregister;
806
645 mutex_lock(&thermal_list_lock); 807 mutex_lock(&thermal_list_lock);
646 list_add_tail(&tz->node, &thermal_tz_list); 808 list_add_tail(&tz->node, &thermal_tz_list);
647 if (ops->bind) 809 if (ops->bind)
@@ -700,6 +862,7 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
700 for (count = 0; count < tz->trips; count++) 862 for (count = 0; count < tz->trips; count++)
701 TRIP_POINT_ATTR_REMOVE(&tz->device, count); 863 TRIP_POINT_ATTR_REMOVE(&tz->device, count);
702 864
865 thermal_remove_hwmon_sysfs(tz);
703 release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id); 866 release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id);
704 idr_destroy(&tz->idr); 867 idr_destroy(&tz->idr);
705 mutex_destroy(&tz->lock); 868 mutex_destroy(&tz->lock);