Skip to content

Commit

Permalink
drm/tidss: Clear the interrupt status for interrupts being disabled
Browse files Browse the repository at this point in the history
The driver does not touch the irqstatus register when it is disabling
interrupts.  This might cause an interrupt to trigger for an interrupt
that was just disabled.

To fix the issue, clear the irqstatus registers right after disabling
the interrupts.

Fixes: 32a1795 ("drm/tidss: New driver for TI Keystone platform Display SubSystem")
Cc: stable@vger.kernel.org
Reported-by: Jonathan Cormier <jcormier@criticallink.com>
Closes: https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1394222/am625-issue-about-tidss-rcu_preempt-self-detected-stall-on-cpu/5424479#5424479
Signed-off-by: Devarsh Thakkar <devarsht@ti.com>
[Tomi: mostly rewrote the patch]
Reviewed-by: Jonathan Cormier <jcormier@criticallink.com>
Tested-by: Jonathan Cormier <jcormier@criticallink.com>
Reviewed-by: Aradhya Bhatia <aradhya.bhatia@linux.dev>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20241021-tidss-irq-fix-v1-5-82ddaec94e4a@ideasonboard.com
  • Loading branch information
Devarsh Thakkar authored and Tomi Valkeinen committed Nov 25, 2024
1 parent 76bae5b commit 361a2eb
Showing 1 changed file with 8 additions and 2 deletions.
10 changes: 8 additions & 2 deletions drivers/gpu/drm/tidss/tidss_dispc.c
Original file line number Diff line number Diff line change
Expand Up @@ -700,14 +700,17 @@ void dispc_k2g_set_irqenable(struct dispc_device *dispc, dispc_irq_t mask)
{
dispc_irq_t old_mask = dispc_k2g_read_irqenable(dispc);

/* clear the irqstatus for newly enabled irqs */
/* clear the irqstatus for irqs that will be enabled */
dispc_k2g_clear_irqstatus(dispc, (mask ^ old_mask) & mask);

dispc_k2g_vp_set_irqenable(dispc, 0, mask);
dispc_k2g_vid_set_irqenable(dispc, 0, mask);

dispc_write(dispc, DISPC_IRQENABLE_SET, (1 << 0) | (1 << 7));

/* clear the irqstatus for irqs that were disabled */
dispc_k2g_clear_irqstatus(dispc, (mask ^ old_mask) & old_mask);

/* flush posted write */
dispc_k2g_read_irqenable(dispc);
}
Expand Down Expand Up @@ -837,7 +840,7 @@ static void dispc_k3_set_irqenable(struct dispc_device *dispc,

old_mask = dispc_k3_read_irqenable(dispc);

/* clear the irqstatus for newly enabled irqs */
/* clear the irqstatus for irqs that will be enabled */
dispc_k3_clear_irqstatus(dispc, (old_mask ^ mask) & mask);

for (i = 0; i < dispc->feat->num_vps; ++i) {
Expand All @@ -862,6 +865,9 @@ static void dispc_k3_set_irqenable(struct dispc_device *dispc,
if (main_disable)
dispc_write(dispc, DISPC_IRQENABLE_CLR, main_disable);

/* clear the irqstatus for irqs that were disabled */
dispc_k3_clear_irqstatus(dispc, (old_mask ^ mask) & old_mask);

/* Flush posted writes */
dispc_read(dispc, DISPC_IRQENABLE_SET);
}
Expand Down

0 comments on commit 361a2eb

Please sign in to comment.