| /* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ | |
| /* | |
| * Copyright (C) 2018, STMicroelectronics - All Rights Reserved | |
| */ | |
| #ifndef _HWSPINLOCK_H_ | |
| #define _HWSPINLOCK_H_ | |
| #include <linux/errno.h> | |
| /** | |
| * Implement a hwspinlock uclass. | |
| * Hardware spinlocks are used to perform hardware protection of | |
| * critical sections and synchronisation between multiprocessors. | |
| */ | |
| struct udevice; | |
| /** | |
| * struct hwspinlock - A handle to (allowing control of) a single hardware | |
| * spinlock. | |
| * | |
| * @dev: The device which implements the hardware spinlock. | |
| * @id: The hardware spinlock ID within the provider. | |
| */ | |
| struct hwspinlock { | |
| struct udevice *dev; | |
| unsigned long id; | |
| }; | |
| #if CONFIG_IS_ENABLED(DM_HWSPINLOCK) | |
| /** | |
| * hwspinlock_get_by_index - Get a hardware spinlock by integer index | |
| * | |
| * This looks up and request a hardware spinlock. The index is relative to the | |
| * client device; each device is assumed to have n hardware spinlock associated | |
| * with it somehow, and this function finds and requests one of them. | |
| * | |
| * @dev: The client device. | |
| * @index: The index of the hardware spinlock to request, within the | |
| * client's list of hardware spinlock. | |
| * @hws: A pointer to a hardware spinlock struct to initialize. | |
| * Return: 0 if OK, or a negative error code. | |
| */ | |
| int hwspinlock_get_by_index(struct udevice *dev, | |
| int index, struct hwspinlock *hws); | |
| /** | |
| * Lock the hardware spinlock | |
| * | |
| * @hws: A hardware spinlock struct that previously requested by | |
| * hwspinlock_get_by_index | |
| * @timeout: Timeout value in msecs | |
| * @return: 0 if OK, -ETIMEDOUT if timeout, -ve on other errors | |
| */ | |
| int hwspinlock_lock_timeout(struct hwspinlock *hws, unsigned int timeout); | |
| /** | |
| * Unlock the hardware spinlock | |
| * | |
| * @hws: A hardware spinlock struct that previously requested by | |
| * hwspinlock_get_by_index | |
| * @return: 0 if OK, -ve on error | |
| */ | |
| int hwspinlock_unlock(struct hwspinlock *hws); | |
| #else | |
| static inline int hwspinlock_get_by_index(struct udevice *dev, | |
| int index, | |
| struct hwspinlock *hws) | |
| { | |
| return -ENOSYS; | |
| } | |
| static inline int hwspinlock_lock_timeout(struct hwspinlock *hws, | |
| int timeout) | |
| { | |
| return -ENOSYS; | |
| } | |
| static inline int hwspinlock_unlock(struct hwspinlock *hws) | |
| { | |
| return -ENOSYS; | |
| } | |
| #endif /* CONFIG_DM_HWSPINLOCK */ | |
| struct ofnode_phandle_args; | |
| /** | |
| * struct hwspinlock_ops - Driver model hwspinlock operations | |
| * | |
| * The uclass interface is implemented by all hwspinlock devices which use | |
| * driver model. | |
| */ | |
| struct hwspinlock_ops { | |
| /** | |
| * of_xlate - Translate a client's device-tree (OF) hardware specifier. | |
| * | |
| * The hardware core calls this function as the first step in | |
| * implementing a client's hwspinlock_get_by_*() call. | |
| * | |
| * @hws: The hardware spinlock struct to hold the translation | |
| * result. | |
| * @args: The hardware spinlock specifier values from device tree. | |
| * @return 0 if OK, or a negative error code. | |
| */ | |
| int (*of_xlate)(struct hwspinlock *hws, | |
| struct ofnode_phandle_args *args); | |
| /** | |
| * Lock the hardware spinlock | |
| * | |
| * @dev: hwspinlock Device | |
| * @index: index of the lock to be used | |
| * @return 0 if OK, -ve on error | |
| */ | |
| int (*lock)(struct udevice *dev, int index); | |
| /** | |
| * Unlock the hardware spinlock | |
| * | |
| * @dev: hwspinlock Device | |
| * @index: index of the lock to be unlocked | |
| * @return 0 if OK, -ve on error | |
| */ | |
| int (*unlock)(struct udevice *dev, int index); | |
| /** | |
| * Relax - optional | |
| * Platform-specific relax method, called by hwspinlock core | |
| * while spinning on a lock, between two successive call to | |
| * lock | |
| * | |
| * @dev: hwspinlock Device | |
| */ | |
| void (*relax)(struct udevice *dev); | |
| }; | |
| #endif /* _HWSPINLOCK_H_ */ |