uart_dev_ns8250.c (158069) | uart_dev_ns8250.c (158844) |
---|---|
1/*- 2 * Copyright (c) 2003 Marcel Moolenaar 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 * --- 11 unchanged lines hidden (view full) --- 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2003 Marcel Moolenaar 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 * --- 11 unchanged lines hidden (view full) --- 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/sys/dev/uart/uart_dev_ns8250.c 158069 2006-04-27 05:43:10Z marcel $"); | 28__FBSDID("$FreeBSD: head/sys/dev/uart/uart_dev_ns8250.c 158844 2006-05-23 00:41:12Z benno $"); |
29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/bus.h> 33#include <sys/conf.h> 34#include <machine/bus.h> 35 36#include <dev/uart/uart.h> --- 33 unchanged lines hidden (view full) --- 70ns8250_delay(struct uart_bas *bas) 71{ 72 int divisor; 73 u_char lcr; 74 75 lcr = uart_getreg(bas, REG_LCR); 76 uart_setreg(bas, REG_LCR, lcr | LCR_DLAB); 77 uart_barrier(bas); | 29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/bus.h> 33#include <sys/conf.h> 34#include <machine/bus.h> 35 36#include <dev/uart/uart.h> --- 33 unchanged lines hidden (view full) --- 70ns8250_delay(struct uart_bas *bas) 71{ 72 int divisor; 73 u_char lcr; 74 75 lcr = uart_getreg(bas, REG_LCR); 76 uart_setreg(bas, REG_LCR, lcr | LCR_DLAB); 77 uart_barrier(bas); |
78 divisor = uart_getdreg(bas, REG_DL); | 78 divisor = uart_getreg(bas, REG_DLL) | (uart_getreg(bas, REG_DLH) << 8); |
79 uart_barrier(bas); 80 uart_setreg(bas, REG_LCR, lcr); 81 uart_barrier(bas); 82 83 /* 1/10th the time to transmit 1 character (estimate). */ 84 return (16000000 * divisor / bas->rclk); 85} 86 --- 107 unchanged lines hidden (view full) --- 194 195 /* Set baudrate. */ 196 if (baudrate > 0) { 197 divisor = ns8250_divisor(bas->rclk, baudrate); 198 if (divisor == 0) 199 return (EINVAL); 200 uart_setreg(bas, REG_LCR, lcr | LCR_DLAB); 201 uart_barrier(bas); | 79 uart_barrier(bas); 80 uart_setreg(bas, REG_LCR, lcr); 81 uart_barrier(bas); 82 83 /* 1/10th the time to transmit 1 character (estimate). */ 84 return (16000000 * divisor / bas->rclk); 85} 86 --- 107 unchanged lines hidden (view full) --- 194 195 /* Set baudrate. */ 196 if (baudrate > 0) { 197 divisor = ns8250_divisor(bas->rclk, baudrate); 198 if (divisor == 0) 199 return (EINVAL); 200 uart_setreg(bas, REG_LCR, lcr | LCR_DLAB); 201 uart_barrier(bas); |
202 uart_setdreg(bas, REG_DL, divisor); | 202 uart_setreg(bas, REG_DLL, divisor & 0xff); 203 uart_setreg(bas, REG_DLH, (divisor >> 8) & 0xff); |
203 uart_barrier(bas); 204 } 205 206 /* Set LCR and clear DLAB. */ 207 uart_setreg(bas, REG_LCR, lcr); 208 uart_barrier(bas); 209 return (0); 210} --- 25 unchanged lines hidden (view full) --- 236 /* Check known 0 bits that don't depend on DLAB. */ 237 val = uart_getreg(bas, REG_IIR); 238 if (val & 0x30) 239 return (ENXIO); 240 val = uart_getreg(bas, REG_MCR); 241 if (val & 0xe0) 242 return (ENXIO); 243 | 204 uart_barrier(bas); 205 } 206 207 /* Set LCR and clear DLAB. */ 208 uart_setreg(bas, REG_LCR, lcr); 209 uart_barrier(bas); 210 return (0); 211} --- 25 unchanged lines hidden (view full) --- 237 /* Check known 0 bits that don't depend on DLAB. */ 238 val = uart_getreg(bas, REG_IIR); 239 if (val & 0x30) 240 return (ENXIO); 241 val = uart_getreg(bas, REG_MCR); 242 if (val & 0xe0) 243 return (ENXIO); 244 |
244 lcr = uart_getreg(bas, REG_LCR); 245 uart_setreg(bas, REG_LCR, lcr & ~LCR_DLAB); 246 uart_barrier(bas); 247 248 /* Check known 0 bits that depend on !DLAB. */ 249 val = uart_getreg(bas, REG_IER); 250 if (val & 0xf0) 251 goto fail; 252 253 uart_setreg(bas, REG_LCR, lcr); 254 uart_barrier(bas); | |
255 return (0); | 245 return (0); |
256 257 fail: 258 uart_setreg(bas, REG_LCR, lcr); 259 uart_barrier(bas); 260 return (ENXIO); | |
261} 262 263static void 264ns8250_init(struct uart_bas *bas, int baudrate, int databits, int stopbits, 265 int parity) 266{ | 246} 247 248static void 249ns8250_init(struct uart_bas *bas, int baudrate, int databits, int stopbits, 250 int parity) 251{ |
252 u_char ier; |
|
267 268 if (bas->rclk == 0) 269 bas->rclk = DEFAULT_RCLK; 270 ns8250_param(bas, baudrate, databits, stopbits, parity); 271 272 /* Disable all interrupt sources. */ | 253 254 if (bas->rclk == 0) 255 bas->rclk = DEFAULT_RCLK; 256 ns8250_param(bas, baudrate, databits, stopbits, parity); 257 258 /* Disable all interrupt sources. */ |
273 uart_setreg(bas, REG_IER, 0); | 259 ier = uart_getreg(bas, REG_IER) & 0xf0; 260 uart_setreg(bas, REG_IER, ier); |
274 uart_barrier(bas); 275 276 /* Disable the FIFO (if present). */ 277 uart_setreg(bas, REG_FCR, 0); 278 uart_barrier(bas); 279 280 /* Set RTS & DTR. */ 281 uart_setreg(bas, REG_MCR, MCR_IE | MCR_RTS | MCR_DTR); --- 129 unchanged lines hidden (view full) --- 411 412 if (ns8250->mcr & MCR_DTR) 413 sc->sc_hwsig |= SER_DTR; 414 if (ns8250->mcr & MCR_RTS) 415 sc->sc_hwsig |= SER_RTS; 416 ns8250_bus_getsig(sc); 417 418 ns8250_clrint(bas); | 261 uart_barrier(bas); 262 263 /* Disable the FIFO (if present). */ 264 uart_setreg(bas, REG_FCR, 0); 265 uart_barrier(bas); 266 267 /* Set RTS & DTR. */ 268 uart_setreg(bas, REG_MCR, MCR_IE | MCR_RTS | MCR_DTR); --- 129 unchanged lines hidden (view full) --- 398 399 if (ns8250->mcr & MCR_DTR) 400 sc->sc_hwsig |= SER_DTR; 401 if (ns8250->mcr & MCR_RTS) 402 sc->sc_hwsig |= SER_RTS; 403 ns8250_bus_getsig(sc); 404 405 ns8250_clrint(bas); |
419 ns8250->ier = IER_EMSC | IER_ERLS | IER_ERXRDY; | 406 ns8250->ier = uart_getreg(bas, REG_IER) & 0xf0; 407 ns8250->ier |= IER_EMSC | IER_ERLS | IER_ERXRDY; |
420 uart_setreg(bas, REG_IER, ns8250->ier); 421 uart_barrier(bas); 422 return (0); 423} 424 425static int 426ns8250_bus_detach(struct uart_softc *sc) 427{ 428 struct uart_bas *bas; | 408 uart_setreg(bas, REG_IER, ns8250->ier); 409 uart_barrier(bas); 410 return (0); 411} 412 413static int 414ns8250_bus_detach(struct uart_softc *sc) 415{ 416 struct uart_bas *bas; |
417 u_char ier; |
|
429 430 bas = &sc->sc_bas; | 418 419 bas = &sc->sc_bas; |
431 uart_setreg(bas, REG_IER, 0); | 420 ier = uart_getreg(bas, REG_IER) & 0xf0; 421 uart_setreg(bas, REG_IER, ier); |
432 uart_barrier(bas); 433 ns8250_clrint(bas); 434 return (0); 435} 436 437static int 438ns8250_bus_flush(struct uart_softc *sc, int what) 439{ --- 84 unchanged lines hidden (view full) --- 524 uart_barrier(bas); 525 uart_setreg(bas, REG_LCR, lcr); 526 uart_barrier(bas); 527 break; 528 case UART_IOCTL_BAUD: 529 lcr = uart_getreg(bas, REG_LCR); 530 uart_setreg(bas, REG_LCR, lcr | LCR_DLAB); 531 uart_barrier(bas); | 422 uart_barrier(bas); 423 ns8250_clrint(bas); 424 return (0); 425} 426 427static int 428ns8250_bus_flush(struct uart_softc *sc, int what) 429{ --- 84 unchanged lines hidden (view full) --- 514 uart_barrier(bas); 515 uart_setreg(bas, REG_LCR, lcr); 516 uart_barrier(bas); 517 break; 518 case UART_IOCTL_BAUD: 519 lcr = uart_getreg(bas, REG_LCR); 520 uart_setreg(bas, REG_LCR, lcr | LCR_DLAB); 521 uart_barrier(bas); |
532 divisor = uart_getdreg(bas, REG_DL); | 522 divisor = uart_getreg(bas, REG_DLL) | 523 (uart_getreg(bas, REG_DLH) << 8); |
533 uart_barrier(bas); 534 uart_setreg(bas, REG_LCR, lcr); 535 uart_barrier(bas); 536 baudrate = (divisor > 0) ? bas->rclk / divisor / 16 : 0; 537 if (baudrate > 0) 538 *(int*)data = baudrate; 539 else 540 error = ENXIO; --- 54 unchanged lines hidden (view full) --- 595 return (error); 596} 597 598static int 599ns8250_bus_probe(struct uart_softc *sc) 600{ 601 struct uart_bas *bas; 602 int count, delay, error, limit; | 524 uart_barrier(bas); 525 uart_setreg(bas, REG_LCR, lcr); 526 uart_barrier(bas); 527 baudrate = (divisor > 0) ? bas->rclk / divisor / 16 : 0; 528 if (baudrate > 0) 529 *(int*)data = baudrate; 530 else 531 error = ENXIO; --- 54 unchanged lines hidden (view full) --- 586 return (error); 587} 588 589static int 590ns8250_bus_probe(struct uart_softc *sc) 591{ 592 struct uart_bas *bas; 593 int count, delay, error, limit; |
603 uint8_t lsr, mcr; | 594 uint8_t lsr, mcr, ier; |
604 605 bas = &sc->sc_bas; 606 607 error = ns8250_probe(bas); 608 if (error) 609 return (error); 610 611 mcr = MCR_IE; --- 67 unchanged lines hidden (view full) --- 679 /* 680 * LSR bits are cleared upon read, so we must accumulate 681 * them to be able to test LSR_OE below. 682 */ 683 while (((lsr |= uart_getreg(bas, REG_LSR)) & LSR_TEMT) == 0 && 684 --limit) 685 DELAY(delay); 686 if (limit == 0) { | 595 596 bas = &sc->sc_bas; 597 598 error = ns8250_probe(bas); 599 if (error) 600 return (error); 601 602 mcr = MCR_IE; --- 67 unchanged lines hidden (view full) --- 670 /* 671 * LSR bits are cleared upon read, so we must accumulate 672 * them to be able to test LSR_OE below. 673 */ 674 while (((lsr |= uart_getreg(bas, REG_LSR)) & LSR_TEMT) == 0 && 675 --limit) 676 DELAY(delay); 677 if (limit == 0) { |
687 uart_setreg(bas, REG_IER, 0); | 678 ier = uart_getreg(bas, REG_IER) & 0xf0; 679 uart_setreg(bas, REG_IER, ier); |
688 uart_setreg(bas, REG_MCR, mcr); 689 uart_setreg(bas, REG_FCR, 0); 690 uart_barrier(bas); 691 count = 0; 692 goto describe; 693 } 694 } while ((lsr & LSR_OE) == 0 && count < 130); 695 count--; --- 135 unchanged lines hidden --- | 680 uart_setreg(bas, REG_MCR, mcr); 681 uart_setreg(bas, REG_FCR, 0); 682 uart_barrier(bas); 683 count = 0; 684 goto describe; 685 } 686 } while ((lsr & LSR_OE) == 0 && count < 130); 687 count--; --- 135 unchanged lines hidden --- |