Date: Sun, 22 Feb 2009 08:28:25 GMT From: Andrew Turner <andrew@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 158057 for review Message-ID: <200902220828.n1M8SPpC081569@repoman.freebsd.org>
index | next in thread | raw e-mail
http://perforce.freebsd.org/chv.cgi?CH=158057 Change 158057 by andrew@andrew_bender on 2009/02/22 08:27:50 Cleanup unmasking of interrupts to only unmask the requested interrupt. Have arm_get_next_irq return the uart interrupt rather than the subinterrupt as we are only interested in this. Call rman_activate_resource in s3c24x0_activate_resource. Get the uart driver working well enough to ask for the single user shell. Affected files ... .. //depot/projects/arm/src/sys/arm/s3c2xx0/s3c24x0.c#6 edit .. //depot/projects/arm/src/sys/arm/s3c2xx0/uart_dev_s3c2410.c#9 edit Differences ... ==== //depot/projects/arm/src/sys/arm/s3c2xx0/s3c24x0.c#6 (text+ko) ==== @@ -247,7 +247,7 @@ s3c24x0_activate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { - return (0); + return (rman_activate_resource(r)); } static int @@ -502,17 +502,17 @@ arm_get_next_irq(void) { uint32_t intpnd; - int irq; + int irq, subirq; if ((irq = bus_space_read_4(&s3c2xx0_bs_tag, s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTOFFSET)) != 0) { /* Clear the pending bit */ - bus_space_write_4(&s3c2xx0_bs_tag, s3c2xx0_softc->sc_intctl_ioh, - INTCTL_SRCPND, (1 << irq)); intpnd = bus_space_read_4(&s3c2xx0_bs_tag, s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTPND); bus_space_write_4(&s3c2xx0_bs_tag, s3c2xx0_softc->sc_intctl_ioh, + INTCTL_SRCPND, intpnd); + bus_space_write_4(&s3c2xx0_bs_tag, s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTPND, intpnd); switch (irq) { @@ -521,22 +521,26 @@ case S3C24X0_INT_UART1: case S3C24X0_INT_UART2: /* Find the sub IRQ */ - irq = 0x7ff; - irq &= bus_space_read_4(&s3c2xx0_bs_tag, + subirq = 0x7ff; + subirq &= bus_space_read_4(&s3c2xx0_bs_tag, s3c2xx0_softc->sc_intctl_ioh, INTCTL_SUBSRCPND); - irq &= ~(bus_space_read_4(&s3c2xx0_bs_tag, + subirq &= ~(bus_space_read_4(&s3c2xx0_bs_tag, s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTSUBMSK)); - if (irq == 0) - return (-1); + if (subirq == 0) + return (irq); - irq = ffs(irq); + subirq = ffs(subirq); /* Clear the sub irq pending bit */ bus_space_write_4(&s3c2xx0_bs_tag, s3c2xx0_softc->sc_intctl_ioh, INTCTL_SUBSRCPND, - (1 << irq)); + (1 << subirq)); + + /* Return the parent IRQ for UART as that is all we ever need */ + if (subirq <= 8) + return (irq); - return (S3C24X0_SUBIRQ_MIN + irq); + return (S3C24X0_SUBIRQ_MIN + subirq); } return (irq); @@ -569,46 +573,17 @@ { u_int32_t mask; - if (irq >= S3C24X0_SUBIRQ_MIN) { + if (irq < S3C24X0_SUBIRQ_MIN) { + mask = bus_space_read_4(&s3c2xx0_bs_tag, + s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTMSK); + mask &= ~(1 << irq); + bus_space_write_4(&s3c2xx0_bs_tag, s3c2xx0_softc->sc_intctl_ioh, + INTCTL_INTMSK, mask); + } else { mask = bus_space_read_4(&s3c2xx0_bs_tag, s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTSUBMSK); mask &= ~(1 << (irq - S3C24X0_SUBIRQ_MIN)); bus_space_write_4(&s3c2xx0_bs_tag, s3c2xx0_softc->sc_intctl_ioh, INTCTL_INTSUBMSK, mask); - - /* Find the other irq to unmask */ - switch (irq) { - case S3C24X0_INT_ADC: - case S3C24X0_INT_TC: - irq = S3C24X0_INT_ADCTC; - break; - case S3C24X0_INT_RXD0: - case S3C24X0_INT_TXD0: - case S3C24X0_INT_ERR0: - irq = S3C24X0_INT_UART0; - break; - - case S3C24X0_INT_RXD1: - case S3C24X0_INT_TXD1: - case S3C24X0_INT_ERR1: - irq = S3C24X0_INT_UART1; - break; - - case S3C24X0_INT_RXD2: - case S3C24X0_INT_TXD2: - case S3C24X0_INT_ERR2: - irq = S3C24X0_INT_UART2; - break; - default: - /* We don't know which other IRQ to unmask */ - return; - } - arm_mask_irq(irq); - return; } - mask = bus_space_read_4(&s3c2xx0_bs_tag, s3c2xx0_softc->sc_intctl_ioh, - INTCTL_INTMSK); - mask &= ~(1 << irq); - bus_space_write_4(&s3c2xx0_bs_tag, s3c2xx0_softc->sc_intctl_ioh, - INTCTL_INTMSK, mask); } ==== //depot/projects/arm/src/sys/arm/s3c2xx0/uart_dev_s3c2410.c#9 (text+ko) ==== @@ -1,6 +1,6 @@ /* * Copyright (c) 2003 Marcel Moolenaar - * Copyright (c) 2007 Andrew Turner + * Copyright (c) 2007-2009 Andrew Turner * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,7 +34,9 @@ #include <sys/conf.h> #include <sys/cons.h> #include <sys/tty.h> +#include <sys/rman.h> #include <machine/bus.h> +#include <machine/intr.h> #include <dev/uart/uart.h> #include <dev/uart/uart_cpu.h> @@ -46,6 +48,15 @@ #define DEFAULT_RCLK 3686400 +/* Finds the subirq from the parent */ +#define get_sub_irq(parent, offset) \ + ((parent == S3C24X0_INT_UART0) ? S3C24X0_SUBIRQ_MIN + offset : \ + ((parent == S3C24X0_INT_UART1) ? S3C24X0_SUBIRQ_MIN + 3 + offset : \ + S3C24X0_SUBIRQ_MIN + 6 + offset)) +#define RX_OFF 0 +#define TX_OFF 1 +#define ERR_OFF 2 + static int sscomspeed(long, long); static int s3c24x0_uart_param(struct uart_bas *, int, int, int, int); @@ -163,7 +174,8 @@ s3c24x0_uart_param(bas, baudrate, databits, stopbits, parity); /* Enable UART. */ - uart_setreg(bas, SSCOM_UCON, UCON_TXMODE_INT|UCON_RXMODE_INT|UCON_TOINT); + uart_setreg(bas, SSCOM_UCON, UCON_TXMODE_INT | UCON_RXMODE_INT | + UCON_TOINT); uart_setreg(bas, SSCOM_UMCON, UMCON_RTS); } @@ -176,7 +188,8 @@ static void s3c2410_putc(struct uart_bas *bas, int c) { - while (!(uart_getreg(bas, SSCOM_UTRSTAT) & UTRSTAT_TXEMPTY)) + while ((bus_space_read_4(bas->bst, bas->bsh, SSCOM_UFSTAT) & + UFSTAT_TXFULL) == UFSTAT_TXFULL) continue; uart_setreg(bas, SSCOM_UTXH, c); @@ -233,6 +246,8 @@ static int s3c2410_bus_attach(struct uart_softc *sc) { + uintptr_t irq; + bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); /* @@ -243,19 +258,34 @@ sc->sc_rxfifosz = 16; sc->sc_hwiflow = 0; sc->sc_hwoflow = 0; + + irq = rman_get_start(sc->sc_ires); + arm_unmask_irq(irq); + arm_unmask_irq(get_sub_irq(irq, RX_OFF)); + arm_unmask_irq(get_sub_irq(irq, TX_OFF)); + arm_unmask_irq(get_sub_irq(irq, ERR_OFF)); return (0); } static int s3c2410_bus_transmit(struct uart_softc *sc) { + uintptr_t irq; + uart_lock(sc->sc_hwmtx); + for (int i = 0; i < sc->sc_txdatasz; i++) { s3c2410_putc(&sc->sc_bas, sc->sc_txbuf[i]); uart_barrier(&sc->sc_bas); } + + sc->sc_txbusy = 1; + uart_unlock(sc->sc_hwmtx); + irq = rman_get_start(sc->sc_ires); + arm_unmask_irq(get_sub_irq(irq, TX_OFF)); + return (0); } @@ -290,17 +320,22 @@ static int s3c2410_bus_ipend(struct uart_softc *sc) { - uint32_t utrstat; + uintptr_t irq; + uint32_t ufstat; int ipend = 0; uart_lock(sc->sc_hwmtx); - utrstat = uart_getreg(&sc->sc_bas, SSCOM_UTRSTAT); + ufstat = bus_space_read_4(sc->sc_bas.bst, sc->sc_bas.bsh, SSCOM_UFSTAT); uart_unlock(sc->sc_hwmtx); - if ((utrstat & UTRSTAT_TXEMPTY) == UTRSTAT_TXEMPTY && sc->sc_txbusy != 0) { - ipend |= SER_INT_TXIDLE; + /* XXX: The register values are incorrect on the s3c244x */ + if ((ufstat & UFSTAT_TXCOUNT) == 0) { + if (sc->sc_txbusy != 0) + ipend |= SER_INT_TXIDLE; + irq = rman_get_start(sc->sc_ires); + arm_mask_irq(get_sub_irq(irq, TX_OFF)); } - if ((utrstat & UTRSTAT_RXREADY) == UTRSTAT_RXREADY) { + if ((ufstat & UFSTAT_RXCOUNT) > 0) { ipend |= SER_INT_RXREADY; }help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200902220828.n1M8SPpC081569>
