#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/err.h>
+#include <linux/hwspinlock.h>
 
 #include <plat/omap_hwmod.h>
 #include <plat/omap_device.h>
 
+static struct hwspinlock_pdata omap_hwspinlock_pdata __initdata = {
+       .base_id = 0,
+};
+
 struct omap_device_pm_latency omap_spinlock_latency[] = {
        {
                .deactivate_func = omap_device_idle_hwmods,
        if (oh == NULL)
                return -EINVAL;
 
-       od = omap_device_build(dev_name, 0, oh, NULL, 0,
+       od = omap_device_build(dev_name, 0, oh, &omap_hwspinlock_pdata,
+                               sizeof(struct hwspinlock_pdata),
                                omap_spinlock_latency,
                                ARRAY_SIZE(omap_spinlock_latency), false);
        if (IS_ERR(od)) {
 
        spin_lock(&hwspinlock_tree_lock);
 
        ret = radix_tree_insert(&hwspinlock_tree, hwlock->id, hwlock);
+       if (ret == -EEXIST)
+               pr_err("hwspinlock id %d already exists!\n", hwlock->id);
        if (ret)
                goto out;
 
 
 
 static int __devinit omap_hwspinlock_probe(struct platform_device *pdev)
 {
+       struct hwspinlock_pdata *pdata = pdev->dev.platform_data;
        struct omap_hwspinlock *omap_lock;
        struct omap_hwspinlock_state *state;
        struct resource *res;
        void __iomem *io_base;
        int i, ret;
 
+       if (!pdata)
+               return -ENODEV;
+
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res)
                return -ENODEV;
                omap_lock = &state->lock[i];
 
                omap_lock->lock.dev = &pdev->dev;
-               omap_lock->lock.id = i;
+               omap_lock->lock.id = pdata->base_id + i;
                omap_lock->lock.ops = &omap_hwspinlock_ops;
                omap_lock->addr = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i;
 
 
 
 struct hwspinlock;
 
+/**
+ * struct hwspinlock_pdata - platform data for hwspinlock drivers
+ * @base_id: base id for this hwspinlock device
+ *
+ * hwspinlock devices provide system-wide hardware locks that are used
+ * by remote processors that have no other way to achieve synchronization.
+ *
+ * To achieve that, each physical lock must have a system-wide id number
+ * that is agreed upon, otherwise remote processors can't possibly assume
+ * they're using the same hardware lock.
+ *
+ * Usually boards have a single hwspinlock device, which provides several
+ * hwspinlocks, and in this case, they can be trivially numbered 0 to
+ * (num-of-locks - 1).
+ *
+ * In case boards have several hwspinlocks devices, a different base id
+ * should be used for each hwspinlock device (they can't all use 0 as
+ * a starting id!).
+ *
+ * This platform data structure should be used to provide the base id
+ * for each device (which is trivially 0 when only a single hwspinlock
+ * device exists). It can be shared between different platforms, hence
+ * its location.
+ */
+struct hwspinlock_pdata {
+       int base_id;
+};
+
 #if defined(CONFIG_HWSPINLOCK) || defined(CONFIG_HWSPINLOCK_MODULE)
 
 int hwspin_lock_register(struct hwspinlock *lock);