summaryrefslogtreecommitdiffstats
path: root/sys/dev/atkbdc
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/atkbdc')
-rw-r--r--sys/dev/atkbdc/atkbd_atkbdc.c6
-rw-r--r--sys/dev/atkbdc/atkbdc_isa.c62
-rw-r--r--sys/dev/atkbdc/atkbdcreg.h1
3 files changed, 55 insertions, 14 deletions
diff --git a/sys/dev/atkbdc/atkbd_atkbdc.c b/sys/dev/atkbdc/atkbd_atkbdc.c
index 9531fa2..8181820 100644
--- a/sys/dev/atkbdc/atkbd_atkbdc.c
+++ b/sys/dev/atkbdc/atkbd_atkbdc.c
@@ -94,8 +94,7 @@ atkbdprobe(device_t dev)
/* see if IRQ is available */
rid = KBDC_RID_KBD;
- res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
- RF_SHAREABLE | RF_ACTIVE);
+ res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
if (res == NULL) {
if (bootverbose)
device_printf(dev, "unable to allocate IRQ\n");
@@ -132,8 +131,7 @@ atkbdattach(device_t dev)
return error;
/* declare our interrupt handler */
- sc->intr = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
- RF_SHAREABLE | RF_ACTIVE);
+ sc->intr = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
if (sc->intr == NULL)
return ENXIO;
error = bus_setup_intr(dev, sc->intr, INTR_TYPE_TTY, NULL, atkbdintr,
diff --git a/sys/dev/atkbdc/atkbdc_isa.c b/sys/dev/atkbdc/atkbdc_isa.c
index 42bb67b..d553216 100644
--- a/sys/dev/atkbdc/atkbdc_isa.c
+++ b/sys/dev/atkbdc/atkbdc_isa.c
@@ -49,6 +49,11 @@ static int atkbdc_isa_probe(device_t dev);
static int atkbdc_isa_attach(device_t dev);
static device_t atkbdc_isa_add_child(device_t bus, u_int order, const char *name,
int unit);
+static struct resource *atkbdc_isa_alloc_resource(device_t dev, device_t child,
+ int type, int *rid, u_long start, u_long end,
+ u_long count, u_int flags);
+static int atkbdc_isa_release_resource(device_t dev, device_t child,
+ int type, int rid, struct resource *r);
static device_method_t atkbdc_isa_methods[] = {
DEVMETHOD(device_probe, atkbdc_isa_probe),
@@ -61,8 +66,8 @@ static device_method_t atkbdc_isa_methods[] = {
DEVMETHOD(bus_read_ivar, atkbdc_read_ivar),
DEVMETHOD(bus_write_ivar, atkbdc_write_ivar),
DEVMETHOD(bus_get_resource_list,atkbdc_get_resource_list),
- DEVMETHOD(bus_alloc_resource, bus_generic_rl_alloc_resource),
- DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource),
+ DEVMETHOD(bus_alloc_resource, atkbdc_isa_alloc_resource),
+ DEVMETHOD(bus_release_resource, atkbdc_isa_release_resource),
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
@@ -170,8 +175,6 @@ atkbdc_isa_probe(device_t dev)
device_verbose(dev);
error = atkbdc_probe_unit(device_get_unit(dev), port0, port1);
- if (error == 0)
- bus_generic_probe(dev);
bus_release_resource(dev, SYS_RES_IOPORT, 0, port0);
bus_release_resource(dev, SYS_RES_IOPORT, 1, port1);
@@ -216,14 +219,25 @@ atkbdc_isa_attach(device_t dev)
return ENXIO;
}
+ /*
+ * If the device is not created by the PnP BIOS or ACPI, then
+ * the hint for the IRQ is on the child atkbd device, not the
+ * keyboard controller, so this can fail.
+ */
+ rid = 0;
+ sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
+
error = atkbdc_attach_unit(unit, sc, sc->port0, sc->port1);
if (error) {
bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->port0);
bus_release_resource(dev, SYS_RES_IOPORT, 1, sc->port1);
+ if (sc->irq != NULL)
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
return error;
}
*(atkbdc_softc_t **)device_get_softc(dev) = sc;
+ bus_generic_probe(dev);
bus_generic_attach(dev);
return 0;
@@ -233,9 +247,11 @@ static device_t
atkbdc_isa_add_child(device_t bus, u_int order, const char *name, int unit)
{
atkbdc_device_t *ivar;
+ atkbdc_softc_t *sc;
device_t child;
int t;
+ sc = *(atkbdc_softc_t **)device_get_softc(bus);
ivar = malloc(sizeof(struct atkbdc_device), M_ATKBDDEV,
M_NOWAIT | M_ZERO);
if (!ivar)
@@ -251,15 +267,16 @@ atkbdc_isa_add_child(device_t bus, u_int order, const char *name, int unit)
ivar->rid = order;
/*
- * If the device is not created by the PnP BIOS or ACPI,
- * refer to device hints for IRQ.
+ * If the device is not created by the PnP BIOS or ACPI, refer
+ * to device hints for IRQ. We always populate the resource
+ * list entry so we can use a standard bus_get_resource()
+ * method.
*/
- if (ISA_PNP_PROBE(device_get_parent(bus), bus, atkbdc_ids) != 0) {
+ if (sc->irq == NULL) {
if (resource_int_value(name, unit, "irq", &t) != 0)
t = -1;
- } else {
- t = bus_get_resource_start(bus, SYS_RES_IRQ, ivar->rid);
- }
+ } else
+ t = rman_get_start(sc->irq);
if (t > 0)
resource_list_add(&ivar->resources, SYS_RES_IRQ, ivar->rid,
t, t, 1);
@@ -272,5 +289,30 @@ atkbdc_isa_add_child(device_t bus, u_int order, const char *name, int unit)
return child;
}
+struct resource *
+atkbdc_isa_alloc_resource(device_t dev, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
+{
+ atkbdc_softc_t *sc;
+
+ sc = *(atkbdc_softc_t **)device_get_softc(dev);
+ if (type == SYS_RES_IRQ && *rid == KBDC_RID_KBD && sc->irq != NULL)
+ return (sc->irq);
+ return (bus_generic_rl_alloc_resource(dev, child, type, rid, start,
+ end, count, flags));
+}
+
+static int
+atkbdc_isa_release_resource(device_t dev, device_t child, int type, int rid,
+ struct resource *r)
+{
+ atkbdc_softc_t *sc;
+
+ sc = *(atkbdc_softc_t **)device_get_softc(dev);
+ if (type == SYS_RES_IRQ && rid == KBDC_RID_KBD && r == sc->irq)
+ return (0);
+ return (bus_generic_rl_release_resource(dev, child, type, rid, r));
+}
+
DRIVER_MODULE(atkbdc, isa, atkbdc_isa_driver, atkbdc_devclass, 0, 0);
DRIVER_MODULE(atkbdc, acpi, atkbdc_isa_driver, atkbdc_devclass, 0, 0);
diff --git a/sys/dev/atkbdc/atkbdcreg.h b/sys/dev/atkbdc/atkbdcreg.h
index 7ea26a6..44a9801 100644
--- a/sys/dev/atkbdc/atkbdcreg.h
+++ b/sys/dev/atkbdc/atkbdcreg.h
@@ -192,6 +192,7 @@ struct resource;
typedef struct atkbdc_softc {
struct resource *port0; /* data port */
struct resource *port1; /* status port */
+ struct resource *irq;
bus_space_tag_t iot;
bus_space_handle_t ioh0;
bus_space_handle_t ioh1;
OpenPOWER on IntegriCloud