diff --git a/[refs] b/[refs] index a48e1e0329bd..5ed9b01986b9 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 7ac3ae32d170cea8cb8e7822acc29ed8f1b1018d +refs/heads/master: 152c300d007c70c4a1847dad39ecdaba22e7d457 diff --git a/trunk/drivers/acpi/dispatcher/dsobject.c b/trunk/drivers/acpi/dispatcher/dsobject.c index a474ca2334d5..954ac8ce958a 100644 --- a/trunk/drivers/acpi/dispatcher/dsobject.c +++ b/trunk/drivers/acpi/dispatcher/dsobject.c @@ -137,6 +137,71 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, return_ACPI_STATUS(status); } } + + /* Special object resolution for elements of a package */ + + if ((op->common.parent->common.aml_opcode == AML_PACKAGE_OP) || + (op->common.parent->common.aml_opcode == + AML_VAR_PACKAGE_OP)) { + /* + * Attempt to resolve the node to a value before we insert it into + * the package. If this is a reference to a common data type, + * resolve it immediately. According to the ACPI spec, package + * elements can only be "data objects" or method references. + * Attempt to resolve to an Integer, Buffer, String or Package. + * If cannot, return the named reference (for things like Devices, + * Methods, etc.) Buffer Fields and Fields will resolve to simple + * objects (int/buf/str/pkg). + * + * NOTE: References to things like Devices, Methods, Mutexes, etc. + * will remain as named references. This behavior is not described + * in the ACPI spec, but it appears to be an oversight. + */ + obj_desc = (union acpi_operand_object *)op->common.node; + + status = + acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR + (struct + acpi_namespace_node, + &obj_desc), + walk_state); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + switch (op->common.node->type) { + /* + * For these types, we need the actual node, not the subobject. + * However, the subobject got an extra reference count above. + */ + case ACPI_TYPE_MUTEX: + case ACPI_TYPE_METHOD: + case ACPI_TYPE_POWER: + case ACPI_TYPE_PROCESSOR: + case ACPI_TYPE_EVENT: + case ACPI_TYPE_REGION: + case ACPI_TYPE_DEVICE: + case ACPI_TYPE_THERMAL: + + obj_desc = + (union acpi_operand_object *)op->common. + node; + break; + + default: + break; + } + + /* + * If above resolved to an operand object, we are done. Otherwise, + * we have a NS node, we must create the package entry as a named + * reference. + */ + if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != + ACPI_DESC_TYPE_NAMED) { + goto exit; + } + } } /* Create and init a new internal ACPI object */ @@ -156,6 +221,7 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, return_ACPI_STATUS(status); } + exit: *obj_desc_ptr = obj_desc; return_ACPI_STATUS(AE_OK); } @@ -356,12 +422,25 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, arg = arg->common.next; for (i = 0; arg && (i < element_count); i++) { if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) { - - /* This package element is already built, just get it */ - - obj_desc->package.elements[i] = - ACPI_CAST_PTR(union acpi_operand_object, - arg->common.node); + if (arg->common.node->type == ACPI_TYPE_METHOD) { + /* + * A method reference "looks" to the parser to be a method + * invocation, so we special case it here + */ + arg->common.aml_opcode = AML_INT_NAMEPATH_OP; + status = + acpi_ds_build_internal_object(walk_state, + arg, + &obj_desc-> + package. + elements[i]); + } else { + /* This package element is already built, just get it */ + + obj_desc->package.elements[i] = + ACPI_CAST_PTR(union acpi_operand_object, + arg->common.node); + } } else { status = acpi_ds_build_internal_object(walk_state, arg, &obj_desc-> diff --git a/trunk/drivers/acpi/processor_throttling.c b/trunk/drivers/acpi/processor_throttling.c index 6742d7bc4777..c26c61fb36c3 100644 --- a/trunk/drivers/acpi/processor_throttling.c +++ b/trunk/drivers/acpi/processor_throttling.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -414,7 +413,7 @@ static int acpi_throttling_rdmsr(struct acpi_processor *pr, } else { msr_low = 0; msr_high = 0; - rdmsr_safe(MSR_IA32_THERM_CONTROL, + rdmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, (u32 *)&msr_low , (u32 *) &msr_high); msr = (msr_high << 32) | msr_low; *value = (acpi_integer) msr; @@ -439,7 +438,7 @@ static int acpi_throttling_wrmsr(struct acpi_processor *pr, acpi_integer value) "HARDWARE addr space,NOT supported yet\n"); } else { msr = value; - wrmsr_safe(MSR_IA32_THERM_CONTROL, + wrmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, msr & 0xffffffff, msr >> 32); ret = 0; } @@ -573,32 +572,21 @@ static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr) return -ENODEV; pr->throttling.state = 0; - + local_irq_disable(); value = 0; ret = acpi_read_throttling_status(pr, &value); if (ret >= 0) { state = acpi_get_throttling_state(pr, value); pr->throttling.state = state; } + local_irq_enable(); return 0; } static int acpi_processor_get_throttling(struct acpi_processor *pr) { - cpumask_t saved_mask; - int ret; - - /* - * Migrate task to the cpu pointed by pr. - */ - saved_mask = current->cpus_allowed; - set_cpus_allowed(current, cpumask_of_cpu(pr->id)); - ret = pr->throttling.acpi_processor_get_throttling(pr); - /* restore the previous state */ - set_cpus_allowed(current, saved_mask); - - return ret; + return pr->throttling.acpi_processor_get_throttling(pr); } static int acpi_processor_get_fadt_info(struct acpi_processor *pr) @@ -729,29 +717,21 @@ static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr, if (state < pr->throttling_platform_limit) return -EPERM; + local_irq_disable(); value = 0; ret = acpi_get_throttling_value(pr, state, &value); if (ret >= 0) { acpi_write_throttling_state(pr, value); pr->throttling.state = state; } + local_irq_enable(); return 0; } int acpi_processor_set_throttling(struct acpi_processor *pr, int state) { - cpumask_t saved_mask; - int ret; - /* - * Migrate task to the cpu pointed by pr. - */ - saved_mask = current->cpus_allowed; - set_cpus_allowed(current, cpumask_of_cpu(pr->id)); - ret = pr->throttling.acpi_processor_set_throttling(pr, state); - /* restore the previous state */ - set_cpus_allowed(current, saved_mask); - return ret; + return pr->throttling.acpi_processor_set_throttling(pr, state); } int acpi_processor_get_throttling_info(struct acpi_processor *pr)