10SN/A/*-
216534Sweijun * Copyright (c) 2006 Juniper Networks
30SN/A * All rights reserved.
40SN/A *
50SN/A * Redistribution and use in source and binary forms, with or without
60SN/A * modification, are permitted provided that the following conditions
72362SN/A * are met:
80SN/A *
92362SN/A * 1. Redistributions of source code must retain the above copyright
100SN/A *    notice, this list of conditions and the following disclaimer.
110SN/A * 2. Redistributions in binary form must reproduce the above copyright
120SN/A *    notice, this list of conditions and the following disclaimer in the
130SN/A *    documentation and/or other materials provided with the distribution.
140SN/A *
150SN/A * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
160SN/A * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
170SN/A * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
180SN/A * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
190SN/A * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
200SN/A * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
212362SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
222362SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
232362SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
240SN/A * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
250SN/A */
265976SN/A
270SN/A#include <sys/cdefs.h>
280SN/A__FBSDID("$FreeBSD$");
291803SN/A
3016788Sweijun#include <sys/param.h>
310SN/A#include <sys/systm.h>
320SN/A#include <sys/bus.h>
330SN/A#include <sys/conf.h>
340SN/A#include <sys/endian.h>
350SN/A#include <machine/bus.h>
360SN/A
370SN/A#include <dev/ic/quicc.h>
381803SN/A
390SN/A#include <dev/uart/uart.h>
400SN/A#include <dev/uart/uart_cpu.h>
410SN/A#include <dev/uart/uart_bus.h>
420SN/A
430SN/A#include "uart_if.h"
444644SN/A
452346SN/A#define	DEFAULT_RCLK	((266000000 * 2) / 16)
460SN/A
470SN/A#define	quicc_read2(bas, reg)		\
4811963Svaleriep	bus_space_read_2((bas)->bst, (bas)->bsh, reg)
4911963Svaleriep#define	quicc_read4(bas, reg)		\
5011963Svaleriep	bus_space_read_4((bas)->bst, (bas)->bsh, reg)
510SN/A
520SN/A#define	quicc_write2(bas, reg, val)	\
530SN/A	bus_space_write_2((bas)->bst, (bas)->bsh, reg, val)
541803SN/A#define	quicc_write4(bas, reg, val)	\
551803SN/A	bus_space_write_4((bas)->bst, (bas)->bsh, reg, val)
562346SN/A
572346SN/Astatic int
580SN/Aquicc_divisor(int rclk, int baudrate)
590SN/A{
602346SN/A	int act_baud, divisor, error;
612346SN/A
622346SN/A	if (baudrate == 0)
632346SN/A		return (-1);
642346SN/A
652346SN/A	divisor = rclk / baudrate / 16;
666658SN/A	if (divisor > 4096)
6710074SN/A		divisor = ((divisor >> 3) - 2) | 1;
6810792Sweijun	else if (divisor >= 0)
690SN/A		divisor = (divisor - 1) << 1;
704644SN/A	if (divisor < 0 || divisor >= 8192)
714644SN/A		return (-1);
720SN/A	act_baud = rclk / (((divisor >> 1) + 1) << ((divisor & 1) ? 8 : 4));
7311963Svaleriep
740SN/A	/* 10 times error in percent: */
750SN/A	error = ((act_baud - baudrate) * 2000 / baudrate + 1) >> 1;
760SN/A
778299SN/A	/* 3.0% maximum error tolerance: */
788299SN/A	if (error < -30 || error > 30)
790SN/A		return (-1);
80903SN/A
815976SN/A	return (divisor);
825976SN/A}
83903SN/A
8411658Sweijunstatic int
850SN/Aquicc_param(struct uart_bas *bas, int baudrate, int databits, int stopbits,
860SN/A    int parity)
870SN/A{
8816032Sasmotrak	int divisor;
895976SN/A	uint16_t psmr;
905976SN/A
9116032Sasmotrak	if (baudrate > 0) {
920SN/A		divisor = quicc_divisor(bas->rclk, baudrate);
930SN/A		if (divisor == -1)
940SN/A			return (EINVAL);
950SN/A		quicc_write4(bas, QUICC_REG_BRG(bas->chan - 1),
960SN/A		    divisor | 0x10000);
970SN/A	}
980SN/A
990SN/A	psmr = 0;
1000SN/A	switch (databits) {
1010SN/A	case 5:		psmr |= 0x0000; break;
1020SN/A	case 6:		psmr |= 0x1000; break;
1030SN/A	case 7:		psmr |= 0x2000; break;
1040SN/A	case 8:		psmr |= 0x3000; break;
1055976SN/A	default:	return (EINVAL);
1060SN/A	}
10711658Sweijun	switch (stopbits) {
10811658Sweijun	case 1:		psmr |= 0x0000; break;
1090SN/A	case 2:		psmr |= 0x4000; break;
1101706SN/A	default:	return (EINVAL);
1110SN/A	}
1120SN/A	switch (parity) {
1130SN/A	case UART_PARITY_EVEN:	psmr |= 0x1a; break;
1140SN/A	case UART_PARITY_MARK:	psmr |= 0x1f; break;
1150SN/A	case UART_PARITY_NONE:	psmr |= 0x00; break;
1160SN/A	case UART_PARITY_ODD:	psmr |= 0x10; break;
1170SN/A	case UART_PARITY_SPACE:	psmr |= 0x15; break;
1180SN/A	default:		return (EINVAL);
1190SN/A	}
1200SN/A	quicc_write2(bas, QUICC_REG_SCC_PSMR(bas->chan - 1), psmr);
121903SN/A	return (0);
122903SN/A}
1230SN/A
1240SN/Astatic void
1250SN/Aquicc_setup(struct uart_bas *bas, int baudrate, int databits, int stopbits,
1260SN/A    int parity)
1270SN/A{
1280SN/A
1290SN/A	if (bas->rclk == 0)
1300SN/A		bas->rclk = DEFAULT_RCLK;
1310SN/A
13215059Sweijun	/*
1330SN/A	 * GSMR_L = 0x00028034
13411178Svinnie	 * GSMR_H = 0x00000020
13515208Sweijun	 */
1360SN/A	quicc_param(bas, baudrate, databits, stopbits, parity);
1370SN/A
1380SN/A	quicc_write2(bas, QUICC_REG_SCC_SCCE(bas->chan - 1), ~0);
1390SN/A	quicc_write2(bas, QUICC_REG_SCC_SCCM(bas->chan - 1), 0x0027);
1400SN/A}
1410SN/A
1420SN/A/*
1430SN/A * Low-level UART interface.
1440SN/A */
1450SN/Astatic int quicc_probe(struct uart_bas *bas);
1460SN/Astatic void quicc_init(struct uart_bas *bas, int, int, int, int);
1470SN/Astatic void quicc_term(struct uart_bas *bas);
1480SN/Astatic void quicc_putc(struct uart_bas *bas, int);
149447SN/Astatic int quicc_rxready(struct uart_bas *bas);
1501803SN/Astatic int quicc_getc(struct uart_bas *bas, struct mtx *);
1510SN/A
1520SN/Astatic struct uart_ops uart_quicc_ops = {
1530SN/A	.probe = quicc_probe,
1540SN/A	.init = quicc_init,
1550SN/A	.term = quicc_term,
1560SN/A	.putc = quicc_putc,
1570SN/A	.rxready = quicc_rxready,
1580SN/A	.getc = quicc_getc,
15915325Sweijun};
16016788Sweijun
1610SN/Astatic int
1620SN/Aquicc_probe(struct uart_bas *bas)
1630SN/A{
1640SN/A
1653388SN/A	return (0);
1660SN/A}
1670SN/A
1683388SN/Astatic void
1693388SN/Aquicc_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
170903SN/A    int parity)
17116788Sweijun{
17216788Sweijun
17316788Sweijun	quicc_setup(bas, baudrate, databits, stopbits, parity);
17416788Sweijun}
17516788Sweijun
17616788Sweijunstatic void
17716788Sweijunquicc_term(struct uart_bas *bas)
17816788Sweijun{
17916788Sweijun}
18016788Sweijun
1811706SN/Astatic void
1823050SN/Aquicc_putc(struct uart_bas *bas, int c)
1832158SN/A{
18415059Sweijun	int unit;
18515059Sweijun	uint16_t toseq;
1863050SN/A
18715325Sweijun	unit = bas->chan - 1;
18815059Sweijun	while (quicc_read2(bas, QUICC_PRAM_SCC_UART_TOSEQ(unit)) & 0x2000)
1892117SN/A		DELAY(10);
1903050SN/A
19115325Sweijun	toseq = 0x2000 | (c & 0xff);
19215059Sweijun	quicc_write2(bas, QUICC_PRAM_SCC_UART_TOSEQ(unit), toseq);
1932117SN/A}
1943050SN/A
19515325Sweijunstatic int
19615059Sweijunquicc_rxready(struct uart_bas *bas)
1972117SN/A{
1983050SN/A	uint16_t rb;
1992158SN/A
2002117SN/A	rb = quicc_read2(bas, QUICC_PRAM_SCC_RBASE(bas->chan - 1));
20115059Sweijun	return ((quicc_read2(bas, rb) & 0x8000) ? 0 : 1);
20215059Sweijun}
2033050SN/A
2042117SN/Astatic int
20515059Sweijunquicc_getc(struct uart_bas *bas, struct mtx *hwmtx)
20615059Sweijun{
2073050SN/A	volatile char *buf;
2082158SN/A	int c;
2092117SN/A	uint16_t rb, sc;
21015059Sweijun
21115059Sweijun	uart_lock(hwmtx);
2123050SN/A
2132117SN/A	rb = quicc_read2(bas, QUICC_PRAM_SCC_RBASE(bas->chan - 1));
21415325Sweijun
21515059Sweijun	while ((sc = quicc_read2(bas, rb)) & 0x8000) {
2162117SN/A		uart_unlock(hwmtx);
2178299SN/A		DELAY(4);
2188299SN/A		uart_lock(hwmtx);
21915059Sweijun	}
22015059Sweijun
2213050SN/A	buf = (void *)(uintptr_t)quicc_read4(bas, rb + 4);
2222117SN/A	c = *buf;
2232117SN/A	quicc_write2(bas, rb, sc | 0x8000);
22414704Sweijun
2252117SN/A	uart_unlock(hwmtx);
22615059Sweijun
2272117SN/A	return (c);
2283050SN/A}
2292117SN/A
23015059Sweijun/*
2312117SN/A * High-level UART interface.
2323050SN/A */
23315325Sweijunstruct quicc_softc {
23415059Sweijun	struct uart_softc base;
2352117SN/A};
2363050SN/A
2372117SN/Astatic int quicc_bus_attach(struct uart_softc *);
2383050SN/Astatic int quicc_bus_detach(struct uart_softc *);
2392117SN/Astatic int quicc_bus_flush(struct uart_softc *, int);
2403050SN/Astatic int quicc_bus_getsig(struct uart_softc *);
2412346SN/Astatic int quicc_bus_ioctl(struct uart_softc *, int, intptr_t);
2423050SN/Astatic int quicc_bus_ipend(struct uart_softc *);
24315325Sweijunstatic int quicc_bus_param(struct uart_softc *, int, int, int, int);
24415059Sweijunstatic int quicc_bus_probe(struct uart_softc *);
2452346SN/Astatic int quicc_bus_receive(struct uart_softc *);
2462346SN/Astatic int quicc_bus_setsig(struct uart_softc *, int);
2472346SN/Astatic int quicc_bus_transmit(struct uart_softc *);
2483050SN/Astatic void quicc_bus_grab(struct uart_softc *);
2492346SN/Astatic void quicc_bus_ungrab(struct uart_softc *);
25015059Sweijun
25115059Sweijunstatic kobj_method_t quicc_methods[] = {
2523050SN/A	KOBJMETHOD(uart_attach,		quicc_bus_attach),
2532117SN/A	KOBJMETHOD(uart_detach,		quicc_bus_detach),
2542117SN/A	KOBJMETHOD(uart_flush,		quicc_bus_flush),
25515059Sweijun	KOBJMETHOD(uart_getsig,		quicc_bus_getsig),
2563050SN/A	KOBJMETHOD(uart_ioctl,		quicc_bus_ioctl),
2572346SN/A	KOBJMETHOD(uart_ipend,		quicc_bus_ipend),
2582346SN/A	KOBJMETHOD(uart_param,		quicc_bus_param),
25915059Sweijun	KOBJMETHOD(uart_probe,		quicc_bus_probe),
26015059Sweijun	KOBJMETHOD(uart_receive,	quicc_bus_receive),
2613050SN/A	KOBJMETHOD(uart_setsig,		quicc_bus_setsig),
2622346SN/A	KOBJMETHOD(uart_transmit,	quicc_bus_transmit),
26315059Sweijun	KOBJMETHOD(uart_grab,		quicc_bus_grab),
2641706SN/A	KOBJMETHOD(uart_ungrab,		quicc_bus_ungrab),
2651706SN/A	{ 0, 0 }
2662117SN/A};
26710074SN/A
26810074SN/Astruct uart_class uart_quicc_class = {
26910074SN/A	"quicc",
27010074SN/A	quicc_methods,
2712117SN/A	sizeof(struct quicc_softc),
2721706SN/A	.uc_ops = &uart_quicc_ops,
2731706SN/A	.uc_range = 2,
27410074SN/A	.uc_rclk = DEFAULT_RCLK
2751706SN/A};
2761706SN/A
2771706SN/A#define	SIGCHG(c, i, s, d)				\
27810074SN/A	if (c) {					\
27910074SN/A		i |= (i & s) ? s : s | d;		\
28010074SN/A	} else {					\
28110074SN/A		i = (i & s) ? (i & ~s) | d : i;		\
28210074SN/A	}
28310074SN/A
28410074SN/Astatic int
28510074SN/Aquicc_bus_attach(struct uart_softc *sc)
28610074SN/A{
28710074SN/A	struct uart_bas *bas;
28810074SN/A	struct uart_devinfo *di;
28910074SN/A	uint16_t st, rb;
29010074SN/A
29110074SN/A	bas = &sc->sc_bas;
29210074SN/A	if (sc->sc_sysdev != NULL) {
29310074SN/A		di = sc->sc_sysdev;
29410074SN/A		quicc_param(bas, di->baudrate, di->databits, di->stopbits,
2951706SN/A		    di->parity);
2961706SN/A	} else {
2971706SN/A		quicc_setup(bas, 9600, 8, 1, UART_PARITY_NONE);
29810074SN/A	}
29910074SN/A
30010074SN/A	/* Enable interrupts on the receive buffer. */
30110074SN/A	rb = quicc_read2(bas, QUICC_PRAM_SCC_RBASE(bas->chan - 1));
30210074SN/A	st = quicc_read2(bas, rb);
30310074SN/A	quicc_write2(bas, rb, st | 0x9000);
30410074SN/A
3052117SN/A	(void)quicc_bus_getsig(sc);
3063050SN/A
30715059Sweijun	return (0);
3083050SN/A}
30915059Sweijun
3103050SN/Astatic int
31115059Sweijunquicc_bus_detach(struct uart_softc *sc)
3123050SN/A{
31315059Sweijun
31415059Sweijun	return (0);
3153050SN/A}
31615059Sweijun
31715059Sweijunstatic int
3183050SN/Aquicc_bus_flush(struct uart_softc *sc, int what)
31915059Sweijun{
32015059Sweijun
3213050SN/A	return (0);
32215059Sweijun}
3233050SN/A
32415325Sweijunstatic int
3253050SN/Aquicc_bus_getsig(struct uart_softc *sc)
3263050SN/A{
32715059Sweijun	uint32_t new, old, sig;
3283050SN/A	uint32_t dummy;
32915059Sweijun
33015059Sweijun	do {
33115059Sweijun		old = sc->sc_hwsig;
33215059Sweijun		sig = old;
3333050SN/A		uart_lock(sc->sc_hwmtx);
33415059Sweijun		/* XXX SIGNALS */
33515059Sweijun		dummy = 0;
3363050SN/A		uart_unlock(sc->sc_hwmtx);
33715059Sweijun		SIGCHG(dummy, sig, SER_CTS, SER_DCTS);
3383050SN/A		SIGCHG(dummy, sig, SER_DCD, SER_DDCD);
33915059Sweijun		SIGCHG(dummy, sig, SER_DSR, SER_DDSR);
3403050SN/A		new = sig & ~SER_MASK_DELTA;
34115059Sweijun	} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
3423050SN/A	return (sig);
34315059Sweijun}
34415059Sweijun
3453050SN/Astatic int
34615059Sweijunquicc_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
3473050SN/A{
3483050SN/A	struct uart_bas *bas;
34915059Sweijun	uint32_t brg;
3502117SN/A	int baudrate, error;
3512117SN/A
3522117SN/A	bas = &sc->sc_bas;
3532117SN/A	error = 0;
3542117SN/A	uart_lock(sc->sc_hwmtx);
3552117SN/A	switch (request) {
3562117SN/A	case UART_IOCTL_BREAK:
3572117SN/A		break;
3582117SN/A	case UART_IOCTL_BAUD:
3592117SN/A		brg = quicc_read4(bas, QUICC_REG_BRG(bas->chan - 1)) & 0x1fff;
3602117SN/A		brg = (brg & 1) ? (brg + 1) << 3 : (brg + 2) >> 1;
3611706SN/A		baudrate = bas->rclk / (brg * 16);
3620SN/A		*(int*)data = baudrate;
3630SN/A		break;
3640SN/A	default:
3650SN/A		error = EINVAL;
36616788Sweijun		break;
3670SN/A	}
3680SN/A	uart_unlock(sc->sc_hwmtx);
3690SN/A	return (error);
3705976SN/A}
3715976SN/A
3720SN/Astatic int
3730SN/Aquicc_bus_ipend(struct uart_softc *sc)
3740SN/A{
3750SN/A	struct uart_bas *bas;
3760SN/A	int ipend;
3770SN/A	uint16_t scce;
3785976SN/A
3790SN/A	bas = &sc->sc_bas;
3800SN/A	ipend = 0;
3815976SN/A
3820SN/A	uart_lock(sc->sc_hwmtx);
3830SN/A	scce = quicc_read2(bas, QUICC_REG_SCC_SCCE(bas->chan - 1));
3840SN/A	quicc_write2(bas, QUICC_REG_SCC_SCCE(bas->chan - 1), ~0);
3850SN/A	uart_unlock(sc->sc_hwmtx);
3860SN/A	if (scce & 0x0001)
38710074SN/A		ipend |= SER_INT_RXREADY;
3881706SN/A	if (scce & 0x0002)
389903SN/A		ipend |= SER_INT_TXIDLE;
390903SN/A	if (scce & 0x0004)
3910SN/A		ipend |= SER_INT_OVERRUN;
3923050SN/A	if (scce & 0x0020)
3930SN/A		ipend |= SER_INT_BREAK;
3940SN/A	/* XXX SIGNALS */
3950SN/A	return (ipend);
3960SN/A}
3970SN/A
3980SN/Astatic int
3990SN/Aquicc_bus_param(struct uart_softc *sc, int baudrate, int databits,
4000SN/A    int stopbits, int parity)
4010SN/A{
40216788Sweijun	int error;
4030SN/A
4040SN/A	uart_lock(sc->sc_hwmtx);
4050SN/A	error = quicc_param(&sc->sc_bas, baudrate, databits, stopbits,
4060SN/A	    parity);
4070SN/A	uart_unlock(sc->sc_hwmtx);
4080SN/A	return (error);
4090SN/A}
4100SN/A
4110SN/Astatic int
4120SN/Aquicc_bus_probe(struct uart_softc *sc)
4130SN/A{
4140SN/A	char buf[80];
4150SN/A	int error;
4160SN/A
4170SN/A	error = quicc_probe(&sc->sc_bas);
4180SN/A	if (error)
41910074SN/A		return (error);
4200SN/A
4210SN/A	sc->sc_rxfifosz = 1;
4221706SN/A	sc->sc_txfifosz = 1;
4230SN/A
42410074SN/A	snprintf(buf, sizeof(buf), "quicc, channel %d", sc->sc_bas.chan);
42510074SN/A	device_set_desc_copy(sc->sc_dev, buf);
42610074SN/A	return (0);
42710074SN/A}
42810074SN/A
42910074SN/Astatic int
43010074SN/Aquicc_bus_receive(struct uart_softc *sc)
43110074SN/A{
43210074SN/A	struct uart_bas *bas;
43310074SN/A	volatile char *buf;
43410074SN/A	uint16_t st, rb;
43510074SN/A
43610074SN/A	bas = &sc->sc_bas;
43710074SN/A	uart_lock(sc->sc_hwmtx);
43810074SN/A	rb = quicc_read2(bas, QUICC_PRAM_SCC_RBASE(bas->chan - 1));
43910074SN/A	st = quicc_read2(bas, rb);
44010074SN/A	buf = (void *)(uintptr_t)quicc_read4(bas, rb + 4);
44110074SN/A	uart_rx_put(sc, *buf);
44210074SN/A	quicc_write2(bas, rb, st | 0x9000);
44310074SN/A	uart_unlock(sc->sc_hwmtx);
44410074SN/A	return (0);
44510074SN/A}
44610074SN/A
44710074SN/Astatic int
44810074SN/Aquicc_bus_setsig(struct uart_softc *sc, int sig)
44910074SN/A{
45010074SN/A	struct uart_bas *bas;
45110074SN/A	uint32_t new, old;
45210074SN/A
45310074SN/A	bas = &sc->sc_bas;
45410074SN/A	do {
45510074SN/A		old = sc->sc_hwsig;
4560SN/A		new = old;
4570SN/A		if (sig & SER_DDTR) {
4580SN/A			SIGCHG(sig & SER_DTR, new, SER_DTR,
4591706SN/A			    SER_DDTR);
4601706SN/A		}
4611706SN/A		if (sig & SER_DRTS) {
4622117SN/A			SIGCHG(sig & SER_RTS, new, SER_RTS,
4631706SN/A			    SER_DRTS);
4642117SN/A		}
4652117SN/A	} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
4661706SN/A
4671706SN/A	uart_lock(sc->sc_hwmtx);
4681706SN/A	/* XXX SIGNALS */
4691706SN/A	uart_unlock(sc->sc_hwmtx);
4701706SN/A	return (0);
4710SN/A}
4721709SN/A
4731709SN/Astatic int
4741709SN/Aquicc_bus_transmit(struct uart_softc *sc)
4751709SN/A{
4761709SN/A	volatile char *buf;
4771709SN/A	struct uart_bas *bas;
4781709SN/A	uint16_t st, tb;
4791709SN/A
48010074SN/A	bas = &sc->sc_bas;
4811709SN/A	uart_lock(sc->sc_hwmtx);
4820SN/A	tb = quicc_read2(bas, QUICC_PRAM_SCC_TBASE(bas->chan - 1));
4830SN/A	st = quicc_read2(bas, tb);
48410074SN/A	buf = (void *)(uintptr_t)quicc_read4(bas, tb + 4);
48510074SN/A	*buf = sc->sc_txbuf[0];
48610074SN/A	quicc_write2(bas, tb + 2, 1);
48710074SN/A	quicc_write2(bas, tb, st | 0x9000);
48810074SN/A	sc->sc_txbusy = 1;
4891706SN/A	uart_unlock(sc->sc_hwmtx);
49010074SN/A	return (0);
49110074SN/A}
49216788Sweijun
49316788Sweijunstatic void
49415325Sweijunquicc_bus_grab(struct uart_softc *sc)
4951706SN/A{
49615325Sweijun	struct uart_bas *bas;
49715325Sweijun	uint16_t st, rb;
49815325Sweijun
49915325Sweijun	/* Disable interrupts on the receive buffer. */
50015325Sweijun	bas = &sc->sc_bas;
50115325Sweijun	uart_lock(sc->sc_hwmtx);
50215325Sweijun	rb = quicc_read2(bas, QUICC_PRAM_SCC_RBASE(bas->chan - 1));
50315325Sweijun	st = quicc_read2(bas, rb);
5040SN/A	quicc_write2(bas, rb, st & ~0x9000);
5050SN/A	uart_unlock(sc->sc_hwmtx);
5061709SN/A}
5070SN/A
5080SN/Astatic void
5090SN/Aquicc_bus_ungrab(struct uart_softc *sc)
5101706SN/A{
51111178Svinnie	struct uart_bas *bas;
5120SN/A	uint16_t st, rb;
5131709SN/A
5140SN/A	/* Enable interrupts on the receive buffer. */
5150SN/A	bas = &sc->sc_bas;
5161706SN/A	uart_lock(sc->sc_hwmtx);
51715208Sweijun	rb = quicc_read2(bas, QUICC_PRAM_SCC_RBASE(bas->chan - 1));
5180SN/A	st = quicc_read2(bas, rb);
5191709SN/A	quicc_write2(bas, rb, st | 0x9000);
5200SN/A	uart_unlock(sc->sc_hwmtx);
5210SN/A}
5221706SN/A
5230SN/A