1 // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
3 * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
9 #include <hwspinlock.h>
11 #include <dm/device-internal.h>
12 #include <dm/device_compat.h>
13 #include <linux/compat.h>
15 static inline const struct hwspinlock_ops *
16 hwspinlock_dev_ops(struct udevice *dev)
18 return (const struct hwspinlock_ops *)dev->driver->ops;
21 static int hwspinlock_of_xlate_default(struct hwspinlock *hws,
22 struct ofnode_phandle_args *args)
24 if (args->args_count > 1) {
25 debug("Invaild args_count: %d\n", args->args_count);
30 hws->id = args->args[0];
37 int hwspinlock_get_by_index(struct udevice *dev, int index,
38 struct hwspinlock *hws)
41 struct ofnode_phandle_args args;
42 struct udevice *dev_hws;
43 const struct hwspinlock_ops *ops;
48 ret = dev_read_phandle_with_args(dev, "hwlocks", "#hwlock-cells", 1,
51 dev_dbg(dev, "%s: dev_read_phandle_with_args: err=%d\n",
56 ret = uclass_get_device_by_ofnode(UCLASS_HWSPINLOCK,
60 "%s: uclass_get_device_by_of_offset failed: err=%d\n",
67 ops = hwspinlock_dev_ops(dev_hws);
70 ret = ops->of_xlate(hws, &args);
72 ret = hwspinlock_of_xlate_default(hws, &args);
74 dev_dbg(dev, "of_xlate() failed: %d\n", ret);
79 int hwspinlock_lock_timeout(struct hwspinlock *hws, unsigned int timeout)
81 const struct hwspinlock_ops *ops;
90 ops = hwspinlock_dev_ops(hws->dev);
96 ret = ops->lock(hws->dev, hws->id);
101 ops->relax(hws->dev);
102 } while (get_timer(start) < timeout);
107 int hwspinlock_unlock(struct hwspinlock *hws)
109 const struct hwspinlock_ops *ops;
116 ops = hwspinlock_dev_ops(hws->dev);
120 return ops->unlock(hws->dev, hws->id);
123 static int hwspinlock_post_bind(struct udevice *dev)
125 #if defined(CONFIG_NEEDS_MANUAL_RELOC)
126 struct hwspinlock_ops *ops = device_get_ops(dev);
127 static int reloc_done;
131 ops->lock += gd->reloc_off;
133 ops->unlock += gd->reloc_off;
135 ops->relax += gd->reloc_off;
143 UCLASS_DRIVER(hwspinlock) = {
144 .id = UCLASS_HWSPINLOCK,
145 .name = "hwspinlock",
146 .post_bind = hwspinlock_post_bind,