svn commit: r236940 - in projects/altix2/sys/dev: ata ioc4 uart

Marcel Moolenaar marcel at FreeBSD.org
Tue Jun 12 03:22:19 UTC 2012


Author: marcel
Date: Tue Jun 12 03:22:18 2012
New Revision: 236940
URL: http://svn.freebsd.org/changeset/base/236940

Log:
  Flesh-out ioc4 a bit more. In particular, add:
  o   uart(4) bus attachment
  o   ata(4) bus attachment
  
  This has been fleshed out enough to indicate that we still have a
  platform problem -- interrupts I suspect. Fixing that should allow
  me to make forward progress on the busdma code again.

Added:
  projects/altix2/sys/dev/ata/ata-ioc4.c   (contents, props changed)
  projects/altix2/sys/dev/ioc4/ioc4_reg.h   (contents, props changed)
  projects/altix2/sys/dev/uart/uart_bus_ioc4.c   (contents, props changed)
Modified:
  projects/altix2/sys/dev/ioc4/ioc4.c
  projects/altix2/sys/dev/ioc4/ioc4_bus.h

Added: projects/altix2/sys/dev/ata/ata-ioc4.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/altix2/sys/dev/ata/ata-ioc4.c	Tue Jun 12 03:22:18 2012	(r236940)
@@ -0,0 +1,138 @@
+/*-
+ * Copyright (c) 2012 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_ata.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/ata.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/malloc.h>
+#include <sys/sema.h>
+#include <sys/taskqueue.h>
+#include <vm/uma.h>
+#include <machine/stdarg.h>
+#include <machine/resource.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+
+#include <dev/ata/ata-all.h>
+
+#include <dev/ioc4/ioc4_bus.h>
+
+#include "ata_if.h"
+
+static int ata_ioc4_probe(device_t);
+static int ata_ioc4_attach(device_t);
+static int ata_ioc4_detach(device_t);
+
+static device_method_t ata_ioc4_methods[] = {
+	/* device interface */
+	DEVMETHOD(device_probe,		ata_ioc4_probe),
+	DEVMETHOD(device_attach,	ata_ioc4_attach),
+	DEVMETHOD(device_detach,	ata_ioc4_detach),
+
+	DEVMETHOD(bus_alloc_resource,	bus_generic_alloc_resource),
+	DEVMETHOD(bus_release_resource,	bus_generic_release_resource),
+	DEVMETHOD(bus_setup_intr,	bus_generic_setup_intr),
+	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
+	DEVMETHOD_END
+};
+
+static driver_t ata_ioc4_driver = {
+	"ata",
+	ata_ioc4_methods,
+	sizeof(struct ata_channel),
+};
+
+DRIVER_MODULE(ata, ioc4, ata_ioc4_driver, ata_devclass, NULL, NULL);
+MODULE_DEPEND(ata, ata, 1, 1, 1);
+
+static int
+ata_ioc4_probe(device_t dev)
+{
+	device_t parent;
+	uintptr_t type;
+
+	parent = device_get_parent(dev);
+	if (BUS_READ_IVAR(parent, dev, IOC4_IVAR_TYPE, &type))
+		return (ENXIO);
+	if (type != IOC4_TYPE_ATA)
+		return (ENXIO);
+
+	device_set_desc(dev, "SGI IOC4 ATA channel");
+	return (ata_probe(dev));
+}
+
+static int
+ata_ioc4_attach(device_t dev)
+{
+	struct ata_channel *ch = device_get_softc(dev);
+	struct resource *mres;
+	int i, rid;
+
+	if (ch->attached)
+		return (0);
+	ch->attached = 1;
+
+	rid = 0;
+	mres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+	if (mres == NULL)
+		return (ENXIO);
+
+	for (i = ATA_DATA; i <= ATA_COMMAND; i++) {
+		ch->r_io[i].res = mres;
+		ch->r_io[i].offset = i << 2;
+	}
+	ch->r_io[ATA_CONTROL].res = mres;
+	ch->r_io[ATA_CONTROL].offset = 32;
+	ata_default_registers(dev);
+
+	ch->unit = 0;
+	ata_generic_hw(dev);
+	return (ata_attach(dev));
+}
+
+int
+ata_ioc4_detach(device_t dev)
+{
+	struct ata_channel *ch = device_get_softc(dev);
+	int error;
+
+	if (!ch->attached)
+		return (0);
+	ch->attached = 0;
+
+	error = ata_detach(dev);
+
+	bus_release_resource(dev, SYS_RES_MEMORY, 0, ch->r_io[ATA_CONTROL].res);
+	return (error);
+}

Modified: projects/altix2/sys/dev/ioc4/ioc4.c
==============================================================================
--- projects/altix2/sys/dev/ioc4/ioc4.c	Tue Jun 12 01:13:59 2012	(r236939)
+++ projects/altix2/sys/dev/ioc4/ioc4.c	Tue Jun 12 03:22:18 2012	(r236940)
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/bus.h>
 #include <sys/conf.h>
 #include <sys/kernel.h>
+#include <sys/malloc.h>
 #include <sys/module.h>
 #include <machine/bus.h>
 #include <sys/rman.h>
@@ -40,6 +41,20 @@ __FBSDID("$FreeBSD$");
 #include <dev/pci/pcireg.h>
 #include <dev/pci/pcivar.h>
 
+#include <dev/ioc4/ioc4_bus.h>
+#include <dev/ioc4/ioc4_reg.h>
+
+struct ioc4_softc;
+
+struct ioc4_child {
+	struct ioc4_softc *ch_softc;
+	device_t	ch_dev;
+	struct resource *ch_ires;
+	struct resource *ch_mres;
+	u_int		ch_type;
+	u_int		ch_unit;
+};
+
 struct ioc4_softc {
 	device_t	sc_dev;
 
@@ -50,6 +65,8 @@ struct ioc4_softc {
 	struct resource	*sc_ires;
 	void		*sc_icookie;
 
+	struct rman	sc_rm;
+
 	u_int		sc_fastintr:1;
 };
 
@@ -57,7 +74,15 @@ static int ioc4_probe(device_t dev);
 static int ioc4_attach(device_t dev);
 static int ioc4_detach(device_t dev);
 
-static char ioc4_name[] = "ioc";
+static int ioc4_bus_read_ivar(device_t, device_t, int, uintptr_t *);
+static struct resource *ioc4_bus_alloc_resource(device_t, device_t, int, int *,
+    u_long, u_long, u_long, u_int);
+static int ioc4_bus_release_resource(device_t, device_t, int, int,
+    struct resource *);
+static int ioc4_bus_get_resource(device_t, device_t, int, int, u_long *,
+    u_long *);
+
+static char ioc4_name[] = "ioc4";
 static devclass_t ioc4_devclass;
 
 static device_method_t ioc4_methods[] = {
@@ -65,7 +90,15 @@ static device_method_t ioc4_methods[] = 
 	DEVMETHOD(device_probe,		ioc4_probe),
 	DEVMETHOD(device_attach,	ioc4_attach),
 	DEVMETHOD(device_detach,	ioc4_detach),
-	{ 0, 0 }
+
+	DEVMETHOD(bus_alloc_resource,	ioc4_bus_alloc_resource),
+	DEVMETHOD(bus_get_resource,	ioc4_bus_get_resource),
+	DEVMETHOD(bus_read_ivar,	ioc4_bus_read_ivar),
+	DEVMETHOD(bus_release_resource,	ioc4_bus_release_resource),
+	DEVMETHOD(bus_setup_intr,	bus_generic_setup_intr),
+	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
+
+	DEVMETHOD_END
 };
 
 static driver_t ioc4_driver = {
@@ -74,6 +107,7 @@ static driver_t ioc4_driver = {
 	sizeof(struct ioc4_softc),
 };
 
+#if 0
 static int
 ioc4_intr(void *arg)
 {
@@ -82,6 +116,80 @@ ioc4_intr(void *arg)
 	device_printf(sc->sc_dev, "%s\n", __func__);
 	return (FILTER_HANDLED);
 }
+#endif
+
+static int
+ioc4_child_add(struct ioc4_softc *sc, u_int type, u_int unit)
+{
+	struct ioc4_child *ch;
+	bus_space_handle_t bsh;
+	bus_space_tag_t bst;
+	u_long base, ofs, len;
+	int error;
+
+	ch = malloc(sizeof(*ch), M_DEVBUF, M_WAITOK | M_ZERO);
+	ch->ch_softc = sc;
+	ch->ch_type = type;
+	ch->ch_unit = unit;
+
+	error = ENXIO;
+
+	ch->ch_dev = device_add_child(sc->sc_dev, NULL, -1);
+	if (ch->ch_dev == NULL)
+		goto fail_free;
+
+	error = ENOMEM;
+
+	base = rman_get_start(sc->sc_mres);
+
+	switch (type) {
+	case IOC4_TYPE_UART:
+		ofs = IOC4_UART_REG(unit);
+		len = IOC4_UART_REG_SIZE;
+		break;
+	case IOC4_TYPE_ATA:
+		ofs = IOC4_ATA_BASE;
+		len = IOC4_ATA_SIZE;
+		break;
+	default:
+		ofs = len = 0;
+		break;
+	}
+	if (len == 0 || ofs == 0)
+		goto fail_free;
+
+	ch->ch_mres = rman_reserve_resource(&sc->sc_rm, base + ofs,
+	    base + ofs + len - 1, len, 0, NULL);
+	if (ch->ch_mres == NULL)
+		goto fail_delete;
+
+	ch->ch_ires = sc->sc_ires;
+
+	bsh = rman_get_bushandle(sc->sc_mres);
+	bst = rman_get_bustag(sc->sc_mres);
+	bus_space_subregion(bst, bsh, ofs, len, &bsh);
+	rman_set_bushandle(ch->ch_mres, bsh);
+	rman_set_bustag(ch->ch_mres, bst);
+
+	device_set_ivars(ch->ch_dev, (void *)ch);
+
+	error = device_probe_and_attach(ch->ch_dev);
+	if (error)
+		goto fail_release;
+
+	return (0);
+
+ fail_release:
+	rman_release_resource(ch->ch_mres);
+
+ fail_delete:
+	device_delete_child(sc->sc_dev, ch->ch_dev);
+
+ fail_free:
+	free(ch, M_DEVBUF);
+	device_printf(sc->sc_dev, "%s: error=%d\n", __func__, error);
+	return (error);
+}
 
 static int
 ioc4_probe(device_t dev)
@@ -99,27 +207,28 @@ ioc4_probe(device_t dev)
 static int
 ioc4_attach(device_t dev)
 {
+	char descr[RM_TEXTLEN];
 	struct ioc4_softc *sc;
 	int error;
 
 	sc = device_get_softc(dev);
 	sc->sc_dev = dev;
 
+	error = ENXIO;
+
 	sc->sc_mrid = PCIR_BAR(0);
 	sc->sc_mres = bus_alloc_resource_any(sc->sc_dev, SYS_RES_MEMORY,
 	    &sc->sc_mrid, RF_ACTIVE);
 	if (sc->sc_mres == NULL)
-		return (ENXIO);
+		goto fail_return;
 
 	sc->sc_irid = 0;
 	sc->sc_ires = bus_alloc_resource_any(sc->sc_dev, SYS_RES_IRQ,
 	    &sc->sc_irid, RF_ACTIVE|RF_SHAREABLE);
-	if (sc->sc_ires == NULL) {
-		bus_release_resource(sc->sc_dev, SYS_RES_MEMORY, sc->sc_mrid,
-		    sc->sc_mres);
-		return (ENXIO);
-	}
+	if (sc->sc_ires == NULL)
+		goto fail_rel_mres;
 
+#if 0
 	error = bus_setup_intr(dev, sc->sc_ires, INTR_TYPE_TTY, ioc4_intr,
 	    NULL, sc, &sc->sc_icookie);
 	if (error)
@@ -129,19 +238,59 @@ ioc4_attach(device_t dev)
 	else
 		sc->sc_fastintr = 1;
 
-	if (error) {
-		bus_release_resource(sc->sc_dev, SYS_RES_IRQ, sc->sc_irid,
-		   sc->sc_ires);
-		bus_release_resource(sc->sc_dev, SYS_RES_MEMORY, sc->sc_mrid,
-		   sc->sc_mres);
-		return (error);
-	}
+	if (error)
+		goto fail_rel_ires;
+#endif
+
+	sc->sc_rm.rm_type = RMAN_ARRAY;
+	error = rman_init(&sc->sc_rm);
+	if (error)
+		goto fail_teardown;
+	error = rman_manage_region(&sc->sc_rm, rman_get_start(sc->sc_mres),
+	    rman_get_end(sc->sc_mres));
+	if (error)
+		goto fail_teardown;
+
+	snprintf(descr, sizeof(descr), "%s I/O memory",
+	    device_get_nameunit(sc->sc_dev));
+	sc->sc_rm.rm_descr = strdup(descr, M_DEVBUF);
+
+	pci_enable_busmaster(sc->sc_dev);
+
+	bus_write_4(sc->sc_mres, IOC4_CTL_CR, 0xf);
+	bus_write_4(sc->sc_mres, IOC4_CTL_GPIO_SET, 0xf0);
+
+	bus_write_4(sc->sc_mres, IOC4_CTL_UART_INT_CLR, ~0U);
+	bus_write_4(sc->sc_mres, IOC4_CTL_UART_INT, ~0U);
+
+	bus_write_4(sc->sc_mres, IOC4_CTL_MISC_INT_CLR, ~0U);
+	bus_write_4(sc->sc_mres, IOC4_CTL_MISC_INT, ~0U);
 
 	/*
 	 * Create, probe and attach children
 	 */
+#if 0
+	for (n = 0; n < 4; n++)
+		ioc4_child_add(sc, IOC4_TYPE_UART, n);
+#endif
+	ioc4_child_add(sc, IOC4_TYPE_ATA, 0);
 
 	return (0);
+
+ fail_teardown:
+	bus_teardown_intr(sc->sc_dev, sc->sc_ires, sc->sc_icookie);
+
+#if 0
+ fail_rel_ires:
+#endif
+	bus_release_resource(sc->sc_dev, SYS_RES_IRQ, sc->sc_irid, sc->sc_ires);
+
+ fail_rel_mres:
+	bus_release_resource(sc->sc_dev, SYS_RES_MEMORY, sc->sc_mrid,
+	    sc->sc_mres);
+
+ fail_return:
+	return (error);
 }
 
 static int
@@ -155,6 +304,9 @@ ioc4_detach(device_t dev)
 	 * Detach children and destroy children
 	 */
 
+	free(__DECONST(void *, sc->sc_rm.rm_descr), M_DEVBUF);
+	rman_fini(&sc->sc_rm);
+
 	bus_teardown_intr(sc->sc_dev, sc->sc_ires, sc->sc_icookie);
 	bus_release_resource(sc->sc_dev, SYS_RES_IRQ, sc->sc_irid,
 	    sc->sc_ires);
@@ -163,4 +315,155 @@ ioc4_detach(device_t dev)
 	return (0);
 }
 
+static struct ioc4_child *
+_ioc4_get_child(device_t dev, device_t child)
+{
+	struct ioc4_child *ch;
+
+	/* Get our immediate child. */
+	while (child != NULL && device_get_parent(child) != dev)
+		child = device_get_parent(child);
+	if (child == NULL)
+		return (NULL);
+
+	ch = device_get_ivars(child);
+	KASSERT(ch != NULL, ("%s %d", __func__, __LINE__));
+	return (ch);
+}
+
+static int
+ioc4_bus_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
+{
+	struct ioc4_child *ch;
+	struct ioc4_softc *sc;
+	uint32_t pci;
+
+	if (result == NULL)
+		return (EINVAL);
+
+	ch = _ioc4_get_child(dev, child);
+	if (ch == NULL)
+		return (EINVAL);
+
+	sc = ch->ch_softc;
+
+	switch(index) {
+	case IOC4_IVAR_CLOCK:
+		pci = bus_read_4(sc->sc_mres, IOC4_CTL_PCI);
+		*result = (pci & 1) ? 66666667 : 33333333;
+		break;
+	case IOC4_IVAR_TYPE:
+		*result = ch->ch_type;
+		break;
+	default:
+		return (ENOENT);
+	}
+	return (0);
+}
+
+static struct resource *
+ioc4_bus_alloc_resource(device_t dev, device_t child, int type, int *rid,
+    u_long start, u_long end, u_long count, u_int flags)
+{
+	struct ioc4_child *ch;
+	struct resource *res;
+	device_t assigned;
+	int error;
+
+	if (rid == NULL || *rid != 0)
+		return (NULL);
+
+	/* We only support default allocations. */
+	if (start != 0UL || end != ~0UL)
+		return (NULL);
+
+	ch = _ioc4_get_child(dev, child);
+	if (ch == NULL)
+		return (NULL);
+
+	if (type == SYS_RES_IRQ)
+		return (ch->ch_ires);
+	if (type != SYS_RES_MEMORY)
+		return (NULL);
+
+	res = ch->ch_mres;
+
+	assigned = rman_get_device(res);
+	if (assigned == NULL)   /* Not allocated */
+		rman_set_device(res, child);
+	else if (assigned != child)
+		return (NULL);
+
+	if (flags & RF_ACTIVE) {
+		error = rman_activate_resource(res);
+		if (error) {
+			if (assigned == NULL)
+				rman_set_device(res, NULL);
+			res = NULL;
+		}
+	}
+
+	return (res);
+}
+
+static int
+ioc4_bus_release_resource(device_t dev, device_t child, int type, int rid,
+    struct resource *res)
+{
+	struct ioc4_child *ch;
+
+	if (rid != 0 || res == NULL)
+		return (EINVAL);
+
+	ch = _ioc4_get_child(dev, child);
+	if (ch == NULL)
+		return (EINVAL);
+
+	if (type == SYS_RES_MEMORY) {
+		if (res != ch->ch_mres)
+			return (EINVAL);
+	} else if (type == SYS_RES_IRQ) {
+		if (res != ch->ch_ires)
+			return (EINVAL);
+	} else
+		return (EINVAL);
+
+	if (rman_get_device(res) != child)
+		return (ENXIO);
+	if (rman_get_flags(res) & RF_ACTIVE)
+		rman_deactivate_resource(res);
+	rman_set_device(res, NULL);
+	return (0);
+}
+
+static int
+ioc4_bus_get_resource(device_t dev, device_t child, int type, int rid,
+    u_long *startp, u_long *countp)
+{
+	struct ioc4_child *ch;
+	struct resource *res;
+	u_long start;
+
+	ch = _ioc4_get_child(dev, child);
+	if (ch == NULL)
+		return (EINVAL);
+
+	if (type == SYS_RES_MEMORY)
+		res = ch->ch_mres;
+	else if (type == SYS_RES_IRQ)
+		res = ch->ch_ires;
+	else
+		return (ENXIO);
+
+	if (rid != 0 || res == NULL)
+		return (ENXIO);
+
+	start = rman_get_start(res);
+	if (startp != NULL)
+		*startp = start;
+	if (countp != NULL)
+		*countp = rman_get_end(res) - start + 1;
+	return (0);
+}
+
 DRIVER_MODULE(ioc4, pci, ioc4_driver, ioc4_devclass, 0, 0);

Modified: projects/altix2/sys/dev/ioc4/ioc4_bus.h
==============================================================================
--- projects/altix2/sys/dev/ioc4/ioc4_bus.h	Tue Jun 12 01:13:59 2012	(r236939)
+++ projects/altix2/sys/dev/ioc4/ioc4_bus.h	Tue Jun 12 03:22:18 2012	(r236940)
@@ -30,8 +30,10 @@
 #define	_DEV_IOC4_BUS_H_
 
 #define	IOC4_IVAR_TYPE		1
+#define	IOC4_IVAR_CLOCK		2
 
 #define	IOC4_TYPE_NONE		0
 #define	IOC4_TYPE_UART		1
+#define	IOC4_TYPE_ATA		2
 
 #endif /* _DEV_IOC4_BUS_H_ */

Added: projects/altix2/sys/dev/ioc4/ioc4_reg.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/altix2/sys/dev/ioc4/ioc4_reg.h	Tue Jun 12 03:22:18 2012	(r236940)
@@ -0,0 +1,71 @@
+/*-
+ * Copyright (c) 2012 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _DEV_IOC4_REG_H_
+#define	_DEV_IOC4_REG_H_
+
+#define	IOC4_CTL_ERR_LO		0x0000
+#define	IOC4_CTL_ERR_HI		0x0004
+#define	IOC4_CTL_UART_INT	0x0008
+#define	IOC4_CTL_MISC_INT	0x000c
+#define	IOC4_CTL_UART_INT_SET	0x0010
+#define	IOC4_CTL_MISC_INT_SET	0x0014
+#define	IOC4_CTL_UART_INT_CLR	0x0018
+#define	IOC4_CTL_MISC_INT_CLR	0x001c
+#define	IOC4_CTL_CR		0x0020
+#define	IOC4_CTL_PCI		0x0024
+#define	IOC4_CTL_EXTINT		0x0028
+
+#define	IOC4_CTL_GPIO_SET	0x0030
+#define	IOC4_CTL_GPIO_CLR	0x0034
+#define	IOC4_CTL_GPIO_DATA	0x0038
+
+#define	IOC4_GPIO_0		0x0040
+#define	IOC4_GPIO_1		0x0044
+#define	IOC4_GPIO_2		0x0048
+#define	IOC4_GPIO_3		0x004C
+#define	IOC4_GPIO_4		0x0050
+#define	IOC4_GPIO_5		0x0054
+#define	IOC4_GPIO_6		0x0058
+#define	IOC4_GPIO_7		0x005C
+
+#define	IOC4_ATA_BASE		0x0100
+#define	IOC4_ATA_SIZE		0x0100
+
+#define	IOC4_KBD_BASE		0x0200
+#define	IOC4_KBD_SIZE		0x0020
+
+#define	IOC4_UART_BASE		0x0300
+#define	IOC4_UART_SIZE		0x0100
+
+#define	IOC4_UART_DMA_SIZE	(7 * 4)
+#define	IOC4_UART_DMA(x)	(0x0310 + (x) * IOC4_UART_DMA_SIZE)
+#define	IOC4_UART_REG_SIZE	8
+#define	IOC4_UART_REG(x)	(0x0380 + (x) * IOC4_UART_REG_SIZE)
+
+#endif /* _DEV_IOC4_REG_H_ */

Added: projects/altix2/sys/dev/uart/uart_bus_ioc4.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/altix2/sys/dev/uart/uart_bus_ioc4.c	Tue Jun 12 03:22:18 2012	(r236940)
@@ -0,0 +1,90 @@
+/*-
+ * Copyright (c) 2012 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+
+#include <sys/serial.h>
+#include <serdev_if.h>
+
+#include <dev/ioc4/ioc4_bus.h>
+
+#include <dev/uart/uart.h>
+#include <dev/uart/uart_bus.h>
+
+static int uart_ioc4_probe(device_t dev);
+
+static device_method_t uart_ioc4_methods[] = {
+	/* Device interface */
+	DEVMETHOD(device_probe,		uart_ioc4_probe),
+	DEVMETHOD(device_attach,	uart_bus_attach),
+	DEVMETHOD(device_detach,	uart_bus_detach),
+	/* Serdev interface */
+	DEVMETHOD(serdev_ihand,		uart_bus_ihand),
+	DEVMETHOD(serdev_ipend,		uart_bus_ipend),
+	{ 0, 0 }
+};
+
+static driver_t uart_ioc4_driver = {
+	uart_driver_name,
+	uart_ioc4_methods,
+	sizeof(struct uart_softc),
+};
+
+static int
+uart_ioc4_probe(device_t dev)
+{
+	device_t parent;
+	struct uart_softc *sc;
+	uintptr_t rclk, type;
+
+	parent = device_get_parent(dev);
+
+	if (BUS_READ_IVAR(parent, dev, IOC4_IVAR_TYPE, &type))
+		return (ENXIO);
+	if (type != IOC4_TYPE_UART)
+		return (ENXIO);
+
+	sc = device_get_softc(dev);
+	sc->sc_class = &uart_ns8250_class;
+
+	if (BUS_READ_IVAR(parent, dev, IOC4_IVAR_CLOCK, &rclk))
+		rclk = 0;
+	return (uart_bus_probe(dev, 0, rclk, 0, 0));
+}
+
+DRIVER_MODULE(uart, ioc4, uart_ioc4_driver, uart_devclass, 0, 0);


More information about the svn-src-projects mailing list