Module Name: src Committed By: reinoud Date: Mon Apr 14 21:16:15 UTC 2014
Modified Files: src/sys/arch/arm/samsung: exynos_sscom.c sscom.c sscom_reg.h sscom_var.h Log Message: Implement sscom interrupt masking and acknowledgement routines To generate a diff of this commit: cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/samsung/exynos_sscom.c \ src/sys/arch/arm/samsung/sscom.c src/sys/arch/arm/samsung/sscom_reg.h \ src/sys/arch/arm/samsung/sscom_var.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/samsung/exynos_sscom.c diff -u src/sys/arch/arm/samsung/exynos_sscom.c:1.1 src/sys/arch/arm/samsung/exynos_sscom.c:1.2 --- src/sys/arch/arm/samsung/exynos_sscom.c:1.1 Sun Apr 13 02:26:26 2014 +++ src/sys/arch/arm/samsung/exynos_sscom.c Mon Apr 14 21:16:15 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: exynos_sscom.c,v 1.1 2014/04/13 02:26:26 matt Exp $ */ +/* $NetBSD: exynos_sscom.c,v 1.2 2014/04/14 21:16:15 reinoud Exp $ */ /* * Copyright (c) 2014 Reinoud Zandijk @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: exynos_sscom.c,v 1.1 2014/04/13 02:26:26 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: exynos_sscom.c,v 1.2 2014/04/14 21:16:15 reinoud Exp $"); #include "opt_sscom.h" #include "opt_ddb.h" @@ -69,11 +69,6 @@ __KERNEL_RCSID(0, "$NetBSD: exynos_sscom static int sscom_match(device_t, cfdata_t, void *); static void sscom_attach(device_t, device_t, void *); -/* XXX cludge for not-existing interrupt code XXX */ -#define exynos_unmask_interrupts(intbits) -#define exynos_mask_interrupts(intbits) - - CFATTACH_DECL_NEW(exynos_sscom, sizeof(struct sscom_softc), sscom_match, sscom_attach, NULL, NULL); @@ -87,6 +82,32 @@ sscom_match(device_t parent, cfdata_t cf } static void +exynos_unmask_interrupts(struct sscom_softc *sc, int intbits) +{ + int psw = disable_interrupts(IF32_bits); + uint32_t val; + + val = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSCOM_UINTM); + val &= ~intbits; + bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSCOM_UINTM, val); + + restore_interrupts(psw); +} + +static void +exynos_mask_interrupts(struct sscom_softc *sc, int intbits) +{ + int psw = disable_interrupts(IF32_bits); + uint32_t val; + + val = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSCOM_UINTM); + val |= intbits; + bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSCOM_UINTM, val); + + restore_interrupts(psw); +} + +static void exynos_change_txrx_interrupts(struct sscom_softc *sc, bool unmask_p, u_int flags) { @@ -96,13 +117,25 @@ exynos_change_txrx_interrupts(struct ssc if (flags & SSCOM_HW_TXINT) intbits |= 1 << sc->sc_tx_irqno; if (unmask_p) { - exynos_unmask_interrupts(intbits); + exynos_unmask_interrupts(sc, intbits); } else { - exynos_mask_interrupts(intbits); + exynos_mask_interrupts(sc, intbits); } } static void +exynos_clear_interrupts(struct sscom_softc *sc, u_int flags) +{ + uint32_t val = 0; + + if (flags & SSCOM_HW_RXINT) + val |= sc->sc_rx_irqno; + if (flags & SSCOM_HW_TXINT) + val |= sc->sc_tx_irqno; + bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSCOM_UINTP, val); +} + +static void sscom_attach(device_t parent, device_t self, void *aux) { struct sscom_softc *sc = device_private(self); @@ -118,9 +151,10 @@ sscom_attach(device_t parent, device_t s sc->sc_frequency = EXYNOS_UART_FREQ; sc->sc_change_txrx_interrupts = exynos_change_txrx_interrupts; + sc->sc_clear_interrupts = exynos_clear_interrupts; - sc->sc_rx_irqno = 0; // S3C2800_INT_RXD0 + sa->sa_index; - sc->sc_tx_irqno = 0; // S3C2800_INT_TXD0 + sa->sa_index; + sc->sc_rx_irqno = UINT_RXD; + sc->sc_tx_irqno = UINT_TXD; if (!sscom_is_console(sc->sc_iot, unit, &sc->sc_ioh) && bus_space_map(sc->sc_iot, iobase, SSCOM_SIZE, 0, &sc->sc_ioh)) { Index: src/sys/arch/arm/samsung/sscom.c diff -u src/sys/arch/arm/samsung/sscom.c:1.1 src/sys/arch/arm/samsung/sscom.c:1.2 --- src/sys/arch/arm/samsung/sscom.c:1.1 Sun Apr 13 02:26:26 2014 +++ src/sys/arch/arm/samsung/sscom.c Mon Apr 14 21:16:15 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: sscom.c,v 1.1 2014/04/13 02:26:26 matt Exp $ */ +/* $NetBSD: sscom.c,v 1.2 2014/04/14 21:16:15 reinoud Exp $ */ /* * Copyright (c) 2002, 2003 Fujitsu Component Limited @@ -98,7 +98,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sscom.c,v 1.1 2014/04/13 02:26:26 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sscom.c,v 1.2 2014/04/14 21:16:15 reinoud Exp $"); #include "opt_sscom.h" #include "opt_ddb.h" @@ -424,6 +424,7 @@ sscom_attach_subr(struct sscom_softc *sc /* Disable interrupts before configuring the device. */ KASSERT(sc->sc_change_txrx_interrupts != NULL); + KASSERT(sc->sc_clear_interrupts != NULL); sscom_disable_txrxint(sc); #ifdef KGDB @@ -1818,7 +1819,18 @@ sscomtxintr(void *arg) int sscomintr(void *v) { - return sscomrxintr(v) + sscomtxintr(v); + struct sscom_softc *sc = v; + int clear = 0; + + if (sscomrxintr(v)) + clear |= SSCOM_HW_RXINT; + if (sscomtxintr(v)) + clear |= SSCOM_HW_TXINT; + + if (clear) + sc->sc_clear_interrupts(sc, clear); + + return clear? 1: 0; } Index: src/sys/arch/arm/samsung/sscom_reg.h diff -u src/sys/arch/arm/samsung/sscom_reg.h:1.1 src/sys/arch/arm/samsung/sscom_reg.h:1.2 --- src/sys/arch/arm/samsung/sscom_reg.h:1.1 Sun Apr 13 02:26:26 2014 +++ src/sys/arch/arm/samsung/sscom_reg.h Mon Apr 14 21:16:15 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: sscom_reg.h,v 1.1 2014/04/13 02:26:26 matt Exp $ */ +/* $NetBSD: sscom_reg.h,v 1.2 2014/04/14 21:16:15 reinoud Exp $ */ /* * Copyright (c) 2002, 2003 Fujitsu Component Limited @@ -140,10 +140,6 @@ #define UINT_ERROR __BIT(1) #define UINT_RXD __BIT(0) -//#define INTCTL_SRCPND 0x00 /* Interrupt request status */ -//#define INTCTL_INTMOD 0x04 /* Interrupt mode (FIQ/IRQ) */ -//#define INTCTL_INTMSK 0x08 /* Interrupt mask */ - #define SSCOM_SIZE 0x3C #endif /* _ARM_SAMSUNG_SSCOM_REG_H_ */ Index: src/sys/arch/arm/samsung/sscom_var.h diff -u src/sys/arch/arm/samsung/sscom_var.h:1.1 src/sys/arch/arm/samsung/sscom_var.h:1.2 --- src/sys/arch/arm/samsung/sscom_var.h:1.1 Sun Apr 13 02:26:26 2014 +++ src/sys/arch/arm/samsung/sscom_var.h Mon Apr 14 21:16:15 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: sscom_var.h,v 1.1 2014/04/13 02:26:26 matt Exp $ */ +/* $NetBSD: sscom_var.h,v 1.2 2014/04/14 21:16:15 reinoud Exp $ */ /* * Copyright (c) 2002, 2003 Fujitsu Component Limited @@ -184,6 +184,7 @@ struct sscom_softc { int (*sc_read_modem_status)( struct sscom_softc * ); void (*sc_set_modem_control)( struct sscom_softc * ); void (*sc_change_txrx_interrupts)(struct sscom_softc *, bool, u_int); + void (*sc_clear_interrupts)(struct sscom_softc *, u_int); }; /* UART register address, etc. */