Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 22 Feb 2015 11:11:06 +0000 (UTC)
From:      Andrew Turner <andrew@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r279153 - head/sys/arm/broadcom/bcm2835
Message-ID:  <201502221111.t1MBB6IR073728@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: andrew
Date: Sun Feb 22 11:11:05 2015
New Revision: 279153
URL: https://svnweb.freebsd.org/changeset/base/279153

Log:
  Add support to the bcm2835 mailbox driver to work before interrupts are
  enabled. This will be needed to enable the power on devices early on in the
  boot process.

Modified:
  head/sys/arm/broadcom/bcm2835/bcm2835_mbox.c

Modified: head/sys/arm/broadcom/bcm2835/bcm2835_mbox.c
==============================================================================
--- head/sys/arm/broadcom/bcm2835/bcm2835_mbox.c	Sun Feb 22 08:54:25 2015	(r279152)
+++ head/sys/arm/broadcom/bcm2835/bcm2835_mbox.c	Sun Feb 22 11:11:05 2015	(r279153)
@@ -89,27 +89,39 @@ struct bcm_mbox_softc {
 #define	mbox_write_4(sc, reg, val)		\
     bus_space_write_4((sc)->bst, (sc)->bsh, reg, val)
 
+static int
+bcm_mbox_read_msg(struct bcm_mbox_softc *sc, int *ochan)
+{
+	uint32_t data;
+	uint32_t msg;
+	int chan;
+
+	msg = mbox_read_4(sc, REG_READ);
+	dprintf("bcm_mbox_intr: raw data %08x\n", msg);
+	chan = MBOX_CHAN(msg);
+	data = MBOX_DATA(msg);
+	if (sc->msg[chan]) {
+		printf("bcm_mbox_intr: channel %d oveflow\n", chan);
+		return (1);
+	}
+	dprintf("bcm_mbox_intr: chan %d, data %08x\n", chan, data);
+	sc->msg[chan] = msg;
+
+	if (ochan != NULL)
+		*ochan = chan;
+
+	return (0);
+}
+
 static void
 bcm_mbox_intr(void *arg)
 {
 	struct bcm_mbox_softc *sc = arg;
 	int chan;
-	uint32_t data;
-	uint32_t msg;
 
-	while (!(mbox_read_4(sc, REG_STATUS) & STATUS_EMPTY)) {
-		msg = mbox_read_4(sc, REG_READ);
-		dprintf("bcm_mbox_intr: raw data %08x\n", msg);
-		chan = MBOX_CHAN(msg);
-		data = MBOX_DATA(msg);
-		if (sc->msg[chan]) {
-			printf("bcm_mbox_intr: channel %d oveflow\n", chan);
-			continue;
-		}
-		dprintf("bcm_mbox_intr: chan %d, data %08x\n", chan, data);
-		sc->msg[chan] = msg;
-		sema_post(&sc->sema[chan]);
-	}
+	while (!(mbox_read_4(sc, REG_STATUS) & STATUS_EMPTY))
+		if (bcm_mbox_read_msg(sc, &chan) == 0)
+			sema_post(&sc->sema[chan]);
 }
 
 static int
@@ -201,14 +213,30 @@ static int
 bcm_mbox_read(device_t dev, int chan, uint32_t *data)
 {
 	struct bcm_mbox_softc *sc = device_get_softc(dev);
+	int err, read_chan;
 
 	dprintf("bcm_mbox_read: chan %d\n", chan);
+
+	err = 0;
 	MBOX_LOCK(sc);
-	while (sema_trywait(&sc->sema[chan]) == 0) {
-		/* do not unlock sc while waiting for the mbox */
-		if (sema_timedwait(&sc->sema[chan], 10*hz) == 0)
-			break;
-		printf("timeout sema for chan %d\n", chan);
+	if (!cold) {
+		while (sema_trywait(&sc->sema[chan]) == 0) {
+			/* do not unlock sc while waiting for the mbox */
+			if (sema_timedwait(&sc->sema[chan], 10*hz) == 0)
+				break;
+			printf("timeout sema for chan %d\n", chan);
+		}
+	} else {
+		do {
+			/* Wait for a message */
+			while ((mbox_read_4(sc, REG_STATUS) & STATUS_EMPTY))
+				;
+			/* Read the message */
+			if (bcm_mbox_read_msg(sc, &read_chan) != 0) {
+				err = EINVAL;
+				goto out;
+			}
+		} while (read_chan != chan);
 	}
 	/*
 	 *  get data from intr handler, the same channel is never coming
@@ -216,10 +244,11 @@ bcm_mbox_read(device_t dev, int chan, ui
 	 */
 	*data = MBOX_DATA(sc->msg[chan]);
 	sc->msg[chan] = 0;
+out:
 	MBOX_UNLOCK(sc);
 	dprintf("bcm_mbox_read: chan %d, data %08x\n", chan, *data);
 
-	return (0);
+	return (err);
 }
 
 static device_method_t bcm_mbox_methods[] = {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201502221111.t1MBB6IR073728>