diff --git a/drivers/macintosh/via-cuda.c b/drivers/macintosh/via-cuda.c index dd51df5a6ec0..64a04af248a1 100644 --- a/drivers/macintosh/via-cuda.c +++ b/drivers/macintosh/via-cuda.c @@ -65,6 +65,36 @@ static DEFINE_SPINLOCK(cuda_lock); #define IER_CLR 0 /* clear bits in IER */ #define SR_INT 0x04 /* Shift register full/empty */ +static inline bool TREQ_asserted(u8 portb) +{ + return !(portb & TREQ); +} + +static inline void assert_TIP(void) +{ + out_8(&via[B], in_8(&via[B]) & ~TIP); +} + +static inline void assert_TACK(void) +{ + out_8(&via[B], in_8(&via[B]) & ~TACK); +} + +static inline void toggle_TACK(void) +{ + out_8(&via[B], in_8(&via[B]) ^ TACK); +} + +static inline void negate_TACK(void) +{ + out_8(&via[B], in_8(&via[B]) | TACK); +} + +static inline void negate_TIP_and_TACK(void) +{ + out_8(&via[B], in_8(&via[B]) | TIP | TACK); +} + static enum cuda_state { idle, sent_first_byte, @@ -262,7 +292,7 @@ static int __init cuda_init_via(void) { out_8(&via[DIRB], (in_8(&via[DIRB]) | TACK | TIP) & ~TREQ); /* TACK & TIP out */ - out_8(&via[B], in_8(&via[B]) | TACK | TIP); /* negate them */ + negate_TIP_and_TACK(); out_8(&via[ACR] ,(in_8(&via[ACR]) & ~SR_CTRL) | SR_EXT); /* SR data in */ (void)in_8(&via[SR]); /* clear any left-over data */ #ifdef CONFIG_PPC @@ -278,10 +308,10 @@ __init cuda_init_via(void) out_8(&via[IFR], SR_INT); /* sync with the CUDA - assert TACK without TIP */ - out_8(&via[B], in_8(&via[B]) & ~TACK); + assert_TACK(); /* wait for the CUDA to assert TREQ in response */ - WAIT_FOR((in_8(&via[B]) & TREQ) == 0, "CUDA response to sync"); + WAIT_FOR(TREQ_asserted(in_8(&via[B])), "CUDA response to sync"); /* wait for the interrupt and then clear it */ WAIT_FOR(in_8(&via[IFR]) & SR_INT, "CUDA response to sync (2)"); @@ -289,14 +319,13 @@ __init cuda_init_via(void) out_8(&via[IFR], SR_INT); /* finish the sync by negating TACK */ - out_8(&via[B], in_8(&via[B]) | TACK); + negate_TACK(); /* wait for the CUDA to negate TREQ and the corresponding interrupt */ - WAIT_FOR(in_8(&via[B]) & TREQ, "CUDA response to sync (3)"); + WAIT_FOR(!TREQ_asserted(in_8(&via[B])), "CUDA response to sync (3)"); WAIT_FOR(in_8(&via[IFR]) & SR_INT, "CUDA response to sync (4)"); (void)in_8(&via[SR]); out_8(&via[IFR], SR_INT); - out_8(&via[B], in_8(&via[B]) | TIP); /* should be unnecessary */ return 0; } @@ -417,13 +446,13 @@ cuda_start(void) /* assert cuda_state == idle */ if (current_req == NULL) return; - if ((in_8(&via[B]) & TREQ) == 0) + if (TREQ_asserted(in_8(&via[B]))) return; /* a byte is coming in from the CUDA */ /* set the shift register to shift out and send a byte */ out_8(&via[ACR], in_8(&via[ACR]) | SR_OUT); out_8(&via[SR], current_req->data[0]); - out_8(&via[B], in_8(&via[B]) & ~TIP); + assert_TIP(); cuda_state = sent_first_byte; } @@ -444,7 +473,7 @@ EXPORT_SYMBOL(cuda_poll); static irqreturn_t cuda_interrupt(int irq, void *arg) { - int status; + u8 status; struct adb_request *req = NULL; unsigned char ibuf[16]; int ibuf_len = 0; @@ -469,13 +498,14 @@ cuda_interrupt(int irq, void *arg) out_8(&via[IFR], SR_INT); } } - - status = (~in_8(&via[B]) & (TIP|TREQ)) | (in_8(&via[ACR]) & SR_OUT); + + status = in_8(&via[B]) & (TIP | TACK | TREQ); + switch (cuda_state) { case idle: /* CUDA has sent us the first byte of data - unsolicited */ (void)in_8(&via[SR]); - out_8(&via[B], in_8(&via[B]) & ~TIP); + assert_TIP(); cuda_state = reading; reply_ptr = cuda_rbuf; reading_reply = 0; @@ -484,22 +514,22 @@ cuda_interrupt(int irq, void *arg) case awaiting_reply: /* CUDA has sent us the first byte of data of a reply */ (void)in_8(&via[SR]); - out_8(&via[B], in_8(&via[B]) & ~TIP); + assert_TIP(); cuda_state = reading; reply_ptr = current_req->reply; reading_reply = 1; break; case sent_first_byte: - if (status == TREQ + TIP + SR_OUT) { + if (TREQ_asserted(status)) { /* collision */ out_8(&via[ACR], in_8(&via[ACR]) & ~SR_OUT); (void)in_8(&via[SR]); - out_8(&via[B], in_8(&via[B]) | TIP | TACK); + negate_TIP_and_TACK(); cuda_state = idle; } else { out_8(&via[SR], current_req->data[1]); - out_8(&via[B], in_8(&via[B]) ^ TACK); + toggle_TACK(); data_index = 2; cuda_state = sending; } @@ -510,7 +540,7 @@ cuda_interrupt(int irq, void *arg) if (data_index >= req->nbytes) { out_8(&via[ACR], in_8(&via[ACR]) & ~SR_OUT); (void)in_8(&via[SR]); - out_8(&via[B], in_8(&via[B]) | TACK | TIP); + negate_TIP_and_TACK(); req->sent = 1; if (req->reply_expected) { cuda_state = awaiting_reply; @@ -523,18 +553,18 @@ cuda_interrupt(int irq, void *arg) } } else { out_8(&via[SR], req->data[data_index++]); - out_8(&via[B], in_8(&via[B]) ^ TACK); + toggle_TACK(); } break; case reading: *reply_ptr++ = in_8(&via[SR]); - if (status == TIP) { + if (!TREQ_asserted(status)) { /* that's all folks */ - out_8(&via[B], in_8(&via[B]) | TACK | TIP); + negate_TIP_and_TACK(); cuda_state = read_done; } else { - out_8(&via[B], in_8(&via[B]) ^ TACK); + toggle_TACK(); } break; @@ -567,8 +597,8 @@ cuda_interrupt(int irq, void *arg) ibuf_len = reply_ptr - cuda_rbuf; memcpy(ibuf, cuda_rbuf, ibuf_len); } - if (status == TREQ) { - out_8(&via[B], in_8(&via[B]) & ~TIP); + if (TREQ_asserted(status)) { + assert_TIP(); cuda_state = reading; reply_ptr = cuda_rbuf; reading_reply = 0;