summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFinn Thain <fthain@telegraphics.com.au>2016-12-31 19:56:26 -0500
committerBen Hutchings <ben@decadent.org.uk>2018-10-03 04:10:07 +0100
commit30170db328324e249143de296a3a56f0a2371493 (patch)
tree4070a835a77340cddc31fc575b3946bfb20a4c62
parentb579b8f2128ee2b9e9393b6a18297bb79080ef34 (diff)
via-cuda: Use spinlock_irq_save/restore instead of enable/disable_irq
commit ac39452e942af6a212e8f89e8a36b71354323845 upstream. The cuda_start() function uses spinlock_irq_save/restore for mutual exclusion. Let's have cuda_poll() do the same when polling the VIA interrupt. The benefit to disabling local irqs when the interrupt is being polled is that the interrupt handler now has the same timing properties regardless of whether it is invoked normally or from cuda_poll(). This driver was written back when local irqs remained enabled during execution of interrupt handlers and cuda_poll() was probably trying to achieve the same effect by use of enable/disable_irq. Tested-by: Stan Johnson <userm57@yahoo.com> Signed-off-by: Finn Thain <fthain@telegraphics.com.au> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r--drivers/macintosh/via-cuda.c16
1 files changed, 5 insertions, 11 deletions
diff --git a/drivers/macintosh/via-cuda.c b/drivers/macintosh/via-cuda.c
index d61f271d2207..2d8c56360fb8 100644
--- a/drivers/macintosh/via-cuda.c
+++ b/drivers/macintosh/via-cuda.c
@@ -432,26 +432,20 @@ cuda_start(void)
void
cuda_poll(void)
{
- /* cuda_interrupt only takes a normal lock, we disable
- * interrupts here to avoid re-entering and thus deadlocking.
- */
- if (cuda_irq)
- disable_irq(cuda_irq);
- cuda_interrupt(0, NULL);
- if (cuda_irq)
- enable_irq(cuda_irq);
+ cuda_interrupt(0, NULL);
}
static irqreturn_t
cuda_interrupt(int irq, void *arg)
{
+ unsigned long flags;
int status;
struct adb_request *req = NULL;
unsigned char ibuf[16];
int ibuf_len = 0;
int complete = 0;
- spin_lock(&cuda_lock);
+ spin_lock_irqsave(&cuda_lock, flags);
/* On powermacs, this handler is registered for the VIA IRQ. But they use
* just the shift register IRQ -- other VIA interrupt sources are disabled.
@@ -464,7 +458,7 @@ cuda_interrupt(int irq, void *arg)
#endif
{
if ((in_8(&via[IFR]) & SR_INT) == 0) {
- spin_unlock(&cuda_lock);
+ spin_unlock_irqrestore(&cuda_lock, flags);
return IRQ_NONE;
} else {
out_8(&via[IFR], SR_INT);
@@ -593,7 +587,7 @@ cuda_interrupt(int irq, void *arg)
default:
printk("cuda_interrupt: unknown cuda_state %d?\n", cuda_state);
}
- spin_unlock(&cuda_lock);
+ spin_unlock_irqrestore(&cuda_lock, flags);
if (complete && req) {
void (*done)(struct adb_request *) = req->done;
mb();