Deleted Added
full compact
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 ---