Merge tag 'pm+acpi-3.15-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafae...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 2 Apr 2014 21:10:21 +0000 (14:10 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 2 Apr 2014 21:10:21 +0000 (14:10 -0700)
Pull more ACPI and power management updates from Rafael Wysocki:
 "These are commits that were not quite ready when I sent the original
  pull request for 3.15-rc1 several days ago, but they have spent some
  time in linux-next since then and appear to be good to go.  All of
  them are fixes and cleanups.

  Specifics:

   - Remaining changes from upstream ACPICA release 20140214 that
     introduce code to automatically serialize the execution of methods
     creating any named objects which really cannot be executed in
     parallel with each other anyway (previously ACPICA attempted to
     address that by aborting methods upon conflict detection, but that
     wasn't reliable enough and led to other issues).  From Bob Moore
     and Lv Zheng.

   - intel_pstate fix to use del_timer_sync() instead of del_timer() in
     the exit path before freeing the timer structure from Dirk
     Brandewie (original patch from Thomas Gleixner).

   - cpufreq fix related to system resume from Viresh Kumar.

   - Serialization of frequency transitions in cpufreq that involve
     PRECHANGE and POSTCHANGE notifications to avoid ordering issues
     resulting from race conditions.  From Srivatsa S Bhat and Viresh
     Kumar.

   - Revert of an ACPI processor driver change that was based on a
     specific interpretation of the ACPI spec which may not be correct
     (the relevant part of the spec appears to be incomplete).  From
     Hanjun Guo.

   - Runtime PM core cleanups and documentation updates from Geert
     Uytterhoeven.

   - PNP core cleanup from Michael Opdenacker"

* tag 'pm+acpi-3.15-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  cpufreq: Make cpufreq_notify_transition & cpufreq_notify_post_transition static
  cpufreq: Convert existing drivers to use cpufreq_freq_transition_{begin|end}
  cpufreq: Make sure frequency transitions are serialized
  intel_pstate: Use del_timer_sync in intel_pstate_cpu_stop
  cpufreq: resume drivers before enabling governors
  PM / Runtime: Spelling s/competing/completing/
  PM / Runtime: s/foo_process_requests/foo_process_next_request/
  PM / Runtime: GENERIC_SUBSYS_PM_OPS is gone
  PM / Runtime: Correct documented return values for generic PM callbacks
  PM / Runtime: Split line longer than 80 characters
  PM / Runtime: dev_pm_info.runtime_error is signed
  Revert "ACPI / processor: Make it possible to get APIC ID via GIC"
  ACPICA: Enable auto-serialization as a default kernel behavior.
  ACPICA: Ignore sync_level for methods that have been auto-serialized.
  ACPICA: Add additional named objects for the auto-serialize method scan.
  ACPICA: Add auto-serialization support for ill-behaved control methods.
  ACPICA: Remove global option to serialize all control methods.
  PNP: remove deprecated IRQF_DISABLED

36 files changed:
Documentation/kernel-parameters.txt
Documentation/power/runtime_pm.txt
drivers/acpi/acpica/acdispat.h
drivers/acpi/acpica/acglobal.h
drivers/acpi/acpica/acinterp.h
drivers/acpi/acpica/acobject.h
drivers/acpi/acpica/acstruct.h
drivers/acpi/acpica/dsinit.c
drivers/acpi/acpica/dsmethod.c
drivers/acpi/acpica/dswload.c
drivers/acpi/acpica/exsystem.c
drivers/acpi/acpica/exutils.c
drivers/acpi/acpica/nsinit.c
drivers/acpi/acpica/nsload.c
drivers/acpi/acpica/psloop.c
drivers/acpi/acpica/psobject.c
drivers/acpi/osl.c
drivers/acpi/processor_core.c
drivers/base/power/generic_ops.c
drivers/cpufreq/cpufreq-nforce2.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/exynos5440-cpufreq.c
drivers/cpufreq/gx-suspmod.c
drivers/cpufreq/integrator-cpufreq.c
drivers/cpufreq/intel_pstate.c
drivers/cpufreq/longhaul.c
drivers/cpufreq/pcc-cpufreq.c
drivers/cpufreq/powernow-k6.c
drivers/cpufreq/powernow-k7.c
drivers/cpufreq/powernow-k8.c
drivers/cpufreq/s3c24xx-cpufreq.c
drivers/cpufreq/sh-cpufreq.c
drivers/cpufreq/unicore2-cpufreq.c
drivers/pnp/resource.c
include/acpi/acpixf.h
include/linux/cpufreq.h

index 2311dad7a57a52f9dcb928d32baf77210e46984a..bc3478581f67ee05d31a58e73cf6fd3e6fcc2b68 100644 (file)
@@ -229,6 +229,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                        use by PCI
                        Format: <irq>,<irq>...
 
+       acpi_no_auto_serialize  [HW,ACPI]
+                       Disable auto-serialization of AML methods
+                       AML control methods that contain the opcodes to create
+                       named objects will be marked as "Serialized" by the
+                       auto-serialization feature.
+                       This feature is enabled by default.
+                       This option allows to turn off the feature.
+
        acpi_no_auto_ssdt       [HW,ACPI] Disable automatic loading of SSDT
 
        acpica_no_return_repair [HW, ACPI]
@@ -306,8 +314,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
        acpi_sci=       [HW,ACPI] ACPI System Control Interrupt trigger mode
                        Format: { level | edge | high | low }
 
-       acpi_serialize  [HW,ACPI] force serialization of AML methods
-
        acpi_skip_timer_override [HW,ACPI]
                        Recognize and ignore IRQ0/pin2 Interrupt Override.
                        For broken nForce2 BIOS resulting in XT-PIC timer.
index b6ce00b2be9ae9682c6821bfb70175e42cc75e57..5f96daf8566abfb5003089696dc1c537793d3c4b 100644 (file)
@@ -232,7 +232,7 @@ defined in include/linux/pm.h:
       equal to zero); the initial value of it is 1 (i.e. runtime PM is
       initially disabled for all devices)
 
-  unsigned int runtime_error;
+  int runtime_error;
     - if set, there was a fatal error (one of the callbacks returned error code
       as described in Section 2), so the helper funtions will not work until
       this flag is cleared; this is the error code returned by the failing
@@ -401,11 +401,11 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
   int pm_runtime_disable(struct device *dev);
     - increment the device's 'power.disable_depth' field (if the value of that
       field was previously zero, this prevents subsystem-level runtime PM
-      callbacks from being run for the device), make sure that all of the pending
-      runtime PM operations on the device are either completed or canceled;
-      returns 1 if there was a resume request pending and it was necessary to
-      execute the subsystem-level resume callback for the device to satisfy that
-      request, otherwise 0 is returned
+      callbacks from being run for the device), make sure that all of the
+      pending runtime PM operations on the device are either completed or
+      canceled; returns 1 if there was a resume request pending and it was
+      necessary to execute the subsystem-level resume callback for the device
+      to satisfy that request, otherwise 0 is returned
 
   int pm_runtime_barrier(struct device *dev);
     - check if there's a resume request pending for the device and resume it
@@ -667,11 +667,11 @@ driver/base/power/generic_ops.c:
 
   int pm_generic_runtime_suspend(struct device *dev);
     - invoke the ->runtime_suspend() callback provided by the driver of this
-      device and return its result, or return -EINVAL if not defined
+      device and return its result, or return 0 if not defined
 
   int pm_generic_runtime_resume(struct device *dev);
     - invoke the ->runtime_resume() callback provided by the driver of this
-      device and return its result, or return -EINVAL if not defined
+      device and return its result, or return 0 if not defined
 
   int pm_generic_suspend(struct device *dev);
     - if the device has not been suspended at run time, invoke the ->suspend()
@@ -727,15 +727,12 @@ driver/base/power/generic_ops.c:
   int pm_generic_restore_noirq(struct device *dev);
     - invoke the ->restore_noirq() callback provided by the device's driver
 
-These functions can be assigned to the ->runtime_idle(), ->runtime_suspend(),
+These functions are the defaults used by the PM core, if a subsystem doesn't
+provide its own callbacks for ->runtime_idle(), ->runtime_suspend(),
 ->runtime_resume(), ->suspend(), ->suspend_noirq(), ->resume(),
 ->resume_noirq(), ->freeze(), ->freeze_noirq(), ->thaw(), ->thaw_noirq(),
-->poweroff(), ->poweroff_noirq(), ->restore(), ->restore_noirq() callback
-pointers in the subsystem-level dev_pm_ops structures.
-
-If a subsystem wishes to use all of them at the same time, it can simply assign
-the GENERIC_SUBSYS_PM_OPS macro, defined in include/linux/pm.h, to its
-dev_pm_ops structure pointer.
+->poweroff(), ->poweroff_noirq(), ->restore(), ->restore_noirq() in the
+subsystem-level dev_pm_ops structure.
 
 Device drivers that wish to use the same function as a system suspend, freeze,
 poweroff and runtime suspend callback, and similarly for system resume, thaw,
@@ -873,7 +870,7 @@ Here is a schematic pseudo-code example:
                foo->is_suspended = 0;
                pm_runtime_mark_last_busy(&foo->dev);
                if (foo->num_pending_requests > 0)
-                       foo_process_requests(foo);
+                       foo_process_next_request(foo);
                unlock(&foo->private_lock);
                return 0;
        }
index 5b472c43c31da376e14e039f4583521e68b184da..d3e2cc395d7fad8bbd862b72162dd6b74c0515d9 100644 (file)
@@ -139,20 +139,21 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
                           struct acpi_walk_state *walk_state);
 
 /*
- * dsload - Parser/Interpreter interface, pass 1 namespace load callbacks
+ * dsload - Parser/Interpreter interface
  */
 acpi_status
 acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number);
 
+/* dsload - pass 1 namespace load callbacks */
+
 acpi_status
 acpi_ds_load1_begin_op(struct acpi_walk_state *walk_state,
                       union acpi_parse_object **out_op);
 
 acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state);
 
-/*
- * dsload - Parser/Interpreter interface, pass 2 namespace load callbacks
- */
+/* dsload - pass 2 namespace load callbacks */
+
 acpi_status
 acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
                       union acpi_parse_object **out_op);
@@ -200,7 +201,9 @@ void acpi_ds_method_data_init(struct acpi_walk_state *walk_state);
 /*
  * dsmethod - Parser/Interpreter interface - control method parsing
  */
-acpi_status acpi_ds_parse_method(struct acpi_namespace_node *node);
+acpi_status
+acpi_ds_auto_serialize_method(struct acpi_namespace_node *node,
+                             union acpi_operand_object *obj_desc);
 
 acpi_status
 acpi_ds_call_control_method(struct acpi_thread_state *thread,
index 8f40bb972ae3907a0eec7c50b7d2e39a48a231cb..49bbc71fad54efd709ba9b7e6a610b5f8a30a7a3 100644 (file)
 ACPI_INIT_GLOBAL(u8, acpi_gbl_enable_interpreter_slack, FALSE);
 
 /*
- * Automatically serialize ALL control methods? Default is FALSE, meaning
- * to use the Serialized/not_serialized method flags on a per method basis.
- * Only change this if the ASL code is poorly written and cannot handle
- * reentrancy even though methods are marked "NotSerialized".
+ * Automatically serialize all methods that create named objects? Default
+ * is TRUE, meaning that all non_serialized methods are scanned once at
+ * table load time to determine those that create named objects. Methods
+ * that create named objects are marked Serialized in order to prevent
+ * possible run-time problems if they are entered by more than one thread.
  */
-ACPI_INIT_GLOBAL(u8, acpi_gbl_all_methods_serialized, FALSE);
+ACPI_INIT_GLOBAL(u8, acpi_gbl_auto_serialize_methods, TRUE);
 
 /*
  * Create the predefined _OSI method in the namespace? Default is TRUE
index c54267748be5bae1f85d0f123919bce602a0df66..b01f71ce05230f58f0e884d38d59b8c222d3eb99 100644 (file)
@@ -458,10 +458,6 @@ void acpi_ex_enter_interpreter(void);
 
 void acpi_ex_exit_interpreter(void);
 
-void acpi_ex_reacquire_interpreter(void);
-
-void acpi_ex_relinquish_interpreter(void);
-
 u8 acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc);
 
 void acpi_ex_acquire_global_lock(u32 rule);
index 1a4d61805ebc64a83bc9242414536f7fecfb25cf..22fb6449d3d61f792ac4777f1f24139b905b08ae 100644 (file)
@@ -193,7 +193,8 @@ struct acpi_object_method {
 #define ACPI_METHOD_INTERNAL_ONLY       0x02   /* Method is implemented internally (_OSI) */
 #define ACPI_METHOD_SERIALIZED          0x04   /* Method is serialized */
 #define ACPI_METHOD_SERIALIZED_PENDING  0x08   /* Method is to be marked serialized */
-#define ACPI_METHOD_MODIFIED_NAMESPACE  0x10   /* Method modified the namespace */
+#define ACPI_METHOD_IGNORE_SYNC_LEVEL   0x10   /* Method was auto-serialized at table load time */
+#define ACPI_METHOD_MODIFIED_NAMESPACE  0x20   /* Method modified the namespace */
 
 /******************************************************************************
  *
index 5d2989a1b68c965a8649243b20837dd5104f74a5..cf7346110bd825e2cd1d514d6eed507b2e262421 100644 (file)
@@ -133,6 +133,9 @@ struct acpi_init_walk_info {
        u32 table_index;
        u32 object_count;
        u32 method_count;
+       u32 serial_method_count;
+       u32 non_serial_method_count;
+       u32 serialized_method_count;
        u32 device_count;
        u32 op_region_count;
        u32 field_count;
index 96644d5ac0e1fa3852cdcb28f934cdf259f92e4e..aee5e45f6d35ecd39eb751e0008baeb9f252cfcc 100644 (file)
@@ -83,8 +83,8 @@ acpi_ds_init_one_object(acpi_handle obj_handle,
            (struct acpi_init_walk_info *)context;
        struct acpi_namespace_node *node =
            (struct acpi_namespace_node *)obj_handle;
-       acpi_object_type type;
        acpi_status status;
+       union acpi_operand_object *obj_desc;
 
        ACPI_FUNCTION_ENTRY();
 
@@ -100,9 +100,7 @@ acpi_ds_init_one_object(acpi_handle obj_handle,
 
        /* And even then, we are only interested in a few object types */
 
-       type = acpi_ns_get_type(obj_handle);
-
-       switch (type) {
+       switch (acpi_ns_get_type(obj_handle)) {
        case ACPI_TYPE_REGION:
 
                status = acpi_ds_initialize_region(obj_handle);
@@ -117,8 +115,44 @@ acpi_ds_init_one_object(acpi_handle obj_handle,
                break;
 
        case ACPI_TYPE_METHOD:
-
+               /*
+                * Auto-serialization support. We will examine each method that is
+                * not_serialized to determine if it creates any Named objects. If
+                * it does, it will be marked serialized to prevent problems if
+                * the method is entered by two or more threads and an attempt is
+                * made to create the same named object twice -- which results in
+                * an AE_ALREADY_EXISTS exception and method abort.
+                */
                info->method_count++;
+               obj_desc = acpi_ns_get_attached_object(node);
+               if (!obj_desc) {
+                       break;
+               }
+
+               /* Ignore if already serialized */
+
+               if (obj_desc->method.info_flags & ACPI_METHOD_SERIALIZED) {
+                       info->serial_method_count++;
+                       break;
+               }
+
+               if (acpi_gbl_auto_serialize_methods) {
+
+                       /* Parse/scan method and serialize it if necessary */
+
+                       acpi_ds_auto_serialize_method(node, obj_desc);
+                       if (obj_desc->method.
+                           info_flags & ACPI_METHOD_SERIALIZED) {
+
+                               /* Method was just converted to Serialized */
+
+                               info->serial_method_count++;
+                               info->serialized_method_count++;
+                               break;
+                       }
+               }
+
+               info->non_serial_method_count++;
                break;
 
        case ACPI_TYPE_DEVICE:
@@ -170,7 +204,6 @@ acpi_ds_initialize_objects(u32 table_index,
 
        ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
                          "**** Starting initialization of namespace objects ****\n"));
-       ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "Parsing all Control Methods:"));
 
        /* Set all init info to zero */
 
@@ -205,14 +238,16 @@ acpi_ds_initialize_objects(u32 table_index,
        }
 
        ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
-                             "\nTable [%4.4s](id %4.4X) - %u Objects with %u Devices %u Methods %u Regions\n",
+                             "Table [%4.4s] (id %4.4X) - %4u Objects with %3u Devices, "
+                             "%3u Regions, %3u Methods (%u/%u/%u Serial/Non/Cvt)\n",
                              table->signature, owner_id, info.object_count,
-                             info.device_count, info.method_count,
-                             info.op_region_count));
+                             info.device_count, info.op_region_count,
+                             info.method_count, info.serial_method_count,
+                             info.non_serial_method_count,
+                             info.serialized_method_count));
 
-       ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
-                         "%u Methods, %u Regions\n", info.method_count,
-                         info.op_region_count));
+       ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "%u Methods, %u Regions\n",
+                         info.method_count, info.op_region_count));
 
        return_ACPI_STATUS(AE_OK);
 }
index 2c6d42c2bc01a4b7f10fcb1424479a6dbab8b667..3c7f7378b94d1692af3266e96902e587f2b8379b 100644 (file)
 #ifdef ACPI_DISASSEMBLER
 #include "acdisasm.h"
 #endif
+#include "acparser.h"
+#include "amlcode.h"
 
 #define _COMPONENT          ACPI_DISPATCHER
 ACPI_MODULE_NAME("dsmethod")
 
 /* Local prototypes */
+static acpi_status
+acpi_ds_detect_named_opcodes(struct acpi_walk_state *walk_state,
+                            union acpi_parse_object **out_op);
+
 static acpi_status
 acpi_ds_create_method_mutex(union acpi_operand_object *method_desc);
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_auto_serialize_method
+ *
+ * PARAMETERS:  node                        - Namespace Node of the method
+ *              obj_desc                    - Method object attached to node
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Parse a control method AML to scan for control methods that
+ *              need serialization due to the creation of named objects.
+ *
+ * NOTE: It is a bit of overkill to mark all such methods serialized, since
+ * there is only a problem if the method actually blocks during execution.
+ * A blocking operation is, for example, a Sleep() operation, or any access
+ * to an operation region. However, it is probably not possible to easily
+ * detect whether a method will block or not, so we simply mark all suspicious
+ * methods as serialized.
+ *
+ * NOTE2: This code is essentially a generic routine for parsing a single
+ * control method.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_auto_serialize_method(struct acpi_namespace_node *node,
+                             union acpi_operand_object *obj_desc)
+{
+       acpi_status status;
+       union acpi_parse_object *op = NULL;
+       struct acpi_walk_state *walk_state;
+
+       ACPI_FUNCTION_TRACE_PTR(ds_auto_serialize_method, node);
+
+       ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
+                         "Method auto-serialization parse [%4.4s] %p\n",
+                         acpi_ut_get_node_name(node), node));
+
+       /* Create/Init a root op for the method parse tree */
+
+       op = acpi_ps_alloc_op(AML_METHOD_OP);
+       if (!op) {
+               return_ACPI_STATUS(AE_NO_MEMORY);
+       }
+
+       acpi_ps_set_name(op, node->name.integer);
+       op->common.node = node;
+
+       /* Create and initialize a new walk state */
+
+       walk_state =
+           acpi_ds_create_walk_state(node->owner_id, NULL, NULL, NULL);
+       if (!walk_state) {
+               return_ACPI_STATUS(AE_NO_MEMORY);
+       }
+
+       status =
+           acpi_ds_init_aml_walk(walk_state, op, node,
+                                 obj_desc->method.aml_start,
+                                 obj_desc->method.aml_length, NULL, 0);
+       if (ACPI_FAILURE(status)) {
+               acpi_ds_delete_walk_state(walk_state);
+               return_ACPI_STATUS(status);
+       }
+
+       walk_state->descending_callback = acpi_ds_detect_named_opcodes;
+
+       /* Parse the method, scan for creation of named objects */
+
+       status = acpi_ps_parse_aml(walk_state);
+       if (ACPI_FAILURE(status)) {
+               return_ACPI_STATUS(status);
+       }
+
+       acpi_ps_delete_parse_tree(op);
+       return_ACPI_STATUS(status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_detect_named_opcodes
+ *
+ * PARAMETERS:  walk_state      - Current state of the parse tree walk
+ *              out_op          - Unused, required for parser interface
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Descending callback used during the loading of ACPI tables.
+ *              Currently used to detect methods that must be marked serialized
+ *              in order to avoid problems with the creation of named objects.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ds_detect_named_opcodes(struct acpi_walk_state *walk_state,
+                            union acpi_parse_object **out_op)
+{
+
+       ACPI_FUNCTION_NAME(acpi_ds_detect_named_opcodes);
+
+       /* We are only interested in opcodes that create a new name */
+
+       if (!
+           (walk_state->op_info->
+            flags & (AML_NAMED | AML_CREATE | AML_FIELD))) {
+               return (AE_OK);
+       }
+
+       /*
+        * At this point, we know we have a Named object opcode.
+        * Mark the method as serialized. Later code will create a mutex for
+        * this method to enforce serialization.
+        *
+        * Note, ACPI_METHOD_IGNORE_SYNC_LEVEL flag means that we will ignore the
+        * Sync Level mechanism for this method, even though it is now serialized.
+        * Otherwise, there can be conflicts with existing ASL code that actually
+        * uses sync levels.
+        */
+       walk_state->method_desc->method.sync_level = 0;
+       walk_state->method_desc->method.info_flags |=
+           (ACPI_METHOD_SERIALIZED | ACPI_METHOD_IGNORE_SYNC_LEVEL);
+
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+                         "Method serialized [%4.4s] %p - [%s] (%4.4X)\n",
+                         walk_state->method_node->name.ascii,
+                         walk_state->method_node, walk_state->op_info->name,
+                         walk_state->opcode));
+
+       /* Abort the parse, no need to examine this method any further */
+
+       return (AE_CTRL_TERMINATE);
+}
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ds_method_error
@@ -74,7 +213,7 @@ acpi_ds_create_method_mutex(union acpi_operand_object *method_desc);
  ******************************************************************************/
 
 acpi_status
-acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state)
+acpi_ds_method_error(acpi_status status, struct acpi_walk_state * walk_state)
 {
        ACPI_FUNCTION_ENTRY();
 
@@ -217,13 +356,19 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
                /*
                 * The current_sync_level (per-thread) must be less than or equal to
                 * the sync level of the method. This mechanism provides some
-                * deadlock prevention
+                * deadlock prevention.
+                *
+                * If the method was auto-serialized, we just ignore the sync level
+                * mechanism, because auto-serialization of methods can interfere
+                * with ASL code that actually uses sync levels.
                 *
                 * Top-level method invocation has no walk state at this point
                 */
                if (walk_state &&
-                   (walk_state->thread->current_sync_level >
-                    obj_desc->method.mutex->mutex.sync_level)) {
+                   (!(obj_desc->method.
+                      info_flags & ACPI_METHOD_IGNORE_SYNC_LEVEL))
+                   && (walk_state->thread->current_sync_level >
+                       obj_desc->method.mutex->mutex.sync_level)) {
                        ACPI_ERROR((AE_INFO,
                                    "Cannot acquire Mutex for method [%4.4s], current SyncLevel is too large (%u)",
                                    acpi_ut_get_node_name(method_node),
@@ -668,7 +813,8 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
                        method_desc->method.info_flags &=
                            ~ACPI_METHOD_SERIALIZED_PENDING;
                        method_desc->method.info_flags |=
-                           ACPI_METHOD_SERIALIZED;
+                           (ACPI_METHOD_SERIALIZED |
+                            ACPI_METHOD_IGNORE_SYNC_LEVEL);
                        method_desc->method.sync_level = 0;
                }
 
index bd7811c64169f8aa2c4be03fd61ef1d9bdffee6f..15623da26200cdf852c90f72aa22648b4535ba09 100644 (file)
@@ -73,8 +73,20 @@ acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number)
 {
 
        switch (pass_number) {
+       case 0:
+
+               /* Parse only - caller will setup callbacks */
+
+               walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
+                   ACPI_PARSE_DELETE_TREE | ACPI_PARSE_DISASSEMBLE;
+               walk_state->descending_callback = NULL;
+               walk_state->ascending_callback = NULL;
+               break;
+
        case 1:
 
+               /* Load pass 1 */
+
                walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
                    ACPI_PARSE_DELETE_TREE;
                walk_state->descending_callback = acpi_ds_load1_begin_op;
@@ -83,6 +95,8 @@ acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number)
 
        case 2:
 
+               /* Load pass 2 */
+
                walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
                    ACPI_PARSE_DELETE_TREE;
                walk_state->descending_callback = acpi_ds_load2_begin_op;
@@ -91,6 +105,8 @@ acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number)
 
        case 3:
 
+               /* Execution pass */
+
 #ifndef ACPI_NO_METHOD_EXECUTION
                walk_state->parse_flags |= ACPI_PARSE_EXECUTE |
                    ACPI_PARSE_DELETE_TREE;
index 841caed11c08a4d8a018c7562c6d40cfca6cdb47..f7da64123ed58b51cbb9679222dadedbb1dcd754 100644 (file)
@@ -77,7 +77,7 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
 
                /* We must wait, so unlock the interpreter */
 
-               acpi_ex_relinquish_interpreter();
+               acpi_ex_exit_interpreter();
 
                status = acpi_os_wait_semaphore(semaphore, 1, timeout);
 
@@ -87,7 +87,7 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
 
                /* Reacquire the interpreter */
 
-               acpi_ex_reacquire_interpreter();
+               acpi_ex_enter_interpreter();
        }
 
        return_ACPI_STATUS(status);
@@ -123,7 +123,7 @@ acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout)
 
                /* We must wait, so unlock the interpreter */
 
-               acpi_ex_relinquish_interpreter();
+               acpi_ex_exit_interpreter();
 
                status = acpi_os_acquire_mutex(mutex, timeout);
 
@@ -133,7 +133,7 @@ acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout)
 
                /* Reacquire the interpreter */
 
-               acpi_ex_reacquire_interpreter();
+               acpi_ex_enter_interpreter();
        }
 
        return_ACPI_STATUS(status);
@@ -198,7 +198,7 @@ acpi_status acpi_ex_system_do_sleep(u64 how_long)
 
        /* Since this thread will sleep, we must release the interpreter */
 
-       acpi_ex_relinquish_interpreter();
+       acpi_ex_exit_interpreter();
 
        /*
         * For compatibility with other ACPI implementations and to prevent
@@ -212,7 +212,7 @@ acpi_status acpi_ex_system_do_sleep(u64 how_long)
 
        /* And now we must get the interpreter again */
 
-       acpi_ex_reacquire_interpreter();
+       acpi_ex_enter_interpreter();
        return (AE_OK);
 }
 
index 5b16c5484bee2555b49c5cfdb54b2b0dceede93b..d9d72dff2a76aa6308592b43d7a8ca3a20a98014 100644 (file)
@@ -98,37 +98,6 @@ void acpi_ex_enter_interpreter(void)
        return_VOID;
 }
 
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ex_reacquire_interpreter
- *
- * PARAMETERS:  None
- *
- * RETURN:      None
- *
- * DESCRIPTION: Reacquire the interpreter execution region from within the
- *              interpreter code. Failure to enter the interpreter region is a
- *              fatal system error. Used in conjunction with
- *              relinquish_interpreter
- *
- ******************************************************************************/
-
-void acpi_ex_reacquire_interpreter(void)
-{
-       ACPI_FUNCTION_TRACE(ex_reacquire_interpreter);
-
-       /*
-        * If the global serialized flag is set, do not release the interpreter,
-        * since it was not actually released by acpi_ex_relinquish_interpreter.
-        * This forces the interpreter to be single threaded.
-        */
-       if (!acpi_gbl_all_methods_serialized) {
-               acpi_ex_enter_interpreter();
-       }
-
-       return_VOID;
-}
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ex_exit_interpreter
@@ -139,7 +108,16 @@ void acpi_ex_reacquire_interpreter(void)
  *
  * DESCRIPTION: Exit the interpreter execution region. This is the top level
  *              routine used to exit the interpreter when all processing has
- *              been completed.
+ *              been completed, or when the method blocks.
+ *
+ * Cases where the interpreter is unlocked internally:
+ *      1) Method will be blocked on a Sleep() AML opcode
+ *      2) Method will be blocked on an Acquire() AML opcode
+ *      3) Method will be blocked on a Wait() AML opcode
+ *      4) Method will be blocked to acquire the global lock
+ *      5) Method will be blocked waiting to execute a serialized control
+ *          method that is currently executing
+ *      6) About to invoke a user-installed opregion handler
  *
  ******************************************************************************/
 
@@ -158,44 +136,6 @@ void acpi_ex_exit_interpreter(void)
        return_VOID;
 }
 
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ex_relinquish_interpreter
- *
- * PARAMETERS:  None
- *
- * RETURN:      None
- *
- * DESCRIPTION: Exit the interpreter execution region, from within the
- *              interpreter - before attempting an operation that will possibly
- *              block the running thread.
- *
- * Cases where the interpreter is unlocked internally
- *      1) Method to be blocked on a Sleep() AML opcode
- *      2) Method to be blocked on an Acquire() AML opcode
- *      3) Method to be blocked on a Wait() AML opcode
- *      4) Method to be blocked to acquire the global lock
- *      5) Method to be blocked waiting to execute a serialized control method
- *          that is currently executing
- *      6) About to invoke a user-installed opregion handler
- *
- ******************************************************************************/
-
-void acpi_ex_relinquish_interpreter(void)
-{
-       ACPI_FUNCTION_TRACE(ex_relinquish_interpreter);
-
-       /*
-        * If the global serialized flag is set, do not release the interpreter.
-        * This forces the interpreter to be single threaded.
-        */
-       if (!acpi_gbl_all_methods_serialized) {
-               acpi_ex_exit_interpreter();
-       }
-
-       return_VOID;
-}
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ex_truncate_for32bit_table
index 5b74677bf74dddfb48d160f390b0aada33eea458..a3fb7e4c08092d05abe5162b85d3c1a6297b9c94 100644 (file)
@@ -111,9 +111,8 @@ acpi_status acpi_ns_initialize_objects(void)
                              info.object_count));
 
        ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
-                         "%u Control Methods found\n", info.method_count));
-       ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
-                         "%u Op Regions found\n", info.op_region_count));
+                         "%u Control Methods found\n%u Op Regions found\n",
+                         info.method_count, info.op_region_count));
 
        return_ACPI_STATUS(AE_OK);
 }
index 7ae521ce8d3f3c09d0f58f95cf4bf52a59d4c91f..7c9d0181f341ea5f762858dac80f5cadb28e24c8 100644 (file)
@@ -128,12 +128,12 @@ unlock:
         * parse trees.
         */
        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                         "**** Begin Table Method Parsing and Object Initialization\n"));
+                         "**** Begin Table Object Initialization\n"));
 
        status = acpi_ds_initialize_objects(table_index, node);
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                         "**** Completed Table Method Parsing and Object Initialization\n"));
+                         "**** Completed Table Object Initialization\n"));
 
        return_ACPI_STATUS(status);
 }
index 646d1a3f6e27b7e5695aaec30746ba4bd4c9aa53..b058e2390fdd6f3558f15e628273558fedd5acda 100644 (file)
@@ -480,6 +480,10 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
                                        status = AE_OK;
                                }
 
+                               if (status == AE_CTRL_TERMINATE) {
+                                       return_ACPI_STATUS(status);
+                               }
+
                                status =
                                    acpi_ps_complete_op(walk_state, &op,
                                                        status);
index af1f46cd37a5ad3620a165351eac2f061da104e0..a6885077d59ee7373c7ff8c6fcc1fb327a455eb3 100644 (file)
@@ -219,7 +219,10 @@ acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
 
        status = walk_state->descending_callback(walk_state, op);
        if (ACPI_FAILURE(status)) {
-               ACPI_EXCEPTION((AE_INFO, status, "During name lookup/catalog"));
+               if (status != AE_CTRL_TERMINATE) {
+                       ACPI_EXCEPTION((AE_INFO, status,
+                                       "During name lookup/catalog"));
+               }
                return_ACPI_STATUS(status);
        }
 
@@ -230,7 +233,7 @@ acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
        status = acpi_ps_next_parse_state(walk_state, *op, status);
        if (ACPI_FAILURE(status)) {
                if (status == AE_CTRL_PENDING) {
-                       return_ACPI_STATUS(AE_CTRL_PARSE_PENDING);
+                       status = AE_CTRL_PARSE_PENDING;
                }
                return_ACPI_STATUS(status);
        }
index 27f84af4e337df87540e3c4e1e84f358eef7cb3c..f7fd72ac69cf52839e6bd92a9f503fc8e7c66dad 100644 (file)
@@ -1537,17 +1537,21 @@ static int __init osi_setup(char *str)
 
 __setup("acpi_osi=", osi_setup);
 
-/* enable serialization to combat AE_ALREADY_EXISTS errors */
-static int __init acpi_serialize_setup(char *str)
+/*
+ * Disable the auto-serialization of named objects creation methods.
+ *
+ * This feature is enabled by default.  It marks the AML control methods
+ * that contain the opcodes to create named objects as "Serialized".
+ */
+static int __init acpi_no_auto_serialize_setup(char *str)
 {
-       printk(KERN_INFO PREFIX "serialize enabled\n");
-
-       acpi_gbl_all_methods_serialized = TRUE;
+       acpi_gbl_auto_serialize_methods = FALSE;
+       pr_info("ACPI: auto-serialization disabled\n");
 
        return 1;
 }
 
-__setup("acpi_serialize", acpi_serialize_setup);
+__setup("acpi_no_auto_serialize", acpi_no_auto_serialize_setup);
 
 /* Check of resource interference between native drivers and ACPI
  * OperationRegions (SystemIO and System Memory only).
index 86d73d5d503f7708f52444e6a10bb4da285e3036..71e2065639a6bcc74134a4447c803cbfac1c7841 100644 (file)
@@ -70,28 +70,6 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
        return 0;
 }
 
-static int map_gic_id(struct acpi_subtable_header *entry,
-               int device_declaration, u32 acpi_id, int *apic_id)
-{
-       struct acpi_madt_generic_interrupt *gic =
-               (struct acpi_madt_generic_interrupt *)entry;
-
-       if (!(gic->flags & ACPI_MADT_ENABLED))
-               return -ENODEV;
-
-       /*
-        * In the GIC interrupt model, logical processors are
-        * required to have a Processor Device object in the DSDT,
-        * so we should check device_declaration here
-        */
-       if (device_declaration && (gic->uid == acpi_id)) {
-               *apic_id = gic->gic_id;
-               return 0;
-       }
-
-       return -EINVAL;
-}
-
 static int map_madt_entry(int type, u32 acpi_id)
 {
        unsigned long madt_end, entry;
@@ -127,9 +105,6 @@ static int map_madt_entry(int type, u32 acpi_id)
                } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
                        if (!map_lsapic_id(header, type, acpi_id, &apic_id))
                                break;
-               } else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) {
-                       if (!map_gic_id(header, type, acpi_id, &apic_id))
-                               break;
                }
                entry += header->length;
        }
@@ -160,8 +135,6 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
                map_lapic_id(header, acpi_id, &apic_id);
        } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
                map_lsapic_id(header, type, acpi_id, &apic_id);
-       } else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) {
-               map_gic_id(header, type, acpi_id, &apic_id);
        }
 
 exit:
index a2e55bfdf572dae86b0b5e0c14c4f0fa5523b865..96a92db83cad863ac286ce2249b573bb7c1085a6 100644 (file)
@@ -285,7 +285,7 @@ int pm_generic_restore(struct device *dev)
 EXPORT_SYMBOL_GPL(pm_generic_restore);
 
 /**
- * pm_generic_complete - Generic routine competing a device power transition.
+ * pm_generic_complete - Generic routine completing a device power transition.
  * @dev: Device to handle.
  *
  * Complete a device power transition during a system-wide power transition.
index a05b876f375e5672c00b05412782c23ead83a773..bc447b9003c3f579a74c706c2083089dc2b00c74 100644 (file)
@@ -270,7 +270,7 @@ static int nforce2_target(struct cpufreq_policy *policy,
        pr_debug("Old CPU frequency %d kHz, new %d kHz\n",
               freqs.old, freqs.new);
 
-       cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
+       cpufreq_freq_transition_begin(policy, &freqs);
 
        /* Disable IRQs */
        /* local_irq_save(flags); */
@@ -285,7 +285,7 @@ static int nforce2_target(struct cpufreq_policy *policy,
        /* Enable IRQs */
        /* local_irq_restore(flags); */
 
-       cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
+       cpufreq_freq_transition_end(policy, &freqs, 0);
 
        return 0;
 }
index 3aa7a7a226b3f23f2977975651fc0fc2869ffd7b..abda6609d3e79f670c7143a01bbec53078e8bce1 100644 (file)
@@ -331,16 +331,15 @@ static void __cpufreq_notify_transition(struct cpufreq_policy *policy,
  * function. It is called twice on all CPU frequency changes that have
  * external effects.
  */
-void cpufreq_notify_transition(struct cpufreq_policy *policy,
+static void cpufreq_notify_transition(struct cpufreq_policy *policy,
                struct cpufreq_freqs *freqs, unsigned int state)
 {
        for_each_cpu(freqs->cpu, policy->cpus)
                __cpufreq_notify_transition(policy, freqs, state);
 }
-EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
 
 /* Do post notifications when there are chances that transition has failed */
-void cpufreq_notify_post_transition(struct cpufreq_policy *policy,
+static void cpufreq_notify_post_transition(struct cpufreq_policy *policy,
                struct cpufreq_freqs *freqs, int transition_failed)
 {
        cpufreq_notify_transition(policy, freqs, CPUFREQ_POSTCHANGE);
@@ -351,7 +350,41 @@ void cpufreq_notify_post_transition(struct cpufreq_policy *policy,
        cpufreq_notify_transition(policy, freqs, CPUFREQ_PRECHANGE);
        cpufreq_notify_transition(policy, freqs, CPUFREQ_POSTCHANGE);
 }
-EXPORT_SYMBOL_GPL(cpufreq_notify_post_transition);
+
+void cpufreq_freq_transition_begin(struct cpufreq_policy *policy,
+               struct cpufreq_freqs *freqs)
+{
+wait:
+       wait_event(policy->transition_wait, !policy->transition_ongoing);
+
+       spin_lock(&policy->transition_lock);
+
+       if (unlikely(policy->transition_ongoing)) {
+               spin_unlock(&policy->transition_lock);
+               goto wait;
+       }
+
+       policy->transition_ongoing = true;
+
+       spin_unlock(&policy->transition_lock);
+
+       cpufreq_notify_transition(policy, freqs, CPUFREQ_PRECHANGE);
+}
+EXPORT_SYMBOL_GPL(cpufreq_freq_transition_begin);
+
+void cpufreq_freq_transition_end(struct cpufreq_policy *policy,
+               struct cpufreq_freqs *freqs, int transition_failed)
+{
+       if (unlikely(WARN_ON(!policy->transition_ongoing)))
+               return;
+
+       cpufreq_notify_post_transition(policy, freqs, transition_failed);
+
+       policy->transition_ongoing = false;
+
+       wake_up(&policy->transition_wait);
+}
+EXPORT_SYMBOL_GPL(cpufreq_freq_transition_end);
 
 
 /*********************************************************************
@@ -985,6 +1018,8 @@ static struct cpufreq_policy *cpufreq_policy_alloc(void)
 
        INIT_LIST_HEAD(&policy->policy_list);
        init_rwsem(&policy->rwsem);
+       spin_lock_init(&policy->transition_lock);
+       init_waitqueue_head(&policy->transition_wait);
 
        return policy;
 
@@ -1470,8 +1505,8 @@ static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
        policy = per_cpu(cpufreq_cpu_data, cpu);
        read_unlock_irqrestore(&cpufreq_driver_lock, flags);
 
-       cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
-       cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
+       cpufreq_freq_transition_begin(policy, &freqs);
+       cpufreq_freq_transition_end(policy, &freqs, 0);
 }
 
 /**
@@ -1652,14 +1687,13 @@ void cpufreq_resume(void)
        cpufreq_suspended = false;
 
        list_for_each_entry(policy, &cpufreq_policy_list, policy_list) {
-               if (__cpufreq_governor(policy, CPUFREQ_GOV_START)
+               if (cpufreq_driver->resume && cpufreq_driver->resume(policy))
+                       pr_err("%s: Failed to resume driver: %p\n", __func__,
+                               policy);
+               else if (__cpufreq_governor(policy, CPUFREQ_GOV_START)
                    || __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))
                        pr_err("%s: Failed to start governor for policy: %p\n",
                                __func__, policy);
-               else if (cpufreq_driver->resume
-                   && cpufreq_driver->resume(policy))
-                       pr_err("%s: Failed to resume driver: %p\n", __func__,
-                               policy);
 
                /*
                 * schedule call cpufreq_update_policy() for boot CPU, i.e. last
@@ -1832,8 +1866,7 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
                        pr_debug("%s: cpu: %d, oldfreq: %u, new freq: %u\n",
                                 __func__, policy->cpu, freqs.old, freqs.new);
 
-                       cpufreq_notify_transition(policy, &freqs,
-                                       CPUFREQ_PRECHANGE);
+                       cpufreq_freq_transition_begin(policy, &freqs);
                }
 
                retval = cpufreq_driver->target_index(policy, index);
@@ -1842,7 +1875,7 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
                               __func__, retval);
 
                if (notify)
-                       cpufreq_notify_post_transition(policy, &freqs, retval);
+                       cpufreq_freq_transition_end(policy, &freqs, retval);
        }
 
 out:
index 7f776aa91e2ff431f972bbb3995fcee82b941c66..a6b8214d7b7712bb7d877d68d71e476e7bde26dc 100644 (file)
@@ -219,7 +219,7 @@ static int exynos_target(struct cpufreq_policy *policy, unsigned int index)
        freqs.old = policy->cur;
        freqs.new = freq_table[index].frequency;
 
-       cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
+       cpufreq_freq_transition_begin(policy, &freqs);
 
        /* Set the target frequency in all C0_3_PSTATE register */
        for_each_cpu(i, policy->cpus) {
@@ -258,7 +258,7 @@ static void exynos_cpufreq_work(struct work_struct *work)
                dev_crit(dvfs_info->dev, "New frequency out of range\n");
                freqs.new = freqs.old;
        }
-       cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
+       cpufreq_freq_transition_end(policy, &freqs, 0);
 
        cpufreq_cpu_put(policy);
        mutex_unlock(&cpufreq_lock);
index d83e8266a58e2eddf824696c80240ced024bab57..1d723dc8880c58605a1e0b407a9e5e38bbb61308 100644 (file)
@@ -265,7 +265,7 @@ static void gx_set_cpuspeed(struct cpufreq_policy *policy, unsigned int khz)
 
        freqs.new = new_khz;
 
-       cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
+       cpufreq_freq_transition_begin(policy, &freqs);
        local_irq_save(flags);
 
        if (new_khz != stock_freq) {
@@ -314,7 +314,7 @@ static void gx_set_cpuspeed(struct cpufreq_policy *policy, unsigned int khz)
 
        gx_params->pci_suscfg = suscfg;
 
-       cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
+       cpufreq_freq_transition_end(policy, &freqs, 0);
 
        pr_debug("suspend modulation w/ duration of ON:%d us, OFF:%d us\n",
                gx_params->on_duration * 32, gx_params->off_duration * 32);
index 0e27844e8c2d91742679580b8596e45d0cfdb6a9..e5122f1bfe78ca8f9d37881053b85cd02b94c881 100644 (file)
@@ -122,7 +122,7 @@ static int integrator_set_target(struct cpufreq_policy *policy,
                return 0;
        }
 
-       cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
+       cpufreq_freq_transition_begin(policy, &freqs);
 
        cm_osc = __raw_readl(cm_base + INTEGRATOR_HDR_OSC_OFFSET);
 
@@ -143,7 +143,7 @@ static int integrator_set_target(struct cpufreq_policy *policy,
         */
        set_cpus_allowed(current, cpus_allowed);
 
-       cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
+       cpufreq_freq_transition_end(policy, &freqs, 0);
 
        return 0;
 }
index bcb9a6d0ae115fbb50ae369296f142a981fa0ceb..099967302bf25939019875846f7819461a4805c2 100644 (file)
@@ -778,7 +778,7 @@ static void intel_pstate_stop_cpu(struct cpufreq_policy *policy)
 
        pr_info("intel_pstate CPU %d exiting\n", cpu_num);
 
-       del_timer(&all_cpu_data[cpu_num]->timer);
+       del_timer_sync(&all_cpu_data[cpu_num]->timer);
        intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate);
        kfree(all_cpu_data[cpu_num]);
        all_cpu_data[cpu_num] = NULL;
index 7b94da3d2d1012e3075f73eb5dcb49523841a985..5c440f87ba8a5973a0cd3e0e8a234415523d45b9 100644 (file)
@@ -269,7 +269,7 @@ static void longhaul_setstate(struct cpufreq_policy *policy,
        freqs.old = calc_speed(longhaul_get_cpu_mult());
        freqs.new = speed;
 
-       cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
+       cpufreq_freq_transition_begin(policy, &freqs);
 
        pr_debug("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n",
                        fsb, mult/10, mult%10, print_speed(speed/1000));
@@ -386,7 +386,7 @@ retry_loop:
                }
        }
        /* Report true CPU frequency */
-       cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
+       cpufreq_freq_transition_end(policy, &freqs, 0);
 
        if (!bm_timeout)
                printk(KERN_INFO PFX "Warning: Timeout while waiting for "
index 1c0f1067af73318387d3d3e133e3d67a990eac61..728a2d8794993defdbe1e10c15fe7ee814c528bb 100644 (file)
@@ -215,7 +215,7 @@ static int pcc_cpufreq_target(struct cpufreq_policy *policy,
 
        freqs.old = policy->cur;
        freqs.new = target_freq;
-       cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
+       cpufreq_freq_transition_begin(policy, &freqs);
 
        input_buffer = 0x1 | (((target_freq * 100)
                               / (ioread32(&pcch_hdr->nominal) * 1000)) << 8);
@@ -231,7 +231,7 @@ static int pcc_cpufreq_target(struct cpufreq_policy *policy,
        status = ioread16(&pcch_hdr->status);
        iowrite16(0, &pcch_hdr->status);
 
-       cpufreq_notify_post_transition(policy, &freqs, status != CMD_COMPLETE);
+       cpufreq_freq_transition_end(policy, &freqs, status != CMD_COMPLETE);
        spin_unlock(&pcc_lock);
 
        if (status != CMD_COMPLETE) {
index ce27e6c26c94de3de132407b168acb1c06ac7782..62c6f2e5afced391ee7260e6ab6065c73954fa58 100644 (file)
@@ -148,11 +148,11 @@ static int powernow_k6_target(struct cpufreq_policy *policy,
        freqs.old = busfreq * powernow_k6_get_cpu_multiplier();
        freqs.new = busfreq * clock_ratio[best_i].driver_data;
 
-       cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
+       cpufreq_freq_transition_begin(policy, &freqs);
 
        powernow_k6_set_cpu_multiplier(best_i);
 
-       cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
+       cpufreq_freq_transition_end(policy, &freqs, 0);
 
        return 0;
 }
index 0e68e027562135fd34214d440abeaab4dc2405ed..f911645c3f6db59e18f32b68c06bfc890283c029 100644 (file)
@@ -269,7 +269,7 @@ static int powernow_target(struct cpufreq_policy *policy, unsigned int index)
 
        freqs.new = powernow_table[index].frequency;
 
-       cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
+       cpufreq_freq_transition_begin(policy, &freqs);
 
        /* Now do the magic poking into the MSRs.  */
 
@@ -290,7 +290,7 @@ static int powernow_target(struct cpufreq_policy *policy, unsigned int index)
        if (have_a0 == 1)
                local_irq_enable();
 
-       cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
+       cpufreq_freq_transition_end(policy, &freqs, 0);
 
        return 0;
 }
index 27eb2be44de56cbae978069c5251fd74c2b76afb..770a9e1b3468f3f13b1b67a8ed81934bf4a1f139 100644 (file)
@@ -963,9 +963,9 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data,
        policy = cpufreq_cpu_get(smp_processor_id());
        cpufreq_cpu_put(policy);
 
-       cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
+       cpufreq_freq_transition_begin(policy, &freqs);
        res = transition_fid_vid(data, fid, vid);
-       cpufreq_notify_post_transition(policy, &freqs, res);
+       cpufreq_freq_transition_end(policy, &freqs, res);
 
        return res;
 }
index 25069741b507588a1ee7139d0568d2fe09fb0d0d..a3dc192d21f98c6e3b1bb22713426f8de1c40658 100644 (file)
@@ -217,7 +217,7 @@ static int s3c_cpufreq_settarget(struct cpufreq_policy *policy,
        s3c_cpufreq_updateclk(clk_pclk, cpu_new.freq.pclk);
 
        /* start the frequency change */
-       cpufreq_notify_transition(policy, &freqs.freqs, CPUFREQ_PRECHANGE);
+       cpufreq_freq_transition_begin(policy, &freqs.freqs);
 
        /* If hclk is staying the same, then we do not need to
         * re-write the IO or the refresh timings whilst we are changing
@@ -261,7 +261,7 @@ static int s3c_cpufreq_settarget(struct cpufreq_policy *policy,
        local_irq_restore(flags);
 
        /* notify everyone we've done this */
-       cpufreq_notify_transition(policy, &freqs.freqs, CPUFREQ_POSTCHANGE);
+       cpufreq_freq_transition_end(policy, &freqs.freqs, 0);
 
        s3c_freq_dbg("%s: finished\n", __func__);
        return 0;
index 696170ebd3a3efb8a92f1946215e863d58ce7e9a..86628e22b2a36827d37f35d552f0624bc9dc387c 100644 (file)
@@ -68,10 +68,10 @@ static int sh_cpufreq_target(struct cpufreq_policy *policy,
        freqs.new       = (freq + 500) / 1000;
        freqs.flags     = 0;
 
-       cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
+       cpufreq_freq_transition_begin(policy, &freqs);
        set_cpus_allowed_ptr(current, &cpus_allowed);
        clk_set_rate(cpuclk, freq);
-       cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
+       cpufreq_freq_transition_end(policy, &freqs, 0);
 
        dev_dbg(dev, "set frequency %lu Hz\n", freq);
 
index 36cc330b8747c70b3430175c6fec28891526688c..13be802b6170e1a8aefb457e28745ff6318ef125 100644 (file)
@@ -44,9 +44,9 @@ static int ucv2_target(struct cpufreq_policy *policy,
        freqs.old = policy->cur;
        freqs.new = target_freq;
 
-       cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
+       cpufreq_freq_transition_begin(policy, &freqs);
        ret = clk_set_rate(policy->mclk, target_freq * 1000);
-       cpufreq_notify_post_transition(policy, &freqs, ret);
+       cpufreq_freq_transition_end(policy, &freqs, ret);
 
        return ret;
 }
index bacddd102ae9558bee539cf70d1fe6f4e5503ee4..01712cbfd92e4b64d2f36a5f6410f4fbe730c8c7 100644 (file)
@@ -385,7 +385,7 @@ int pnp_check_irq(struct pnp_dev *dev, struct resource *res)
         * device is active because it itself may be in use */
        if (!dev->active) {
                if (request_irq(*irq, pnp_test_handler,
-                               IRQF_DISABLED | IRQF_PROBE_SHARED, "pnp", NULL))
+                               IRQF_PROBE_SHARED, "pnp", NULL))
                        return 0;
                free_irq(*irq, NULL);
        }
index b0b01b13ea990655c490d7e2c81db4336e486bce..44f5e97496015092e07314c56c5f8933a2aac8da 100644 (file)
@@ -71,7 +71,7 @@ extern u32 acpi_dbg_layer;
 
 /* ACPICA runtime options */
 
-extern u8 acpi_gbl_all_methods_serialized;
+extern u8 acpi_gbl_auto_serialize_methods;
 extern u8 acpi_gbl_copy_dsdt_locally;
 extern u8 acpi_gbl_create_osi_method;
 extern u8 acpi_gbl_disable_auto_repair;
index 2d2e62c8666ad71962315ac4f7041029474a5fec..c48e595f623e682cea2b8a8e5d83cd30f5275ad0 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/completion.h>
 #include <linux/kobject.h>
 #include <linux/notifier.h>
+#include <linux/spinlock.h>
 #include <linux/sysfs.h>
 
 /*********************************************************************
@@ -104,6 +105,11 @@ struct cpufreq_policy {
         *     __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT);
         */
        struct rw_semaphore     rwsem;
+
+       /* Synchronization for frequency transitions */
+       bool                    transition_ongoing; /* Tracks transition status */
+       spinlock_t              transition_lock;
+       wait_queue_head_t       transition_wait;
 };
 
 /* Only for ACPI */
@@ -333,9 +339,9 @@ static inline void cpufreq_resume(void) {}
 int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list);
 int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list);
 
-void cpufreq_notify_transition(struct cpufreq_policy *policy,
-               struct cpufreq_freqs *freqs, unsigned int state);
-void cpufreq_notify_post_transition(struct cpufreq_policy *policy,
+void cpufreq_freq_transition_begin(struct cpufreq_policy *policy,
+               struct cpufreq_freqs *freqs);
+void cpufreq_freq_transition_end(struct cpufreq_policy *policy,
                struct cpufreq_freqs *freqs, int transition_failed);
 
 #else /* CONFIG_CPU_FREQ */