Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/panthor: Rework panthor_irq::suspended into panthor_irq::state

To deal with the threaded interrupt handler and a suspend action
overlapping, the boolean panthor_irq::suspended is not sufficient.

Rework it into taking several different values depending on the current
state, and check it and set it within the IRQ helper functions.

Co-developed-by: Boris Brezillon <boris.brezillon@collabora.com>
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Reviewed-by: Steven Price <steven.price@arm.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Link: https://patch.msgid.link/20260116-panthor-tracepoints-v10-1-d925986e3d1b@collabora.com

authored by

Nicolas Frattaroli and committed by
Boris Brezillon
0b2d8667 68b271a3

+28 -7
+28 -7
drivers/gpu/drm/panthor/panthor_device.h
··· 61 61 PANTHOR_DEVICE_PM_STATE_SUSPENDING, 62 62 }; 63 63 64 + enum panthor_irq_state { 65 + /** @PANTHOR_IRQ_STATE_ACTIVE: IRQ is active and ready to process events. */ 66 + PANTHOR_IRQ_STATE_ACTIVE = 0, 67 + /** @PANTHOR_IRQ_STATE_PROCESSING: IRQ is currently processing events. */ 68 + PANTHOR_IRQ_STATE_PROCESSING, 69 + /** @PANTHOR_IRQ_STATE_SUSPENDED: IRQ is suspended. */ 70 + PANTHOR_IRQ_STATE_SUSPENDED, 71 + /** @PANTHOR_IRQ_STATE_SUSPENDING: IRQ is being suspended. */ 72 + PANTHOR_IRQ_STATE_SUSPENDING, 73 + }; 74 + 64 75 /** 65 76 * struct panthor_irq - IRQ data 66 77 * ··· 87 76 /** @mask: Current mask being applied to xxx_INT_MASK. */ 88 77 u32 mask; 89 78 90 - /** @suspended: Set to true when the IRQ is suspended. */ 91 - atomic_t suspended; 79 + /** @state: one of &enum panthor_irq_state reflecting the current state. */ 80 + atomic_t state; 92 81 }; 93 82 94 83 /** ··· 420 409 { \ 421 410 struct panthor_irq *pirq = data; \ 422 411 struct panthor_device *ptdev = pirq->ptdev; \ 412 + enum panthor_irq_state old_state; \ 423 413 \ 424 - if (atomic_read(&pirq->suspended)) \ 425 - return IRQ_NONE; \ 426 414 if (!gpu_read(ptdev, __reg_prefix ## _INT_STAT)) \ 415 + return IRQ_NONE; \ 416 + \ 417 + old_state = atomic_cmpxchg(&pirq->state, \ 418 + PANTHOR_IRQ_STATE_ACTIVE, \ 419 + PANTHOR_IRQ_STATE_PROCESSING); \ 420 + if (old_state != PANTHOR_IRQ_STATE_ACTIVE) \ 427 421 return IRQ_NONE; \ 428 422 \ 429 423 gpu_write(ptdev, __reg_prefix ## _INT_MASK, 0); \ ··· 439 423 { \ 440 424 struct panthor_irq *pirq = data; \ 441 425 struct panthor_device *ptdev = pirq->ptdev; \ 426 + enum panthor_irq_state old_state; \ 442 427 irqreturn_t ret = IRQ_NONE; \ 443 428 \ 444 429 while (true) { \ ··· 452 435 ret = IRQ_HANDLED; \ 453 436 } \ 454 437 \ 455 - if (!atomic_read(&pirq->suspended)) \ 438 + old_state = atomic_cmpxchg(&pirq->state, \ 439 + PANTHOR_IRQ_STATE_PROCESSING, \ 440 + PANTHOR_IRQ_STATE_ACTIVE); \ 441 + if (old_state == PANTHOR_IRQ_STATE_PROCESSING) \ 456 442 gpu_write(ptdev, __reg_prefix ## _INT_MASK, pirq->mask); \ 457 443 \ 458 444 return ret; \ ··· 465 445 { \ 466 446 pirq->mask = 0; \ 467 447 gpu_write(pirq->ptdev, __reg_prefix ## _INT_MASK, 0); \ 448 + atomic_set(&pirq->state, PANTHOR_IRQ_STATE_SUSPENDING); \ 468 449 synchronize_irq(pirq->irq); \ 469 - atomic_set(&pirq->suspended, true); \ 450 + atomic_set(&pirq->state, PANTHOR_IRQ_STATE_SUSPENDED); \ 470 451 } \ 471 452 \ 472 453 static inline void panthor_ ## __name ## _irq_resume(struct panthor_irq *pirq, u32 mask) \ 473 454 { \ 474 - atomic_set(&pirq->suspended, false); \ 475 455 pirq->mask = mask; \ 456 + atomic_set(&pirq->state, PANTHOR_IRQ_STATE_ACTIVE); \ 476 457 gpu_write(pirq->ptdev, __reg_prefix ## _INT_CLEAR, mask); \ 477 458 gpu_write(pirq->ptdev, __reg_prefix ## _INT_MASK, mask); \ 478 459 } \