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