Deleted Added
full compact
bcm2835_mbox.c (261884) bcm2835_mbox.c (275963)
1/*-
2 * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/arm/broadcom/bcm2835/bcm2835_mbox.c 261884 2014-02-14 11:18:15Z brueffer $");
28__FBSDID("$FreeBSD: head/sys/arm/broadcom/bcm2835/bcm2835_mbox.c 275963 2014-12-20 19:15:10Z rpaulo $");
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/bus.h>
33#include <sys/kernel.h>
34#include <sys/module.h>
35#include <sys/malloc.h>
36#include <sys/rman.h>
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/bus.h>
33#include <sys/kernel.h>
34#include <sys/module.h>
35#include <sys/malloc.h>
36#include <sys/rman.h>
37#include <sys/sema.h>
37#include <sys/timeet.h>
38#include <sys/timetc.h>
39#include <sys/watchdog.h>
40#include <machine/bus.h>
41#include <machine/cpu.h>
42#include <machine/intr.h>
43
44#include <dev/fdt/fdt_common.h>

--- 38 unchanged lines hidden (view full) ---

83
84struct bcm_mbox_softc {
85 struct mtx lock;
86 struct resource * mem_res;
87 struct resource * irq_res;
88 void* intr_hl;
89 bus_space_tag_t bst;
90 bus_space_handle_t bsh;
38#include <sys/timeet.h>
39#include <sys/timetc.h>
40#include <sys/watchdog.h>
41#include <machine/bus.h>
42#include <machine/cpu.h>
43#include <machine/intr.h>
44
45#include <dev/fdt/fdt_common.h>

--- 38 unchanged lines hidden (view full) ---

84
85struct bcm_mbox_softc {
86 struct mtx lock;
87 struct resource * mem_res;
88 struct resource * irq_res;
89 void* intr_hl;
90 bus_space_tag_t bst;
91 bus_space_handle_t bsh;
91 int valid[BCM2835_MBOX_CHANS];
92 int msg[BCM2835_MBOX_CHANS];
92 int msg[BCM2835_MBOX_CHANS];
93 struct sema sema[BCM2835_MBOX_CHANS];
93};
94
95#define mbox_read_4(sc, reg) \
96 bus_space_read_4((sc)->bst, (sc)->bsh, reg)
97#define mbox_write_4(sc, reg, val) \
98 bus_space_write_4((sc)->bst, (sc)->bsh, reg, val)
99
100static void
101bcm_mbox_intr(void *arg)
102{
103 struct bcm_mbox_softc *sc = arg;
104 int chan;
105 uint32_t data;
106 uint32_t msg;
107
94};
95
96#define mbox_read_4(sc, reg) \
97 bus_space_read_4((sc)->bst, (sc)->bsh, reg)
98#define mbox_write_4(sc, reg, val) \
99 bus_space_write_4((sc)->bst, (sc)->bsh, reg, val)
100
101static void
102bcm_mbox_intr(void *arg)
103{
104 struct bcm_mbox_softc *sc = arg;
105 int chan;
106 uint32_t data;
107 uint32_t msg;
108
108 MBOX_LOCK(sc);
109 while (!(mbox_read_4(sc, REG_STATUS) & STATUS_EMPTY)) {
110 msg = mbox_read_4(sc, REG_READ);
111 dprintf("bcm_mbox_intr: raw data %08x\n", msg);
112 chan = MBOX_CHAN(msg);
113 data = MBOX_DATA(msg);
109 while (!(mbox_read_4(sc, REG_STATUS) & STATUS_EMPTY)) {
110 msg = mbox_read_4(sc, REG_READ);
111 dprintf("bcm_mbox_intr: raw data %08x\n", msg);
112 chan = MBOX_CHAN(msg);
113 data = MBOX_DATA(msg);
114 if (sc->valid[chan]) {
114 if (sc->msg[chan]) {
115 printf("bcm_mbox_intr: channel %d oveflow\n", chan);
116 continue;
117 }
118 dprintf("bcm_mbox_intr: chan %d, data %08x\n", chan, data);
115 printf("bcm_mbox_intr: channel %d oveflow\n", chan);
116 continue;
117 }
118 dprintf("bcm_mbox_intr: chan %d, data %08x\n", chan, data);
119 sc->msg[chan] = data;
120 sc->valid[chan] = 1;
121 wakeup(&sc->msg[chan]);
122
119 sc->msg[chan] = MBOX_MSG(data, 0xf);
120 sema_post(&sc->sema[chan]);
123 }
121 }
124 MBOX_UNLOCK(sc);
125}
126
127static int
128bcm_mbox_probe(device_t dev)
129{
130
131 if (!ofw_bus_status_okay(dev))
132 return (ENXIO);

--- 34 unchanged lines hidden (view full) ---

167 NULL, bcm_mbox_intr, sc, &sc->intr_hl) != 0) {
168 bus_release_resource(dev, SYS_RES_IRQ, rid, sc->irq_res);
169 device_printf(dev, "Unable to setup the clock irq handler.\n");
170 return (ENXIO);
171 }
172
173 mtx_init(&sc->lock, "vcio mbox", NULL, MTX_DEF);
174 for (i = 0; i < BCM2835_MBOX_CHANS; i++) {
122}
123
124static int
125bcm_mbox_probe(device_t dev)
126{
127
128 if (!ofw_bus_status_okay(dev))
129 return (ENXIO);

--- 34 unchanged lines hidden (view full) ---

164 NULL, bcm_mbox_intr, sc, &sc->intr_hl) != 0) {
165 bus_release_resource(dev, SYS_RES_IRQ, rid, sc->irq_res);
166 device_printf(dev, "Unable to setup the clock irq handler.\n");
167 return (ENXIO);
168 }
169
170 mtx_init(&sc->lock, "vcio mbox", NULL, MTX_DEF);
171 for (i = 0; i < BCM2835_MBOX_CHANS; i++) {
175 sc->valid[0] = 0;
176 sc->msg[0] = 0;
172 sc->msg[i] = 0;
173 sema_init(&sc->sema[i], 0, "mbox");
177 }
178
179 /* Read all pending messages */
180 bcm_mbox_intr(sc);
181
182 mbox_write_4(sc, REG_CONFIG, CONFIG_DATA_IRQ);
183
184 return (0);

--- 29 unchanged lines hidden (view full) ---

214
215static int
216bcm_mbox_read(device_t dev, int chan, uint32_t *data)
217{
218 struct bcm_mbox_softc *sc = device_get_softc(dev);
219
220 dprintf("bcm_mbox_read: chan %d\n", chan);
221 MBOX_LOCK(sc);
174 }
175
176 /* Read all pending messages */
177 bcm_mbox_intr(sc);
178
179 mbox_write_4(sc, REG_CONFIG, CONFIG_DATA_IRQ);
180
181 return (0);

--- 29 unchanged lines hidden (view full) ---

211
212static int
213bcm_mbox_read(device_t dev, int chan, uint32_t *data)
214{
215 struct bcm_mbox_softc *sc = device_get_softc(dev);
216
217 dprintf("bcm_mbox_read: chan %d\n", chan);
218 MBOX_LOCK(sc);
222 while (!sc->valid[chan])
223 msleep(&sc->msg[chan], &sc->lock, PZERO, "vcio mbox read", 0);
224 *data = sc->msg[chan];
225 sc->valid[chan] = 0;
219 while (sema_trywait(&sc->sema[chan]) == 0) {
220 /* do not unlock sc while waiting for the mbox */
221 if (sema_timedwait(&sc->sema[chan], 10*hz) == 0)
222 break;
223 printf("timeout sema for chan %d\n", chan);
224 }
225 /*
226 * get data from intr handler, the same channel is never coming
227 * because of holding sc lock.
228 */
229 *data = MBOX_DATA(sc->msg[chan]);
230 sc->msg[chan] = 0;
226 MBOX_UNLOCK(sc);
227 dprintf("bcm_mbox_read: chan %d, data %08x\n", chan, *data);
228
229 return (0);
230}
231
232static device_method_t bcm_mbox_methods[] = {
233 DEVMETHOD(device_probe, bcm_mbox_probe),

--- 18 unchanged lines hidden ---
231 MBOX_UNLOCK(sc);
232 dprintf("bcm_mbox_read: chan %d, data %08x\n", chan, *data);
233
234 return (0);
235}
236
237static device_method_t bcm_mbox_methods[] = {
238 DEVMETHOD(device_probe, bcm_mbox_probe),

--- 18 unchanged lines hidden ---