aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/hwspinlock.c8
-rw-r--r--drivers/hwspinlock/hwspinlock_core.c2
-rw-r--r--drivers/hwspinlock/omap_hwspinlock.c6
-rw-r--r--include/linux/hwspinlock.h28
4 files changed, 42 insertions, 2 deletions
diff --git a/arch/arm/mach-omap2/hwspinlock.c b/arch/arm/mach-omap2/hwspinlock.c
index 06d4a80660a5..eb7e509957db 100644
--- a/arch/arm/mach-omap2/hwspinlock.c
+++ b/arch/arm/mach-omap2/hwspinlock.c
@@ -19,10 +19,15 @@
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/err.h> 21#include <linux/err.h>
22#include <linux/hwspinlock.h>
22 23
23#include <plat/omap_hwmod.h> 24#include <plat/omap_hwmod.h>
24#include <plat/omap_device.h> 25#include <plat/omap_device.h>
25 26
27static struct hwspinlock_pdata omap_hwspinlock_pdata __initdata = {
28 .base_id = 0,
29};
30
26struct omap_device_pm_latency omap_spinlock_latency[] = { 31struct omap_device_pm_latency omap_spinlock_latency[] = {
27 { 32 {
28 .deactivate_func = omap_device_idle_hwmods, 33 .deactivate_func = omap_device_idle_hwmods,
@@ -48,7 +53,8 @@ int __init hwspinlocks_init(void)
48 if (oh == NULL) 53 if (oh == NULL)
49 return -EINVAL; 54 return -EINVAL;
50 55
51 od = omap_device_build(dev_name, 0, oh, NULL, 0, 56 od = omap_device_build(dev_name, 0, oh, &omap_hwspinlock_pdata,
57 sizeof(struct hwspinlock_pdata),
52 omap_spinlock_latency, 58 omap_spinlock_latency,
53 ARRAY_SIZE(omap_spinlock_latency), false); 59 ARRAY_SIZE(omap_spinlock_latency), false);
54 if (IS_ERR(od)) { 60 if (IS_ERR(od)) {
diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c
index af5175c5d5f4..4eb85b4a320e 100644
--- a/drivers/hwspinlock/hwspinlock_core.c
+++ b/drivers/hwspinlock/hwspinlock_core.c
@@ -282,6 +282,8 @@ int hwspin_lock_register(struct hwspinlock *hwlock)
282 spin_lock(&hwspinlock_tree_lock); 282 spin_lock(&hwspinlock_tree_lock);
283 283
284 ret = radix_tree_insert(&hwspinlock_tree, hwlock->id, hwlock); 284 ret = radix_tree_insert(&hwspinlock_tree, hwlock->id, hwlock);
285 if (ret == -EEXIST)
286 pr_err("hwspinlock id %d already exists!\n", hwlock->id);
285 if (ret) 287 if (ret)
286 goto out; 288 goto out;
287 289
diff --git a/drivers/hwspinlock/omap_hwspinlock.c b/drivers/hwspinlock/omap_hwspinlock.c
index d0583480fe33..2044d181e49d 100644
--- a/drivers/hwspinlock/omap_hwspinlock.c
+++ b/drivers/hwspinlock/omap_hwspinlock.c
@@ -94,12 +94,16 @@ static const struct hwspinlock_ops omap_hwspinlock_ops = {
94 94
95static int __devinit omap_hwspinlock_probe(struct platform_device *pdev) 95static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
96{ 96{
97 struct hwspinlock_pdata *pdata = pdev->dev.platform_data;
97 struct omap_hwspinlock *omap_lock; 98 struct omap_hwspinlock *omap_lock;
98 struct omap_hwspinlock_state *state; 99 struct omap_hwspinlock_state *state;
99 struct resource *res; 100 struct resource *res;
100 void __iomem *io_base; 101 void __iomem *io_base;
101 int i, ret; 102 int i, ret;
102 103
104 if (!pdata)
105 return -ENODEV;
106
103 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 107 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
104 if (!res) 108 if (!res)
105 return -ENODEV; 109 return -ENODEV;
@@ -141,7 +145,7 @@ static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
141 omap_lock = &state->lock[i]; 145 omap_lock = &state->lock[i];
142 146
143 omap_lock->lock.dev = &pdev->dev; 147 omap_lock->lock.dev = &pdev->dev;
144 omap_lock->lock.id = i; 148 omap_lock->lock.id = pdata->base_id + i;
145 omap_lock->lock.ops = &omap_hwspinlock_ops; 149 omap_lock->lock.ops = &omap_hwspinlock_ops;
146 omap_lock->addr = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i; 150 omap_lock->addr = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i;
147 151
diff --git a/include/linux/hwspinlock.h b/include/linux/hwspinlock.h
index 8390efc457eb..f85cef5452f2 100644
--- a/include/linux/hwspinlock.h
+++ b/include/linux/hwspinlock.h
@@ -27,6 +27,34 @@
27 27
28struct hwspinlock; 28struct hwspinlock;
29 29
30/**
31 * struct hwspinlock_pdata - platform data for hwspinlock drivers
32 * @base_id: base id for this hwspinlock device
33 *
34 * hwspinlock devices provide system-wide hardware locks that are used
35 * by remote processors that have no other way to achieve synchronization.
36 *
37 * To achieve that, each physical lock must have a system-wide id number
38 * that is agreed upon, otherwise remote processors can't possibly assume
39 * they're using the same hardware lock.
40 *
41 * Usually boards have a single hwspinlock device, which provides several
42 * hwspinlocks, and in this case, they can be trivially numbered 0 to
43 * (num-of-locks - 1).
44 *
45 * In case boards have several hwspinlocks devices, a different base id
46 * should be used for each hwspinlock device (they can't all use 0 as
47 * a starting id!).
48 *
49 * This platform data structure should be used to provide the base id
50 * for each device (which is trivially 0 when only a single hwspinlock
51 * device exists). It can be shared between different platforms, hence
52 * its location.
53 */
54struct hwspinlock_pdata {
55 int base_id;
56};
57
30#if defined(CONFIG_HWSPINLOCK) || defined(CONFIG_HWSPINLOCK_MODULE) 58#if defined(CONFIG_HWSPINLOCK) || defined(CONFIG_HWSPINLOCK_MODULE)
31 59
32int hwspin_lock_register(struct hwspinlock *lock); 60int hwspin_lock_register(struct hwspinlock *lock);