summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/conf/files.powerpc1
-rw-r--r--sys/powerpc/powermac/macio.c1
-rw-r--r--sys/powerpc/powermac/pswitch.c143
3 files changed, 144 insertions, 1 deletions
diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc
index 96f2e1c..59294d3 100644
--- a/sys/conf/files.powerpc
+++ b/sys/conf/files.powerpc
@@ -73,6 +73,7 @@ powerpc/ofw/ofw_pcib_pci.c optional pci
powerpc/powermac/uninorth.c optional powermac pci
powerpc/powermac/macio.c optional powermac pci
powerpc/powermac/ata_macio.c optional powermac ata
+powerpc/powermac/pswitch.c optional pswitch powermac
powerpc/psim/iobus.c optional psim
powerpc/psim/ata_iobus.c optional ata psim
diff --git a/sys/powerpc/powermac/macio.c b/sys/powerpc/powermac/macio.c
index 1ad6b9c..0497ff4 100644
--- a/sys/powerpc/powermac/macio.c
+++ b/sys/powerpc/powermac/macio.c
@@ -137,7 +137,6 @@ struct macio_quirk_entry {
static struct macio_quirk_entry macio_quirks[] = {
{ "interrupt-controller", MACIO_QUIRK_IGNORE },
{ "escc-legacy", MACIO_QUIRK_IGNORE },
- { "gpio", MACIO_QUIRK_IGNORE },
{ "timer", MACIO_QUIRK_IGNORE },
{ "escc", MACIO_QUIRK_CHILD_HAS_INTR },
{ NULL, 0 }
diff --git a/sys/powerpc/powermac/pswitch.c b/sys/powerpc/powermac/pswitch.c
new file mode 100644
index 0000000..faf2f04
--- /dev/null
+++ b/sys/powerpc/powermac/pswitch.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2002 Benno Rice.
+ * 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 Benno Rice ``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 TOOLS GMBH 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$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+
+#include <machine/resource.h>
+
+#include <dev/ofw/openfirm.h>
+
+#include <powerpc/powermac/maciovar.h>
+
+struct pswitch_softc {
+ int sc_irqrid;
+ struct resource *sc_irq;
+ void *sc_ih;
+};
+
+static int pswitch_probe(device_t);
+static int pswitch_attach(device_t);
+
+static void pswitch_intr(void *);
+
+static device_method_t pswitch_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, pswitch_probe),
+ DEVMETHOD(device_attach, pswitch_attach),
+
+ { 0, 0 }
+};
+
+static driver_t pswitch_driver = {
+ "pswitch",
+ pswitch_methods,
+ sizeof(struct pswitch_softc)
+};
+
+static devclass_t pswitch_devclass;
+
+DRIVER_MODULE(pswitch, macio, pswitch_driver, pswitch_devclass, 0, 0);
+
+static int
+pswitch_probe(device_t dev)
+{
+ char *type = macio_get_devtype(dev);
+
+ if (strcmp(type, "gpio") != 0)
+ return (ENXIO);
+
+ device_set_desc(dev, "GPIO Programmer's Switch");
+ return (0);
+}
+
+static int
+pswitch_attach(device_t dev)
+{
+ struct pswitch_softc *sc;
+ phandle_t node, child;
+ char type[32];
+ u_int irq[2];
+
+ sc = device_get_softc(dev);
+ node = macio_get_node(dev);
+
+ for (child = OF_child(node); child != 0; child = OF_peer(child)) {
+ if (OF_getprop(child, "device_type", type, 32) == -1)
+ continue;
+
+ if (strcmp(type, "programmer-switch") == 0)
+ break;
+ }
+
+ if (child == 0) {
+ device_printf(dev, "could not find correct node\n");
+ return (ENXIO);
+ }
+
+ if (OF_getprop(child, "interrupts", irq, sizeof(irq)) == -1) {
+ device_printf(dev, "could not get interrupt\n");
+ return (ENXIO);
+ }
+
+ sc->sc_irqrid = 0;
+ sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->sc_irqrid,
+ irq[0], irq[0], 1, RF_ACTIVE);
+ if (sc->sc_irq == NULL) {
+ device_printf(dev, "could not allocate interrupt\n");
+ return (ENXIO);
+ }
+
+ if (bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC | INTR_FAST,
+ pswitch_intr, dev, &sc->sc_ih) != 0) {
+ device_printf(dev, "could not setup interrupt\n");
+ bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irqrid,
+ sc->sc_irq);
+ return (ENXIO);
+ }
+
+ return (0);
+}
+
+static void
+pswitch_intr(void *arg)
+{
+ device_t dev;
+
+ dev = (device_t)arg;
+
+#ifdef DDB
+ Debugger(device_get_nameunit(dev));
+#else
+ device_printf(dev, "close, but no debugger\n");
+#endif
+}
OpenPOWER on IntegriCloud