Commit 92178fca authored by Finn Thain's avatar Finn Thain Committed by Geert Uytterhoeven

m68k/mac: Add mutual exclusion for IOP interrupt polling

The IOP interrupt handler iop_ism_irq() is used by the adb-iop
driver to poll for ADB request completion. Unfortunately, it is not
re-entrant. Fix the race condition by adding an iop_ism_irq_poll()
function with suitable mutual exclusion.
Tested-by: default avatarStan Johnson <userm57@yahoo.com>
Signed-off-by: default avatarFinn Thain <fthain@telegraphics.com.au>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: default avatarGeert Uytterhoeven <geert@linux-m68k.org>
parent 8ee90c5c
...@@ -158,6 +158,7 @@ extern void iop_complete_message(struct iop_msg *); ...@@ -158,6 +158,7 @@ extern void iop_complete_message(struct iop_msg *);
extern void iop_upload_code(uint, __u8 *, uint, __u16); extern void iop_upload_code(uint, __u8 *, uint, __u16);
extern void iop_download_code(uint, __u8 *, uint, __u16); extern void iop_download_code(uint, __u8 *, uint, __u16);
extern __u8 *iop_compare_code(uint, __u8 *, uint, __u16); extern __u8 *iop_compare_code(uint, __u8 *, uint, __u16);
extern void iop_ism_irq_poll(uint);
extern void iop_register_interrupts(void); extern void iop_register_interrupts(void);
......
...@@ -598,3 +598,12 @@ irqreturn_t iop_ism_irq(int irq, void *dev_id) ...@@ -598,3 +598,12 @@ irqreturn_t iop_ism_irq(int irq, void *dev_id)
} }
return IRQ_HANDLED; return IRQ_HANDLED;
} }
void iop_ism_irq_poll(uint iop_num)
{
unsigned long flags;
local_irq_save(flags);
iop_ism_irq(0, (void *)iop_num);
local_irq_restore(flags);
}
...@@ -29,8 +29,6 @@ ...@@ -29,8 +29,6 @@
/*#define DEBUG_ADB_IOP*/ /*#define DEBUG_ADB_IOP*/
extern void iop_ism_irq(int, void *);
static struct adb_request *current_req; static struct adb_request *current_req;
static struct adb_request *last_req; static struct adb_request *last_req;
#if 0 #if 0
...@@ -265,7 +263,7 @@ int adb_iop_autopoll(int devs) ...@@ -265,7 +263,7 @@ int adb_iop_autopoll(int devs)
void adb_iop_poll(void) void adb_iop_poll(void)
{ {
if (adb_iop_state == idle) adb_iop_start(); if (adb_iop_state == idle) adb_iop_start();
iop_ism_irq(0, (void *) ADB_IOP); iop_ism_irq_poll(ADB_IOP);
} }
int adb_iop_reset_bus(void) int adb_iop_reset_bus(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment