/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ /* * Copyright (C) 2018, STMicroelectronics - All Rights Reserved */ #ifndef _HWSPINLOCK_H_ #define _HWSPINLOCK_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_ */