ARM: cpu topology: Add debugfs interface for cpu_power
[cmplus.git] / drivers / usb / otg / otg_id.c
blob8037edbf3141217f444d5be314341d22d8d7e166
1 /*
2 * Copyright (C) 2011 Google, Inc.
4 * Author:
5 * Colin Cross <ccross@android.com>
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
18 #include <linux/kernel.h>
19 #include <linux/mutex.h>
20 #include <linux/notifier.h>
21 #include <linux/usb/otg_id.h>
23 static DEFINE_MUTEX(otg_id_lock);
24 static struct plist_head otg_id_plist =
25 PLIST_HEAD_INIT(otg_id_plist);
26 static struct otg_id_notifier_block *otg_id_active;
27 static bool otg_id_cancelling;
28 static bool otg_id_inited;
29 static int otg_id_suspended;
30 static bool otg_id_pending;
32 static void otg_id_cancel(void)
34 if (otg_id_active) {
35 otg_id_cancelling = true;
36 mutex_unlock(&otg_id_lock);
38 otg_id_active->cancel(otg_id_active);
40 mutex_lock(&otg_id_lock);
41 otg_id_cancelling = false;
45 static void __otg_id_notify(void)
47 int ret;
48 struct otg_id_notifier_block *otg_id_nb;
49 bool proxy_wait = false;
50 if (plist_head_empty(&otg_id_plist))
51 return;
53 plist_for_each_entry(otg_id_nb, &otg_id_plist, p) {
54 if (proxy_wait) {
55 if (otg_id_nb->proxy_wait)
56 ret = otg_id_nb->proxy_wait(otg_id_nb);
57 } else {
58 ret = otg_id_nb->detect(otg_id_nb);
60 if (ret == OTG_ID_HANDLED) {
61 otg_id_active = otg_id_nb;
62 return;
64 if (ret == OTG_ID_PROXY_WAIT)
65 proxy_wait = true;
69 WARN(1, "otg id event not handled");
70 otg_id_active = NULL;
73 int otg_id_init(void)
75 mutex_lock(&otg_id_lock);
77 otg_id_inited = true;
78 __otg_id_notify();
80 mutex_unlock(&otg_id_lock);
81 return 0;
83 late_initcall(otg_id_init);
85 /**
86 * otg_id_register_notifier
87 * @otg_id_nb: notifier block containing priority and callback function
89 * Register a notifier that will be called on any USB cable state change.
90 * The priority determines the order the callback will be called in, a higher
91 * number will be called first. A callback function needs to determine the
92 * type of USB cable that is connected. If it can determine the type, it
93 * should notify the appropriate drivers (for example, call an otg notifier
94 * with USB_EVENT_VBUS), and return OTG_ID_HANDLED. Once a callback has
95 * returned OTG_ID_HANDLED, it is responsible for calling otg_id_notify() when
96 * the detected USB cable is disconnected.
98 int otg_id_register_notifier(struct otg_id_notifier_block *otg_id_nb)
100 plist_node_init(&otg_id_nb->p, otg_id_nb->priority);
102 mutex_lock(&otg_id_lock);
103 plist_add(&otg_id_nb->p, &otg_id_plist);
105 if (otg_id_inited) {
106 otg_id_cancel();
107 __otg_id_notify();
110 mutex_unlock(&otg_id_lock);
112 return 0;
115 void otg_id_unregister_notifier(struct otg_id_notifier_block *otg_id_nb)
117 mutex_lock(&otg_id_lock);
119 plist_del(&otg_id_nb->p, &otg_id_plist);
121 if (otg_id_inited && (otg_id_active == otg_id_nb)) {
122 otg_id_cancel();
123 __otg_id_notify();
126 mutex_unlock(&otg_id_lock);
130 * otg_id_notify
132 * Notify listeners on any USB cable state change.
134 * A driver may only call otg_id_notify if it returned OTG_ID_HANDLED the last
135 * time it's notifier was called, and it's cancel function has not been called.
137 void otg_id_notify(void)
139 mutex_lock(&otg_id_lock);
141 if (otg_id_cancelling)
142 goto out;
144 if (otg_id_suspended != 0) {
145 otg_id_pending = true;
146 goto out;
149 __otg_id_notify();
150 out:
151 mutex_unlock(&otg_id_lock);
155 * otg_id_suspend
157 * Mark the otg_id subsystem as going into suspend. From here on out,
158 * any notifications will be deferred until the last otg_id client resumes.
159 * If there is a pending notification when calling this function, it will
160 * return a negative errno and expects that the caller will abort suspend.
161 * Returs 0 on success.
163 int otg_id_suspend(void)
165 int ret = 0;
167 mutex_lock(&otg_id_lock);
170 * if there's a pending notification, tell the caller to abort suspend
172 if (otg_id_suspended != 0 && otg_id_pending) {
173 pr_info("otg_id: pending notification, should abort suspend\n");
174 ret = -EBUSY;
175 goto out;
178 otg_id_suspended++;
179 out:
180 mutex_unlock(&otg_id_lock);
181 return ret;
185 * otg_id_resume
187 * Inform the otg_id subsystem that a client is resuming. If this is the
188 * last client to be resumed and there's a pending notification,
189 * otg_id_notify() is called.
191 void otg_id_resume(void)
193 mutex_lock(&otg_id_lock);
194 if (WARN(!otg_id_suspended, "unbalanced otg_id_resume\n"))
195 goto out;
196 if (--otg_id_suspended == 0) {
197 if (otg_id_pending) {
198 pr_info("otg_id: had pending notification\n");
199 otg_id_pending = false;
200 __otg_id_notify();
203 out:
204 mutex_unlock(&otg_id_lock);