|
@@ -98,10 +98,29 @@ static int omap_hwspinlock_probe(struct platform_device *pdev)
|
|
if (!io_base)
|
|
if (!io_base)
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * make sure the module is enabled and clocked before reading
|
|
|
|
+ * the module SYSSTATUS register
|
|
|
|
+ */
|
|
|
|
+ pm_runtime_enable(&pdev->dev);
|
|
|
|
+ ret = pm_runtime_get_sync(&pdev->dev);
|
|
|
|
+ if (ret < 0) {
|
|
|
|
+ pm_runtime_put_noidle(&pdev->dev);
|
|
|
|
+ goto iounmap_base;
|
|
|
|
+ }
|
|
|
|
+
|
|
/* Determine number of locks */
|
|
/* Determine number of locks */
|
|
i = readl(io_base + SYSSTATUS_OFFSET);
|
|
i = readl(io_base + SYSSTATUS_OFFSET);
|
|
i >>= SPINLOCK_NUMLOCKS_BIT_OFFSET;
|
|
i >>= SPINLOCK_NUMLOCKS_BIT_OFFSET;
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * runtime PM will make sure the clock of this module is
|
|
|
|
+ * enabled again iff at least one lock is requested
|
|
|
|
+ */
|
|
|
|
+ ret = pm_runtime_put(&pdev->dev);
|
|
|
|
+ if (ret < 0)
|
|
|
|
+ goto iounmap_base;
|
|
|
|
+
|
|
/* one of the four lsb's must be set, and nothing else */
|
|
/* one of the four lsb's must be set, and nothing else */
|
|
if (hweight_long(i & 0xf) != 1 || i > 8) {
|
|
if (hweight_long(i & 0xf) != 1 || i > 8) {
|
|
ret = -EINVAL;
|
|
ret = -EINVAL;
|
|
@@ -121,12 +140,6 @@ static int omap_hwspinlock_probe(struct platform_device *pdev)
|
|
for (i = 0, hwlock = &bank->lock[0]; i < num_locks; i++, hwlock++)
|
|
for (i = 0, hwlock = &bank->lock[0]; i < num_locks; i++, hwlock++)
|
|
hwlock->priv = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i;
|
|
hwlock->priv = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i;
|
|
|
|
|
|
- /*
|
|
|
|
- * runtime PM will make sure the clock of this module is
|
|
|
|
- * enabled iff at least one lock is requested
|
|
|
|
- */
|
|
|
|
- pm_runtime_enable(&pdev->dev);
|
|
|
|
-
|
|
|
|
ret = hwspin_lock_register(bank, &pdev->dev, &omap_hwspinlock_ops,
|
|
ret = hwspin_lock_register(bank, &pdev->dev, &omap_hwspinlock_ops,
|
|
pdata->base_id, num_locks);
|
|
pdata->base_id, num_locks);
|
|
if (ret)
|
|
if (ret)
|
|
@@ -135,9 +148,9 @@ static int omap_hwspinlock_probe(struct platform_device *pdev)
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
reg_fail:
|
|
reg_fail:
|
|
- pm_runtime_disable(&pdev->dev);
|
|
|
|
kfree(bank);
|
|
kfree(bank);
|
|
iounmap_base:
|
|
iounmap_base:
|
|
|
|
+ pm_runtime_disable(&pdev->dev);
|
|
iounmap(io_base);
|
|
iounmap(io_base);
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|