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

Commit 3027691e authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt
Browse files

powerpc/pmac: Don't add_timer() twice



If the interrupt and the timeout happen roughly at the same
time, we can get into a situation where the timer function
is run while the interrupt has already been processed. In
this case, the timer function might end up doing an add_timer
on an already pending timer, causing a BUG_ON() to trigger.

Instead, just skip the whole timeout operation if we see that
the timer is pending. The spinlock ensures that the only way
that happens is if we already started a new operation and thus
the timeout can be ignored.

Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 2ef822c5
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -366,11 +366,20 @@ static void kw_i2c_timeout(unsigned long data)
	unsigned long flags;

	spin_lock_irqsave(&host->lock, flags);

	/*
	 * If the timer is pending, that means we raced with the
	 * irq, in which case we just return
	 */
	if (timer_pending(&host->timeout_timer))
		goto skip;

	kw_i2c_handle_interrupt(host, kw_read_reg(reg_isr));
	if (host->state != state_idle) {
		host->timeout_timer.expires = jiffies + KW_POLL_TIMEOUT;
		add_timer(&host->timeout_timer);
	}
 skip:
	spin_unlock_irqrestore(&host->lock, flags);
}