xref: /openbmc/linux/drivers/hwspinlock/hwspinlock_core.c (revision a0ae2562c6c4b2721d9fddba63b7286c13517d9f)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Hardware spinlock framework
4  *
5  * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com
6  *
7  * Contact: Ohad Ben-Cohen <ohad@wizery.com>
8  */
9 
10 #define pr_fmt(fmt)    "%s: " fmt, __func__
11 
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/spinlock.h>
15 #include <linux/types.h>
16 #include <linux/err.h>
17 #include <linux/jiffies.h>
18 #include <linux/radix-tree.h>
19 #include <linux/hwspinlock.h>
20 #include <linux/pm_runtime.h>
21 #include <linux/mutex.h>
22 #include <linux/of.h>
23 
24 #include "hwspinlock_internal.h"
25 
26 /* radix tree tags */
27 #define HWSPINLOCK_UNUSED	(0) /* tags an hwspinlock as unused */
28 
29 /*
30  * A radix tree is used to maintain the available hwspinlock instances.
31  * The tree associates hwspinlock pointers with their integer key id,
32  * and provides easy-to-use API which makes the hwspinlock core code simple
33  * and easy to read.
34  *
35  * Radix trees are quick on lookups, and reasonably efficient in terms of
36  * storage, especially with high density usages such as this framework
37  * requires (a continuous range of integer keys, beginning with zero, is
38  * used as the ID's of the hwspinlock instances).
39  *
40  * The radix tree API supports tagging items in the tree, which this
41  * framework uses to mark unused hwspinlock instances (see the
42  * HWSPINLOCK_UNUSED tag above). As a result, the process of querying the
43  * tree, looking for an unused hwspinlock instance, is now reduced to a
44  * single radix tree API call.
45  */
46 static RADIX_TREE(hwspinlock_tree, GFP_KERNEL);
47 
48 /*
49  * Synchronization of access to the tree is achieved using this mutex,
50  * as the radix-tree API requires that users provide all synchronisation.
51  * A mutex is needed because we're using non-atomic radix tree allocations.
52  */
53 static DEFINE_MUTEX(hwspinlock_tree_lock);
54 
55 
56 /**
57  * __hwspin_trylock() - attempt to lock a specific hwspinlock
58  * @hwlock: an hwspinlock which we want to trylock
59  * @mode: controls whether local interrupts are disabled or not
60  * @flags: a pointer where the caller's interrupt state will be saved at (if
61  *         requested)
62  *
63  * This function attempts to lock an hwspinlock, and will immediately
64  * fail if the hwspinlock is already taken.
65  *
66  * Caution: If the mode is HWLOCK_RAW, that means user must protect the routine
67  * of getting hardware lock with mutex or spinlock. Since in some scenarios,
68  * user need some time-consuming or sleepable operations under the hardware
69  * lock, they need one sleepable lock (like mutex) to protect the operations.
70  *
71  * If the mode is not HWLOCK_RAW, upon a successful return from this function,
72  * preemption (and possibly interrupts) is disabled, so the caller must not
73  * sleep, and is advised to release the hwspinlock as soon as possible. This is
74  * required in order to minimize remote cores polling on the hardware
75  * interconnect.
76  *
77  * The user decides whether local interrupts are disabled or not, and if yes,
78  * whether he wants their previous state to be saved. It is up to the user
79  * to choose the appropriate @mode of operation, exactly the same way users
80  * should decide between spin_trylock, spin_trylock_irq and
81  * spin_trylock_irqsave.
82  *
83  * Returns 0 if we successfully locked the hwspinlock or -EBUSY if
84  * the hwspinlock was already taken.
85  * This function will never sleep.
86  */
87 int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
88 {
89 	int ret;
90 
91 	BUG_ON(!hwlock);
92 	BUG_ON(!flags && mode == HWLOCK_IRQSTATE);
93 
94 	/*
95 	 * This spin_lock{_irq, _irqsave} serves three purposes:
96 	 *
97 	 * 1. Disable preemption, in order to minimize the period of time
98 	 *    in which the hwspinlock is taken. This is important in order
99 	 *    to minimize the possible polling on the hardware interconnect
100 	 *    by a remote user of this lock.
101 	 * 2. Make the hwspinlock SMP-safe (so we can take it from
102 	 *    additional contexts on the local host).
103 	 * 3. Ensure that in_atomic/might_sleep checks catch potential
104 	 *    problems with hwspinlock usage (e.g. scheduler checks like
105 	 *    'scheduling while atomic' etc.)
106 	 */
107 	switch (mode) {
108 	case HWLOCK_IRQSTATE:
109 		ret = spin_trylock_irqsave(&hwlock->lock, *flags);
110 		break;
111 	case HWLOCK_IRQ:
112 		ret = spin_trylock_irq(&hwlock->lock);
113 		break;
114 	case HWLOCK_RAW:
115 		ret = 1;
116 		break;
117 	default:
118 		ret = spin_trylock(&hwlock->lock);
119 		break;
120 	}
121 
122 	/* is lock already taken by another context on the local cpu ? */
123 	if (!ret)
124 		return -EBUSY;
125 
126 	/* try to take the hwspinlock device */
127 	ret = hwlock->bank->ops->trylock(hwlock);
128 
129 	/* if hwlock is already taken, undo spin_trylock_* and exit */
130 	if (!ret) {
131 		switch (mode) {
132 		case HWLOCK_IRQSTATE:
133 			spin_unlock_irqrestore(&hwlock->lock, *flags);
134 			break;
135 		case HWLOCK_IRQ:
136 			spin_unlock_irq(&hwlock->lock);
137 			break;
138 		case HWLOCK_RAW:
139 			/* Nothing to do */
140 			break;
141 		default:
142 			spin_unlock(&hwlock->lock);
143 			break;
144 		}
145 
146 		return -EBUSY;
147 	}
148 
149 	/*
150 	 * We can be sure the other core's memory operations
151 	 * are observable to us only _after_ we successfully take
152 	 * the hwspinlock, and we must make sure that subsequent memory
153 	 * operations (both reads and writes) will not be reordered before
154 	 * we actually took the hwspinlock.
155 	 *
156 	 * Note: the implicit memory barrier of the spinlock above is too
157 	 * early, so we need this additional explicit memory barrier.
158 	 */
159 	mb();
160 
161 	return 0;
162 }
163 EXPORT_SYMBOL_GPL(__hwspin_trylock);
164 
165 /**
166  * __hwspin_lock_timeout() - lock an hwspinlock with timeout limit
167  * @hwlock: the hwspinlock to be locked
168  * @timeout: timeout value in msecs
169  * @mode: mode which controls whether local interrupts are disabled or not
170  * @flags: a pointer to where the caller's interrupt state will be saved at (if
171  *         requested)
172  *
173  * This function locks the given @hwlock. If the @hwlock
174  * is already taken, the function will busy loop waiting for it to
175  * be released, but give up after @timeout msecs have elapsed.
176  *
177  * Caution: If the mode is HWLOCK_RAW, that means user must protect the routine
178  * of getting hardware lock with mutex or spinlock. Since in some scenarios,
179  * user need some time-consuming or sleepable operations under the hardware
180  * lock, they need one sleepable lock (like mutex) to protect the operations.
181  *
182  * If the mode is not HWLOCK_RAW, upon a successful return from this function,
183  * preemption is disabled (and possibly local interrupts, too), so the caller
184  * must not sleep, and is advised to release the hwspinlock as soon as possible.
185  * This is required in order to minimize remote cores polling on the
186  * hardware interconnect.
187  *
188  * The user decides whether local interrupts are disabled or not, and if yes,
189  * whether he wants their previous state to be saved. It is up to the user
190  * to choose the appropriate @mode of operation, exactly the same way users
191  * should decide between spin_lock, spin_lock_irq and spin_lock_irqsave.
192  *
193  * Returns 0 when the @hwlock was successfully taken, and an appropriate
194  * error code otherwise (most notably -ETIMEDOUT if the @hwlock is still
195  * busy after @timeout msecs). The function will never sleep.
196  */
197 int __hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int to,
198 					int mode, unsigned long *flags)
199 {
200 	int ret;
201 	unsigned long expire;
202 
203 	expire = msecs_to_jiffies(to) + jiffies;
204 
205 	for (;;) {
206 		/* Try to take the hwspinlock */
207 		ret = __hwspin_trylock(hwlock, mode, flags);
208 		if (ret != -EBUSY)
209 			break;
210 
211 		/*
212 		 * The lock is already taken, let's check if the user wants
213 		 * us to try again
214 		 */
215 		if (time_is_before_eq_jiffies(expire))
216 			return -ETIMEDOUT;
217 
218 		/*
219 		 * Allow platform-specific relax handlers to prevent
220 		 * hogging the interconnect (no sleeping, though)
221 		 */
222 		if (hwlock->bank->ops->relax)
223 			hwlock->bank->ops->relax(hwlock);
224 	}
225 
226 	return ret;
227 }
228 EXPORT_SYMBOL_GPL(__hwspin_lock_timeout);
229 
230 /**
231  * __hwspin_unlock() - unlock a specific hwspinlock
232  * @hwlock: a previously-acquired hwspinlock which we want to unlock
233  * @mode: controls whether local interrupts needs to be restored or not
234  * @flags: previous caller's interrupt state to restore (if requested)
235  *
236  * This function will unlock a specific hwspinlock, enable preemption and
237  * (possibly) enable interrupts or restore their previous state.
238  * @hwlock must be already locked before calling this function: it is a bug
239  * to call unlock on a @hwlock that is already unlocked.
240  *
241  * The user decides whether local interrupts should be enabled or not, and
242  * if yes, whether he wants their previous state to be restored. It is up
243  * to the user to choose the appropriate @mode of operation, exactly the
244  * same way users decide between spin_unlock, spin_unlock_irq and
245  * spin_unlock_irqrestore.
246  *
247  * The function will never sleep.
248  */
249 void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
250 {
251 	BUG_ON(!hwlock);
252 	BUG_ON(!flags && mode == HWLOCK_IRQSTATE);
253 
254 	/*
255 	 * We must make sure that memory operations (both reads and writes),
256 	 * done before unlocking the hwspinlock, will not be reordered
257 	 * after the lock is released.
258 	 *
259 	 * That's the purpose of this explicit memory barrier.
260 	 *
261 	 * Note: the memory barrier induced by the spin_unlock below is too
262 	 * late; the other core is going to access memory soon after it will
263 	 * take the hwspinlock, and by then we want to be sure our memory
264 	 * operations are already observable.
265 	 */
266 	mb();
267 
268 	hwlock->bank->ops->unlock(hwlock);
269 
270 	/* Undo the spin_trylock{_irq, _irqsave} called while locking */
271 	switch (mode) {
272 	case HWLOCK_IRQSTATE:
273 		spin_unlock_irqrestore(&hwlock->lock, *flags);
274 		break;
275 	case HWLOCK_IRQ:
276 		spin_unlock_irq(&hwlock->lock);
277 		break;
278 	case HWLOCK_RAW:
279 		/* Nothing to do */
280 		break;
281 	default:
282 		spin_unlock(&hwlock->lock);
283 		break;
284 	}
285 }
286 EXPORT_SYMBOL_GPL(__hwspin_unlock);
287 
288 /**
289  * of_hwspin_lock_simple_xlate - translate hwlock_spec to return a lock id
290  * @bank: the hwspinlock device bank
291  * @hwlock_spec: hwlock specifier as found in the device tree
292  *
293  * This is a simple translation function, suitable for hwspinlock platform
294  * drivers that only has a lock specifier length of 1.
295  *
296  * Returns a relative index of the lock within a specified bank on success,
297  * or -EINVAL on invalid specifier cell count.
298  */
299 static inline int
300 of_hwspin_lock_simple_xlate(const struct of_phandle_args *hwlock_spec)
301 {
302 	if (WARN_ON(hwlock_spec->args_count != 1))
303 		return -EINVAL;
304 
305 	return hwlock_spec->args[0];
306 }
307 
308 /**
309  * of_hwspin_lock_get_id() - get lock id for an OF phandle-based specific lock
310  * @np: device node from which to request the specific hwlock
311  * @index: index of the hwlock in the list of values
312  *
313  * This function provides a means for DT users of the hwspinlock module to
314  * get the global lock id of a specific hwspinlock using the phandle of the
315  * hwspinlock device, so that it can be requested using the normal
316  * hwspin_lock_request_specific() API.
317  *
318  * Returns the global lock id number on success, -EPROBE_DEFER if the hwspinlock
319  * device is not yet registered, -EINVAL on invalid args specifier value or an
320  * appropriate error as returned from the OF parsing of the DT client node.
321  */
322 int of_hwspin_lock_get_id(struct device_node *np, int index)
323 {
324 	struct of_phandle_args args;
325 	struct hwspinlock *hwlock;
326 	struct radix_tree_iter iter;
327 	void **slot;
328 	int id;
329 	int ret;
330 
331 	ret = of_parse_phandle_with_args(np, "hwlocks", "#hwlock-cells", index,
332 					 &args);
333 	if (ret)
334 		return ret;
335 
336 	/* Find the hwspinlock device: we need its base_id */
337 	ret = -EPROBE_DEFER;
338 	rcu_read_lock();
339 	radix_tree_for_each_slot(slot, &hwspinlock_tree, &iter, 0) {
340 		hwlock = radix_tree_deref_slot(slot);
341 		if (unlikely(!hwlock))
342 			continue;
343 		if (radix_tree_deref_retry(hwlock)) {
344 			slot = radix_tree_iter_retry(&iter);
345 			continue;
346 		}
347 
348 		if (hwlock->bank->dev->of_node == args.np) {
349 			ret = 0;
350 			break;
351 		}
352 	}
353 	rcu_read_unlock();
354 	if (ret < 0)
355 		goto out;
356 
357 	id = of_hwspin_lock_simple_xlate(&args);
358 	if (id < 0 || id >= hwlock->bank->num_locks) {
359 		ret = -EINVAL;
360 		goto out;
361 	}
362 	id += hwlock->bank->base_id;
363 
364 out:
365 	of_node_put(args.np);
366 	return ret ? ret : id;
367 }
368 EXPORT_SYMBOL_GPL(of_hwspin_lock_get_id);
369 
370 static int hwspin_lock_register_single(struct hwspinlock *hwlock, int id)
371 {
372 	struct hwspinlock *tmp;
373 	int ret;
374 
375 	mutex_lock(&hwspinlock_tree_lock);
376 
377 	ret = radix_tree_insert(&hwspinlock_tree, id, hwlock);
378 	if (ret) {
379 		if (ret == -EEXIST)
380 			pr_err("hwspinlock id %d already exists!\n", id);
381 		goto out;
382 	}
383 
384 	/* mark this hwspinlock as available */
385 	tmp = radix_tree_tag_set(&hwspinlock_tree, id, HWSPINLOCK_UNUSED);
386 
387 	/* self-sanity check which should never fail */
388 	WARN_ON(tmp != hwlock);
389 
390 out:
391 	mutex_unlock(&hwspinlock_tree_lock);
392 	return 0;
393 }
394 
395 static struct hwspinlock *hwspin_lock_unregister_single(unsigned int id)
396 {
397 	struct hwspinlock *hwlock = NULL;
398 	int ret;
399 
400 	mutex_lock(&hwspinlock_tree_lock);
401 
402 	/* make sure the hwspinlock is not in use (tag is set) */
403 	ret = radix_tree_tag_get(&hwspinlock_tree, id, HWSPINLOCK_UNUSED);
404 	if (ret == 0) {
405 		pr_err("hwspinlock %d still in use (or not present)\n", id);
406 		goto out;
407 	}
408 
409 	hwlock = radix_tree_delete(&hwspinlock_tree, id);
410 	if (!hwlock) {
411 		pr_err("failed to delete hwspinlock %d\n", id);
412 		goto out;
413 	}
414 
415 out:
416 	mutex_unlock(&hwspinlock_tree_lock);
417 	return hwlock;
418 }
419 
420 /**
421  * hwspin_lock_register() - register a new hw spinlock device
422  * @bank: the hwspinlock device, which usually provides numerous hw locks
423  * @dev: the backing device
424  * @ops: hwspinlock handlers for this device
425  * @base_id: id of the first hardware spinlock in this bank
426  * @num_locks: number of hwspinlocks provided by this device
427  *
428  * This function should be called from the underlying platform-specific
429  * implementation, to register a new hwspinlock device instance.
430  *
431  * Should be called from a process context (might sleep)
432  *
433  * Returns 0 on success, or an appropriate error code on failure
434  */
435 int hwspin_lock_register(struct hwspinlock_device *bank, struct device *dev,
436 		const struct hwspinlock_ops *ops, int base_id, int num_locks)
437 {
438 	struct hwspinlock *hwlock;
439 	int ret = 0, i;
440 
441 	if (!bank || !ops || !dev || !num_locks || !ops->trylock ||
442 							!ops->unlock) {
443 		pr_err("invalid parameters\n");
444 		return -EINVAL;
445 	}
446 
447 	bank->dev = dev;
448 	bank->ops = ops;
449 	bank->base_id = base_id;
450 	bank->num_locks = num_locks;
451 
452 	for (i = 0; i < num_locks; i++) {
453 		hwlock = &bank->lock[i];
454 
455 		spin_lock_init(&hwlock->lock);
456 		hwlock->bank = bank;
457 
458 		ret = hwspin_lock_register_single(hwlock, base_id + i);
459 		if (ret)
460 			goto reg_failed;
461 	}
462 
463 	return 0;
464 
465 reg_failed:
466 	while (--i >= 0)
467 		hwspin_lock_unregister_single(base_id + i);
468 	return ret;
469 }
470 EXPORT_SYMBOL_GPL(hwspin_lock_register);
471 
472 /**
473  * hwspin_lock_unregister() - unregister an hw spinlock device
474  * @bank: the hwspinlock device, which usually provides numerous hw locks
475  *
476  * This function should be called from the underlying platform-specific
477  * implementation, to unregister an existing (and unused) hwspinlock.
478  *
479  * Should be called from a process context (might sleep)
480  *
481  * Returns 0 on success, or an appropriate error code on failure
482  */
483 int hwspin_lock_unregister(struct hwspinlock_device *bank)
484 {
485 	struct hwspinlock *hwlock, *tmp;
486 	int i;
487 
488 	for (i = 0; i < bank->num_locks; i++) {
489 		hwlock = &bank->lock[i];
490 
491 		tmp = hwspin_lock_unregister_single(bank->base_id + i);
492 		if (!tmp)
493 			return -EBUSY;
494 
495 		/* self-sanity check that should never fail */
496 		WARN_ON(tmp != hwlock);
497 	}
498 
499 	return 0;
500 }
501 EXPORT_SYMBOL_GPL(hwspin_lock_unregister);
502 
503 /**
504  * __hwspin_lock_request() - tag an hwspinlock as used and power it up
505  *
506  * This is an internal function that prepares an hwspinlock instance
507  * before it is given to the user. The function assumes that
508  * hwspinlock_tree_lock is taken.
509  *
510  * Returns 0 or positive to indicate success, and a negative value to
511  * indicate an error (with the appropriate error code)
512  */
513 static int __hwspin_lock_request(struct hwspinlock *hwlock)
514 {
515 	struct device *dev = hwlock->bank->dev;
516 	struct hwspinlock *tmp;
517 	int ret;
518 
519 	/* prevent underlying implementation from being removed */
520 	if (!try_module_get(dev->driver->owner)) {
521 		dev_err(dev, "%s: can't get owner\n", __func__);
522 		return -EINVAL;
523 	}
524 
525 	/* notify PM core that power is now needed */
526 	ret = pm_runtime_get_sync(dev);
527 	if (ret < 0) {
528 		dev_err(dev, "%s: can't power on device\n", __func__);
529 		pm_runtime_put_noidle(dev);
530 		module_put(dev->driver->owner);
531 		return ret;
532 	}
533 
534 	/* mark hwspinlock as used, should not fail */
535 	tmp = radix_tree_tag_clear(&hwspinlock_tree, hwlock_to_id(hwlock),
536 							HWSPINLOCK_UNUSED);
537 
538 	/* self-sanity check that should never fail */
539 	WARN_ON(tmp != hwlock);
540 
541 	return ret;
542 }
543 
544 /**
545  * hwspin_lock_get_id() - retrieve id number of a given hwspinlock
546  * @hwlock: a valid hwspinlock instance
547  *
548  * Returns the id number of a given @hwlock, or -EINVAL if @hwlock is invalid.
549  */
550 int hwspin_lock_get_id(struct hwspinlock *hwlock)
551 {
552 	if (!hwlock) {
553 		pr_err("invalid hwlock\n");
554 		return -EINVAL;
555 	}
556 
557 	return hwlock_to_id(hwlock);
558 }
559 EXPORT_SYMBOL_GPL(hwspin_lock_get_id);
560 
561 /**
562  * hwspin_lock_request() - request an hwspinlock
563  *
564  * This function should be called by users of the hwspinlock device,
565  * in order to dynamically assign them an unused hwspinlock.
566  * Usually the user of this lock will then have to communicate the lock's id
567  * to the remote core before it can be used for synchronization (to get the
568  * id of a given hwlock, use hwspin_lock_get_id()).
569  *
570  * Should be called from a process context (might sleep)
571  *
572  * Returns the address of the assigned hwspinlock, or NULL on error
573  */
574 struct hwspinlock *hwspin_lock_request(void)
575 {
576 	struct hwspinlock *hwlock;
577 	int ret;
578 
579 	mutex_lock(&hwspinlock_tree_lock);
580 
581 	/* look for an unused lock */
582 	ret = radix_tree_gang_lookup_tag(&hwspinlock_tree, (void **)&hwlock,
583 						0, 1, HWSPINLOCK_UNUSED);
584 	if (ret == 0) {
585 		pr_warn("a free hwspinlock is not available\n");
586 		hwlock = NULL;
587 		goto out;
588 	}
589 
590 	/* sanity check that should never fail */
591 	WARN_ON(ret > 1);
592 
593 	/* mark as used and power up */
594 	ret = __hwspin_lock_request(hwlock);
595 	if (ret < 0)
596 		hwlock = NULL;
597 
598 out:
599 	mutex_unlock(&hwspinlock_tree_lock);
600 	return hwlock;
601 }
602 EXPORT_SYMBOL_GPL(hwspin_lock_request);
603 
604 /**
605  * hwspin_lock_request_specific() - request for a specific hwspinlock
606  * @id: index of the specific hwspinlock that is requested
607  *
608  * This function should be called by users of the hwspinlock module,
609  * in order to assign them a specific hwspinlock.
610  * Usually early board code will be calling this function in order to
611  * reserve specific hwspinlock ids for predefined purposes.
612  *
613  * Should be called from a process context (might sleep)
614  *
615  * Returns the address of the assigned hwspinlock, or NULL on error
616  */
617 struct hwspinlock *hwspin_lock_request_specific(unsigned int id)
618 {
619 	struct hwspinlock *hwlock;
620 	int ret;
621 
622 	mutex_lock(&hwspinlock_tree_lock);
623 
624 	/* make sure this hwspinlock exists */
625 	hwlock = radix_tree_lookup(&hwspinlock_tree, id);
626 	if (!hwlock) {
627 		pr_warn("hwspinlock %u does not exist\n", id);
628 		goto out;
629 	}
630 
631 	/* sanity check (this shouldn't happen) */
632 	WARN_ON(hwlock_to_id(hwlock) != id);
633 
634 	/* make sure this hwspinlock is unused */
635 	ret = radix_tree_tag_get(&hwspinlock_tree, id, HWSPINLOCK_UNUSED);
636 	if (ret == 0) {
637 		pr_warn("hwspinlock %u is already in use\n", id);
638 		hwlock = NULL;
639 		goto out;
640 	}
641 
642 	/* mark as used and power up */
643 	ret = __hwspin_lock_request(hwlock);
644 	if (ret < 0)
645 		hwlock = NULL;
646 
647 out:
648 	mutex_unlock(&hwspinlock_tree_lock);
649 	return hwlock;
650 }
651 EXPORT_SYMBOL_GPL(hwspin_lock_request_specific);
652 
653 /**
654  * hwspin_lock_free() - free a specific hwspinlock
655  * @hwlock: the specific hwspinlock to free
656  *
657  * This function mark @hwlock as free again.
658  * Should only be called with an @hwlock that was retrieved from
659  * an earlier call to omap_hwspin_lock_request{_specific}.
660  *
661  * Should be called from a process context (might sleep)
662  *
663  * Returns 0 on success, or an appropriate error code on failure
664  */
665 int hwspin_lock_free(struct hwspinlock *hwlock)
666 {
667 	struct device *dev;
668 	struct hwspinlock *tmp;
669 	int ret;
670 
671 	if (!hwlock) {
672 		pr_err("invalid hwlock\n");
673 		return -EINVAL;
674 	}
675 
676 	dev = hwlock->bank->dev;
677 	mutex_lock(&hwspinlock_tree_lock);
678 
679 	/* make sure the hwspinlock is used */
680 	ret = radix_tree_tag_get(&hwspinlock_tree, hwlock_to_id(hwlock),
681 							HWSPINLOCK_UNUSED);
682 	if (ret == 1) {
683 		dev_err(dev, "%s: hwlock is already free\n", __func__);
684 		dump_stack();
685 		ret = -EINVAL;
686 		goto out;
687 	}
688 
689 	/* notify the underlying device that power is not needed */
690 	ret = pm_runtime_put(dev);
691 	if (ret < 0)
692 		goto out;
693 
694 	/* mark this hwspinlock as available */
695 	tmp = radix_tree_tag_set(&hwspinlock_tree, hwlock_to_id(hwlock),
696 							HWSPINLOCK_UNUSED);
697 
698 	/* sanity check (this shouldn't happen) */
699 	WARN_ON(tmp != hwlock);
700 
701 	module_put(dev->driver->owner);
702 
703 out:
704 	mutex_unlock(&hwspinlock_tree_lock);
705 	return ret;
706 }
707 EXPORT_SYMBOL_GPL(hwspin_lock_free);
708 
709 MODULE_LICENSE("GPL v2");
710 MODULE_DESCRIPTION("Hardware spinlock interface");
711 MODULE_AUTHOR("Ohad Ben-Cohen <ohad@wizery.com>");
712