Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7c320eda authored by Marc Zyngier's avatar Marc Zyngier Committed by Greg Kroah-Hartman
Browse files

drm/rockchip: Clear all interrupts before requesting the IRQ



commit 5f9e93fed4d45e9a8f84728aff1a8f2ab8922902 upstream.

Calling request_irq() followed by disable_irq() is usually a bad idea,
specially if the interrupt can be pending, and you're not yet in a
position to handle it.

This is exactly what happens on my kevin system when rebooting in a
second kernel using kexec: Some interrupt is left pending from
the previous kernel, and we take it too early, before disable_irq()
could do anything.

Let's clear the pending interrupts as we initialize the HW, and move
the interrupt request after that point. This ensures that we're in
a sane state when the interrupt is requested.

Cc: stable@vger.kernel.org
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
[adapted to recent rockchip-drm changes]
Signed-off-by: default avatarHeiko Stuebner <heiko@sntech.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20180220130120.5254-2-marc.zyngier@arm.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent aab59482
Loading
Loading
Loading
Loading
+12 −11
Original line number Diff line number Diff line
@@ -1386,6 +1386,9 @@ static int vop_initial(struct vop *vop)
	usleep_range(10, 20);
	reset_control_deassert(ahb_rst);

	VOP_INTR_SET_TYPE(vop, clear, INTR_MASK, 1);
	VOP_INTR_SET_TYPE(vop, enable, INTR_MASK, 0);

	memcpy(vop->regsbak, vop->regs, vop->len);

	for (i = 0; i < vop_data->table_size; i++)
@@ -1541,17 +1544,9 @@ static int vop_bind(struct device *dev, struct device *master, void *data)

	mutex_init(&vop->vsync_mutex);

	ret = devm_request_irq(dev, vop->irq, vop_isr,
			       IRQF_SHARED, dev_name(dev), vop);
	if (ret)
		return ret;

	/* IRQ is initially disabled; it gets enabled in power_on */
	disable_irq(vop->irq);

	ret = vop_create_crtc(vop);
	if (ret)
		goto err_enable_irq;
		return ret;

	pm_runtime_enable(&pdev->dev);

@@ -1561,13 +1556,19 @@ static int vop_bind(struct device *dev, struct device *master, void *data)
		goto err_disable_pm_runtime;
	}

	ret = devm_request_irq(dev, vop->irq, vop_isr,
			       IRQF_SHARED, dev_name(dev), vop);
	if (ret)
		goto err_disable_pm_runtime;

	/* IRQ is initially disabled; it gets enabled in power_on */
	disable_irq(vop->irq);

	return 0;

err_disable_pm_runtime:
	pm_runtime_disable(&pdev->dev);
	vop_destroy_crtc(vop);
err_enable_irq:
	enable_irq(vop->irq); /* To balance out the disable_irq above */
	return ret;
}