diff options
-rw-r--r-- | MAINTAINERS | 2 | ||||
-rw-r--r-- | drivers/hwspinlock/hwspinlock_core.c | 16 | ||||
-rw-r--r-- | drivers/hwspinlock/sprd_hwspinlock.c | 48 | ||||
-rw-r--r-- | drivers/hwspinlock/u8500_hsem.c | 53 |
4 files changed, 42 insertions, 77 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index e5f15368c1b5..4ce75013205a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7284,7 +7284,7 @@ M: Ohad Ben-Cohen <ohad@wizery.com> M: Bjorn Andersson <bjorn.andersson@linaro.org> L: linux-remoteproc@vger.kernel.org S: Maintained -T: git git://git.kernel.org/pub/scm/linux/kernel/git/ohad/hwspinlock.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/andersson/remoteproc.git hwspinlock-next F: Documentation/devicetree/bindings/hwlock/ F: Documentation/hwspinlock.txt F: drivers/hwspinlock/ diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c index 8862445aa858..fd5f5c5a5244 100644 --- a/drivers/hwspinlock/hwspinlock_core.c +++ b/drivers/hwspinlock/hwspinlock_core.c @@ -92,8 +92,8 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags) { int ret; - BUG_ON(!hwlock); - BUG_ON(!flags && mode == HWLOCK_IRQSTATE); + if (WARN_ON(!hwlock || (!flags && mode == HWLOCK_IRQSTATE))) + return -EINVAL; /* * This spin_lock{_irq, _irqsave} serves three purposes: @@ -264,8 +264,8 @@ EXPORT_SYMBOL_GPL(__hwspin_lock_timeout); */ void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags) { - BUG_ON(!hwlock); - BUG_ON(!flags && mode == HWLOCK_IRQSTATE); + if (WARN_ON(!hwlock || (!flags && mode == HWLOCK_IRQSTATE))) + return; /* * We must make sure that memory operations (both reads and writes), @@ -657,13 +657,15 @@ static int __hwspin_lock_request(struct hwspinlock *hwlock) /* notify PM core that power is now needed */ ret = pm_runtime_get_sync(dev); - if (ret < 0) { + if (ret < 0 && ret != -EACCES) { dev_err(dev, "%s: can't power on device\n", __func__); pm_runtime_put_noidle(dev); module_put(dev->driver->owner); return ret; } + ret = 0; + /* mark hwspinlock as used, should not fail */ tmp = radix_tree_tag_clear(&hwspinlock_tree, hwlock_to_id(hwlock), HWSPINLOCK_UNUSED); @@ -820,9 +822,7 @@ int hwspin_lock_free(struct hwspinlock *hwlock) } /* notify the underlying device that power is not needed */ - ret = pm_runtime_put(dev); - if (ret < 0) - goto out; + pm_runtime_put(dev); /* mark this hwspinlock as available */ tmp = radix_tree_tag_set(&hwspinlock_tree, hwlock_to_id(hwlock), diff --git a/drivers/hwspinlock/sprd_hwspinlock.c b/drivers/hwspinlock/sprd_hwspinlock.c index dc42bf51f3e6..36dc8038bbb4 100644 --- a/drivers/hwspinlock/sprd_hwspinlock.c +++ b/drivers/hwspinlock/sprd_hwspinlock.c @@ -15,7 +15,6 @@ #include <linux/of.h> #include <linux/of_device.h> #include <linux/platform_device.h> -#include <linux/pm_runtime.h> #include <linux/slab.h> #include "hwspinlock_internal.h" @@ -79,11 +78,17 @@ static const struct hwspinlock_ops sprd_hwspinlock_ops = { .relax = sprd_hwspinlock_relax, }; +static void sprd_hwspinlock_disable(void *data) +{ + struct sprd_hwspinlock_dev *sprd_hwlock = data; + + clk_disable_unprepare(sprd_hwlock->clk); +} + static int sprd_hwspinlock_probe(struct platform_device *pdev) { struct sprd_hwspinlock_dev *sprd_hwlock; struct hwspinlock *lock; - struct resource *res; int i, ret; if (!pdev->dev.of_node) @@ -96,8 +101,7 @@ static int sprd_hwspinlock_probe(struct platform_device *pdev) if (!sprd_hwlock) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - sprd_hwlock->base = devm_ioremap_resource(&pdev->dev, res); + sprd_hwlock->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(sprd_hwlock->base)) return PTR_ERR(sprd_hwlock->base); @@ -107,7 +111,17 @@ static int sprd_hwspinlock_probe(struct platform_device *pdev) return PTR_ERR(sprd_hwlock->clk); } - clk_prepare_enable(sprd_hwlock->clk); + ret = clk_prepare_enable(sprd_hwlock->clk); + if (ret) + return ret; + + ret = devm_add_action_or_reset(&pdev->dev, sprd_hwspinlock_disable, + sprd_hwlock); + if (ret) { + dev_err(&pdev->dev, + "Failed to add hwspinlock disable action\n"); + return ret; + } /* set the hwspinlock to record user id to identify subsystems */ writel(HWSPINLOCK_USER_BITS, sprd_hwlock->base + HWSPINLOCK_RECCTRL); @@ -118,27 +132,10 @@ static int sprd_hwspinlock_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, sprd_hwlock); - pm_runtime_enable(&pdev->dev); - ret = hwspin_lock_register(&sprd_hwlock->bank, &pdev->dev, - &sprd_hwspinlock_ops, 0, SPRD_HWLOCKS_NUM); - if (ret) { - pm_runtime_disable(&pdev->dev); - clk_disable_unprepare(sprd_hwlock->clk); - return ret; - } - - return 0; -} - -static int sprd_hwspinlock_remove(struct platform_device *pdev) -{ - struct sprd_hwspinlock_dev *sprd_hwlock = platform_get_drvdata(pdev); - - hwspin_lock_unregister(&sprd_hwlock->bank); - pm_runtime_disable(&pdev->dev); - clk_disable_unprepare(sprd_hwlock->clk); - return 0; + return devm_hwspin_lock_register(&pdev->dev, &sprd_hwlock->bank, + &sprd_hwspinlock_ops, 0, + SPRD_HWLOCKS_NUM); } static const struct of_device_id sprd_hwspinlock_of_match[] = { @@ -149,7 +146,6 @@ MODULE_DEVICE_TABLE(of, sprd_hwspinlock_of_match); static struct platform_driver sprd_hwspinlock_driver = { .probe = sprd_hwspinlock_probe, - .remove = sprd_hwspinlock_remove, .driver = { .name = "sprd_hwspinlock", .of_match_table = of_match_ptr(sprd_hwspinlock_of_match), diff --git a/drivers/hwspinlock/u8500_hsem.c b/drivers/hwspinlock/u8500_hsem.c index 572ca79d77e8..67845c0c9701 100644 --- a/drivers/hwspinlock/u8500_hsem.c +++ b/drivers/hwspinlock/u8500_hsem.c @@ -16,7 +16,6 @@ #include <linux/module.h> #include <linux/delay.h> #include <linux/io.h> -#include <linux/pm_runtime.h> #include <linux/slab.h> #include <linux/spinlock.h> #include <linux/hwspinlock.h> @@ -88,21 +87,16 @@ static int u8500_hsem_probe(struct platform_device *pdev) struct hwspinlock_pdata *pdata = pdev->dev.platform_data; struct hwspinlock_device *bank; struct hwspinlock *hwlock; - struct resource *res; void __iomem *io_base; - int i, ret, num_locks = U8500_MAX_SEMAPHORE; + int i, num_locks = U8500_MAX_SEMAPHORE; ulong val; if (!pdata) return -ENODEV; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - - io_base = ioremap(res->start, resource_size(res)); - if (!io_base) - return -ENOMEM; + io_base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(io_base)) + return PTR_ERR(io_base); /* make sure protocol 1 is selected */ val = readl(io_base + HSEM_CTRL_REG); @@ -111,54 +105,29 @@ static int u8500_hsem_probe(struct platform_device *pdev) /* clear all interrupts */ writel(0xFFFF, io_base + HSEM_ICRALL); - bank = kzalloc(struct_size(bank, lock, num_locks), GFP_KERNEL); - if (!bank) { - ret = -ENOMEM; - goto iounmap_base; - } + bank = devm_kzalloc(&pdev->dev, struct_size(bank, lock, num_locks), + GFP_KERNEL); + if (!bank) + return -ENOMEM; platform_set_drvdata(pdev, bank); for (i = 0, hwlock = &bank->lock[0]; i < num_locks; i++, hwlock++) hwlock->priv = io_base + HSEM_REGISTER_OFFSET + sizeof(u32) * i; - /* no pm needed for HSem but required to comply with hwspilock core */ - pm_runtime_enable(&pdev->dev); - - ret = hwspin_lock_register(bank, &pdev->dev, &u8500_hwspinlock_ops, - pdata->base_id, num_locks); - if (ret) - goto reg_fail; - - return 0; - -reg_fail: - pm_runtime_disable(&pdev->dev); - kfree(bank); -iounmap_base: - iounmap(io_base); - return ret; + return devm_hwspin_lock_register(&pdev->dev, bank, + &u8500_hwspinlock_ops, + pdata->base_id, num_locks); } static int u8500_hsem_remove(struct platform_device *pdev) { struct hwspinlock_device *bank = platform_get_drvdata(pdev); void __iomem *io_base = bank->lock[0].priv - HSEM_REGISTER_OFFSET; - int ret; /* clear all interrupts */ writel(0xFFFF, io_base + HSEM_ICRALL); - ret = hwspin_lock_unregister(bank); - if (ret) { - dev_err(&pdev->dev, "%s failed: %d\n", __func__, ret); - return ret; - } - - pm_runtime_disable(&pdev->dev); - iounmap(io_base); - kfree(bank); - return 0; } |