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

macintosh/via-macii: Simplify locking



Modifying the request queue or changing the current state requires
mutual exclusion. Use local_irq_disable() consistently for this
rather than disabling the ADB interrupt. This simplifies the locking
scheme and brings via-macii into line with the other ADB drivers.

Tested-by: default avatarStan Johnson <userm57@yahoo.com>
Signed-off-by: default avatarFinn Thain <fthain@telegraphics.com.au>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 5f93d708
Loading
Loading
Loading
Loading
+18 −8
Original line number Original line Diff line number Diff line
@@ -216,22 +216,23 @@ static void macii_queue_poll(void)
static int macii_send_request(struct adb_request *req, int sync)
static int macii_send_request(struct adb_request *req, int sync)
{
{
	int err;
	int err;
	unsigned long flags;


	local_irq_save(flags);
	err = macii_write(req);
	err = macii_write(req);
	local_irq_restore(flags);
	if (err)
		return err;


	if (!err && sync)
	if (sync)
		while (!req->complete)
		while (!req->complete)
			macii_poll();
			macii_poll();


	return err;
	return 0;
}
}


/* Send an ADB request (append to request queue) */
/* Send an ADB request (append to request queue) */
static int macii_write(struct adb_request *req)
static int macii_write(struct adb_request *req)
{
{
	unsigned long flags;

	if (req->nbytes < 2 || req->data[0] != ADB_PACKET || req->nbytes > 15) {
	if (req->nbytes < 2 || req->data[0] != ADB_PACKET || req->nbytes > 15) {
		req->complete = 1;
		req->complete = 1;
		return -EINVAL;
		return -EINVAL;
@@ -242,6 +243,8 @@ static int macii_write(struct adb_request *req)
	req->complete = 0;
	req->complete = 0;
	req->reply_len = 0;
	req->reply_len = 0;


	local_irq_save(flags);

	if (current_req != NULL) {
	if (current_req != NULL) {
		last_req->next = req;
		last_req->next = req;
		last_req = req;
		last_req = req;
@@ -250,6 +253,9 @@ static int macii_write(struct adb_request *req)
		last_req = req;
		last_req = req;
		if (macii_state == idle) macii_start();
		if (macii_state == idle) macii_start();
	}
	}

	local_irq_restore(flags);

	return 0;
	return 0;
}
}


@@ -293,9 +299,7 @@ static inline int need_autopoll(void) {
/* Prod the chip without interrupts */
/* Prod the chip without interrupts */
static void macii_poll(void)
static void macii_poll(void)
{
{
	disable_irq(IRQ_MAC_ADB);
	macii_interrupt(0, NULL);
	macii_interrupt(0, NULL);
	enable_irq(IRQ_MAC_ADB);
}
}


/* Reset the bus */
/* Reset the bus */
@@ -358,14 +362,19 @@ static irqreturn_t macii_interrupt(int irq, void *arg)
{
{
	int x;
	int x;
	struct adb_request *req;
	struct adb_request *req;
	unsigned long flags;

	local_irq_save(flags);


	if (!arg) {
	if (!arg) {
		/* Clear the SR IRQ flag when polling. */
		/* Clear the SR IRQ flag when polling. */
		if (via[IFR] & SR_INT)
		if (via[IFR] & SR_INT)
			via[IFR] = SR_INT;
			via[IFR] = SR_INT;
		else
		else {
			local_irq_restore(flags);
			return IRQ_NONE;
			return IRQ_NONE;
		}
		}
	}


	last_status = status;
	last_status = status;
	status = via[B] & (ST_MASK|CTLR_IRQ);
	status = via[B] & (ST_MASK|CTLR_IRQ);
@@ -512,5 +521,6 @@ static irqreturn_t macii_interrupt(int irq, void *arg)
		break;
		break;
	}
	}


	local_irq_restore(flags);
	return IRQ_HANDLED;
	return IRQ_HANDLED;
}
}