]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/acpi/device_pm.c
ACPI / PM: Move routines for adding/removing device wakeup notifiers
[karo-tx-linux.git] / drivers / acpi / device_pm.c
1 /*
2  * drivers/acpi/device_pm.c - ACPI device power management routines.
3  *
4  * Copyright (C) 2012, Intel Corp.
5  * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
6  *
7  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License version 2 as published
11  *  by the Free Software Foundation.
12  *
13  *  This program is distributed in the hope that it will be useful, but
14  *  WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *  General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License along
19  *  with this program; if not, write to the Free Software Foundation, Inc.,
20  *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21  *
22  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23  */
24
25 #include <linux/device.h>
26 #include <linux/mutex.h>
27
28 #include <acpi/acpi.h>
29 #include <acpi/acpi_bus.h>
30
31 static DEFINE_MUTEX(acpi_pm_notifier_lock);
32
33 /**
34  * acpi_add_pm_notifier - Register PM notifier for given ACPI device.
35  * @adev: ACPI device to add the notifier for.
36  * @context: Context information to pass to the notifier routine.
37  *
38  * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of
39  * PM wakeup events.  For example, wakeup events may be generated for bridges
40  * if one of the devices below the bridge is signaling wakeup, even if the
41  * bridge itself doesn't have a wakeup GPE associated with it.
42  */
43 acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
44                                  acpi_notify_handler handler, void *context)
45 {
46         acpi_status status = AE_ALREADY_EXISTS;
47
48         mutex_lock(&acpi_pm_notifier_lock);
49
50         if (adev->wakeup.flags.notifier_present)
51                 goto out;
52
53         status = acpi_install_notify_handler(adev->handle,
54                                              ACPI_SYSTEM_NOTIFY,
55                                              handler, context);
56         if (ACPI_FAILURE(status))
57                 goto out;
58
59         adev->wakeup.flags.notifier_present = true;
60
61  out:
62         mutex_unlock(&acpi_pm_notifier_lock);
63         return status;
64 }
65
66 /**
67  * acpi_remove_pm_notifier - Unregister PM notifier from given ACPI device.
68  * @adev: ACPI device to remove the notifier from.
69  */
70 acpi_status acpi_remove_pm_notifier(struct acpi_device *adev,
71                                     acpi_notify_handler handler)
72 {
73         acpi_status status = AE_BAD_PARAMETER;
74
75         mutex_lock(&acpi_pm_notifier_lock);
76
77         if (!adev->wakeup.flags.notifier_present)
78                 goto out;
79
80         status = acpi_remove_notify_handler(adev->handle,
81                                             ACPI_SYSTEM_NOTIFY,
82                                             handler);
83         if (ACPI_FAILURE(status))
84                 goto out;
85
86         adev->wakeup.flags.notifier_present = false;
87
88  out:
89         mutex_unlock(&acpi_pm_notifier_lock);
90         return status;
91 }