diff options
author | Finn Thain <fthain@telegraphics.com.au> | 2017-10-26 22:45:24 -0400 |
---|---|---|
committer | Geert Uytterhoeven <geert@linux-m68k.org> | 2017-11-09 17:02:57 -0500 |
commit | 92178fcabbcd39fc9ccd4e58ec4be83dd5323a46 (patch) | |
tree | e06ac4b6dd750c56f16f8c29e2a58a9eb855da1a | |
parent | 8ee90c5c3fd1af8e68133defb15cfc66c1de3f88 (diff) |
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: Stan Johnson <userm57@yahoo.com>
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
-rw-r--r-- | arch/m68k/include/asm/mac_iop.h | 1 | ||||
-rw-r--r-- | arch/m68k/mac/iop.c | 9 | ||||
-rw-r--r-- | drivers/macintosh/adb-iop.c | 4 |
3 files changed, 11 insertions, 3 deletions
diff --git a/arch/m68k/include/asm/mac_iop.h b/arch/m68k/include/asm/mac_iop.h index 42566fd052bc..d2a08e004e2c 100644 --- a/arch/m68k/include/asm/mac_iop.h +++ b/arch/m68k/include/asm/mac_iop.h | |||
@@ -158,6 +158,7 @@ extern void iop_complete_message(struct iop_msg *); | |||
158 | extern void iop_upload_code(uint, __u8 *, uint, __u16); | 158 | extern void iop_upload_code(uint, __u8 *, uint, __u16); |
159 | extern void iop_download_code(uint, __u8 *, uint, __u16); | 159 | extern void iop_download_code(uint, __u8 *, uint, __u16); |
160 | extern __u8 *iop_compare_code(uint, __u8 *, uint, __u16); | 160 | extern __u8 *iop_compare_code(uint, __u8 *, uint, __u16); |
161 | extern void iop_ism_irq_poll(uint); | ||
161 | 162 | ||
162 | extern void iop_register_interrupts(void); | 163 | extern void iop_register_interrupts(void); |
163 | 164 | ||
diff --git a/arch/m68k/mac/iop.c b/arch/m68k/mac/iop.c index a2ea52db7d18..9bfa17015768 100644 --- a/arch/m68k/mac/iop.c +++ b/arch/m68k/mac/iop.c | |||
@@ -598,3 +598,12 @@ irqreturn_t iop_ism_irq(int irq, void *dev_id) | |||
598 | } | 598 | } |
599 | return IRQ_HANDLED; | 599 | return IRQ_HANDLED; |
600 | } | 600 | } |
601 | |||
602 | void iop_ism_irq_poll(uint iop_num) | ||
603 | { | ||
604 | unsigned long flags; | ||
605 | |||
606 | local_irq_save(flags); | ||
607 | iop_ism_irq(0, (void *)iop_num); | ||
608 | local_irq_restore(flags); | ||
609 | } | ||
diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c index f5f4da3d0b67..4b0ad3995497 100644 --- a/drivers/macintosh/adb-iop.c +++ b/drivers/macintosh/adb-iop.c | |||
@@ -29,8 +29,6 @@ | |||
29 | 29 | ||
30 | /*#define DEBUG_ADB_IOP*/ | 30 | /*#define DEBUG_ADB_IOP*/ |
31 | 31 | ||
32 | extern void iop_ism_irq(int, void *); | ||
33 | |||
34 | static struct adb_request *current_req; | 32 | static struct adb_request *current_req; |
35 | static struct adb_request *last_req; | 33 | static struct adb_request *last_req; |
36 | #if 0 | 34 | #if 0 |
@@ -265,7 +263,7 @@ int adb_iop_autopoll(int devs) | |||
265 | void adb_iop_poll(void) | 263 | void adb_iop_poll(void) |
266 | { | 264 | { |
267 | if (adb_iop_state == idle) adb_iop_start(); | 265 | if (adb_iop_state == idle) adb_iop_start(); |
268 | iop_ism_irq(0, (void *) ADB_IOP); | 266 | iop_ism_irq_poll(ADB_IOP); |
269 | } | 267 | } |
270 | 268 | ||
271 | int adb_iop_reset_bus(void) | 269 | int adb_iop_reset_bus(void) |