Module Name: src Committed By: jmcneill Date: Wed Jul 4 13:14:51 UTC 2018
Modified Files: src/sys/arch/arm/samsung: exynos_sscom.c sscom.c sscom_var.h Log Message: Only process a tx or rx interrupt if the pending bit is set. To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.11 src/sys/arch/arm/samsung/exynos_sscom.c cvs rdiff -u -r1.9 -r1.10 src/sys/arch/arm/samsung/sscom.c cvs rdiff -u -r1.4 -r1.5 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.10 src/sys/arch/arm/samsung/exynos_sscom.c:1.11 --- src/sys/arch/arm/samsung/exynos_sscom.c:1.10 Mon Jun 19 21:58:13 2017 +++ src/sys/arch/arm/samsung/exynos_sscom.c Wed Jul 4 13:14:51 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: exynos_sscom.c,v 1.10 2017/06/19 21:58:13 jmcneill Exp $ */ +/* $NetBSD: exynos_sscom.c,v 1.11 2018/07/04 13:14:51 jmcneill Exp $ */ /* * Copyright (c) 2014 Reinoud Zandijk @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: exynos_sscom.c,v 1.10 2017/06/19 21:58:13 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: exynos_sscom.c,v 1.11 2018/07/04 13:14:51 jmcneill Exp $"); #include "opt_sscom.h" #include "opt_ddb.h" @@ -95,27 +95,17 @@ 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); + uint32_t 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); + uint32_t 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 @@ -134,6 +124,20 @@ exynos_change_txrx_interrupts(struct ssc } } +static int +exynos_pending_interrupts(struct sscom_softc *sc) +{ + uint32_t val, ret = 0; + + val = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSCOM_UINTP); + if (val & UINT_RXD) + ret |= SSCOM_HW_RXINT; + if (val & UINT_TXD) + ret |= SSCOM_HW_TXINT; + + return ret; +} + static void exynos_clear_interrupts(struct sscom_softc *sc, u_int flags) { @@ -193,6 +197,7 @@ sscom_attach(device_t parent, device_t s sc->sc_frequency = clk_get_rate(clk_uart_baud0); sc->sc_change_txrx_interrupts = exynos_change_txrx_interrupts; + sc->sc_pending_interrupts = exynos_pending_interrupts; sc->sc_clear_interrupts = exynos_clear_interrupts; /* not used here, but do initialise */ @@ -204,6 +209,11 @@ sscom_attach(device_t parent, device_t s aprint_normal("\n"); + /* Disable interrupts */ + bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSCOM_UINTM, 0); + bus_space_write_4(sc->sc_iot, sc->sc_ioh, SSCOM_UINTP, + bus_space_read_4(sc->sc_iot, sc->sc_ioh, SSCOM_UINTP)); + if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { aprint_error_dev(self, "failed to decode interrupt\n"); return; Index: src/sys/arch/arm/samsung/sscom.c diff -u src/sys/arch/arm/samsung/sscom.c:1.9 src/sys/arch/arm/samsung/sscom.c:1.10 --- src/sys/arch/arm/samsung/sscom.c:1.9 Sat Jun 10 15:13:18 2017 +++ src/sys/arch/arm/samsung/sscom.c Wed Jul 4 13:14:51 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: sscom.c,v 1.9 2017/06/10 15:13:18 jmcneill Exp $ */ +/* $NetBSD: sscom.c,v 1.10 2018/07/04 13:14:51 jmcneill Exp $ */ /* * Copyright (c) 2002, 2003 Fujitsu Component Limited @@ -98,7 +98,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sscom.c,v 1.9 2017/06/10 15:13:18 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sscom.c,v 1.10 2018/07/04 13:14:51 jmcneill Exp $"); #include "opt_sscom.h" #include "opt_ddb.h" @@ -422,6 +422,7 @@ sscom_attach_subr(struct sscom_softc *sc /* Disable interrupts before configuring the device. */ KASSERT(sc->sc_change_txrx_interrupts != NULL); + KASSERT(sc->sc_pending_interrupts != NULL); KASSERT(sc->sc_clear_interrupts != NULL); sscom_disable_txrxint(sc); @@ -1818,17 +1819,19 @@ int sscomintr(void *v) { struct sscom_softc *sc = v; - int clear = 0; + int pend, rv = 0; - if (sscomrxintr(v)) - clear |= SSCOM_HW_RXINT; - if (sscomtxintr(v)) - clear |= SSCOM_HW_TXINT; + pend = sc->sc_pending_interrupts(sc); - if (clear) - sc->sc_clear_interrupts(sc, clear); + if (pend & SSCOM_HW_RXINT) + rv += sscomrxintr(v); + if (pend & SSCOM_HW_TXINT) + rv += sscomtxintr(v); - return clear? 1: 0; + if (pend) + sc->sc_clear_interrupts(sc, pend); + + return rv; } Index: src/sys/arch/arm/samsung/sscom_var.h diff -u src/sys/arch/arm/samsung/sscom_var.h:1.4 src/sys/arch/arm/samsung/sscom_var.h:1.5 --- src/sys/arch/arm/samsung/sscom_var.h:1.4 Tue Apr 14 20:32:35 2015 +++ src/sys/arch/arm/samsung/sscom_var.h Wed Jul 4 13:14:51 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: sscom_var.h,v 1.4 2015/04/14 20:32:35 riastradh Exp $ */ +/* $NetBSD: sscom_var.h,v 1.5 2018/07/04 13:14:51 jmcneill Exp $ */ /* * Copyright (c) 2002, 2003 Fujitsu Component Limited @@ -187,6 +187,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); + int (*sc_pending_interrupts)(struct sscom_softc *); void (*sc_clear_interrupts)(struct sscom_softc *, u_int); };