Implement sscom interrupt masking and acknowledgement routines
This commit is contained in:
parent
68aeaa009b
commit
4ff24160d3
@ -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
|
* Copyright (c) 2014 Reinoud Zandijk
|
||||||
@ -34,7 +34,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#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_sscom.h"
|
||||||
#include "opt_ddb.h"
|
#include "opt_ddb.h"
|
||||||
@ -69,11 +69,6 @@ __KERNEL_RCSID(0, "$NetBSD: exynos_sscom.c,v 1.1 2014/04/13 02:26:26 matt Exp $"
|
|||||||
static int sscom_match(device_t, cfdata_t, void *);
|
static int sscom_match(device_t, cfdata_t, void *);
|
||||||
static void sscom_attach(device_t, device_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,
|
CFATTACH_DECL_NEW(exynos_sscom, sizeof(struct sscom_softc), sscom_match,
|
||||||
sscom_attach, NULL, NULL);
|
sscom_attach, NULL, NULL);
|
||||||
|
|
||||||
@ -86,6 +81,32 @@ sscom_match(device_t parent, cfdata_t cf, void *aux)
|
|||||||
return port >= 0 && port <= 4;
|
return port >= 0 && port <= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
static void
|
||||||
exynos_change_txrx_interrupts(struct sscom_softc *sc, bool unmask_p,
|
exynos_change_txrx_interrupts(struct sscom_softc *sc, bool unmask_p,
|
||||||
u_int flags)
|
u_int flags)
|
||||||
@ -96,12 +117,24 @@ exynos_change_txrx_interrupts(struct sscom_softc *sc, bool unmask_p,
|
|||||||
if (flags & SSCOM_HW_TXINT)
|
if (flags & SSCOM_HW_TXINT)
|
||||||
intbits |= 1 << sc->sc_tx_irqno;
|
intbits |= 1 << sc->sc_tx_irqno;
|
||||||
if (unmask_p) {
|
if (unmask_p) {
|
||||||
exynos_unmask_interrupts(intbits);
|
exynos_unmask_interrupts(sc, intbits);
|
||||||
} else {
|
} 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
|
static void
|
||||||
sscom_attach(device_t parent, device_t self, void *aux)
|
sscom_attach(device_t parent, device_t self, void *aux)
|
||||||
{
|
{
|
||||||
@ -118,9 +151,10 @@ sscom_attach(device_t parent, device_t self, void *aux)
|
|||||||
sc->sc_frequency = EXYNOS_UART_FREQ;
|
sc->sc_frequency = EXYNOS_UART_FREQ;
|
||||||
|
|
||||||
sc->sc_change_txrx_interrupts = exynos_change_txrx_interrupts;
|
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_rx_irqno = UINT_RXD;
|
||||||
sc->sc_tx_irqno = 0; // S3C2800_INT_TXD0 + sa->sa_index;
|
sc->sc_tx_irqno = UINT_TXD;
|
||||||
|
|
||||||
if (!sscom_is_console(sc->sc_iot, unit, &sc->sc_ioh)
|
if (!sscom_is_console(sc->sc_iot, unit, &sc->sc_ioh)
|
||||||
&& bus_space_map(sc->sc_iot, iobase, SSCOM_SIZE, 0, &sc->sc_ioh)) {
|
&& bus_space_map(sc->sc_iot, iobase, SSCOM_SIZE, 0, &sc->sc_ioh)) {
|
||||||
|
@ -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
|
* Copyright (c) 2002, 2003 Fujitsu Component Limited
|
||||||
@ -98,7 +98,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#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_sscom.h"
|
||||||
#include "opt_ddb.h"
|
#include "opt_ddb.h"
|
||||||
@ -424,6 +424,7 @@ sscom_attach_subr(struct sscom_softc *sc)
|
|||||||
|
|
||||||
/* Disable interrupts before configuring the device. */
|
/* Disable interrupts before configuring the device. */
|
||||||
KASSERT(sc->sc_change_txrx_interrupts != NULL);
|
KASSERT(sc->sc_change_txrx_interrupts != NULL);
|
||||||
|
KASSERT(sc->sc_clear_interrupts != NULL);
|
||||||
sscom_disable_txrxint(sc);
|
sscom_disable_txrxint(sc);
|
||||||
|
|
||||||
#ifdef KGDB
|
#ifdef KGDB
|
||||||
@ -1818,7 +1819,18 @@ sscomtxintr(void *arg)
|
|||||||
int
|
int
|
||||||
sscomintr(void *v)
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
* Copyright (c) 2002, 2003 Fujitsu Component Limited
|
||||||
@ -140,10 +140,6 @@
|
|||||||
#define UINT_ERROR __BIT(1)
|
#define UINT_ERROR __BIT(1)
|
||||||
#define UINT_RXD __BIT(0)
|
#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
|
#define SSCOM_SIZE 0x3C
|
||||||
|
|
||||||
#endif /* _ARM_SAMSUNG_SSCOM_REG_H_ */
|
#endif /* _ARM_SAMSUNG_SSCOM_REG_H_ */
|
||||||
|
@ -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
|
* Copyright (c) 2002, 2003 Fujitsu Component Limited
|
||||||
@ -184,6 +184,7 @@ struct sscom_softc {
|
|||||||
int (*sc_read_modem_status)( struct sscom_softc * );
|
int (*sc_read_modem_status)( struct sscom_softc * );
|
||||||
void (*sc_set_modem_control)( struct sscom_softc * );
|
void (*sc_set_modem_control)( struct sscom_softc * );
|
||||||
void (*sc_change_txrx_interrupts)(struct sscom_softc *, bool, u_int);
|
void (*sc_change_txrx_interrupts)(struct sscom_softc *, bool, u_int);
|
||||||
|
void (*sc_clear_interrupts)(struct sscom_softc *, u_int);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* UART register address, etc. */
|
/* UART register address, etc. */
|
||||||
|
Loading…
Reference in New Issue
Block a user