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