2 * Copyright (c) 2014, Linaro Limited
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 #include <linux/slab.h>
14 #include "tee_mutex_wait.h"
16 struct tee_mutex_wait {
17 struct list_head link;
18 struct completion comp;
25 * Compares two serial numbers using Serial Number Arithmetic
26 * (https://www.ietf.org/rfc/rfc1982.txt).
28 #define TICK_GT(t1, t2) \
29 (((t1) < (t2) && (t2) - (t1) > 0xFFFFFFFFu) || \
30 ((t1) > (t2) && (t1) - (t2) < 0xFFFFFFFFu))
32 static struct tee_mutex_wait *tee_mutex_wait_get(struct device *dev,
33 struct tee_mutex_wait_private *priv, u32 key)
35 struct tee_mutex_wait *w;
37 mutex_lock(&priv->mu);
39 list_for_each_entry(w, &priv->db, link)
43 w = kmalloc(sizeof(struct tee_mutex_wait), GFP_KERNEL);
45 dev_err(dev, "kmalloc <struct tee_mutex_wait> failed\n");
49 init_completion(&w->comp);
53 list_add_tail(&w->link, &priv->db);
55 mutex_unlock(&priv->mu);
59 static void tee_mutex_wait_delete_entry(struct tee_mutex_wait *w)
62 mutex_destroy(&w->mu);
66 void tee_mutex_wait_delete(struct device *dev,
67 struct tee_mutex_wait_private *priv,
70 struct tee_mutex_wait *w;
72 mutex_lock(&priv->mu);
74 list_for_each_entry(w, &priv->db, link) {
76 tee_mutex_wait_delete_entry(w);
81 mutex_unlock(&priv->mu);
83 EXPORT_SYMBOL(tee_mutex_wait_delete);
85 void tee_mutex_wait_wakeup(struct device *dev,
86 struct tee_mutex_wait_private *priv,
87 u32 key, u32 wait_after)
89 struct tee_mutex_wait *w = tee_mutex_wait_get(dev, priv, key);
95 w->wait_after = wait_after;
99 EXPORT_SYMBOL(tee_mutex_wait_wakeup);
101 void tee_mutex_wait_sleep(struct device *dev,
102 struct tee_mutex_wait_private *priv,
103 u32 key, u32 wait_tick)
105 struct tee_mutex_wait *w = tee_mutex_wait_get(dev, priv, key);
112 wait_after = w->wait_after;
113 mutex_unlock(&w->mu);
115 if (TICK_GT(wait_tick, wait_after))
116 wait_for_completion_timeout(&w->comp, HZ);
118 EXPORT_SYMBOL(tee_mutex_wait_sleep);
120 int tee_mutex_wait_init(struct tee_mutex_wait_private *priv)
122 mutex_init(&priv->mu);
123 INIT_LIST_HEAD(&priv->db);
126 EXPORT_SYMBOL(tee_mutex_wait_init);
128 void tee_mutex_wait_exit(struct tee_mutex_wait_private *priv)
131 * It's the callers responibility to ensure that no one is using
132 * anything inside priv.
135 mutex_destroy(&priv->mu);
136 while (!list_empty(&priv->db)) {
137 struct tee_mutex_wait *w =
138 list_first_entry(&priv->db,
139 struct tee_mutex_wait,
141 tee_mutex_wait_delete_entry(w);
144 EXPORT_SYMBOL(tee_mutex_wait_exit);