160727d8bSWarner Losh /*-
2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
371e3c308SPedro F. Giffuni *
4d674899bSBenno Rice * Copyright (C) 2002 Benno Rice.
5d674899bSBenno Rice * All rights reserved.
6d674899bSBenno Rice *
7d674899bSBenno Rice * Redistribution and use in source and binary forms, with or without
8d674899bSBenno Rice * modification, are permitted provided that the following conditions
9d674899bSBenno Rice * are met:
10d674899bSBenno Rice * 1. Redistributions of source code must retain the above copyright
11d674899bSBenno Rice * notice, this list of conditions and the following disclaimer.
12d674899bSBenno Rice * 2. Redistributions in binary form must reproduce the above copyright
13d674899bSBenno Rice * notice, this list of conditions and the following disclaimer in the
14d674899bSBenno Rice * documentation and/or other materials provided with the distribution.
15d674899bSBenno Rice *
16d674899bSBenno Rice * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
17d674899bSBenno Rice * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18d674899bSBenno Rice * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19d674899bSBenno Rice * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20d674899bSBenno Rice * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21d674899bSBenno Rice * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22d674899bSBenno Rice * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23d674899bSBenno Rice * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24d674899bSBenno Rice * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25d674899bSBenno Rice * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26d674899bSBenno Rice */
27d674899bSBenno Rice
28658930c2SBenno Rice #include "opt_ddb.h"
29658930c2SBenno Rice
30d674899bSBenno Rice #include <sys/param.h>
31d674899bSBenno Rice #include <sys/systm.h>
3282ab2f48SAndrew Gallatin #include <sys/kdb.h>
33d674899bSBenno Rice #include <sys/kernel.h>
3482ab2f48SAndrew Gallatin #include <sys/module.h>
35d674899bSBenno Rice #include <sys/malloc.h>
36d674899bSBenno Rice #include <sys/bus.h>
37d674899bSBenno Rice #include <machine/bus.h>
38d674899bSBenno Rice #include <sys/rman.h>
39d674899bSBenno Rice
40d674899bSBenno Rice #include <machine/resource.h>
41d674899bSBenno Rice
420c9f52d4SBrandon Bergren #include <dev/ofw/ofw_bus.h>
43d674899bSBenno Rice #include <dev/ofw/openfirm.h>
44d674899bSBenno Rice
45d674899bSBenno Rice #include <powerpc/powermac/maciovar.h>
46d674899bSBenno Rice
47d674899bSBenno Rice struct pswitch_softc {
480c9f52d4SBrandon Bergren int sc_irq_rid;
49d674899bSBenno Rice struct resource *sc_irq;
50d674899bSBenno Rice void *sc_ih;
51d674899bSBenno Rice };
52d674899bSBenno Rice
53d674899bSBenno Rice static int pswitch_probe(device_t);
54d674899bSBenno Rice static int pswitch_attach(device_t);
55d674899bSBenno Rice
56fab48452SPaolo Pisati static int pswitch_intr(void *);
57d674899bSBenno Rice
58d674899bSBenno Rice static device_method_t pswitch_methods[] = {
59d674899bSBenno Rice /* Device interface */
60d674899bSBenno Rice DEVMETHOD(device_probe, pswitch_probe),
61d674899bSBenno Rice DEVMETHOD(device_attach, pswitch_attach),
62d674899bSBenno Rice { 0, 0 }
63d674899bSBenno Rice };
64d674899bSBenno Rice
65d674899bSBenno Rice static driver_t pswitch_driver = {
66d674899bSBenno Rice "pswitch",
67d674899bSBenno Rice pswitch_methods,
68d674899bSBenno Rice sizeof(struct pswitch_softc)
69d674899bSBenno Rice };
70d674899bSBenno Rice
71992ae60bSJohn Baldwin EARLY_DRIVER_MODULE(pswitch, macgpio, pswitch_driver, 0, 0, BUS_PASS_RESOURCE);
72d674899bSBenno Rice
73d674899bSBenno Rice static int
pswitch_probe(device_t dev)74d674899bSBenno Rice pswitch_probe(device_t dev)
75d674899bSBenno Rice {
760c9f52d4SBrandon Bergren const char *type = ofw_bus_get_type(dev);
77d674899bSBenno Rice
780c9f52d4SBrandon Bergren if (strcmp(type, "programmer-switch") != 0)
79d674899bSBenno Rice return (ENXIO);
80d674899bSBenno Rice
81d674899bSBenno Rice device_set_desc(dev, "GPIO Programmer's Switch");
82d674899bSBenno Rice return (0);
83d674899bSBenno Rice }
84d674899bSBenno Rice
85d674899bSBenno Rice static int
pswitch_attach(device_t dev)86d674899bSBenno Rice pswitch_attach(device_t dev)
87d674899bSBenno Rice {
88d674899bSBenno Rice struct pswitch_softc *sc;
89d674899bSBenno Rice
90d674899bSBenno Rice sc = device_get_softc(dev);
91d674899bSBenno Rice
920c9f52d4SBrandon Bergren sc->sc_irq_rid = 0;
930c9f52d4SBrandon Bergren sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
940c9f52d4SBrandon Bergren &sc->sc_irq_rid, RF_ACTIVE);
95d674899bSBenno Rice if (sc->sc_irq == NULL) {
96d674899bSBenno Rice device_printf(dev, "could not allocate interrupt\n");
97d674899bSBenno Rice return (ENXIO);
98d674899bSBenno Rice }
99d674899bSBenno Rice
1000c9f52d4SBrandon Bergren if (bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC | INTR_EXCL,
10183496acdSPaolo Pisati pswitch_intr, NULL, dev, &sc->sc_ih) != 0) {
102d674899bSBenno Rice device_printf(dev, "could not setup interrupt\n");
1030c9f52d4SBrandon Bergren bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irq_rid,
104d674899bSBenno Rice sc->sc_irq);
105d674899bSBenno Rice return (ENXIO);
106d674899bSBenno Rice }
107d674899bSBenno Rice
108d674899bSBenno Rice return (0);
109d674899bSBenno Rice }
110d674899bSBenno Rice
111fab48452SPaolo Pisati static int
pswitch_intr(void * arg)112d674899bSBenno Rice pswitch_intr(void *arg)
113d674899bSBenno Rice {
114d674899bSBenno Rice device_t dev;
115d674899bSBenno Rice
116d674899bSBenno Rice dev = (device_t)arg;
117d674899bSBenno Rice
1183de213ccSRobert Watson kdb_enter(KDB_WHY_POWERPC, device_get_nameunit(dev));
119fab48452SPaolo Pisati return (FILTER_HANDLED);
120d674899bSBenno Rice }
121