static int sprd_hwspinlock_remove(struct platform_device *pdev)
{
	struct sprd_hwspinlock_state *state = platform_get_drvdata(pdev);
	struct hwspinlock *lock;
	struct sprd_hwspinlock *sprd_lock;
	int i;

	for (i = 0; i < state->num_locks; i++) {
		lock = hwspin_lock_unregister(i);
		/* this shouldn't happen at this point. if it does, at least
		 * don't continue with the remove */
		if (!lock) {
			dev_err(&pdev->dev, "%s: failed on %d\n", __func__, i);
			return -EBUSY;
		}

		sprd_lock = to_sprd_hwspinlock(lock);
		kfree(sprd_lock);
	}

	pm_runtime_disable(&pdev->dev);
	kfree(state);

	return 0;
}
Example #2
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;
}
Example #3
0
static int omap_hwspinlock_remove(struct platform_device *pdev)
{
	struct hwspinlock_device *bank = platform_get_drvdata(pdev);
	void __iomem *io_base = bank->lock[0].priv - LOCK_BASE_OFFSET;
	int ret;

	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;
}
Example #4
0
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;
}
static int __devinit sprd_hwspinlock_probe(struct platform_device *pdev)
{
	struct sprd_hwspinlock *sprd_lock;
	struct sprd_hwspinlock_state *state;
	struct hwspinlock *lock;
	struct resource *res;
	int i, ret;

	sci_glb_set(REG_AHB_AHB_CTL0, BIT_SPINLOCK_EB);
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		return -ENODEV;

	state = kzalloc(sizeof(*state), GFP_KERNEL);
	if (!state)
		return -ENOMEM;

	if (!res->start) {
		ret = -ENOMEM;
		goto free_state;
	}

	state->num_locks = HWSPINLOCK_MAX_NUM;
	state->io_base = (void __iomem *)res->start;
	hwspinlock_base = state->io_base;

	platform_set_drvdata(pdev, state);

	/*
	 * runtime PM will make sure the clock of this module is
	 * enabled if at least one lock is requested
	 */
	pm_runtime_enable(&pdev->dev);

	for (i = 0; i < state->num_locks; i++) {
		sprd_lock = kzalloc(sizeof(*sprd_lock), GFP_KERNEL);
		if (!sprd_lock) {
			ret = -ENOMEM;
			goto free_locks;
		}

		sprd_lock->lock.dev = &pdev->dev;
		sprd_lock->lock.owner = THIS_MODULE;
		sprd_lock->lock.id = i;
		sprd_lock->lock.ops = &sprd_hwspinlock_ops;
		sprd_lock->addr =
		    (void __iomem *)(res->start + HWSPINLOCK_TOKEN(i));

		ret = hwspin_lock_register(&sprd_lock->lock);
		if (ret) {
			kfree(sprd_lock);
			goto free_locks;
		}
	}

	printk("sprd_hwspinlock_probe ok\n");
	return 0;

free_locks:
	while (--i >= 0) {
		lock = hwspin_lock_unregister(i);
		/* this should't happen, but let's give our best effort */
		if (!lock) {
			dev_err(&pdev->dev, "%s: cleanups failed\n", __func__);
			continue;
		}
		sprd_lock = to_sprd_hwspinlock(lock);
		kfree(sprd_lock);
	}

	pm_runtime_disable(&pdev->dev);

free_state:
	kfree(state);
	return ret;
}