1/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ 2/* 3 * Copyright (C) 2018, STMicroelectronics - All Rights Reserved 4 */ 5 6#ifndef _HWSPINLOCK_H_ 7#define _HWSPINLOCK_H_ 8 9/** 10 * Implement a hwspinlock uclass. 11 * Hardware spinlocks are used to perform hardware protection of 12 * critical sections and synchronisation between multiprocessors. 13 */ 14 15struct udevice; 16 17/** 18 * struct hwspinlock - A handle to (allowing control of) a single hardware 19 * spinlock. 20 * 21 * @dev: The device which implements the hardware spinlock. 22 * @id: The hardware spinlock ID within the provider. 23 */ 24struct hwspinlock { 25 struct udevice *dev; 26 unsigned long id; 27}; 28 29#if CONFIG_IS_ENABLED(DM_HWSPINLOCK) 30 31/** 32 * hwspinlock_get_by_index - Get a hardware spinlock by integer index 33 * 34 * This looks up and request a hardware spinlock. The index is relative to the 35 * client device; each device is assumed to have n hardware spinlock associated 36 * with it somehow, and this function finds and requests one of them. 37 * 38 * @dev: The client device. 39 * @index: The index of the hardware spinlock to request, within the 40 * client's list of hardware spinlock. 41 * @hws: A pointer to a hardware spinlock struct to initialize. 42 * @return 0 if OK, or a negative error code. 43 */ 44int hwspinlock_get_by_index(struct udevice *dev, 45 int index, struct hwspinlock *hws); 46 47/** 48 * Lock the hardware spinlock 49 * 50 * @hws: A hardware spinlock struct that previously requested by 51 * hwspinlock_get_by_index 52 * @timeout: Timeout value in msecs 53 * @return: 0 if OK, -ETIMEDOUT if timeout, -ve on other errors 54 */ 55int hwspinlock_lock_timeout(struct hwspinlock *hws, unsigned int timeout); 56 57/** 58 * Unlock the hardware spinlock 59 * 60 * @hws: A hardware spinlock struct that previously requested by 61 * hwspinlock_get_by_index 62 * @return: 0 if OK, -ve on error 63 */ 64int hwspinlock_unlock(struct hwspinlock *hws); 65 66#else 67 68static inline int hwspinlock_get_by_index(struct udevice *dev, 69 int index, 70 struct hwspinlock *hws) 71{ 72 return -ENOSYS; 73} 74 75static inline int hwspinlock_lock_timeout(struct hwspinlock *hws, 76 int timeout) 77{ 78 return -ENOSYS; 79} 80 81static inline int hwspinlock_unlock(struct hwspinlock *hws) 82{ 83 return -ENOSYS; 84} 85 86#endif /* CONFIG_DM_HWSPINLOCK */ 87 88struct ofnode_phandle_args; 89 90/** 91 * struct hwspinlock_ops - Driver model hwspinlock operations 92 * 93 * The uclass interface is implemented by all hwspinlock devices which use 94 * driver model. 95 */ 96struct hwspinlock_ops { 97 /** 98 * of_xlate - Translate a client's device-tree (OF) hardware specifier. 99 * 100 * The hardware core calls this function as the first step in 101 * implementing a client's hwspinlock_get_by_*() call. 102 * 103 * @hws: The hardware spinlock struct to hold the translation 104 * result. 105 * @args: The hardware spinlock specifier values from device tree. 106 * @return 0 if OK, or a negative error code. 107 */ 108 int (*of_xlate)(struct hwspinlock *hws, 109 struct ofnode_phandle_args *args); 110 111 /** 112 * Lock the hardware spinlock 113 * 114 * @dev: hwspinlock Device 115 * @index: index of the lock to be used 116 * @return 0 if OK, -ve on error 117 */ 118 int (*lock)(struct udevice *dev, int index); 119 120 /** 121 * Unlock the hardware spinlock 122 * 123 * @dev: hwspinlock Device 124 * @index: index of the lock to be unlocked 125 * @return 0 if OK, -ve on error 126 */ 127 int (*unlock)(struct udevice *dev, int index); 128 129 /** 130 * Relax - optional 131 * Platform-specific relax method, called by hwspinlock core 132 * while spinning on a lock, between two successive call to 133 * lock 134 * 135 * @dev: hwspinlock Device 136 */ 137 void (*relax)(struct udevice *dev); 138}; 139 140#endif /* _HWSPINLOCK_H_ */ 141