Cleanup sscom to make more SoC invariant

This commit is contained in:
matt 2014-03-14 21:40:48 +00:00
parent c4aa7bf7ad
commit 2b85113592
5 changed files with 99 additions and 77 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: sscom.c,v 1.40 2014/03/10 04:25:51 htodd Exp $ */
/* $NetBSD: sscom.c,v 1.41 2014/03/14 21:40:48 matt Exp $ */
/*
* Copyright (c) 2002, 2003 Fujitsu Component Limited
@ -98,7 +98,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sscom.c,v 1.40 2014/03/10 04:25:51 htodd Exp $");
__KERNEL_RCSID(0, "$NetBSD: sscom.c,v 1.41 2014/03/14 21:40:48 matt Exp $");
#include "opt_sscom.h"
#include "opt_ddb.h"
@ -142,6 +142,7 @@ __KERNEL_RCSID(0, "$NetBSD: sscom.c,v 1.40 2014/03/10 04:25:51 htodd Exp $");
#include <sys/kauth.h>
#include <sys/intr.h>
#include <sys/bus.h>
#include <sys/mutex.h>
#include <arm/s3c2xx0/s3c2xx0reg.h>
#include <arm/s3c2xx0/s3c2xx0var.h>
@ -244,8 +245,8 @@ void sscom_kgdb_putc (void *, int);
#if (defined(MULTIPROCESSOR) || defined(LOCKDEBUG)) && defined(SSCOM_MPLOCK)
#define SSCOM_LOCK(sc) simple_lock((sc)->sc_lock)
#define SSCOM_UNLOCK(sc) simple_unlock((sc)->sc_lock)
#define SSCOM_LOCK(sc) mutex_enter((sc)->sc_lock)
#define SSCOM_UNLOCK(sc) mutex_exit((sc)->sc_lock)
#else
@ -365,7 +366,7 @@ sscom_enable_debugport(struct sscom_softc *sc)
sc->sc_ucon = UCON_DEBUGPORT;
bus_space_write_2(sc->sc_iot, sc->sc_ioh, SSCOM_UCON, sc->sc_ucon);
sc->sc_umcon = UMCON_RTS|UMCON_DTR;
sc->set_modem_control(sc);
sc->sc_set_modem_control(sc);
sscom_enable_rxint(sc);
sscom_disable_txint(sc);
SSCOM_UNLOCK(sc);
@ -402,7 +403,7 @@ sscom_attach_subr(struct sscom_softc *sc)
callout_init(&sc->sc_diag_callout, 0);
#if (defined(MULTIPROCESSOR) || defined(LOCKDEBUG)) && defined(SSCOM_MPLOCK)
simple_lock_init(&sc->sc_lock);
sc->sc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SERIAL);
#endif
sc->sc_ucon = UCON_RXINT_ENABLE|UCON_TXINT_ENABLE;
@ -410,12 +411,13 @@ sscom_attach_subr(struct sscom_softc *sc)
/*
* set default for modem control hook
*/
if (sc->set_modem_control == NULL)
sc->set_modem_control = sscom_set_modem_control;
if (sc->read_modem_status == NULL)
sc->read_modem_status = sscom_read_modem_status;
if (sc->sc_set_modem_control == NULL)
sc->sc_set_modem_control = sscom_set_modem_control;
if (sc->sc_read_modem_status == NULL)
sc->sc_read_modem_status = sscom_read_modem_status;
/* Disable interrupts before configuring the device. */
KASSERT(sc->sc_change_txrx_interrupts != NULL);
sscom_disable_txrxint(sc);
#ifdef KGDB
@ -640,7 +642,7 @@ sscomopen(dev_t dev, int flag, int mode, struct lwp *l)
sscom_enable_txrxint(sc);
/* Fetch the current modem control status, needed later. */
sc->sc_msts = sc->read_modem_status(sc);
sc->sc_msts = sc->sc_read_modem_status(sc);
#if 0
/* Clear PPS capture state on first open. */
@ -1206,7 +1208,7 @@ sscom_loadchannelregs(struct sscom_softc *sc)
bus_space_write_2(iot, ioh, SSCOM_UBRDIV, sc->sc_ubrdiv);
bus_space_write_1(iot, ioh, SSCOM_ULCON, sc->sc_ulcon);
sc->set_modem_control(sc);
sc->sc_set_modem_control(sc);
bus_space_write_2(iot, ioh, SSCOM_UCON, sc->sc_ucon);
}
@ -1262,7 +1264,7 @@ sscom_hwiflow(struct sscom_softc *sc)
SET(sc->sc_umcon, sc->sc_mcr_rts);
SET(sc->sc_mcr_active, sc->sc_mcr_rts);
}
sc->set_modem_control(sc);
sc->sc_set_modem_control(sc);
}
@ -1634,7 +1636,7 @@ sscomrxintr(void *arg)
}
msts = sc->read_modem_status(sc);
msts = sc->sc_read_modem_status(sc);
delta = msts ^ sc->sc_msts;
sc->sc_msts = msts;

View File

@ -1,4 +1,4 @@
/* $NetBSD: sscom_s3c2410.c,v 1.6 2012/10/27 17:17:40 chs Exp $ */
/* $NetBSD: sscom_s3c2410.c,v 1.7 2014/03/14 21:40:48 matt Exp $ */
/*
* Copyright (c) 2002, 2003 Fujitsu Component Limited
@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sscom_s3c2410.c,v 1.6 2012/10/27 17:17:40 chs Exp $");
__KERNEL_RCSID(0, "$NetBSD: sscom_s3c2410.c,v 1.7 2014/03/14 21:40:48 matt Exp $");
#include "opt_sscom.h"
#include "opt_ddb.h"
@ -106,6 +106,26 @@ sscom_match(device_t parent, cfdata_t cf, void *aux)
return unit == 0 || unit == 1;
}
/* RXINTn, TXINTn and ERRn interrupts are cascaded to UARTn irq. */
#define _sscom_intbit(irqno) (1<<((irqno)-S3C2410_SUBIRQ_MIN))
static void
s3c2410_change_txrx_interrupts(struct sscom_softc *sc, bool unmask_p,
u_int flags)
{
int intbits = 0;
if (flags & SSCOM_HW_RXINT)
intbits |= _sscom_intbit((sc)->sc_rx_irqno);
if (flags & SSCOM_HW_TXINT)
intbits |= _sscom_intbit((sc)->sc_rx_irqno);
if (unmask_p) {
s3c2410_unmask_subinterrupts(intbits);
} else {
s3c2410_mask_subinterrupts(intbits);
}
}
static void
sscom_attach(device_t parent, device_t self, void *aux)
{
@ -114,18 +134,20 @@ sscom_attach(device_t parent, device_t self, void *aux)
int unit = sa->sa_index;
bus_addr_t iobase = s3c2410_uart_config[unit].iobase;
printf( ": UART%d addr=%lx", sa->sa_index, iobase );
aprint_normal(": UART%d addr=%lx", sa->sa_index, iobase );
sc->sc_dev = self;
sc->sc_iot = s3c2xx0_softc->sc_iot;
sc->sc_unit = unit;
sc->sc_frequency = s3c2xx0_softc->sc_pclk;
sc->sc_change_txrx_interrupts = s3c2410_change_txrx_interrupts;
sc->sc_rx_irqno = s3c2410_uart_config[sa->sa_index].rx_int;
sc->sc_tx_irqno = s3c2410_uart_config[sa->sa_index].tx_int;
if (bus_space_map(sc->sc_iot, iobase, SSCOM_SIZE, 0, &sc->sc_ioh)) {
printf( ": failed to map registers\n" );
aprint_error( ": failed to map registers\n" );
return;
}

View File

@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sscom_s3c2440.c,v 1.3 2012/10/27 17:17:40 chs Exp $");
__KERNEL_RCSID(0, "$NetBSD: sscom_s3c2440.c,v 1.4 2014/03/14 21:40:48 matt Exp $");
#include "opt_sscom.h"
#include "opt_ddb.h"
@ -126,6 +126,24 @@ sscom_match(device_t parent, struct cfdata *cf, void *aux)
return (unit == 0 || unit == 1 || unit == 2);
}
#define _sscom_intbit(irqno) (1<<((irqno)-S3C2440_SUBIRQ_MIN))
static void
s3c2440_change_txrx_interrupts(struct sscom_softc *sc, bool unmask_p,
u_int flags)
{
int intrbits = 0;
if (flags & SSCOM_HW_RXINT)
intrbits |= _sscom_intbit((sc)->sc_rx_irqno);
if (flags & SSCOM_HW_TXINT)
intrbits |= _sscom_intbit((sc)->sc_tx_irqno);
if (unmask_p) {
s3c2440_unmask_subinterrupts(intrbits);
} else {
s3c2440_mask_subinterrupts(intrbits);
}
}
static void
sscom_attach(device_t parent, device_t self, void *aux)
{
@ -143,6 +161,8 @@ sscom_attach(device_t parent, device_t self, void *aux)
sc->sc_unit = unit;
sc->sc_frequency = s3c2xx0_softc->sc_pclk;
sc->sc_change_txrx_interrupts = s3c2440_change_txrx_interrupts;
sc->sc_rx_irqno = s3c2440_uart_config[unit].rx_int;
sc->sc_tx_irqno = s3c2440_uart_config[unit].tx_int;

View File

@ -1,4 +1,4 @@
/* $NetBSD: sscom_s3c2800.c,v 1.9 2012/10/27 17:17:40 chs Exp $ */
/* $NetBSD: sscom_s3c2800.c,v 1.10 2014/03/14 21:40:48 matt Exp $ */
/*
* Copyright (c) 2002, 2003 Fujitsu Component Limited
@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sscom_s3c2800.c,v 1.9 2012/10/27 17:17:40 chs Exp $");
__KERNEL_RCSID(0, "$NetBSD: sscom_s3c2800.c,v 1.10 2014/03/14 21:40:48 matt Exp $");
#include "opt_sscom.h"
#include "opt_ddb.h"
@ -98,6 +98,22 @@ sscom_match(device_t parent, cfdata_t cf, void *aux)
return unit == 0 || unit == 1;
}
static void
s3c2800_change_txrx_interrupts(struct sscom_softc *sc, bool unmask_p,
u_int flags)
{
int intbits = 0;
if (flags & SSCOM_HW_RXINT)
intbits |= 1 << sc->sc_rx_irqno;
if (flags & SSCOM_HW_TXINT)
intbits |= 1 << sc->sc_tx_irqno;
if (unmask_p) {
s3c2xx0_unmask_interrupts(intbits);
} else {
s3c2xx0_mask_interrupts(intbits);
}
}
static void
sscom_attach(device_t parent, device_t self, void *aux)
{
@ -113,6 +129,8 @@ sscom_attach(device_t parent, device_t self, void *aux)
sc->sc_unit = unit;
sc->sc_frequency = s3c2xx0_softc->sc_pclk;
sc->sc_change_txrx_interrupts = s3c2800_change_txrx_interrupts;
sc->sc_rx_irqno = S3C2800_INT_RXD0 + sa->sa_index;
sc->sc_tx_irqno = S3C2800_INT_TXD0 + sa->sa_index;

View File

@ -1,4 +1,4 @@
/* $NetBSD: sscom_var.h,v 1.12 2012/10/27 17:17:41 chs Exp $ */
/* $NetBSD: sscom_var.h,v 1.13 2014/03/14 21:40:48 matt Exp $ */
/*
* Copyright (c) 2002, 2003 Fujitsu Component Limited
@ -175,10 +175,10 @@ struct sscom_softc {
#endif
#ifdef RND_COM
krndsource_t rnd_source;
krndsource_t sc_rnd_source;
#endif
#if (defined(MULTIPROCESSOR) || defined(LOCKDEBUG)) && defined(SSCOM_MPLOCK)
struct simplelock sc_lock;
kmutex_t sc_lock;
#endif
/*
@ -187,8 +187,9 @@ struct sscom_softc {
* or provided by other means such as GPIO. Platform specific attach routine
* have to provide functions to read/write modem control/status pins.
*/
int (* read_modem_status)( struct sscom_softc * );
void (* set_modem_control)( 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);
};
/* UART register address, etc. */
@ -203,61 +204,20 @@ struct sscom_uart_info {
#define sscom_getc(iot,ioh) bus_space_read_1((iot), (ioh), SSCOM_URXH)
#define sscom_geterr(iot,ioh) bus_space_read_1((iot), (ioh), SSCOM_UERSTAT)
/*
* we need to tweak interrupt controller to mask/unmask rxint and/or txint.
*/
#ifdef SSCOM_S3C2410
/* RXINTn, TXINTn and ERRn interrupts are cascaded to UARTn irq. */
#define _sscom_intbit(irqno) (1<<((irqno)-S3C2410_SUBIRQ_MIN))
#define sscom_unmask_rxint(sc) \
s3c2410_unmask_subinterrupts(_sscom_intbit((sc)->sc_rx_irqno))
#define sscom_mask_rxint(sc) \
s3c2410_mask_subinterrupts(_sscom_intbit((sc)->sc_rx_irqno))
#define sscom_unmask_txint(sc) \
s3c2410_unmask_subinterrupts(_sscom_intbit((sc)->sc_tx_irqno))
#define sscom_mask_txint(sc) \
s3c2410_mask_subinterrupts(_sscom_intbit((sc)->sc_tx_irqno))
#define sscom_unmask_txrxint(sc) \
s3c2410_unmask_subinterrupts(_sscom_intbit((sc)->sc_tx_irqno) | \
_sscom_intbit((sc)->sc_rx_irqno))
#define sscom_mask_txrxint(sc) \
s3c2410_mask_subinterrupts(_sscom_intbit((sc)->sc_tx_irqno) | \
_sscom_intbit((sc)->sc_rx_irqno))
#elif defined(SSCOM_S3C2440)
/* RXINTn, TXINTn and ERRn interrupts are cascaded to UARTn irq. */
#define _sscom_intbit(irqno) (1<<((irqno)-S3C2440_SUBIRQ_MIN))
(*(sc)->sc_change_txrx_interrupts)((sc), false, SSCOM_HW_RXINT)
#define sscom_unmask_rxint(sc) \
s3c2440_unmask_subinterrupts(_sscom_intbit((sc)->sc_rx_irqno))
#define sscom_mask_rxint(sc) \
s3c2440_mask_subinterrupts(_sscom_intbit((sc)->sc_rx_irqno))
#define sscom_unmask_txint(sc) \
s3c2440_unmask_subinterrupts(_sscom_intbit((sc)->sc_tx_irqno))
(*(sc)->sc_change_txrx_interrupts)((sc), true, SSCOM_HW_RXINT)
#define sscom_mask_txint(sc) \
s3c2440_mask_subinterrupts(_sscom_intbit((sc)->sc_tx_irqno))
#define sscom_unmask_txrxint(sc) \
s3c2440_unmask_subinterrupts(_sscom_intbit((sc)->sc_tx_irqno) | \
_sscom_intbit((sc)->sc_rx_irqno))
(*(sc)->sc_change_txrx_interrupts)((sc), false, SSCOM_HW_TXINT)
#define sscom_unmask_txint(sc) \
(*(sc)->sc_change_txrx_interrupts)((sc), true, SSCOM_HW_TXINT)
#define sscom_mask_txrxint(sc) \
s3c2440_mask_subinterrupts(_sscom_intbit((sc)->sc_tx_irqno) | \
_sscom_intbit((sc)->sc_rx_irqno))
#else
/* for S3C2800 and S3C2400 */
#define sscom_unmask_rxint(sc) s3c2xx0_unmask_interrupts(1<<(sc)->sc_rx_irqno)
#define sscom_mask_rxint(sc) s3c2xx0_mask_interrupts(1<<(sc)->sc_rx_irqno)
#define sscom_unmask_txint(sc) s3c2xx0_unmask_interrupts(1<<(sc)->sc_tx_irqno)
#define sscom_mask_txint(sc) s3c2xx0_mask_interrupts(1<<(sc)->sc_tx_irqno)
(*(sc)->sc_change_txrx_interrupts)((sc), false, \
SSCOM_HW_RXINT | SSCOM_HW_TXINT)
#define sscom_unmask_txrxint(sc) \
s3c2xx0_unmask_interrupts((1<<(sc)->sc_tx_irqno)|(1<<(sc)->sc_rx_irqno))
#define sscom_mask_txrxint(sc) \
s3c2xx0_mask_interrupts((1<<(sc)->sc_tx_irqno)|(1<<(sc)->sc_rx_irqno))
#endif /* SSCOM_S3C2410 */
(*(sc)->sc_change_txrx_interrupts)((sc), true, \
SSCOM_HW_RXINT | SSCOM_HW_TXINT)
#define sscom_enable_rxint(sc) \
(sscom_unmask_rxint(sc), ((sc)->sc_hwflags |= SSCOM_HW_RXINT))