forked from enclustra-bsp/xilinx-uboot
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is uclass for Hardware Spinlocks. It implements two mandatory operations: lock and unlock and one optional relax operation. Signed-off-by: Benjamin Gaignard <[email protected]> Reviewed-by: Simon Glass <[email protected]> Reviewed-by: Patrice Chotard <[email protected]>
- Loading branch information
1 parent
3b074fb
commit 7f84fc6
Showing
13 changed files
with
414 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
menu "Hardware Spinlock Support" | ||
|
||
config DM_HWSPINLOCK | ||
bool "Enable U-Boot hardware spinlock support" | ||
help | ||
This option enables U-Boot hardware spinlock support | ||
|
||
config HWSPINLOCK_SANDBOX | ||
bool "Enable Hardware Spinlock support for Sandbox" | ||
depends on SANDBOX && DM_HWSPINLOCK | ||
help | ||
Enable hardware spinlock support in Sandbox. This is a dummy device that | ||
can be probed and support all the methods of HWSPINLOCK, but does not | ||
really do anything. | ||
|
||
endmenu |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause | ||
# | ||
# Copyright (C) 2018, STMicroelectronics - All Rights Reserved | ||
|
||
obj-$(CONFIG_DM_HWSPINLOCK) += hwspinlock-uclass.o | ||
obj-$(CONFIG_HWSPINLOCK_SANDBOX) += sandbox_hwspinlock.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause | ||
/* | ||
* Copyright (C) 2018, STMicroelectronics - All Rights Reserved | ||
*/ | ||
|
||
#include <common.h> | ||
#include <dm.h> | ||
#include <errno.h> | ||
#include <hwspinlock.h> | ||
#include <dm/device-internal.h> | ||
|
||
static inline const struct hwspinlock_ops * | ||
hwspinlock_dev_ops(struct udevice *dev) | ||
{ | ||
return (const struct hwspinlock_ops *)dev->driver->ops; | ||
} | ||
|
||
static int hwspinlock_of_xlate_default(struct hwspinlock *hws, | ||
struct ofnode_phandle_args *args) | ||
{ | ||
if (args->args_count > 1) { | ||
debug("Invaild args_count: %d\n", args->args_count); | ||
return -EINVAL; | ||
} | ||
|
||
if (args->args_count) | ||
hws->id = args->args[0]; | ||
else | ||
hws->id = 0; | ||
|
||
return 0; | ||
} | ||
|
||
int hwspinlock_get_by_index(struct udevice *dev, int index, | ||
struct hwspinlock *hws) | ||
{ | ||
int ret; | ||
struct ofnode_phandle_args args; | ||
struct udevice *dev_hws; | ||
const struct hwspinlock_ops *ops; | ||
|
||
assert(hws); | ||
hws->dev = NULL; | ||
|
||
ret = dev_read_phandle_with_args(dev, "hwlocks", "#hwlock-cells", 1, | ||
index, &args); | ||
if (ret) { | ||
dev_dbg(dev, "%s: dev_read_phandle_with_args: err=%d\n", | ||
__func__, ret); | ||
return ret; | ||
} | ||
|
||
ret = uclass_get_device_by_ofnode(UCLASS_HWSPINLOCK, | ||
args.node, &dev_hws); | ||
if (ret) { | ||
dev_dbg(dev, | ||
"%s: uclass_get_device_by_of_offset failed: err=%d\n", | ||
__func__, ret); | ||
return ret; | ||
} | ||
|
||
hws->dev = dev_hws; | ||
|
||
ops = hwspinlock_dev_ops(dev_hws); | ||
|
||
if (ops->of_xlate) | ||
ret = ops->of_xlate(hws, &args); | ||
else | ||
ret = hwspinlock_of_xlate_default(hws, &args); | ||
if (ret) | ||
dev_dbg(dev, "of_xlate() failed: %d\n", ret); | ||
|
||
return ret; | ||
} | ||
|
||
int hwspinlock_lock_timeout(struct hwspinlock *hws, unsigned int timeout) | ||
{ | ||
const struct hwspinlock_ops *ops; | ||
ulong start; | ||
int ret; | ||
|
||
assert(hws); | ||
|
||
if (!hws->dev) | ||
return -EINVAL; | ||
|
||
ops = hwspinlock_dev_ops(hws->dev); | ||
if (!ops->lock) | ||
return -ENOSYS; | ||
|
||
start = get_timer(0); | ||
do { | ||
ret = ops->lock(hws->dev, hws->id); | ||
if (!ret) | ||
return ret; | ||
|
||
if (ops->relax) | ||
ops->relax(hws->dev); | ||
} while (get_timer(start) < timeout); | ||
|
||
return -ETIMEDOUT; | ||
} | ||
|
||
int hwspinlock_unlock(struct hwspinlock *hws) | ||
{ | ||
const struct hwspinlock_ops *ops; | ||
|
||
assert(hws); | ||
|
||
if (!hws->dev) | ||
return -EINVAL; | ||
|
||
ops = hwspinlock_dev_ops(hws->dev); | ||
if (!ops->unlock) | ||
return -ENOSYS; | ||
|
||
return ops->unlock(hws->dev, hws->id); | ||
} | ||
|
||
static int hwspinlock_post_bind(struct udevice *dev) | ||
{ | ||
#if defined(CONFIG_NEEDS_MANUAL_RELOC) | ||
struct hwspinlock_ops *ops = device_get_ops(dev); | ||
static int reloc_done; | ||
|
||
if (!reloc_done) { | ||
if (ops->lock) | ||
ops->lock += gd->reloc_off; | ||
if (ops->unlock) | ||
ops->unlock += gd->reloc_off; | ||
if (ops->relax) | ||
ops->relax += gd->reloc_off; | ||
|
||
reloc_done++; | ||
} | ||
#endif | ||
return 0; | ||
} | ||
|
||
UCLASS_DRIVER(hwspinlock) = { | ||
.id = UCLASS_HWSPINLOCK, | ||
.name = "hwspinlock", | ||
.post_bind = hwspinlock_post_bind, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause | ||
/* | ||
* Copyright (C) 2018, STMicroelectronics - All Rights Reserved | ||
*/ | ||
|
||
#include <common.h> | ||
#include <dm.h> | ||
#include <hwspinlock.h> | ||
#include <asm/state.h> | ||
|
||
static int sandbox_lock(struct udevice *dev, int index) | ||
{ | ||
struct sandbox_state *state = state_get_current(); | ||
|
||
if (index != 0) | ||
return -1; | ||
|
||
if (state->hwspinlock) | ||
return -1; | ||
|
||
state->hwspinlock = true; | ||
|
||
return 0; | ||
} | ||
|
||
static int sandbox_unlock(struct udevice *dev, int index) | ||
{ | ||
struct sandbox_state *state = state_get_current(); | ||
|
||
if (index != 0) | ||
return -1; | ||
|
||
if (!state->hwspinlock) | ||
return -1; | ||
|
||
state->hwspinlock = false; | ||
|
||
return 0; | ||
} | ||
|
||
static const struct hwspinlock_ops sandbox_hwspinlock_ops = { | ||
.lock = sandbox_lock, | ||
.unlock = sandbox_unlock, | ||
}; | ||
|
||
static const struct udevice_id sandbox_hwspinlock_ids[] = { | ||
{ .compatible = "sandbox,hwspinlock" }, | ||
{} | ||
}; | ||
|
||
U_BOOT_DRIVER(hwspinlock_sandbox) = { | ||
.name = "hwspinlock_sandbox", | ||
.id = UCLASS_HWSPINLOCK, | ||
.of_match = sandbox_hwspinlock_ids, | ||
.ops = &sandbox_hwspinlock_ops, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.