Commit b16b6768 authored by Finn Thain's avatar Finn Thain Committed by Michael Ellerman
Browse files

macintosh/via-macii: Remove read_done state



The driver state machine may enter the 'read_done' state when leaving the
'idle' or 'reading' state. This transition is pointless, as is the extra
interrupt it requires. The interrupt is produced by the transceiver
(even when it has no data to send) because an extra EVEN/ODD toggle
was signalled by the driver. Drop the extra state to simplify the code.

Fixes: 1da177e4 ("Linux-2.6.12-rc2") # v5.0+
Signed-off-by: default avatarFinn Thain <fthain@telegraphics.com.au>
Tested-by: default avatarStan Johnson <userm57@yahoo.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/0253194363af4426f9788796811a6a29fb87c713.1593318192.git.fthain@telegraphics.com.au
parent b4d76c28
Loading
Loading
Loading
Loading
+28 −42
Original line number Diff line number Diff line
@@ -110,7 +110,6 @@ static enum macii_state {
	idle,
	sending,
	reading,
	read_done,
} macii_state;

static struct adb_request *current_req; /* first request struct in the queue */
@@ -411,8 +410,8 @@ static irqreturn_t macii_interrupt(int irq, void *arg)
			reply_len = 1;
		} else {
			/* bus timeout */
			macii_state = read_done;
			reply_len = 0;
			break;
		}

		/* set ADB state = even for first data byte */
@@ -471,20 +470,6 @@ static irqreturn_t macii_interrupt(int irq, void *arg)
				current_req = req->next;
				if (req->done)
					(*req->done)(req);

				if (!current_req)
					macii_queue_poll();

				if (current_req && macii_state == idle)
					macii_start();

				if (macii_state == idle) {
					/* reset to shift in */
					via[ACR] &= ~SR_OUT;
					x = via[SR];
					/* set ADB state idle - might get SRQ */
					via[B] = (via[B] & ~ST_MASK) | ST_IDLE;
				}
				break;
			}
		} else {
@@ -511,52 +496,53 @@ static irqreturn_t macii_interrupt(int irq, void *arg)
			} else if (status == ST_ODD && reply_len == 2) {
				srq_asserted = true;
			} else {
				macii_state = read_done;
			}
		}

		if (macii_state == reading &&
		    reply_len < ARRAY_SIZE(reply_buf)) {
			reply_ptr++;
			*reply_ptr = x;
			reply_len++;
		}

		/* invert state bits, toggle ODD/EVEN */
		via[B] ^= ST_MASK;
		break;

	case read_done:
		x = via[SR];
				macii_state = idle;

				if (bus_timeout)
					reply_len = 0;

				if (reading_reply) {
			reading_reply = 0;
			req = current_req;
					struct adb_request *req = current_req;

					req->reply_len = reply_len;

					req->complete = 1;
					current_req = req->next;
					if (req->done)
						(*req->done)(req);
		} else if (reply_len && autopoll_devs)
				} else if (reply_len && autopoll_devs) {
					adb_input(reply_buf, reply_len, 0);
				}
				break;
			}
		}

		macii_state = idle;
		if (reply_len < ARRAY_SIZE(reply_buf)) {
			reply_ptr++;
			*reply_ptr = x;
			reply_len++;
		}

		/* invert state bits, toggle ODD/EVEN */
		via[B] ^= ST_MASK;
		break;

	default:
		break;
	}

	if (macii_state == idle) {
		if (!current_req)
			macii_queue_poll();

		if (current_req)
			macii_start();

		if (macii_state == idle)
		if (macii_state == idle) {
			via[ACR] &= ~SR_OUT;
			x = via[SR];
			via[B] = (via[B] & ~ST_MASK) | ST_IDLE;
		break;

	default:
		break;
		}
	}

	local_irq_restore(flags);