Page MenuHomeFreeBSD

D999.id2094.diff
No OneTemporary

D999.id2094.diff

Index: sys/dev/gpio/gpiobus.c
===================================================================
--- sys/dev/gpio/gpiobus.c
+++ sys/dev/gpio/gpiobus.c
@@ -38,6 +38,13 @@
#include "gpiobus_if.h"
+#define GPIOBUS_DEBUG
+#ifdef GPIOBUS_DEBUG
+#define dprintf printf
+#else
+#define dprintf(x, arg...)
+#endif
+
static int gpiobus_parse_pins(struct gpiobus_softc *, device_t, int);
static int gpiobus_probe(device_t);
static int gpiobus_attach(device_t);
@@ -99,6 +106,39 @@
printf("%d", range_start);
}
+int
+gpiobus_init_softc(device_t dev)
+{
+ struct gpiobus_softc *sc;
+
+ sc = GPIOBUS_SOFTC(dev);
+ sc->sc_busdev = dev;
+ sc->sc_dev = device_get_parent(dev);
+ sc->sc_intr_rman.rm_type = RMAN_ARRAY;
+ sc->sc_intr_rman.rm_descr = "GPIO Interrupts";
+ if (rman_init(&sc->sc_intr_rman) != 0 ||
+ rman_manage_region(&sc->sc_intr_rman, 0, ~0) != 0)
+ panic("%s: failed to set up rman.", __func__);
+
+ if (GPIO_PIN_MAX(sc->sc_dev, &sc->sc_npins) != 0)
+ return (ENXIO);
+
+ KASSERT(sc->sc_npins != 0, ("GPIO device with no pins"));
+
+ /* Pins = GPIO_PIN_MAX() + 1 */
+ sc->sc_npins++;
+
+ sc->sc_pins_mapped = malloc(sizeof(int) * sc->sc_npins, M_DEVBUF,
+ M_NOWAIT | M_ZERO);
+ if (sc->sc_pins_mapped == NULL)
+ return (ENOMEM);
+
+ /* Initialize the bus lock. */
+ GPIOBUS_LOCK_INIT(sc);
+
+ return (0);
+}
+
static int
gpiobus_parse_pins(struct gpiobus_softc *sc, device_t child, int mask)
{
@@ -163,30 +203,11 @@
static int
gpiobus_attach(device_t dev)
{
- struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev);
- int res;
-
- sc->sc_busdev = dev;
- sc->sc_dev = device_get_parent(dev);
- res = GPIO_PIN_MAX(sc->sc_dev, &sc->sc_npins);
- if (res)
- return (ENXIO);
-
- KASSERT(sc->sc_npins != 0, ("GPIO device with no pins"));
-
- /*
- * Increase to get number of pins
- */
- sc->sc_npins++;
-
- sc->sc_pins_mapped = malloc(sizeof(int) * sc->sc_npins, M_DEVBUF,
- M_NOWAIT | M_ZERO);
-
- if (!sc->sc_pins_mapped)
- return (ENOMEM);
+ int err;
- /* init bus lock */
- GPIOBUS_LOCK_INIT(sc);
+ err = gpiobus_init_softc(dev);
+ if (err != 0)
+ return (err);
/*
* Get parent's pins and mark them as unmapped
@@ -260,6 +281,7 @@
retval += bus_print_child_header(dev, child);
retval += printf(" at pin(s) ");
gpiobus_print_pins(devi);
+ resource_list_print_type(&devi->rl, "irq", SYS_RES_IRQ, "%ld");
retval += bus_print_child_footer(dev, child);
return (retval);
@@ -297,7 +319,9 @@
device_delete_child(dev, child);
return (0);
}
+ resource_list_init(&devi->rl);
device_set_ivars(child, devi);
+
return (child);
}
@@ -307,14 +331,111 @@
struct gpiobus_softc *sc = GPIOBUS_SOFTC(bus);
struct gpiobus_ivar *devi;
device_t child;
- int pins;
-
+ int irq, pins;
child = BUS_ADD_CHILD(bus, 0, dname, dunit);
devi = GPIOBUS_IVAR(child);
resource_int_value(dname, dunit, "pins", &pins);
if (gpiobus_parse_pins(sc, child, pins))
device_delete_child(bus, child);
+ if (resource_int_value(dname, dunit, "irq", &irq) == 0) {
+ if (bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1) != 0)
+ device_printf(bus,
+ "warning: bus_set_resource() failed\n");
+ }
+}
+
+static int
+gpiobus_set_resource(device_t dev, device_t child, int type, int rid,
+ u_long start, u_long count)
+{
+ struct gpiobus_ivar *devi;
+ struct resource_list *rl;
+ struct resource_list_entry *rle;
+
+ devi = GPIOBUS_IVAR(child);
+ rl = &devi->rl;
+
+ dprintf("%s: entry (%p, %p, %d, %d, %p, %ld)\n",
+ __func__, dev, child, type, rid, (void *)(intptr_t)start, count);
+
+ rle = resource_list_add(rl, type, rid, start, start + count - 1,
+ count);
+ if (rle == NULL)
+ return (ENXIO);
+
+ return (0);
+}
+
+static struct resource *
+gpiobus_alloc_resource(device_t bus, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
+{
+ struct gpiobus_softc *sc;
+ struct resource *rv;
+ struct resource_list *rl;
+ struct resource_list_entry *rle;
+ int isdefault;
+
+ if (type != SYS_RES_IRQ)
+ return (NULL);
+
+ isdefault = (start == 0UL && end == ~0UL && count == 1);
+ rle = NULL;
+
+ if (isdefault) {
+ rl = BUS_GET_RESOURCE_LIST(bus, child);
+ if (rl == NULL)
+ return (NULL);
+ rle = resource_list_find(rl, type, *rid);
+ if (rle == NULL)
+ return (NULL);
+ if (rle->res != NULL)
+ panic("%s: resource entry is busy", __func__);
+ start = rle->start;
+ count = rle->count;
+ end = rle->end;
+ }
+
+ sc = device_get_softc(bus);
+ rv = rman_reserve_resource(&sc->sc_intr_rman, start, end, count, flags,
+ child);
+ if (rv == NULL)
+ return (NULL);
+ rman_set_rid(rv, *rid);
+
+ if ((flags & RF_ACTIVE) != 0 &&
+ bus_activate_resource(child, type, *rid, rv) != 0) {
+ rman_release_resource(rv);
+ return (NULL);
+ }
+
+ return (rv);
+}
+
+static int
+gpiobus_release_resource(device_t bus __unused, device_t child, int type,
+ int rid, struct resource *r)
+{
+ int error;
+
+ if ((rman_get_flags(r) & RF_ACTIVE) != 0) {
+ error = bus_deactivate_resource(child, type, rid, r);
+ if (error)
+ return (error);
+ }
+
+ return (rman_release_resource(r));
+}
+
+static struct resource_list *
+gpiobus_get_resource_list(device_t bus __unused, device_t child)
+{
+ struct gpiobus_ivar *ivar;
+
+ ivar = GPIOBUS_IVAR(child);
+
+ return (&ivar->rl);
}
static void
@@ -453,6 +574,15 @@
DEVMETHOD(device_resume, gpiobus_resume),
/* Bus interface */
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_config_intr, bus_generic_config_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+ DEVMETHOD(bus_set_resource, gpiobus_set_resource),
+ DEVMETHOD(bus_alloc_resource, gpiobus_alloc_resource),
+ DEVMETHOD(bus_release_resource, gpiobus_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_get_resource_list, gpiobus_get_resource_list),
DEVMETHOD(bus_add_child, gpiobus_add_child),
DEVMETHOD(bus_print_child, gpiobus_print_child),
DEVMETHOD(bus_child_pnpinfo_str, gpiobus_child_pnpinfo_str),
Index: sys/dev/gpio/gpiobusvar.h
===================================================================
--- sys/dev/gpio/gpiobusvar.h
+++ sys/dev/gpio/gpiobusvar.h
@@ -34,6 +34,7 @@
#include <sys/lock.h>
#include <sys/mutex.h>
+#include <sys/rman.h>
#ifdef FDT
#include <dev/ofw/ofw_bus_subr.h>
@@ -41,7 +42,12 @@
#include "gpio_if.h"
+#ifdef FDT
+#define GPIOBUS_IVAR(d) (struct gpiobus_ivar *) \
+ &((struct ofw_gpiobus_devinfo *)device_get_ivars(d))->opd_dinfo
+#else
#define GPIOBUS_IVAR(d) (struct gpiobus_ivar *) device_get_ivars(d)
+#endif
#define GPIOBUS_SOFTC(d) (struct gpiobus_softc *) device_get_softc(d)
#define GPIOBUS_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
#define GPIOBUS_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
@@ -54,6 +60,7 @@
struct gpiobus_softc
{
struct mtx sc_mtx; /* bus mutex */
+ struct rman sc_intr_rman; /* isr resources */
device_t sc_busdev; /* bus device */
device_t sc_owner; /* bus owner */
device_t sc_dev; /* driver device */
@@ -63,6 +70,7 @@
struct gpiobus_ivar
{
+ struct resource_list rl; /* isr resource list */
uint32_t npins; /* pins total */
uint32_t *flags; /* pins flags */
uint32_t *pins; /* pins map */
@@ -84,6 +92,7 @@
device_t ofw_gpiobus_add_fdt_child(device_t, phandle_t);
#endif
void gpiobus_print_pins(struct gpiobus_ivar *);
+int gpiobus_init_softc(device_t);
extern driver_t gpiobus_driver;
Index: sys/dev/gpio/ofw_gpiobus.c
===================================================================
--- sys/dev/gpio/ofw_gpiobus.c
+++ sys/dev/gpio/ofw_gpiobus.c
@@ -239,6 +239,14 @@
return (NULL);
}
+ /* And now the interrupt resources. */
+ resource_list_init(&dinfo->opd_dinfo.rl);
+ if (ofw_bus_intr_to_rl(dev, node, &dinfo->opd_dinfo.rl) != 0) {
+ ofw_bus_gen_destroy_devinfo(&dinfo->opd_obdinfo);
+ free(dinfo, M_DEVBUF);
+ return (NULL);
+ }
+
return (dinfo);
}
@@ -246,6 +254,7 @@
ofw_gpiobus_destroy_devinfo(struct ofw_gpiobus_devinfo *dinfo)
{
+ resource_list_free(&dinfo->opd_dinfo.rl);
ofw_bus_gen_destroy_devinfo(&dinfo->opd_obdinfo);
free(dinfo, M_DEVBUF);
}
@@ -264,33 +273,13 @@
static int
ofw_gpiobus_attach(device_t dev)
{
- struct gpiobus_softc *sc;
+ int err;
phandle_t child;
- sc = GPIOBUS_SOFTC(dev);
- sc->sc_busdev = dev;
- sc->sc_dev = device_get_parent(dev);
-
- /* Read the pin max. value */
- if (GPIO_PIN_MAX(sc->sc_dev, &sc->sc_npins) != 0)
- return (ENXIO);
-
- KASSERT(sc->sc_npins != 0, ("GPIO device with no pins"));
-
- /*
- * Increase to get number of pins.
- */
- sc->sc_npins++;
-
- sc->sc_pins_mapped = malloc(sizeof(int) * sc->sc_npins, M_DEVBUF,
- M_NOWAIT | M_ZERO);
-
- if (!sc->sc_pins_mapped)
- return (ENOMEM);
-
- /* Init the bus lock. */
- GPIOBUS_LOCK_INIT(sc);
-
+ err = gpiobus_init_softc(dev);
+ if (err != 0)
+ return (err);
+
bus_generic_probe(dev);
bus_enumerate_hinted_children(dev);
@@ -346,6 +335,8 @@
retval += bus_print_child_header(dev, child);
retval += printf(" at pin(s) ");
gpiobus_print_pins(&devi->opd_dinfo);
+ resource_list_print_type(&devi->opd_dinfo.rl, "irq", SYS_RES_IRQ,
+ "%ld");
retval += bus_print_child_footer(dev, child);
return (retval);

File Metadata

Mime Type
text/plain
Expires
Mon, Apr 20, 11:15 PM (17 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31870783
Default Alt Text
D999.id2094.diff (9 KB)

Event Timeline