diff options
-rw-r--r-- | arch/arm/mach-omap2/hwspinlock.c | 8 | ||||
-rw-r--r-- | drivers/hwspinlock/hwspinlock_core.c | 2 | ||||
-rw-r--r-- | drivers/hwspinlock/omap_hwspinlock.c | 6 | ||||
-rw-r--r-- | include/linux/hwspinlock.h | 28 |
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 | ||
27 | static struct hwspinlock_pdata omap_hwspinlock_pdata __initdata = { | ||
28 | .base_id = 0, | ||
29 | }; | ||
30 | |||
26 | struct omap_device_pm_latency omap_spinlock_latency[] = { | 31 | struct 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 | ||
95 | static int __devinit omap_hwspinlock_probe(struct platform_device *pdev) | 95 | static 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 | ||
28 | struct hwspinlock; | 28 | struct 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 | */ | ||
54 | struct 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 | ||
32 | int hwspin_lock_register(struct hwspinlock *lock); | 60 | int hwspin_lock_register(struct hwspinlock *lock); |