===================================================================
@@ -426,6 +426,8 @@ struct acpi_gpe_event_info {
struct acpi_gpe_register_info *register_info; /* Backpointer to register info */
u8 flags; /* Misc info about this GPE */
u8 gpe_number; /* This GPE */
+ u8 runtime_count;
+ u8 wakeup_count;
};
/* Information about a GPE register pair, one per each status/enable pair in an array */
===================================================================
@@ -201,6 +201,103 @@ ACPI_EXPORT_SYMBOL(acpi_enable_event)
/*******************************************************************************
*
+ * FUNCTION: acpi_get_gpe
+ *
+ * PARAMETERS: gpe_device - Parent GPE Device
+ * gpe_number - GPE level within the GPE block
+ * type - Purpose the GPE will be used for
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Take a reference to a GPE and enable it if necessary
+ *
+ ******************************************************************************/
+acpi_status acpi_get_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type)
+{
+ acpi_status status = AE_OK;
+ acpi_cpu_flags flags;
+ struct acpi_gpe_event_info *gpe_event_info;
+
+ ACPI_FUNCTION_TRACE(acpi_ref_runtime_gpe);
+
+ flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
+
+ /* Ensure that we have a valid GPE number */
+ gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
+ if (!gpe_event_info) {
+ status = AE_BAD_PARAMETER;
+ goto unlock_and_exit;
+ }
+
+ if (type & ACPI_GPE_TYPE_RUNTIME) {
+ if (++gpe_event_info->runtime_count == 1)
+ status = acpi_ev_enable_gpe(gpe_event_info, TRUE);
+
+ if (ACPI_FAILURE(status))
+ gpe_event_info->runtime_count--;
+ }
+
+ if (type & ACPI_GPE_TYPE_WAKE) {
+ if (++gpe_event_info->wakeup_count == 1)
+ acpi_ev_update_gpe_enable_masks(gpe_event_info,
+ ACPI_GPE_ENABLE);
+ }
+
+unlock_and_exit:
+ acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
+ return_ACPI_STATUS(status);
+}
+ACPI_EXPORT_SYMBOL(acpi_get_gpe)
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_put_gpe
+ *
+ * PARAMETERS: gpe_device - Parent GPE Device
+ * gpe_number - GPE level within the GPE block
+ * type - Purpose the GPE won't be used for any more
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Release a reference to a GPE and disable it if necessary
+ *
+ ******************************************************************************/
+acpi_status acpi_put_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type)
+{
+ acpi_status status = AE_OK;
+ acpi_cpu_flags flags;
+ struct acpi_gpe_event_info *gpe_event_info;
+
+ ACPI_FUNCTION_TRACE(acpi_unref_runtime_gpe);
+
+ flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
+
+ /* Ensure that we have a valid GPE number */
+ gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
+ if (!gpe_event_info) {
+ status = AE_BAD_PARAMETER;
+ goto unlock_and_exit;
+ }
+
+ if ((type & ACPI_GPE_TYPE_WAKE) && gpe_event_info->runtime_count) {
+ if (--gpe_event_info->runtime_count == 0)
+ acpi_ev_disable_gpe(gpe_event_info);
+ }
+
+ if ((type & ACPI_GPE_TYPE_RUNTIME) && gpe_event_info->wakeup_count) {
+ if (--gpe_event_info->wakeup_count == 0)
+ acpi_ev_update_gpe_enable_masks(gpe_event_info,
+ ACPI_GPE_DISABLE);
+ }
+
+unlock_and_exit:
+ acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
+ return_ACPI_STATUS(status);
+}
+ACPI_EXPORT_SYMBOL(acpi_put_gpe)
+
+/*******************************************************************************
+ *
* FUNCTION: acpi_set_gpe_type
*
* PARAMETERS: gpe_device - Parent GPE Device
===================================================================
@@ -283,6 +283,10 @@ acpi_status acpi_get_event_status(u32 ev
*/
acpi_status acpi_set_gpe_type(acpi_handle gpe_device, u32 gpe_number, u8 type);
+acpi_status acpi_get_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type);
+
+acpi_status acpi_put_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type);
+
acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number);
acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number);