diff options
Diffstat (limited to 'drivers/hwspinlock/omap_hwspinlock.c')
| -rw-r--r-- | drivers/hwspinlock/omap_hwspinlock.c | 27 | 
1 files changed, 20 insertions, 7 deletions
diff --git a/drivers/hwspinlock/omap_hwspinlock.c b/drivers/hwspinlock/omap_hwspinlock.c index 292869cc9034..c1e2cd4d85fe 100644 --- a/drivers/hwspinlock/omap_hwspinlock.c +++ b/drivers/hwspinlock/omap_hwspinlock.c @@ -98,10 +98,29 @@ static int omap_hwspinlock_probe(struct platform_device *pdev)  	if (!io_base)  		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 */  	i = readl(io_base + SYSSTATUS_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 */  	if (hweight_long(i & 0xf) != 1 || i > 8) {  		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++)  		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,  						pdata->base_id, num_locks);  	if (ret) @@ -135,9 +148,9 @@ static int omap_hwspinlock_probe(struct platform_device *pdev)  	return 0;  reg_fail: -	pm_runtime_disable(&pdev->dev);  	kfree(bank);  iounmap_base: +	pm_runtime_disable(&pdev->dev);  	iounmap(io_base);  	return ret;  }  |