diff mbox series

Add Altera hardware mutex driver

Message ID 20220331214911.27194-1-niravkumar.l.rabara@intel.com
State Changes Requested, archived
Headers show
Series Add Altera hardware mutex driver | expand

Checks

Context Check Description
robh/checkpatch warning total: 2 errors, 6 warnings, 429 lines checked
robh/patch-applied success
robh/dtbs-check success
robh/dt-meta-schema success

Commit Message

Rabara, Niravkumar L March 31, 2022, 9:49 p.m. UTC
From: Niravkumar L Rabara <niravkumar.l.rabara@intel.com>

Altera hardware mutex soft IP provides hardware assistance for
synchronization and mutual exclusion between processors in
asymmetric/symmetric multiprocessing (AMP/SMP) system or
multi processes/threads in uniprocessor system.

Signed-off-by: Niravkumar L Rabara <niravkumar.l.rabara@intel.com>
---
 .../bindings/misc/altera-hwmutex.yaml         |  47 +++
 drivers/misc/Kconfig                          |   6 +
 drivers/misc/Makefile                         |   1 +
 drivers/misc/altera_hwmutex.c                 | 321 ++++++++++++++++++
 include/linux/altera_hwmutex.h                |  42 +++
 5 files changed, 417 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/misc/altera-hwmutex.yaml
 create mode 100644 drivers/misc/altera_hwmutex.c
 create mode 100644 include/linux/altera_hwmutex.h

Comments

Greg Kroah-Hartman March 31, 2022, 1:56 p.m. UTC | #1
On Fri, Apr 01, 2022 at 05:49:11AM +0800, niravkumar.l.rabara@intel.com wrote:
> From: Niravkumar L Rabara <niravkumar.l.rabara@intel.com>
> 
> Altera hardware mutex soft IP provides hardware assistance for
> synchronization and mutual exclusion between processors in
> asymmetric/symmetric multiprocessing (AMP/SMP) system or
> multi processes/threads in uniprocessor system.
> 
> Signed-off-by: Niravkumar L Rabara <niravkumar.l.rabara@intel.com>

Sorry, but you have not followed the Intel-required rules for submitting
changes to the kernel.  Please contact the Intel Linux kernel team for
details about this to help prevent some of the problems that this
submission contains.

thanks!

greg k-h
Greg Kroah-Hartman March 31, 2022, 1:57 p.m. UTC | #2
On Fri, Apr 01, 2022 at 05:49:11AM +0800, niravkumar.l.rabara@intel.com wrote:
> ---
>  .../bindings/misc/altera-hwmutex.yaml         |  47 +++
>  drivers/misc/Kconfig                          |   6 +
>  drivers/misc/Makefile                         |   1 +
>  drivers/misc/altera_hwmutex.c                 | 321 ++++++++++++++++++
>  include/linux/altera_hwmutex.h                |  42 +++

There is no need for a .h file for a single .c file.  Please fix that up
for your next submission.

I don't think I need to read anymore :)

thanks,

greg k-h
Rob Herring (Arm) April 1, 2022, 2:04 p.m. UTC | #3
On Fri, Apr 01, 2022 at 05:49:11AM +0800, niravkumar.l.rabara@intel.com wrote:
> From: Niravkumar L Rabara <niravkumar.l.rabara@intel.com>
> 
> Altera hardware mutex soft IP provides hardware assistance for
> synchronization and mutual exclusion between processors in
> asymmetric/symmetric multiprocessing (AMP/SMP) system or
> multi processes/threads in uniprocessor system.
> 
> Signed-off-by: Niravkumar L Rabara <niravkumar.l.rabara@intel.com>
> ---
>  .../bindings/misc/altera-hwmutex.yaml         |  47 +++

Bindings should be separate patch. We have a subsystem/class for this 
type of h/w. The binding (and driver) belongs there.

>  drivers/misc/Kconfig                          |   6 +
>  drivers/misc/Makefile                         |   1 +
>  drivers/misc/altera_hwmutex.c                 | 321 ++++++++++++++++++
>  include/linux/altera_hwmutex.h                |  42 +++
>  5 files changed, 417 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/misc/altera-hwmutex.yaml
>  create mode 100644 drivers/misc/altera_hwmutex.c
>  create mode 100644 include/linux/altera_hwmutex.h
> 
> diff --git a/Documentation/devicetree/bindings/misc/altera-hwmutex.yaml b/Documentation/devicetree/bindings/misc/altera-hwmutex.yaml
> new file mode 100644
> index 000000000000..57a9ea19c563
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/misc/altera-hwmutex.yaml
> @@ -0,0 +1,47 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/misc/altera-hwmutex.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Altera hardware mutex
> +
> +maintainers:
> +  - Niravkumar L Rabara <niravkumar.l.rabara@intel.com>
> +
> +description:
> +  Altera hardware mutex can provide hardware assistance for synchronization
> +  and mutual exclusion between processors in asymmetric/symmetric multiprocessing
> +  (AMP/SMP) system or multi processes/threads in uniprocessor system.

Link to IP documentation?

> +
> +properties:
> +  compatible:
> +    enum:
> +      - altr,hwmutex-1.0

1.0? I feel like you made up this version.

> +      - client-1.0

No.

> +
> +  reg:
> +    items:
> +      - description: physical address of hw mutex and length of memory mapped
> +         region
> +
> +additionalProperties: false
> +
> +required:
> +  - compatible
> +  - reg
> +
> +examples:
> +  - |
> +    mutex0: mutex0@100 {
> +        compatible = "altr,hwmutex-1.0";
> +        reg = <0x100 0x8>;
> +    };
> +
> +
> +   #Example of mutex's client node that includes mutex phandle    
> +   #mclient0: mclient0@200 {
> +   #     compatible = "client-1.0";
> +   # 	reg = <0x200 0x10>;
> +   #	mutex = <&mutex0>;

We have a standard binding for this.

> +   # };
> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> index 0f5a49fc7c9e..707acf740c6f 100644
> --- a/drivers/misc/Kconfig
> +++ b/drivers/misc/Kconfig
> @@ -435,6 +435,12 @@ config DW_XDATA_PCIE
>  
>  	  If unsure, say N.
>  
> +config ALTERA_HWMUTEX
> +       tristate "Altera Hardware Mutex"
> +       help
> +         This option enables device driver support for Altera Hardware Mutex.
> +         Say Y here if you want to use the Altera hardware mutex support.
> +
>  config PCI_ENDPOINT_TEST
>  	depends on PCI
>  	select CRC32
> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> index a086197af544..6fcbbd36b3cf 100644
> --- a/drivers/misc/Makefile
> +++ b/drivers/misc/Makefile
> @@ -40,6 +40,7 @@ obj-$(CONFIG_PCH_PHUB)		+= pch_phub.o
>  obj-y				+= ti-st/
>  obj-y				+= lis3lv02d/
>  obj-$(CONFIG_ALTERA_STAPL)	+=altera-stapl/
> +obj-$(CONFIG_ALTERA_HWMUTEX)   += altera_hwmutex.o
>  obj-$(CONFIG_INTEL_MEI)		+= mei/
>  obj-$(CONFIG_VMWARE_VMCI)	+= vmw_vmci/
>  obj-$(CONFIG_LATTICE_ECP3_CONFIG)	+= lattice-ecp3-config.o
> diff --git a/drivers/misc/altera_hwmutex.c b/drivers/misc/altera_hwmutex.c
> new file mode 100644
> index 000000000000..45f98e4b13d0
> --- /dev/null
> +++ b/drivers/misc/altera_hwmutex.c
> @@ -0,0 +1,321 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright Intel Corporation (C) 2022. All rights reserved
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program.  If not, see <http://www.gnu.org/licenses/>.

Drop the license text. You only need SPDX-License-Identifier
Arnd Bergmann April 1, 2022, 2:08 p.m. UTC | #4
On Thu, Mar 31, 2022 at 11:49 PM <niravkumar.l.rabara@intel.com> wrote:
>
> From: Niravkumar L Rabara <niravkumar.l.rabara@intel.com>
>
> Altera hardware mutex soft IP provides hardware assistance for
> synchronization and mutual exclusion between processors in
> asymmetric/symmetric multiprocessing (AMP/SMP) system or
> multi processes/threads in uniprocessor system.
>
> Signed-off-by: Niravkumar L Rabara <niravkumar.l.rabara@intel.com>
> ---
>  .../bindings/misc/altera-hwmutex.yaml         |  47 +++
>  drivers/misc/Kconfig                          |   6 +
>  drivers/misc/Makefile                         |   1 +
>  drivers/misc/altera_hwmutex.c                 | 321 ++++++++++++++++++
>  include/linux/altera_hwmutex.h                |  42 +++

Why does this use a custom interface rather than the generic drivers/hwspinlock/
subsystem?

        Arnd
diff mbox series

Patch

diff --git a/Documentation/devicetree/bindings/misc/altera-hwmutex.yaml b/Documentation/devicetree/bindings/misc/altera-hwmutex.yaml
new file mode 100644
index 000000000000..57a9ea19c563
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/altera-hwmutex.yaml
@@ -0,0 +1,47 @@ 
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/misc/altera-hwmutex.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Altera hardware mutex
+
+maintainers:
+  - Niravkumar L Rabara <niravkumar.l.rabara@intel.com>
+
+description:
+  Altera hardware mutex can provide hardware assistance for synchronization
+  and mutual exclusion between processors in asymmetric/symmetric multiprocessing
+  (AMP/SMP) system or multi processes/threads in uniprocessor system.
+
+properties:
+  compatible:
+    enum:
+      - altr,hwmutex-1.0
+      - client-1.0
+
+  reg:
+    items:
+      - description: physical address of hw mutex and length of memory mapped
+         region
+
+additionalProperties: false
+
+required:
+  - compatible
+  - reg
+
+examples:
+  - |
+    mutex0: mutex0@100 {
+        compatible = "altr,hwmutex-1.0";
+        reg = <0x100 0x8>;
+    };
+
+
+   #Example of mutex's client node that includes mutex phandle    
+   #mclient0: mclient0@200 {
+   #     compatible = "client-1.0";
+   # 	reg = <0x200 0x10>;
+   #	mutex = <&mutex0>;
+   # };
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 0f5a49fc7c9e..707acf740c6f 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -435,6 +435,12 @@  config DW_XDATA_PCIE
 
 	  If unsure, say N.
 
+config ALTERA_HWMUTEX
+       tristate "Altera Hardware Mutex"
+       help
+         This option enables device driver support for Altera Hardware Mutex.
+         Say Y here if you want to use the Altera hardware mutex support.
+
 config PCI_ENDPOINT_TEST
 	depends on PCI
 	select CRC32
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index a086197af544..6fcbbd36b3cf 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -40,6 +40,7 @@  obj-$(CONFIG_PCH_PHUB)		+= pch_phub.o
 obj-y				+= ti-st/
 obj-y				+= lis3lv02d/
 obj-$(CONFIG_ALTERA_STAPL)	+=altera-stapl/
+obj-$(CONFIG_ALTERA_HWMUTEX)   += altera_hwmutex.o
 obj-$(CONFIG_INTEL_MEI)		+= mei/
 obj-$(CONFIG_VMWARE_VMCI)	+= vmw_vmci/
 obj-$(CONFIG_LATTICE_ECP3_CONFIG)	+= lattice-ecp3-config.o
diff --git a/drivers/misc/altera_hwmutex.c b/drivers/misc/altera_hwmutex.c
new file mode 100644
index 000000000000..45f98e4b13d0
--- /dev/null
+++ b/drivers/misc/altera_hwmutex.c
@@ -0,0 +1,321 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright Intel Corporation (C) 2022. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/altera_hwmutex.h>
+
+#define DRV_NAME	"altera_hwmutex"
+
+
+static DEFINE_SPINLOCK(list_lock);	/* protect mutex_list */
+static LIST_HEAD(mutex_list);
+
+/* Mutex Registers */
+#define MUTEX_REG			0x0
+
+#define MUTEX_REG_VALUE_MASK		0xFFFF
+#define MUTEX_REG_OWNER_OFFSET		16
+#define MUTEX_REG_OWNER_MASK		0xFFFF
+#define MUTEX_GET_OWNER(reg)			\
+	((reg >> MUTEX_REG_OWNER_OFFSET) & MUTEX_REG_OWNER_MASK)
+
+/**
+ *	altera_mutex_request - Retrieves a pointer to an acquired mutex device
+ *			       structure
+ *	@mutex_np:	The pointer to mutex device node
+ *
+ *	Returns a pointer to the mutex device structure associated with the
+ *	supplied device node, or NULL if no corresponding mutex device was
+ *	found.
+ */
+struct altera_mutex *altera_mutex_request(struct device_node *mutex_np)
+{
+	struct altera_mutex *mutex;
+
+	spin_lock(&list_lock);
+	list_for_each_entry(mutex, &mutex_list, list) {
+		if (mutex_np == mutex->pdev->dev.of_node) {
+			if (!mutex->requested) {
+				mutex->requested = true;
+				spin_unlock(&list_lock);
+				return mutex;
+			} else {
+				pr_info("Mutex device is in use.\n");
+				spin_unlock(&list_lock);
+				return NULL;
+			}
+		}
+	}
+	spin_unlock(&list_lock);
+	pr_info("Mutex device not found!\n");
+	return NULL;
+}
+EXPORT_SYMBOL(altera_mutex_request);
+
+/**
+ *	altera_mutex_free - Free the mutex
+ *	@mutex:	the mutex
+ *
+ *	Return 0 if success. Otherwise, returns non-zero.
+ */
+int altera_mutex_free(struct altera_mutex *mutex)
+{
+	if (!mutex || !mutex->requested)
+		return -EINVAL;
+
+	spin_lock(&list_lock);
+	mutex->requested = false;
+	spin_unlock(&list_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL(altera_mutex_free);
+
+static int __mutex_trylock(struct altera_mutex *mutex, u16 owner, u16 value)
+{
+	u32 read;
+	int ret = 0;
+	u32 data = (owner << MUTEX_REG_OWNER_OFFSET) | value;
+
+	mutex_lock(&mutex->lock);
+	__raw_writel(data, mutex->regs + MUTEX_REG);
+	read = __raw_readl(mutex->regs + MUTEX_REG);
+	if (read != data)
+		ret = -1;
+
+	mutex_unlock(&mutex->lock);
+	return ret;
+}
+
+/**
+ *	altera_mutex_lock - Acquires a hardware mutex, wait until it can get it.
+ *	@mutex:	the mutex to be acquired
+ *	@owner:	owner ID
+ *	@value:	the new non-zero value to write to mutex
+ *
+ *	Returns 0 if mutex was successfully locked. Otherwise, returns non-zero.
+ *
+ *	The mutex must later on be released by the same owner that acquired it.
+ *	This function is not ISR callable.
+ */
+int altera_mutex_lock(struct altera_mutex *mutex, u16 owner, u16 value)
+{
+	if (!mutex || !mutex->requested)
+		return -EINVAL;
+
+	while (__mutex_trylock(mutex, owner, value) != 0)
+		;
+
+	return 0;
+}
+EXPORT_SYMBOL(altera_mutex_lock);
+
+/**
+ *	altera_mutex_trylock - Tries once to lock the hardware mutex and returns
+ *				immediately
+ *	@mutex:	the mutex to be acquired
+ *	@owner:	owner ID
+ *	@value:	the new non-zero value to write to mutex
+ *
+ *	Returns 0 if mutex was successfully locked. Otherwise, returns non-zero.
+ *
+ *	The mutex must later on be released by the same owner that acquired it.
+ *	This function is not ISR callable.
+ */
+int altera_mutex_trylock(struct altera_mutex *mutex, u16 owner, u16 value)
+{
+	if (!mutex || !mutex->requested)
+		return -EINVAL;
+
+	return __mutex_trylock(mutex, owner, value);
+}
+EXPORT_SYMBOL(altera_mutex_trylock);
+
+/**
+ *	altera_mutex_unlock - Unlock a mutex that has been locked by this owner
+ *			      previously that was locked on the
+ *			      altera_mutex_lock. Upon release, the value stored
+ *			      in the mutex is set to zero.
+ *	@mutex:	the mutex to be released
+ *	@owner:	Owner ID
+ *
+ *	Returns 0 if mutex was successfully unlocked. Otherwise, returns
+ *	non-zero.
+ *
+ *	This function is not ISR callable.
+ */
+int altera_mutex_unlock(struct altera_mutex *mutex, u16 owner)
+{
+	u32 reg;
+
+	if (!mutex || !mutex->requested)
+		return -EINVAL;
+
+	mutex_lock(&mutex->lock);
+
+	__raw_writel(owner << MUTEX_REG_OWNER_OFFSET,
+		mutex->regs + MUTEX_REG);
+
+	reg = __raw_readl(mutex->regs + MUTEX_REG);
+	if (reg & MUTEX_REG_VALUE_MASK) {
+		/* Unlock failed */
+		dev_dbg(&mutex->pdev->dev,
+			"Unlock mutex failed, owner %d and expected owner %d\n",
+			owner, MUTEX_GET_OWNER(reg));
+		mutex_unlock(&mutex->lock);
+		return -EINVAL;
+	}
+
+	mutex_unlock(&mutex->lock);
+	return 0;
+}
+EXPORT_SYMBOL(altera_mutex_unlock);
+
+/**
+ *	altera_mutex_owned - Determines if this owner owns the mutex
+ *	@mutex:	the mutex to be queried
+ *	@owner:	Owner ID
+ *
+ *	Returns 1 if the owner owns the mutex. Otherwise, returns zero.
+ */
+int altera_mutex_owned(struct altera_mutex *mutex, u16 owner)
+{
+	u32 reg;
+	u16 actual_owner;
+	int ret = 0;
+
+	if (!mutex || !mutex->requested)
+		return ret;
+
+	mutex_lock(&mutex->lock);
+	reg = __raw_readl(mutex->regs + MUTEX_REG);
+	actual_owner = MUTEX_GET_OWNER(reg);
+	if (actual_owner == owner)
+		ret = 1;
+
+	mutex_unlock(&mutex->lock);
+	return ret;
+}
+EXPORT_SYMBOL(altera_mutex_owned);
+
+/**
+ *	altera_mutex_is_locked - Determines if the mutex is locked
+ *	@mutex:	the mutex to be queried
+ *
+ *	Returns 1 if the mutex is locked, 0 if unlocked.
+ */
+int altera_mutex_is_locked(struct altera_mutex *mutex)
+{
+	u32 reg;
+	int ret = 0;
+
+	if (!mutex || !mutex->requested)
+		return ret;
+
+	mutex_lock(&mutex->lock);
+	reg = __raw_readl(mutex->regs + MUTEX_REG);
+	reg &= MUTEX_REG_VALUE_MASK;
+	if (reg)
+		ret = 1;
+
+	mutex_unlock(&mutex->lock);
+	return ret;
+}
+EXPORT_SYMBOL(altera_mutex_is_locked);
+
+static int altera_mutex_probe(struct platform_device *pdev)
+{
+	struct altera_mutex *mutex;
+	struct resource	*regs;
+
+	mutex = devm_kzalloc(&pdev->dev, sizeof(struct altera_mutex),
+		GFP_KERNEL);
+	if (!mutex)
+		return -ENOMEM;
+
+	mutex->pdev = pdev;
+
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!regs)
+		return -ENXIO;
+
+	mutex->regs = devm_ioremap_resource(&pdev->dev, regs);
+	if (IS_ERR(mutex->regs))
+		return PTR_ERR(mutex->regs);
+
+	mutex_init(&mutex->lock);
+
+	spin_lock(&list_lock);
+	list_add_tail(&mutex->list, &mutex_list);
+	spin_unlock(&list_lock);
+
+	platform_set_drvdata(pdev, mutex);
+
+	return 0;
+}
+
+static int altera_mutex_remove(struct platform_device *pdev)
+{
+	struct altera_mutex *mutex = platform_get_drvdata(pdev);
+
+	spin_lock(&list_lock);
+	if (mutex)
+		list_del(&mutex->list);
+	spin_unlock(&list_lock);
+
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+static const struct of_device_id altera_mutex_match[] = {
+	{ .compatible = "altr,hwmutex-1.0" },
+	{ /* Sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, altera_mutex_match);
+
+static struct platform_driver altera_mutex_platform_driver = {
+	.driver = {
+		.name		= DRV_NAME,
+		.of_match_table	= altera_mutex_match,
+	},
+	.remove			= altera_mutex_remove,
+};
+
+static int __init altera_mutex_init(void)
+{
+	return platform_driver_probe(&altera_mutex_platform_driver,
+		altera_mutex_probe);
+}
+
+static void __exit altera_mutex_exit(void)
+{
+	platform_driver_unregister(&altera_mutex_platform_driver);
+}
+
+module_init(altera_mutex_init);
+module_exit(altera_mutex_exit);
+
+MODULE_AUTHOR("Niravkumar L Rabara <niravkumar.l.rabara@intel.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Altera Hardware Mutex driver");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/include/linux/altera_hwmutex.h b/include/linux/altera_hwmutex.h
new file mode 100644
index 000000000000..18b73e9120bc
--- /dev/null
+++ b/include/linux/altera_hwmutex.h
@@ -0,0 +1,42 @@ 
+// SPDX-License-Identifier: GPL-2.0 
+/*
+ * Copyright Intel Corporation (C) 2022. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _ALTERA_MUTEX_H
+#define _ALTERA_MUTEX_H
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+
+struct altera_mutex {
+	struct list_head	list;
+	struct platform_device	*pdev;
+	struct mutex		lock;
+	void __iomem		*regs;
+	bool			requested;
+};
+
+extern struct altera_mutex *altera_mutex_request(struct device_node *mutex_np);
+extern int altera_mutex_free(struct altera_mutex *mutex);
+
+extern int altera_mutex_lock(struct altera_mutex *mutex, u16 owner, u16 value);
+
+extern int altera_mutex_trylock(struct altera_mutex *mutex, u16 owner,
+	u16 value);
+extern int altera_mutex_unlock(struct altera_mutex *mutex, u16 owner);
+extern int altera_mutex_owned(struct altera_mutex *mutex, u16 owner);
+extern int altera_mutex_is_locked(struct altera_mutex *mutex);
+
+#endif /* _ALTERA_MUTEX_H */