18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Hardware spinlocks internal header
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Contact: Ohad Ben-Cohen <ohad@wizery.com>
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#ifndef __HWSPINLOCK_HWSPINLOCK_H
118c2ecf20Sopenharmony_ci#define __HWSPINLOCK_HWSPINLOCK_H
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#include <linux/spinlock.h>
148c2ecf20Sopenharmony_ci#include <linux/device.h>
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_cistruct hwspinlock_device;
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci/**
198c2ecf20Sopenharmony_ci * struct hwspinlock_ops - platform-specific hwspinlock handlers
208c2ecf20Sopenharmony_ci *
218c2ecf20Sopenharmony_ci * @trylock: make a single attempt to take the lock. returns 0 on
228c2ecf20Sopenharmony_ci *	     failure and true on success. may _not_ sleep.
238c2ecf20Sopenharmony_ci * @unlock:  release the lock. always succeed. may _not_ sleep.
248c2ecf20Sopenharmony_ci * @relax:   optional, platform-specific relax handler, called by hwspinlock
258c2ecf20Sopenharmony_ci *	     core while spinning on a lock, between two successive
268c2ecf20Sopenharmony_ci *	     invocations of @trylock. may _not_ sleep.
278c2ecf20Sopenharmony_ci */
288c2ecf20Sopenharmony_cistruct hwspinlock_ops {
298c2ecf20Sopenharmony_ci	int (*trylock)(struct hwspinlock *lock);
308c2ecf20Sopenharmony_ci	void (*unlock)(struct hwspinlock *lock);
318c2ecf20Sopenharmony_ci	void (*relax)(struct hwspinlock *lock);
328c2ecf20Sopenharmony_ci};
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci/**
358c2ecf20Sopenharmony_ci * struct hwspinlock - this struct represents a single hwspinlock instance
368c2ecf20Sopenharmony_ci * @bank: the hwspinlock_device structure which owns this lock
378c2ecf20Sopenharmony_ci * @lock: initialized and used by hwspinlock core
388c2ecf20Sopenharmony_ci * @priv: private data, owned by the underlying platform-specific hwspinlock drv
398c2ecf20Sopenharmony_ci */
408c2ecf20Sopenharmony_cistruct hwspinlock {
418c2ecf20Sopenharmony_ci	struct hwspinlock_device *bank;
428c2ecf20Sopenharmony_ci	spinlock_t lock;
438c2ecf20Sopenharmony_ci	void *priv;
448c2ecf20Sopenharmony_ci};
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci/**
478c2ecf20Sopenharmony_ci * struct hwspinlock_device - a device which usually spans numerous hwspinlocks
488c2ecf20Sopenharmony_ci * @dev: underlying device, will be used to invoke runtime PM api
498c2ecf20Sopenharmony_ci * @ops: platform-specific hwspinlock handlers
508c2ecf20Sopenharmony_ci * @base_id: id index of the first lock in this device
518c2ecf20Sopenharmony_ci * @num_locks: number of locks in this device
528c2ecf20Sopenharmony_ci * @lock: dynamically allocated array of 'struct hwspinlock'
538c2ecf20Sopenharmony_ci */
548c2ecf20Sopenharmony_cistruct hwspinlock_device {
558c2ecf20Sopenharmony_ci	struct device *dev;
568c2ecf20Sopenharmony_ci	const struct hwspinlock_ops *ops;
578c2ecf20Sopenharmony_ci	int base_id;
588c2ecf20Sopenharmony_ci	int num_locks;
598c2ecf20Sopenharmony_ci	struct hwspinlock lock[];
608c2ecf20Sopenharmony_ci};
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_cistatic inline int hwlock_to_id(struct hwspinlock *hwlock)
638c2ecf20Sopenharmony_ci{
648c2ecf20Sopenharmony_ci	int local_id = hwlock - &hwlock->bank->lock[0];
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci	return hwlock->bank->base_id + local_id;
678c2ecf20Sopenharmony_ci}
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci#endif /* __HWSPINLOCK_HWSPINLOCK_H */
70