uart_dev_ns8250.c (291010) | uart_dev_ns8250.c (293781) |
---|---|
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 * --- 14 unchanged lines hidden (view full) --- 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 "opt_platform.h" 28#include "opt_uart.h" 29 30#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 * --- 14 unchanged lines hidden (view full) --- 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 "opt_platform.h" 28#include "opt_uart.h" 29 30#include <sys/cdefs.h> |
31__FBSDID("$FreeBSD: head/sys/dev/uart/uart_dev_ns8250.c 291010 2015-11-18 06:24:21Z adrian $"); | 31__FBSDID("$FreeBSD: head/sys/dev/uart/uart_dev_ns8250.c 293781 2016-01-12 18:42:00Z ian $"); |
32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/bus.h> 36#include <sys/conf.h> 37#include <sys/kernel.h> 38#include <sys/sysctl.h> 39#include <machine/bus.h> --- 6 unchanged lines hidden (view full) --- 46 47#include <dev/uart/uart.h> 48#include <dev/uart/uart_cpu.h> 49#ifdef FDT 50#include <dev/uart/uart_cpu_fdt.h> 51#endif 52#include <dev/uart/uart_bus.h> 53#include <dev/uart/uart_dev_ns8250.h> | 32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/bus.h> 36#include <sys/conf.h> 37#include <sys/kernel.h> 38#include <sys/sysctl.h> 39#include <machine/bus.h> --- 6 unchanged lines hidden (view full) --- 46 47#include <dev/uart/uart.h> 48#include <dev/uart/uart_cpu.h> 49#ifdef FDT 50#include <dev/uart/uart_cpu_fdt.h> 51#endif 52#include <dev/uart/uart_bus.h> 53#include <dev/uart/uart_dev_ns8250.h> |
54#include <dev/uart/uart_ppstypes.h> |
|
54 55#include <dev/ic/ns16550.h> 56 57#include "uart_if.h" 58 59#define DEFAULT_RCLK 1843200 60 61/* --- 334 unchanged lines hidden (view full) --- 396#ifdef FDT 397static struct ofw_compat_data compat_data[] = { 398 {"ns16550", (uintptr_t)&uart_ns8250_class}, 399 {NULL, (uintptr_t)NULL}, 400}; 401UART_FDT_CLASS_AND_DEVICE(compat_data); 402#endif 403 | 55 56#include <dev/ic/ns16550.h> 57 58#include "uart_if.h" 59 60#define DEFAULT_RCLK 1843200 61 62/* --- 334 unchanged lines hidden (view full) --- 397#ifdef FDT 398static struct ofw_compat_data compat_data[] = { 399 {"ns16550", (uintptr_t)&uart_ns8250_class}, 400 {NULL, (uintptr_t)NULL}, 401}; 402UART_FDT_CLASS_AND_DEVICE(compat_data); 403#endif 404 |
404#define SIGCHG(c, i, s, d) \ 405 if (c) { \ 406 i |= (i & s) ? s : s | d; \ 407 } else { \ 408 i = (i & s) ? (i & ~s) | d : i; \ | 405/* Use token-pasting to form SER_ and MSR_ named constants. */ 406#define SER(sig) SER_##sig 407#define SERD(sig) SER_D##sig 408#define MSR(sig) MSR_##sig 409#define MSRD(sig) MSR_D##sig 410 411/* 412 * Detect signal changes using software delta detection. The previous state of 413 * the signals is in 'var' the new hardware state is in 'msr', and 'sig' is the 414 * short name (DCD, CTS, etc) of the signal bit being processed; 'var' gets the 415 * new state of both the signal and the delta bits. 416 */ 417#define SIGCHGSW(var, msr, sig) \ 418 if ((msr) & MSR(sig)) { \ 419 if ((var & SER(sig)) == 0) \ 420 var |= SERD(sig) | SER(sig); \ 421 } else { \ 422 if ((var & SER(sig)) != 0) \ 423 var = SERD(sig) | (var & ~SER(sig)); \ |
409 } 410 | 424 } 425 |
426/* 427 * Detect signal changes using the hardware msr delta bits. This is currently 428 * used only when PPS timing information is being captured using the "narrow 429 * pulse" option. With a narrow PPS pulse the signal may not still be asserted 430 * by time the interrupt handler is invoked. The hardware will latch the fact 431 * that it changed in the delta bits. 432 */ 433#define SIGCHGHW(var, msr, sig) \ 434 if ((msr) & MSRD(sig)) { \ 435 if (((msr) & MSR(sig)) != 0) \ 436 var |= SERD(sig) | SER(sig); \ 437 else \ 438 var = SERD(sig) | (var & ~SER(sig)); \ 439 } 440 |
|
411int 412ns8250_bus_attach(struct uart_softc *sc) 413{ 414 struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc; 415 struct uart_bas *bas; 416 unsigned int ivar; 417#ifdef FDT 418 phandle_t node; --- 108 unchanged lines hidden (view full) --- 527 error = ns8250_drain(bas, what); 528 uart_unlock(sc->sc_hwmtx); 529 return (error); 530} 531 532int 533ns8250_bus_getsig(struct uart_softc *sc) 534{ | 441int 442ns8250_bus_attach(struct uart_softc *sc) 443{ 444 struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc; 445 struct uart_bas *bas; 446 unsigned int ivar; 447#ifdef FDT 448 phandle_t node; --- 108 unchanged lines hidden (view full) --- 557 error = ns8250_drain(bas, what); 558 uart_unlock(sc->sc_hwmtx); 559 return (error); 560} 561 562int 563ns8250_bus_getsig(struct uart_softc *sc) 564{ |
535 uint32_t new, old, sig; | 565 uint32_t old, sig; |
536 uint8_t msr; 537 | 566 uint8_t msr; 567 |
568 /* 569 * The delta bits are reputed to be broken on some hardware, so use 570 * software delta detection by default. Use the hardware delta bits 571 * when capturing PPS pulses which are too narrow for software detection 572 * to see the edges. Hardware delta for RI doesn't work like the 573 * others, so always use software for it. Other threads may be changing 574 * other (non-MSR) bits in sc_hwsig, so loop until it can succesfully 575 * update without other changes happening. Note that the SIGCHGxx() 576 * macros carefully preserve the delta bits when we have to loop several 577 * times and a signal transitions between iterations. 578 */ |
|
538 do { 539 old = sc->sc_hwsig; 540 sig = old; 541 uart_lock(sc->sc_hwmtx); 542 msr = uart_getreg(&sc->sc_bas, REG_MSR); 543 uart_unlock(sc->sc_hwmtx); | 579 do { 580 old = sc->sc_hwsig; 581 sig = old; 582 uart_lock(sc->sc_hwmtx); 583 msr = uart_getreg(&sc->sc_bas, REG_MSR); 584 uart_unlock(sc->sc_hwmtx); |
544 SIGCHG(msr & MSR_DSR, sig, SER_DSR, SER_DDSR); 545 SIGCHG(msr & MSR_CTS, sig, SER_CTS, SER_DCTS); 546 SIGCHG(msr & MSR_DCD, sig, SER_DCD, SER_DDCD); 547 SIGCHG(msr & MSR_RI, sig, SER_RI, SER_DRI); 548 new = sig & ~SER_MASK_DELTA; 549 } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); | 585 if (sc->sc_pps_mode & UART_PPS_NARROW_PULSE) { 586 SIGCHGHW(sig, msr, DSR); 587 SIGCHGHW(sig, msr, CTS); 588 SIGCHGHW(sig, msr, DCD); 589 } else { 590 SIGCHGSW(sig, msr, DSR); 591 SIGCHGSW(sig, msr, CTS); 592 SIGCHGSW(sig, msr, DCD); 593 } 594 SIGCHGSW(sig, msr, RI); 595 } while (!atomic_cmpset_32(&sc->sc_hwsig, old, sig & ~SER_MASK_DELTA)); |
550 return (sig); 551} 552 553int 554ns8250_bus_ioctl(struct uart_softc *sc, int request, intptr_t data) 555{ 556 struct uart_bas *bas; 557 int baudrate, divisor, error; --- 337 unchanged lines hidden (view full) --- 895 struct uart_bas *bas; 896 uint32_t new, old; 897 898 bas = &sc->sc_bas; 899 do { 900 old = sc->sc_hwsig; 901 new = old; 902 if (sig & SER_DDTR) { | 596 return (sig); 597} 598 599int 600ns8250_bus_ioctl(struct uart_softc *sc, int request, intptr_t data) 601{ 602 struct uart_bas *bas; 603 int baudrate, divisor, error; --- 337 unchanged lines hidden (view full) --- 941 struct uart_bas *bas; 942 uint32_t new, old; 943 944 bas = &sc->sc_bas; 945 do { 946 old = sc->sc_hwsig; 947 new = old; 948 if (sig & SER_DDTR) { |
903 SIGCHG(sig & SER_DTR, new, SER_DTR, 904 SER_DDTR); | 949 new = (new & ~SER_DTR) | (sig & (SER_DTR | SER_DDTR)); |
905 } 906 if (sig & SER_DRTS) { | 950 } 951 if (sig & SER_DRTS) { |
907 SIGCHG(sig & SER_RTS, new, SER_RTS, 908 SER_DRTS); | 952 new = (new & ~SER_RTS) | (sig & (SER_RTS | SER_DRTS)); |
909 } 910 } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); 911 uart_lock(sc->sc_hwmtx); 912 ns8250->mcr &= ~(MCR_DTR|MCR_RTS); 913 if (new & SER_DTR) 914 ns8250->mcr |= MCR_DTR; 915 if (new & SER_RTS) 916 ns8250->mcr |= MCR_RTS; --- 66 unchanged lines hidden --- | 953 } 954 } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); 955 uart_lock(sc->sc_hwmtx); 956 ns8250->mcr &= ~(MCR_DTR|MCR_RTS); 957 if (new & SER_DTR) 958 ns8250->mcr |= MCR_DTR; 959 if (new & SER_RTS) 960 ns8250->mcr |= MCR_RTS; --- 66 unchanged lines hidden --- |