summaryrefslogtreecommitdiffstats
path: root/sys/dev/puc
diff options
context:
space:
mode:
authorsobomax <sobomax@FreeBSD.org>2003-03-15 16:25:40 +0000
committersobomax <sobomax@FreeBSD.org>2003-03-15 16:25:40 +0000
commitb8597af91cb6ffe5daabe96d27818547ef65ff33 (patch)
tree55efefc19da767f399830aeb6d78166bc554ea4f /sys/dev/puc
parent9cb5290df7bf3276f0ddc34c782809f8d1573ee4 (diff)
downloadFreeBSD-src-b8597af91cb6ffe5daabe96d27818547ef65ff33.zip
FreeBSD-src-b8597af91cb6ffe5daabe96d27818547ef65ff33.tar.gz
- Add minimal support for TI16754 4xUART chip into sio(4) driver and remove
now unnecessary hack from the previous commit; - Add support for Interrupt Latch Register (ILR) into puc(4). So far only ILRs compatible with specifications from Digi International are supported. Support for other types of ILRs could be easily added later; - Correct clock frequency for IC Book Labs Dreadnought x16 Lite board; - Enable ILR detection/usage for IC Book Labs Dreadnought x16 boards. Sponsored by: IC Book Labs MFC after: 2 weeks
Diffstat (limited to 'sys/dev/puc')
-rw-r--r--sys/dev/puc/puc.c74
-rw-r--r--sys/dev/puc/pucdata.c70
-rw-r--r--sys/dev/puc/pucvar.h9
3 files changed, 113 insertions, 40 deletions
diff --git a/sys/dev/puc/puc.c b/sys/dev/puc/puc.c
index 18d2fba..fedf9bb 100644
--- a/sys/dev/puc/puc.c
+++ b/sys/dev/puc/puc.c
@@ -130,6 +130,35 @@ puc_port_bar_index(struct puc_softc *sc, int bar)
return (i);
}
+static int
+puc_probe_ilr(struct puc_softc *sc, struct resource *res)
+{
+ u_char t1, t2;
+ int i;
+
+ switch (sc->sc_desc->ilr_type) {
+ case PUC_ILR_TYPE_DIGI:
+ sc->ilr_st = rman_get_bustag(res);
+ sc->ilr_sh = rman_get_bushandle(res);
+ for (i = 0; i < 2; i++) {
+ t1 = bus_space_read_1(sc->ilr_st, sc->ilr_sh,
+ sc->sc_desc->ilr_offset[i]);
+ t1 = ~t1;
+ bus_space_write_1(sc->ilr_st, sc->ilr_sh,
+ sc->sc_desc->ilr_offset[i], t1);
+ t2 = bus_space_read_1(sc->ilr_st, sc->ilr_sh,
+ sc->sc_desc->ilr_offset[i]);
+ if (t2 == t1)
+ return (0);
+ }
+ return (1);
+
+ default:
+ break;
+ }
+ return (0);
+}
+
int
puc_attach(device_t dev, const struct puc_device_description *desc)
{
@@ -195,6 +224,14 @@ puc_attach(device_t dev, const struct puc_device_description *desc)
}
sc->sc_bar_mappings[bidx].type = type;
sc->sc_bar_mappings[bidx].res = res;
+
+ if (sc->sc_desc->ilr_type != PUC_ILR_TYPE_NONE) {
+ sc->ilr_enabled = puc_probe_ilr(sc, res);
+ if (sc->ilr_enabled)
+ device_printf(dev, "ILR enabled\n");
+ else
+ device_printf(dev, "ILR disabled\n");
+ }
#ifdef PUC_DEBUG
printf("%s rid %d bst %x, start %x, end %x\n",
(type == SYS_RES_MEMORY) ? "memory" : "port", rid,
@@ -307,22 +344,47 @@ puc_attach(device_t dev, const struct puc_device_description *desc)
return (0);
}
+static u_int32_t
+puc_ilr_read(struct puc_softc *sc)
+{
+ u_int32_t mask;
+ int i;
+
+ mask = 0;
+ switch (sc->sc_desc->ilr_type) {
+ case PUC_ILR_TYPE_DIGI:
+ for (i = 1; i >= 0; i--) {
+ mask = (mask << 8) | (bus_space_read_1(sc->ilr_st,
+ sc->ilr_sh, sc->sc_desc->ilr_offset[i]) & 0xff);
+ }
+ break;
+
+ default:
+ mask = 0xffffffff;
+ break;
+ }
+ return (mask);
+}
+
/*
- * This is just a brute force interrupt handler. It just calls all the
- * registered handlers sequencially.
- *
- * Later on we should maybe have a different handler for boards that can
- * tell us which device generated the interrupt.
+ * This is an interrupt handler. For boards that can't tell us which
+ * device generated the interrupt it just calls all the registered
+ * handlers sequencially, but for boards that can tell us which
+ * device(s) generated the interrupt it calls only handlers for devices
+ * that actually generated the interrupt.
*/
static void
puc_intr(void *arg)
{
int i;
+ u_int32_t ilr_mask;
struct puc_softc *sc;
sc = (struct puc_softc *)arg;
+ ilr_mask = sc->ilr_enabled ? puc_ilr_read(sc) : 0xffffffff;
for (i = 0; i < PUC_MAX_PORTS; i++)
- if (sc->sc_ports[i].ihand != NULL)
+ if (sc->sc_ports[i].ihand != NULL &&
+ ((ilr_mask >> i) & 0x00000001))
(sc->sc_ports[i].ihand)(sc->sc_ports[i].ihandarg);
}
diff --git a/sys/dev/puc/pucdata.c b/sys/dev/puc/pucdata.c
index e556215..7e65aa7 100644
--- a/sys/dev/puc/pucdata.c
+++ b/sys/dev/puc/pucdata.c
@@ -1000,23 +1000,24 @@ const struct puc_device_description puc_devices[] = {
{ 0xb00c, 0x091c, 0, 0 },
{ 0xffff, 0xffff, 0, 0 },
{
- { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x20, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x28, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x30, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x38, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x40, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x48, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x50, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x58, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x60, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x68, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x70, COM_FREQ * 4 },
- { PUC_PORT_TYPE_COM, 0x10, 0x78, COM_FREQ * 4 },
- },
+ { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x20, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x28, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x30, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x38, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x40, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x48, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x50, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x58, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x60, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x68, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x70, COM_FREQ },
+ { PUC_PORT_TYPE_COM, 0x10, 0x78, COM_FREQ },
+ },
+ PUC_ILR_TYPE_DIGI, { 0x07, 0x47 },
},
{ "IC Book Labs Dreadnought x16 Pro",
@@ -1024,23 +1025,24 @@ const struct puc_device_description puc_devices[] = {
{ 0xb00c, 0x081c, 0, 0 },
{ 0xffff, 0xffff, 0, 0 },
{
- { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x20, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x28, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x30, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x38, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x40, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x48, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x50, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x58, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x60, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x68, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x70, COM_FREQ * 8 },
- { PUC_PORT_TYPE_COM, 0x10, 0x78, COM_FREQ * 8 },
- },
+ { PUC_PORT_TYPE_COM, 0x10, 0x00, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x08, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x10, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x18, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x20, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x28, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x30, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x38, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x40, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x48, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x50, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x58, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x60, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x68, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x70, COM_FREQ * 8, 0x200000 },
+ { PUC_PORT_TYPE_COM, 0x10, 0x78, COM_FREQ * 8, 0x200000 },
+ },
+ PUC_ILR_TYPE_DIGI, { 0x07, 0x47 },
},
{ 0 }
diff --git a/sys/dev/puc/pucvar.h b/sys/dev/puc/pucvar.h
index fcbb0eb..9bb3928 100644
--- a/sys/dev/puc/pucvar.h
+++ b/sys/dev/puc/pucvar.h
@@ -80,6 +80,8 @@ struct puc_device_description {
u_int serialfreq;
u_int flags;
} ports[PUC_MAX_PORTS];
+ uint32_t ilr_type;
+ uint32_t ilr_offset[2];
};
#define PUC_REG_VEND 0
@@ -91,6 +93,10 @@ struct puc_device_description {
#define PUC_PORT_TYPE_COM 1
#define PUC_PORT_TYPE_LPT 2
+/* Interrupt Latch Register (ILR) types */
+#define PUC_ILR_TYPE_NONE 0
+#define PUC_ILR_TYPE_DIGI 1
+
#define PUC_FLAGS_MEMORY 0x0001 /* Use memory mapped I/O. */
#define PUC_PORT_VALID(desc, port) \
@@ -126,6 +132,9 @@ struct puc_softc {
int irqrid;
struct resource *irqres;
void *intr_cookie;
+ int ilr_enabled;
+ bus_space_tag_t ilr_st;
+ bus_space_handle_t ilr_sh;
struct {
int used;
OpenPOWER on IntegriCloud