123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- From fb7737e949e31d8a71acee6bbb670f32dbd2a2c0 Mon Sep 17 00:00:00 2001
- From: Suman Anna <s-anna@ti.com>
- Date: Wed, 4 Mar 2015 20:01:14 -0600
- Subject: [PATCH] hwspinlock/core: add device tree support
- This patch adds a new OF-friendly API of_hwspin_lock_get_id()
- for hwspinlock clients to use/request locks from a hwspinlock
- device instantiated through a device-tree blob. This new API
- can be used by hwspinlock clients to get the id for a specific
- lock using the phandle + args specifier, so that it can be
- requested using the available hwspin_lock_request_specific()
- API.
- Signed-off-by: Suman Anna <s-anna@ti.com>
- Reviewed-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
- [small comment clarification]
- Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
- ---
- Documentation/hwspinlock.txt | 10 +++++
- drivers/hwspinlock/hwspinlock_core.c | 79 ++++++++++++++++++++++++++++++++++++
- include/linux/hwspinlock.h | 7 ++++
- 3 files changed, 96 insertions(+)
- --- a/Documentation/hwspinlock.txt
- +++ b/Documentation/hwspinlock.txt
- @@ -48,6 +48,16 @@ independent, drivers.
- ids for predefined purposes.
- Should be called from a process context (might sleep).
-
- + int of_hwspin_lock_get_id(struct device_node *np, int index);
- + - retrieve the global lock id for an OF phandle-based specific lock.
- + This function provides a means for DT users of a hwspinlock module
- + to get the global lock id of a specific hwspinlock, so that it can
- + be requested using the normal hwspin_lock_request_specific() API.
- + The function returns a lock id number on success, -EPROBE_DEFER if
- + the hwspinlock device is not yet registered with the core, or other
- + error values.
- + Should be called from a process context (might sleep).
- +
- int hwspin_lock_free(struct hwspinlock *hwlock);
- - free a previously-assigned hwspinlock; returns 0 on success, or an
- appropriate error code on failure (e.g. -EINVAL if the hwspinlock
- --- a/drivers/hwspinlock/hwspinlock_core.c
- +++ b/drivers/hwspinlock/hwspinlock_core.c
- @@ -27,6 +27,7 @@
- #include <linux/hwspinlock.h>
- #include <linux/pm_runtime.h>
- #include <linux/mutex.h>
- +#include <linux/of.h>
-
- #include "hwspinlock_internal.h"
-
- @@ -257,6 +258,84 @@ void __hwspin_unlock(struct hwspinlock *
- }
- EXPORT_SYMBOL_GPL(__hwspin_unlock);
-
- +/**
- + * of_hwspin_lock_simple_xlate - translate hwlock_spec to return a lock id
- + * @bank: the hwspinlock device bank
- + * @hwlock_spec: hwlock specifier as found in the device tree
- + *
- + * This is a simple translation function, suitable for hwspinlock platform
- + * drivers that only has a lock specifier length of 1.
- + *
- + * Returns a relative index of the lock within a specified bank on success,
- + * or -EINVAL on invalid specifier cell count.
- + */
- +static inline int
- +of_hwspin_lock_simple_xlate(const struct of_phandle_args *hwlock_spec)
- +{
- + if (WARN_ON(hwlock_spec->args_count != 1))
- + return -EINVAL;
- +
- + return hwlock_spec->args[0];
- +}
- +
- +/**
- + * of_hwspin_lock_get_id() - get lock id for an OF phandle-based specific lock
- + * @np: device node from which to request the specific hwlock
- + * @index: index of the hwlock in the list of values
- + *
- + * This function provides a means for DT users of the hwspinlock module to
- + * get the global lock id of a specific hwspinlock using the phandle of the
- + * hwspinlock device, so that it can be requested using the normal
- + * hwspin_lock_request_specific() API.
- + *
- + * Returns the global lock id number on success, -EPROBE_DEFER if the hwspinlock
- + * device is not yet registered, -EINVAL on invalid args specifier value or an
- + * appropriate error as returned from the OF parsing of the DT client node.
- + */
- +int of_hwspin_lock_get_id(struct device_node *np, int index)
- +{
- + struct of_phandle_args args;
- + struct hwspinlock *hwlock;
- + struct radix_tree_iter iter;
- + void **slot;
- + int id;
- + int ret;
- +
- + ret = of_parse_phandle_with_args(np, "hwlocks", "#hwlock-cells", index,
- + &args);
- + if (ret)
- + return ret;
- +
- + /* Find the hwspinlock device: we need its base_id */
- + ret = -EPROBE_DEFER;
- + rcu_read_lock();
- + radix_tree_for_each_slot(slot, &hwspinlock_tree, &iter, 0) {
- + hwlock = radix_tree_deref_slot(slot);
- + if (unlikely(!hwlock))
- + continue;
- +
- + if (hwlock->bank->dev->of_node == args.np) {
- + ret = 0;
- + break;
- + }
- + }
- + rcu_read_unlock();
- + if (ret < 0)
- + goto out;
- +
- + id = of_hwspin_lock_simple_xlate(&args);
- + if (id < 0 || id >= hwlock->bank->num_locks) {
- + ret = -EINVAL;
- + goto out;
- + }
- + id += hwlock->bank->base_id;
- +
- +out:
- + of_node_put(args.np);
- + return ret ? ret : id;
- +}
- +EXPORT_SYMBOL_GPL(of_hwspin_lock_get_id);
- +
- static int hwspin_lock_register_single(struct hwspinlock *hwlock, int id)
- {
- struct hwspinlock *tmp;
- --- a/include/linux/hwspinlock.h
- +++ b/include/linux/hwspinlock.h
- @@ -26,6 +26,7 @@
- #define HWLOCK_IRQ 0x02 /* Disable interrupts, don't save state */
-
- struct device;
- +struct device_node;
- struct hwspinlock;
- struct hwspinlock_device;
- struct hwspinlock_ops;
- @@ -66,6 +67,7 @@ int hwspin_lock_unregister(struct hwspin
- struct hwspinlock *hwspin_lock_request(void);
- struct hwspinlock *hwspin_lock_request_specific(unsigned int id);
- int hwspin_lock_free(struct hwspinlock *hwlock);
- +int of_hwspin_lock_get_id(struct device_node *np, int index);
- int hwspin_lock_get_id(struct hwspinlock *hwlock);
- int __hwspin_lock_timeout(struct hwspinlock *, unsigned int, int,
- unsigned long *);
- @@ -120,6 +122,11 @@ void __hwspin_unlock(struct hwspinlock *
- {
- }
-
- +static inline int of_hwspin_lock_get_id(struct device_node *np, int index)
- +{
- + return 0;
- +}
- +
- static inline int hwspin_lock_get_id(struct hwspinlock *hwlock)
- {
- return 0;
|