Implement GPIO_GET_BUS() method for all GPIO drivers.

Add helper routines to deal with attach and detach of gpiobus and gpioc
devices that are common to all drivers.
This commit is contained in:
Luiz Otavio O Souza 2015-01-31 19:32:14 +00:00
parent 79215b4a3d
commit 7836352b50
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=277996
21 changed files with 320 additions and 68 deletions

View File

@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <machine/intr.h> #include <machine/intr.h>
#include <dev/fdt/fdt_common.h> #include <dev/fdt/fdt_common.h>
#include <dev/gpio/gpiobusvar.h>
#include <dev/ofw/ofw_bus.h> #include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h> #include <dev/ofw/ofw_bus_subr.h>
@ -75,6 +76,7 @@ __FBSDID("$FreeBSD$");
struct a10_gpio_softc { struct a10_gpio_softc {
device_t sc_dev; device_t sc_dev;
device_t sc_busdev;
struct mtx sc_mtx; struct mtx sc_mtx;
struct resource * sc_mem_res; struct resource * sc_mem_res;
struct resource * sc_irq_res; struct resource * sc_irq_res;
@ -217,6 +219,16 @@ a10_gpio_pin_configure(struct a10_gpio_softc *sc, struct gpio_pin *pin,
A10_GPIO_UNLOCK(sc); A10_GPIO_UNLOCK(sc);
} }
static device_t
a10_gpio_get_bus(device_t dev)
{
struct a10_gpio_softc *sc;
sc = device_get_softc(dev);
return (sc->sc_busdev);
}
static int static int
a10_gpio_pin_max(device_t dev, int *maxpin) a10_gpio_pin_max(device_t dev, int *maxpin)
{ {
@ -458,13 +470,12 @@ a10_gpio_attach(device_t dev)
sc->sc_gpio_pins[i].gp_flags = a10_gpio_func_flag(func); sc->sc_gpio_pins[i].gp_flags = a10_gpio_func_flag(func);
} }
sc->sc_gpio_npins = i; sc->sc_gpio_npins = i;
device_add_child(dev, "gpioc", -1);
device_add_child(dev, "gpiobus", -1);
a10_gpio_sc = sc; a10_gpio_sc = sc;
sc->sc_busdev = gpiobus_attach_bus(dev);
if (sc->sc_busdev == NULL)
goto fail;
return (bus_generic_attach(dev)); return (0);
fail: fail:
if (sc->sc_irq_res) if (sc->sc_irq_res)
@ -490,6 +501,7 @@ static device_method_t a10_gpio_methods[] = {
DEVMETHOD(device_detach, a10_gpio_detach), DEVMETHOD(device_detach, a10_gpio_detach),
/* GPIO protocol */ /* GPIO protocol */
DEVMETHOD(gpio_get_bus, a10_gpio_get_bus),
DEVMETHOD(gpio_pin_max, a10_gpio_pin_max), DEVMETHOD(gpio_pin_max, a10_gpio_pin_max),
DEVMETHOD(gpio_pin_getname, a10_gpio_pin_getname), DEVMETHOD(gpio_pin_getname, a10_gpio_pin_getname),
DEVMETHOD(gpio_pin_getflags, a10_gpio_pin_getflags), DEVMETHOD(gpio_pin_getflags, a10_gpio_pin_getflags),

View File

@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$");
#include <sys/gpio.h> #include <sys/gpio.h>
#include <dev/fdt/fdt_common.h> #include <dev/fdt/fdt_common.h>
#include <dev/gpio/gpiobusvar.h>
#include <dev/ofw/openfirm.h> #include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h> #include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h> #include <dev/ofw/ofw_bus_subr.h>
@ -107,6 +108,7 @@ enum port_no {
/* /*
* GPIO interface * GPIO interface
*/ */
static device_t socfpga_gpio_get_bus(device_t);
static int socfpga_gpio_pin_max(device_t, int *); static int socfpga_gpio_pin_max(device_t, int *);
static int socfpga_gpio_pin_getcaps(device_t, uint32_t, uint32_t *); static int socfpga_gpio_pin_getcaps(device_t, uint32_t, uint32_t *);
static int socfpga_gpio_pin_getname(device_t, uint32_t, char *); static int socfpga_gpio_pin_getname(device_t, uint32_t, char *);
@ -122,6 +124,7 @@ struct socfpga_gpio_softc {
bus_space_handle_t bsh; bus_space_handle_t bsh;
device_t dev; device_t dev;
device_t busdev;
struct mtx sc_mtx; struct mtx sc_mtx;
int gpio_npins; int gpio_npins;
struct gpio_pin gpio_pins[NR_GPIO_MAX]; struct gpio_pin gpio_pins[NR_GPIO_MAX];
@ -196,11 +199,24 @@ socfpga_gpio_attach(device_t dev)
snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME, snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME,
"socfpga_gpio%d.%d", device_get_unit(dev), i); "socfpga_gpio%d.%d", device_get_unit(dev), i);
} }
sc->busdev = gpiobus_attach_bus(dev);
if (sc->busdev == NULL) {
bus_release_resources(dev, socfpga_gpio_spec, sc->res);
mtx_destroy(&sc->sc_mtx);
return (ENXIO);
}
device_add_child(dev, "gpioc", -1); return (0);
device_add_child(dev, "gpiobus", -1); }
return (bus_generic_attach(dev)); static device_t
socfpga_gpio_get_bus(device_t dev)
{
struct socfpga_gpio_softc *sc;
sc = device_get_softc(dev);
return (sc->busdev);
} }
static int static int
@ -415,6 +431,7 @@ static device_method_t socfpga_gpio_methods[] = {
DEVMETHOD(device_attach, socfpga_gpio_attach), DEVMETHOD(device_attach, socfpga_gpio_attach),
/* GPIO protocol */ /* GPIO protocol */
DEVMETHOD(gpio_get_bus, socfpga_gpio_get_bus),
DEVMETHOD(gpio_pin_max, socfpga_gpio_pin_max), DEVMETHOD(gpio_pin_max, socfpga_gpio_pin_max),
DEVMETHOD(gpio_pin_getname, socfpga_gpio_pin_getname), DEVMETHOD(gpio_pin_getname, socfpga_gpio_pin_getname),
DEVMETHOD(gpio_pin_getcaps, socfpga_gpio_pin_getcaps), DEVMETHOD(gpio_pin_getcaps, socfpga_gpio_pin_getcaps),

View File

@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <machine/intr.h> #include <machine/intr.h>
#include <dev/fdt/fdt_common.h> #include <dev/fdt/fdt_common.h>
#include <dev/gpio/gpiobusvar.h>
#include <dev/ofw/ofw_bus.h> #include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h> #include <dev/ofw/ofw_bus_subr.h>
@ -83,6 +84,7 @@ struct bcm_gpio_sysctl {
struct bcm_gpio_softc { struct bcm_gpio_softc {
device_t sc_dev; device_t sc_dev;
device_t sc_busdev;
struct mtx sc_mtx; struct mtx sc_mtx;
struct resource * sc_res[BCM_GPIO_IRQS + 1]; struct resource * sc_res[BCM_GPIO_IRQS + 1];
bus_space_tag_t sc_bst; bus_space_tag_t sc_bst;
@ -317,6 +319,16 @@ bcm_gpio_pin_configure(struct bcm_gpio_softc *sc, struct gpio_pin *pin,
BCM_GPIO_UNLOCK(sc); BCM_GPIO_UNLOCK(sc);
} }
static device_t
bcm_gpio_get_bus(device_t dev)
{
struct bcm_gpio_softc *sc;
sc = device_get_softc(dev);
return (sc->sc_busdev);
}
static int static int
bcm_gpio_pin_max(device_t dev, int *maxpin) bcm_gpio_pin_max(device_t dev, int *maxpin)
{ {
@ -709,13 +721,12 @@ bcm_gpio_attach(device_t dev)
i++; i++;
} }
sc->sc_gpio_npins = i; sc->sc_gpio_npins = i;
bcm_gpio_sysctl_init(sc); bcm_gpio_sysctl_init(sc);
sc->sc_busdev = gpiobus_attach_bus(dev);
if (sc->sc_busdev == NULL)
goto fail;
device_add_child(dev, "gpioc", -1); return (0);
device_add_child(dev, "gpiobus", -1);
return (bus_generic_attach(dev));
fail: fail:
bus_release_resources(dev, bcm_gpio_res_spec, sc->sc_res); bus_release_resources(dev, bcm_gpio_res_spec, sc->sc_res);
@ -746,6 +757,7 @@ static device_method_t bcm_gpio_methods[] = {
DEVMETHOD(device_detach, bcm_gpio_detach), DEVMETHOD(device_detach, bcm_gpio_detach),
/* GPIO protocol */ /* GPIO protocol */
DEVMETHOD(gpio_get_bus, bcm_gpio_get_bus),
DEVMETHOD(gpio_pin_max, bcm_gpio_pin_max), DEVMETHOD(gpio_pin_max, bcm_gpio_pin_max),
DEVMETHOD(gpio_pin_getname, bcm_gpio_pin_getname), DEVMETHOD(gpio_pin_getname, bcm_gpio_pin_getname),
DEVMETHOD(gpio_pin_getflags, bcm_gpio_pin_getflags), DEVMETHOD(gpio_pin_getflags, bcm_gpio_pin_getflags),

View File

@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
#include <machine/resource.h> #include <machine/resource.h>
#include <dev/fdt/fdt_common.h> #include <dev/fdt/fdt_common.h>
#include <dev/gpio/gpiobusvar.h>
#include <dev/ofw/openfirm.h> #include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h> #include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h> #include <dev/ofw/ofw_bus_subr.h>
@ -92,6 +93,7 @@ __FBSDID("$FreeBSD$");
struct imx51_gpio_softc { struct imx51_gpio_softc {
device_t dev; device_t dev;
device_t sc_busdev;
struct mtx sc_mtx; struct mtx sc_mtx;
struct resource *sc_res[11]; /* 1 x mem, 2 x IRQ, 8 x IRQ */ struct resource *sc_res[11]; /* 1 x mem, 2 x IRQ, 8 x IRQ */
void *gpio_ih[11]; /* 1 ptr is not a big waste */ void *gpio_ih[11]; /* 1 ptr is not a big waste */
@ -145,6 +147,7 @@ static int imx51_gpio_intr(void *);
/* /*
* GPIO interface * GPIO interface
*/ */
static device_t imx51_gpio_get_bus(device_t);
static int imx51_gpio_pin_max(device_t, int *); static int imx51_gpio_pin_max(device_t, int *);
static int imx51_gpio_pin_getcaps(device_t, uint32_t, uint32_t *); static int imx51_gpio_pin_getcaps(device_t, uint32_t, uint32_t *);
static int imx51_gpio_pin_getflags(device_t, uint32_t, uint32_t *); static int imx51_gpio_pin_getflags(device_t, uint32_t, uint32_t *);
@ -179,6 +182,16 @@ imx51_gpio_pin_configure(struct imx51_gpio_softc *sc, struct gpio_pin *pin,
GPIO_UNLOCK(sc); GPIO_UNLOCK(sc);
} }
static device_t
imx51_gpio_get_bus(device_t dev)
{
struct imx51_gpio_softc *sc;
sc = device_get_softc(dev);
return (sc->sc_busdev);
}
static int static int
imx51_gpio_pin_max(device_t dev, int *maxpin) imx51_gpio_pin_max(device_t dev, int *maxpin)
{ {
@ -427,11 +440,13 @@ imx51_gpio_attach(device_t dev)
snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME, snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME,
"imx_gpio%d.%d", device_get_unit(dev), i); "imx_gpio%d.%d", device_get_unit(dev), i);
} }
sc->sc_busdev = gpiobus_attach_bus(dev);
if (sc->sc_busdev == NULL) {
imx51_gpio_detach(dev);
return (ENXIO);
}
device_add_child(dev, "gpioc", -1); return (0);
device_add_child(dev, "gpiobus", -1);
return (bus_generic_attach(dev));
} }
static int static int
@ -444,7 +459,7 @@ imx51_gpio_detach(device_t dev)
KASSERT(mtx_initialized(&sc->sc_mtx), ("gpio mutex not initialized")); KASSERT(mtx_initialized(&sc->sc_mtx), ("gpio mutex not initialized"));
bus_generic_detach(dev); gpiobus_detach_bus(dev);
for (irq = 1; irq <= sc->sc_l_irq; irq ++) { for (irq = 1; irq <= sc->sc_l_irq; irq ++) {
if (sc->gpio_ih[irq]) if (sc->gpio_ih[irq])
bus_teardown_intr(dev, sc->sc_res[irq], sc->gpio_ih[irq]); bus_teardown_intr(dev, sc->sc_res[irq], sc->gpio_ih[irq]);
@ -462,6 +477,7 @@ static device_method_t imx51_gpio_methods[] = {
DEVMETHOD(device_detach, imx51_gpio_detach), DEVMETHOD(device_detach, imx51_gpio_detach),
/* GPIO protocol */ /* GPIO protocol */
DEVMETHOD(gpio_get_bus, imx51_gpio_get_bus),
DEVMETHOD(gpio_pin_max, imx51_gpio_pin_max), DEVMETHOD(gpio_pin_max, imx51_gpio_pin_max),
DEVMETHOD(gpio_pin_getname, imx51_gpio_pin_getname), DEVMETHOD(gpio_pin_getname, imx51_gpio_pin_getname),
DEVMETHOD(gpio_pin_getflags, imx51_gpio_pin_getflags), DEVMETHOD(gpio_pin_getflags, imx51_gpio_pin_getflags),

View File

@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <sys/gpio.h> #include <sys/gpio.h>
#include <dev/fdt/fdt_common.h> #include <dev/fdt/fdt_common.h>
#include <dev/gpio/gpiobusvar.h>
#include <dev/ofw/openfirm.h> #include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h> #include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h> #include <dev/ofw/ofw_bus_subr.h>
@ -74,6 +75,7 @@ __FBSDID("$FreeBSD$");
/* /*
* GPIO interface * GPIO interface
*/ */
static device_t vf_gpio_get_bus(device_t);
static int vf_gpio_pin_max(device_t, int *); static int vf_gpio_pin_max(device_t, int *);
static int vf_gpio_pin_getcaps(device_t, uint32_t, uint32_t *); static int vf_gpio_pin_getcaps(device_t, uint32_t, uint32_t *);
static int vf_gpio_pin_getname(device_t, uint32_t, char *); static int vf_gpio_pin_getname(device_t, uint32_t, char *);
@ -88,6 +90,7 @@ struct vf_gpio_softc {
bus_space_tag_t bst; bus_space_tag_t bst;
bus_space_handle_t bsh; bus_space_handle_t bsh;
device_t sc_busdev;
struct mtx sc_mtx; struct mtx sc_mtx;
int gpio_npins; int gpio_npins;
struct gpio_pin gpio_pins[NGPIO]; struct gpio_pin gpio_pins[NGPIO];
@ -147,10 +150,24 @@ vf_gpio_attach(device_t dev)
"vf_gpio%d.%d", device_get_unit(dev), i); "vf_gpio%d.%d", device_get_unit(dev), i);
} }
device_add_child(dev, "gpioc", -1); sc->sc_busdev = gpiobus_attach_bus(dev);
device_add_child(dev, "gpiobus", -1); if (sc->sc_busdev == NULL) {
bus_release_resources(dev, vf_gpio_spec, sc->res);
mtx_destroy(&sc->sc_mtx);
return (ENXIO);
}
return (bus_generic_attach(dev)); return (0);
}
static device_t
vf_gpio_get_bus(device_t dev)
{
struct vf_gpio_softc *sc;
sc = device_get_softc(dev);
return (sc->sc_busdev);
} }
static int static int
@ -348,6 +365,7 @@ static device_method_t vf_gpio_methods[] = {
DEVMETHOD(device_attach, vf_gpio_attach), DEVMETHOD(device_attach, vf_gpio_attach),
/* GPIO protocol */ /* GPIO protocol */
DEVMETHOD(gpio_get_bus, vf_gpio_get_bus),
DEVMETHOD(gpio_pin_max, vf_gpio_pin_max), DEVMETHOD(gpio_pin_max, vf_gpio_pin_max),
DEVMETHOD(gpio_pin_getname, vf_gpio_pin_getname), DEVMETHOD(gpio_pin_getname, vf_gpio_pin_getname),
DEVMETHOD(gpio_pin_getcaps, vf_gpio_pin_getcaps), DEVMETHOD(gpio_pin_getcaps, vf_gpio_pin_getcaps),

View File

@ -79,6 +79,7 @@ __FBSDID("$FreeBSD$");
#include <machine/intr.h> #include <machine/intr.h>
#include <machine/fdt.h> #include <machine/fdt.h>
#include <dev/gpio/gpiobusvar.h>
#include <dev/ofw/ofw_bus.h> #include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h> #include <dev/ofw/ofw_bus_subr.h>
@ -90,6 +91,7 @@ __FBSDID("$FreeBSD$");
struct lpc_gpio_softc struct lpc_gpio_softc
{ {
device_t lg_dev; device_t lg_dev;
device_t lg_busdev;
struct resource * lg_res; struct resource * lg_res;
bus_space_tag_t lg_bst; bus_space_tag_t lg_bst;
bus_space_handle_t lg_bsh; bus_space_handle_t lg_bsh;
@ -135,6 +137,7 @@ static int lpc_gpio_probe(device_t);
static int lpc_gpio_attach(device_t); static int lpc_gpio_attach(device_t);
static int lpc_gpio_detach(device_t); static int lpc_gpio_detach(device_t);
static device_t lpc_gpio_get_bus(device_t);
static int lpc_gpio_pin_max(device_t, int *); static int lpc_gpio_pin_max(device_t, int *);
static int lpc_gpio_pin_getcaps(device_t, uint32_t, uint32_t *); static int lpc_gpio_pin_getcaps(device_t, uint32_t, uint32_t *);
static int lpc_gpio_pin_getflags(device_t, uint32_t, uint32_t *); static int lpc_gpio_pin_getflags(device_t, uint32_t, uint32_t *);
@ -192,10 +195,13 @@ lpc_gpio_attach(device_t dev)
lpc_gpio_sc = sc; lpc_gpio_sc = sc;
device_add_child(dev, "gpioc", -1); sc->lg_busdev = gpiobus_attach_bus(dev);
device_add_child(dev, "gpiobus", -1); if (sc->lg_busdev == NULL) {
bus_release_resource(dev, SYS_RES_MEMORY, rid, sc->lg_res);
return (ENXIO);
}
return (bus_generic_attach(dev)); return (0);
} }
static int static int
@ -204,6 +210,16 @@ lpc_gpio_detach(device_t dev)
return (EBUSY); return (EBUSY);
} }
static device_t
lpc_gpio_get_bus(device_t dev)
{
struct lpc_gpio_softc *sc;
sc = device_get_softc(dev);
return (sc->lg_busdev);
}
static int static int
lpc_gpio_pin_max(device_t dev, int *npins) lpc_gpio_pin_max(device_t dev, int *npins)
{ {
@ -527,6 +543,7 @@ static device_method_t lpc_gpio_methods[] = {
DEVMETHOD(device_detach, lpc_gpio_detach), DEVMETHOD(device_detach, lpc_gpio_detach),
/* GPIO interface */ /* GPIO interface */
DEVMETHOD(gpio_get_bus, lpc_gpio_get_bus),
DEVMETHOD(gpio_pin_max, lpc_gpio_pin_max), DEVMETHOD(gpio_pin_max, lpc_gpio_pin_max),
DEVMETHOD(gpio_pin_getcaps, lpc_gpio_pin_getcaps), DEVMETHOD(gpio_pin_getcaps, lpc_gpio_pin_getcaps),
DEVMETHOD(gpio_pin_getflags, lpc_gpio_pin_getflags), DEVMETHOD(gpio_pin_getflags, lpc_gpio_pin_getflags),

View File

@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <machine/intr.h> #include <machine/intr.h>
#include <dev/fdt/fdt_common.h> #include <dev/fdt/fdt_common.h>
#include <dev/gpio/gpiobusvar.h>
#include <dev/ofw/ofw_bus.h> #include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h> #include <dev/ofw/ofw_bus_subr.h>
@ -73,6 +74,7 @@ __FBSDID("$FreeBSD$");
struct rk30_gpio_softc { struct rk30_gpio_softc {
device_t sc_dev; device_t sc_dev;
device_t sc_busdev;
struct mtx sc_mtx; struct mtx sc_mtx;
struct resource * sc_mem_res; struct resource * sc_mem_res;
struct resource * sc_irq_res; struct resource * sc_irq_res;
@ -210,6 +212,16 @@ rk30_gpio_pin_configure(struct rk30_gpio_softc *sc, struct gpio_pin *pin,
RK30_GPIO_UNLOCK(sc); RK30_GPIO_UNLOCK(sc);
} }
static device_t
rk30_gpio_get_bus(device_t dev)
{
struct rk30_gpio_softc *sc;
sc = device_get_softc(dev);
return (sc->sc_busdev);
}
static int static int
rk30_gpio_pin_max(device_t dev, int *maxpin) rk30_gpio_pin_max(device_t dev, int *maxpin)
{ {
@ -449,15 +461,13 @@ rk30_gpio_attach(device_t dev)
sc->sc_gpio_pins[i].gp_flags = rk30_gpio_get_function(sc, i); sc->sc_gpio_pins[i].gp_flags = rk30_gpio_get_function(sc, i);
} }
sc->sc_gpio_npins = i; sc->sc_gpio_npins = i;
device_add_child(dev, "gpioc", -1);
device_add_child(dev, "gpiobus", -1);
rk30_gpio_sc = sc; rk30_gpio_sc = sc;
rk30_gpio_init(); rk30_gpio_init();
sc->sc_busdev = gpiobus_attach_bus(dev);
return (bus_generic_attach(dev)); if (sc->sc_busdev == NULL)
goto fail;
return (0);
fail: fail:
if (sc->sc_irq_res) if (sc->sc_irq_res)
@ -483,6 +493,7 @@ static device_method_t rk30_gpio_methods[] = {
DEVMETHOD(device_detach, rk30_gpio_detach), DEVMETHOD(device_detach, rk30_gpio_detach),
/* GPIO protocol */ /* GPIO protocol */
DEVMETHOD(gpio_get_bus, rk30_gpio_get_bus),
DEVMETHOD(gpio_pin_max, rk30_gpio_pin_max), DEVMETHOD(gpio_pin_max, rk30_gpio_pin_max),
DEVMETHOD(gpio_pin_getname, rk30_gpio_pin_getname), DEVMETHOD(gpio_pin_getname, rk30_gpio_pin_getname),
DEVMETHOD(gpio_pin_getflags, rk30_gpio_pin_getflags), DEVMETHOD(gpio_pin_getflags, rk30_gpio_pin_getflags),

View File

@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h> #include <sys/mutex.h>
#include <sys/gpio.h> #include <sys/gpio.h>
#include <dev/gpio/gpiobusvar.h>
#include <dev/ofw/openfirm.h> #include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h> #include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h> #include <dev/ofw/ofw_bus_subr.h>
@ -82,6 +83,7 @@ __FBSDID("$FreeBSD$");
/* /*
* GPIO interface * GPIO interface
*/ */
static device_t pad_get_bus(device_t);
static int pad_pin_max(device_t, int *); static int pad_pin_max(device_t, int *);
static int pad_pin_getcaps(device_t, uint32_t, uint32_t *); static int pad_pin_getcaps(device_t, uint32_t, uint32_t *);
static int pad_pin_getname(device_t, uint32_t, char *); static int pad_pin_getname(device_t, uint32_t, char *);
@ -111,6 +113,7 @@ struct pad_softc {
struct gpio_pin gpio_pins[MAX_NGPIO]; struct gpio_pin gpio_pins[MAX_NGPIO];
void *gpio_ih[MAX_PORTS]; void *gpio_ih[MAX_PORTS];
device_t dev; device_t dev;
device_t busdev;
int model; int model;
struct resource_spec *pad_spec; struct resource_spec *pad_spec;
struct gpio_bank *gpio_map; struct gpio_bank *gpio_map;
@ -558,11 +561,11 @@ pad_attach(device_t dev)
snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME, snprintf(sc->gpio_pins[i].gp_name, GPIOMAXNAME,
"pad%d.%d", device_get_unit(dev), i); "pad%d.%d", device_get_unit(dev), i);
} }
sc->busdev = gpiobus_attach_bus(dev);
if (sc->busdev == NULL)
goto fail;
device_add_child(dev, "gpioc", -1); return (0);
device_add_child(dev, "gpiobus", -1);
return (bus_generic_attach(dev));
fail: fail:
for (i = 0; i < sc->nports; i++) { for (i = 0; i < sc->nports; i++) {
@ -576,6 +579,16 @@ pad_attach(device_t dev)
return (ENXIO); return (ENXIO);
} }
static device_t
pad_get_bus(device_t dev)
{
struct pad_softc *sc;
sc = device_get_softc(dev);
return (sc->busdev);
}
static int static int
pad_pin_max(device_t dev, int *maxpin) pad_pin_max(device_t dev, int *maxpin)
{ {
@ -817,6 +830,7 @@ static device_method_t pad_methods[] = {
DEVMETHOD(device_attach, pad_attach), DEVMETHOD(device_attach, pad_attach),
/* GPIO protocol */ /* GPIO protocol */
DEVMETHOD(gpio_get_bus, pad_get_bus),
DEVMETHOD(gpio_pin_max, pad_pin_max), DEVMETHOD(gpio_pin_max, pad_pin_max),
DEVMETHOD(gpio_pin_getname, pad_pin_getname), DEVMETHOD(gpio_pin_getname, pad_pin_getname),
DEVMETHOD(gpio_pin_getcaps, pad_pin_getcaps), DEVMETHOD(gpio_pin_getcaps, pad_pin_getcaps),

View File

@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
#include <arm/ti/ti_prcm.h> #include <arm/ti/ti_prcm.h>
#include <dev/fdt/fdt_common.h> #include <dev/fdt/fdt_common.h>
#include <dev/gpio/gpiobusvar.h>
#include <dev/ofw/openfirm.h> #include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h> #include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h> #include <dev/ofw/ofw_bus_subr.h>
@ -309,6 +310,16 @@ ti_gpio_intr_status(struct ti_gpio_softc *sc, unsigned int bank)
return (reg); return (reg);
} }
static device_t
ti_gpio_get_bus(device_t dev)
{
struct ti_gpio_softc *sc;
sc = device_get_softc(dev);
return (sc->sc_busdev);
}
/** /**
* ti_gpio_pin_max - Returns the maximum number of GPIO pins * ti_gpio_pin_max - Returns the maximum number of GPIO pins
* @dev: gpio device handle * @dev: gpio device handle
@ -815,12 +826,13 @@ ti_gpio_attach(device_t dev)
} }
} }
} }
sc->sc_busdev = gpiobus_attach_bus(dev);
if (sc->sc_busdev == NULL) {
ti_gpio_detach(dev);
return (ENXIO);
}
/* Finish of the probe call */ return (0);
device_add_child(dev, "gpioc", -1);
device_add_child(dev, "gpiobus", -1);
return (bus_generic_attach(dev));
} }
/** /**
@ -849,7 +861,7 @@ ti_gpio_detach(device_t dev)
if (sc->sc_mem_res[i] != NULL) if (sc->sc_mem_res[i] != NULL)
ti_gpio_intr_clr(sc, i, 0xffffffff); ti_gpio_intr_clr(sc, i, 0xffffffff);
} }
bus_generic_detach(dev); gpiobus_detach_bus(dev);
if (sc->sc_events) if (sc->sc_events)
free(sc->sc_events, M_DEVBUF); free(sc->sc_events, M_DEVBUF);
if (sc->sc_irq_polarity) if (sc->sc_irq_polarity)
@ -1065,6 +1077,7 @@ static device_method_t ti_gpio_methods[] = {
DEVMETHOD(device_detach, ti_gpio_detach), DEVMETHOD(device_detach, ti_gpio_detach),
/* GPIO protocol */ /* GPIO protocol */
DEVMETHOD(gpio_get_bus, ti_gpio_get_bus),
DEVMETHOD(gpio_pin_max, ti_gpio_pin_max), DEVMETHOD(gpio_pin_max, ti_gpio_pin_max),
DEVMETHOD(gpio_pin_getname, ti_gpio_pin_getname), DEVMETHOD(gpio_pin_getname, ti_gpio_pin_getname),
DEVMETHOD(gpio_pin_getflags, ti_gpio_pin_getflags), DEVMETHOD(gpio_pin_getflags, ti_gpio_pin_getflags),

View File

@ -46,6 +46,7 @@
*/ */
struct ti_gpio_softc { struct ti_gpio_softc {
device_t sc_dev; device_t sc_dev;
device_t sc_busdev;
/* Interrupt trigger type and level. */ /* Interrupt trigger type and level. */
enum intr_trigger *sc_irq_trigger; enum intr_trigger *sc_irq_trigger;

View File

@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$");
#include <machine/stdarg.h> #include <machine/stdarg.h>
#include <dev/fdt/fdt_common.h> #include <dev/fdt/fdt_common.h>
#include <dev/gpio/gpiobusvar.h>
#include <dev/ofw/ofw_bus.h> #include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h> #include <dev/ofw/ofw_bus_subr.h>
@ -88,6 +89,7 @@ __FBSDID("$FreeBSD$");
struct zy7_gpio_softc { struct zy7_gpio_softc {
device_t dev; device_t dev;
device_t busdev;
struct mtx sc_mtx; struct mtx sc_mtx;
struct resource *mem_res; /* Memory resource */ struct resource *mem_res; /* Memory resource */
}; };
@ -113,6 +115,15 @@ struct zy7_gpio_softc {
#define ZY7_GPIO_INT_POLARITY(b) (0x0220+0x40*(b)) /* int polarity */ #define ZY7_GPIO_INT_POLARITY(b) (0x0220+0x40*(b)) /* int polarity */
#define ZY7_GPIO_INT_ANY(b) (0x0224+0x40*(b)) /* any edge */ #define ZY7_GPIO_INT_ANY(b) (0x0224+0x40*(b)) /* any edge */
static device_t
zy7_gpio_get_bus(device_t dev)
{
struct zy7_gpio_softc *sc;
sc = device_get_softc(dev);
return (sc->busdev);
}
static int static int
zy7_gpio_pin_max(device_t dev, int *maxpin) zy7_gpio_pin_max(device_t dev, int *maxpin)
@ -329,10 +340,13 @@ zy7_gpio_attach(device_t dev)
/* Completely reset. */ /* Completely reset. */
zy7_gpio_hw_reset(sc); zy7_gpio_hw_reset(sc);
device_add_child(dev, "gpioc", -1); sc->busdev = gpiobus_attach_bus(dev);
device_add_child(dev, "gpiobus", -1); if (sc->busdev == NULL) {
zy7_gpio_detach(dev);
return (ENOMEM);
}
return (bus_generic_attach(dev)); return (0);
} }
static int static int
@ -340,7 +354,7 @@ zy7_gpio_detach(device_t dev)
{ {
struct zy7_gpio_softc *sc = device_get_softc(dev); struct zy7_gpio_softc *sc = device_get_softc(dev);
bus_generic_detach(dev); gpiobus_detach_bus(dev);
if (sc->mem_res != NULL) { if (sc->mem_res != NULL) {
/* Release memory resource. */ /* Release memory resource. */
@ -360,6 +374,7 @@ static device_method_t zy7_gpio_methods[] = {
DEVMETHOD(device_detach, zy7_gpio_detach), DEVMETHOD(device_detach, zy7_gpio_detach),
/* GPIO protocol */ /* GPIO protocol */
DEVMETHOD(gpio_get_bus, zy7_gpio_get_bus),
DEVMETHOD(gpio_pin_max, zy7_gpio_pin_max), DEVMETHOD(gpio_pin_max, zy7_gpio_pin_max),
DEVMETHOD(gpio_pin_getname, zy7_gpio_pin_getname), DEVMETHOD(gpio_pin_getname, zy7_gpio_pin_getname),
DEVMETHOD(gpio_pin_getflags, zy7_gpio_pin_getflags), DEVMETHOD(gpio_pin_getflags, zy7_gpio_pin_getflags),

View File

@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
#include <machine/resource.h> #include <machine/resource.h>
#include <arm/xscale/ixp425/ixp425reg.h> #include <arm/xscale/ixp425/ixp425reg.h>
#include <arm/xscale/ixp425/ixp425var.h> #include <arm/xscale/ixp425/ixp425var.h>
#include <dev/gpio/gpiobusvar.h>
#include "gpio_if.h" #include "gpio_if.h"
@ -60,6 +61,7 @@ __FBSDID("$FreeBSD$");
struct avila_gpio_softc { struct avila_gpio_softc {
device_t sc_dev; device_t sc_dev;
device_t sc_busdev;
bus_space_tag_t sc_iot; bus_space_tag_t sc_iot;
bus_space_handle_t sc_gpio_ioh; bus_space_handle_t sc_gpio_ioh;
uint32_t sc_valid; uint32_t sc_valid;
@ -116,6 +118,7 @@ static int avila_gpio_detach(device_t dev);
/* /*
* GPIO interface * GPIO interface
*/ */
static device_t avila_gpio_get_bus(device_t);
static int avila_gpio_pin_max(device_t dev, int *maxpin); static int avila_gpio_pin_max(device_t dev, int *maxpin);
static int avila_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps); static int avila_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps);
static int avila_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t static int avila_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t
@ -162,6 +165,16 @@ avila_gpio_pin_configure(struct avila_gpio_softc *sc, struct gpio_pin *pin,
} }
} }
static device_t
avila_gpio_get_bus(device_t dev)
{
struct avila_gpio_softc *sc;
sc = device_get_softc(dev);
return (sc->sc_busdev);
}
static int static int
avila_gpio_pin_max(device_t dev, int *maxpin) avila_gpio_pin_max(device_t dev, int *maxpin)
{ {
@ -310,10 +323,11 @@ avila_gpio_attach(device_t dev)
sc->sc_valid |= 1 << p->pin; sc->sc_valid |= 1 << p->pin;
} }
device_add_child(dev, "gpioc", -1); sc->sc_busdev = gpiobus_attach_bus(dev);
device_add_child(dev, "gpiobus", -1); if (sc->sc_busdev == NULL)
return (ENXIO);
return (bus_generic_attach(dev)); return (0);
#undef N #undef N
} }
@ -321,7 +335,7 @@ static int
avila_gpio_detach(device_t dev) avila_gpio_detach(device_t dev)
{ {
bus_generic_detach(dev); gpiobus_detach_bus(dev);
return(0); return(0);
} }
@ -332,6 +346,7 @@ static device_method_t gpio_avila_methods[] = {
DEVMETHOD(device_detach, avila_gpio_detach), DEVMETHOD(device_detach, avila_gpio_detach),
/* GPIO protocol */ /* GPIO protocol */
DEVMETHOD(gpio_get_bus, avila_gpio_get_bus),
DEVMETHOD(gpio_pin_max, avila_gpio_pin_max), DEVMETHOD(gpio_pin_max, avila_gpio_pin_max),
DEVMETHOD(gpio_pin_getname, avila_gpio_pin_getname), DEVMETHOD(gpio_pin_getname, avila_gpio_pin_getname),
DEVMETHOD(gpio_pin_getflags, avila_gpio_pin_getflags), DEVMETHOD(gpio_pin_getflags, avila_gpio_pin_getflags),

View File

@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$");
#include <arm/xscale/ixp425/ixp425var.h> #include <arm/xscale/ixp425/ixp425var.h>
#include <arm/xscale/ixp425/ixdp425reg.h> #include <arm/xscale/ixp425/ixdp425reg.h>
#include <dev/gpio/gpiobusvar.h>
#include <dev/iicbus/iiconf.h> #include <dev/iicbus/iiconf.h>
#include <dev/iicbus/iicbus.h> #include <dev/iicbus/iicbus.h>
@ -79,6 +80,7 @@ __FBSDID("$FreeBSD$");
#define GPIO_PINS 5 #define GPIO_PINS 5
struct cambria_gpio_softc { struct cambria_gpio_softc {
device_t sc_dev; device_t sc_dev;
device_t sc_busdev;
bus_space_tag_t sc_iot; bus_space_tag_t sc_iot;
bus_space_handle_t sc_gpio_ioh; bus_space_handle_t sc_gpio_ioh;
struct mtx sc_mtx; struct mtx sc_mtx;
@ -119,6 +121,7 @@ static int cambria_gpio_detach(device_t dev);
/* /*
* GPIO interface * GPIO interface
*/ */
static device_t cambria_gpio_get_bus(device_t);
static int cambria_gpio_pin_max(device_t dev, int *maxpin); static int cambria_gpio_pin_max(device_t dev, int *maxpin);
static int cambria_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps); static int cambria_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps);
static int cambria_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t static int cambria_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t
@ -261,6 +264,16 @@ cambria_gpio_write(struct cambria_gpio_softc *sc)
return (0); return (0);
} }
static device_t
cambria_gpio_get_bus(device_t dev)
{
struct cambria_gpio_softc *sc;
sc = device_get_softc(dev);
return (sc->sc_busdev);
}
static int static int
cambria_gpio_pin_max(device_t dev, int *maxpin) cambria_gpio_pin_max(device_t dev, int *maxpin)
{ {
@ -438,10 +451,13 @@ cambria_gpio_attach(device_t dev)
cambria_gpio_pin_setflags(dev, pin, p->flags); cambria_gpio_pin_setflags(dev, pin, p->flags);
} }
device_add_child(dev, "gpioc", -1); sc->sc_busdev = gpiobus_attach_bus(dev);
device_add_child(dev, "gpiobus", -1); if (sc->sc_busdev == NULL) {
mtx_destroy(&sc->sc_mtx);
return (ENXIO);
}
return (bus_generic_attach(dev)); return (0);
} }
static int static int
@ -451,8 +467,7 @@ cambria_gpio_detach(device_t dev)
KASSERT(mtx_initialized(&sc->sc_mtx), ("gpio mutex not initialized")); KASSERT(mtx_initialized(&sc->sc_mtx), ("gpio mutex not initialized"));
bus_generic_detach(dev); gpiobus_detach_bus(dev);
mtx_destroy(&sc->sc_mtx); mtx_destroy(&sc->sc_mtx);
return(0); return(0);
@ -464,6 +479,7 @@ static device_method_t cambria_gpio_methods[] = {
DEVMETHOD(device_detach, cambria_gpio_detach), DEVMETHOD(device_detach, cambria_gpio_detach),
/* GPIO protocol */ /* GPIO protocol */
DEVMETHOD(gpio_get_bus, cambria_gpio_get_bus),
DEVMETHOD(gpio_pin_max, cambria_gpio_pin_max), DEVMETHOD(gpio_pin_max, cambria_gpio_pin_max),
DEVMETHOD(gpio_pin_getname, cambria_gpio_pin_getname), DEVMETHOD(gpio_pin_getname, cambria_gpio_pin_getname),
DEVMETHOD(gpio_pin_getflags, cambria_gpio_pin_getflags), DEVMETHOD(gpio_pin_getflags, cambria_gpio_pin_getflags),

View File

@ -131,6 +131,30 @@ gpiobus_print_pins(struct gpiobus_ivar *devi, char *buf, size_t buflen)
strlcat(buf, tmp, buflen); strlcat(buf, tmp, buflen);
} }
device_t
gpiobus_attach_bus(device_t dev)
{
device_t busdev;
busdev = device_add_child(dev, "gpiobus", -1);
if (busdev == NULL)
return (NULL);
if (device_add_child(dev, "gpioc", -1) == NULL) {
device_delete_child(dev, busdev);
return (NULL);
}
bus_generic_attach(dev);
return (busdev);
}
int
gpiobus_detach_bus(device_t dev)
{
return (bus_generic_detach(dev));
}
int int
gpiobus_init_softc(device_t dev) gpiobus_init_softc(device_t dev)
{ {

View File

@ -95,6 +95,8 @@ gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells,
device_t ofw_gpiobus_add_fdt_child(device_t, phandle_t); device_t ofw_gpiobus_add_fdt_child(device_t, phandle_t);
#endif #endif
int gpio_check_flags(uint32_t, uint32_t); int gpio_check_flags(uint32_t, uint32_t);
device_t gpiobus_attach_bus(device_t);
int gpiobus_detach_bus(device_t);
int gpiobus_init_softc(device_t); int gpiobus_init_softc(device_t);
extern driver_t gpiobus_driver; extern driver_t gpiobus_driver;

View File

@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
#include <mips/atheros/ar71xx_gpiovar.h> #include <mips/atheros/ar71xx_gpiovar.h>
#include <mips/atheros/ar933xreg.h> #include <mips/atheros/ar933xreg.h>
#include <mips/atheros/ar934xreg.h> #include <mips/atheros/ar934xreg.h>
#include <dev/gpio/gpiobusvar.h>
#include "gpio_if.h" #include "gpio_if.h"
@ -79,6 +80,7 @@ static void ar71xx_gpio_intr(void *arg);
/* /*
* GPIO interface * GPIO interface
*/ */
static device_t ar71xx_gpio_get_bus(device_t);
static int ar71xx_gpio_pin_max(device_t dev, int *maxpin); static int ar71xx_gpio_pin_max(device_t dev, int *maxpin);
static int ar71xx_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps); static int ar71xx_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps);
static int ar71xx_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t static int ar71xx_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t
@ -135,6 +137,16 @@ ar71xx_gpio_pin_configure(struct ar71xx_gpio_softc *sc, struct gpio_pin *pin,
} }
} }
static device_t
ar71xx_gpio_get_bus(device_t dev)
{
struct ar71xx_gpio_softc *sc;
sc = device_get_softc(dev);
return (sc->busdev);
}
static int static int
ar71xx_gpio_pin_max(device_t dev, int *maxpin) ar71xx_gpio_pin_max(device_t dev, int *maxpin)
{ {
@ -433,10 +445,13 @@ ar71xx_gpio_attach(device_t dev)
ar71xx_gpio_pin_set(dev, j, 1); ar71xx_gpio_pin_set(dev, j, 1);
} }
} }
device_add_child(dev, "gpioc", -1); sc->busdev = gpiobus_attach_bus(dev);
device_add_child(dev, "gpiobus", -1); if (sc->busdev == NULL) {
ar71xx_gpio_detach(dev);
return (ENXIO);
}
return (bus_generic_attach(dev)); return (0);
} }
static int static int
@ -446,7 +461,7 @@ ar71xx_gpio_detach(device_t dev)
KASSERT(mtx_initialized(&sc->gpio_mtx), ("gpio mutex not initialized")); KASSERT(mtx_initialized(&sc->gpio_mtx), ("gpio mutex not initialized"));
bus_generic_detach(dev); gpiobus_detach_bus(dev);
if (sc->gpio_ih) if (sc->gpio_ih)
bus_teardown_intr(dev, sc->gpio_irq_res, sc->gpio_ih); bus_teardown_intr(dev, sc->gpio_irq_res, sc->gpio_ih);
if (sc->gpio_irq_res) if (sc->gpio_irq_res)
@ -468,6 +483,7 @@ static device_method_t ar71xx_gpio_methods[] = {
DEVMETHOD(device_detach, ar71xx_gpio_detach), DEVMETHOD(device_detach, ar71xx_gpio_detach),
/* GPIO protocol */ /* GPIO protocol */
DEVMETHOD(gpio_get_bus, ar71xx_gpio_get_bus),
DEVMETHOD(gpio_pin_max, ar71xx_gpio_pin_max), DEVMETHOD(gpio_pin_max, ar71xx_gpio_pin_max),
DEVMETHOD(gpio_pin_getname, ar71xx_gpio_pin_getname), DEVMETHOD(gpio_pin_getname, ar71xx_gpio_pin_getname),
DEVMETHOD(gpio_pin_getflags, ar71xx_gpio_pin_getflags), DEVMETHOD(gpio_pin_getflags, ar71xx_gpio_pin_getflags),

View File

@ -57,6 +57,7 @@
struct ar71xx_gpio_softc { struct ar71xx_gpio_softc {
device_t dev; device_t dev;
device_t busdev;
struct mtx gpio_mtx; struct mtx gpio_mtx;
struct resource *gpio_mem_res; struct resource *gpio_mem_res;
int gpio_mem_rid; int gpio_mem_rid;

View File

@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <mips/cavium/octeon_irq.h> #include <mips/cavium/octeon_irq.h>
#include <mips/cavium/octeon_gpiovar.h> #include <mips/cavium/octeon_gpiovar.h>
#include <dev/gpio/gpiobusvar.h>
#include "gpio_if.h" #include "gpio_if.h"
@ -90,6 +91,7 @@ static void octeon_gpio_intr(void *arg);
/* /*
* GPIO interface * GPIO interface
*/ */
static device_t octeon_gpio_get_bus(device_t);
static int octeon_gpio_pin_max(device_t dev, int *maxpin); static int octeon_gpio_pin_max(device_t dev, int *maxpin);
static int octeon_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps); static int octeon_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps);
static int octeon_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t static int octeon_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t
@ -134,6 +136,16 @@ octeon_gpio_pin_configure(struct octeon_gpio_softc *sc, struct gpio_pin *pin,
GPIO_UNLOCK(sc); GPIO_UNLOCK(sc);
} }
static device_t
octeon_gpio_get_bus(device_t dev)
{
struct octeon_gpio_softc *sc;
sc = device_get_softc(dev);
return (sc->busdev);
}
static int static int
octeon_gpio_pin_max(device_t dev, int *maxpin) octeon_gpio_pin_max(device_t dev, int *maxpin)
{ {
@ -434,11 +446,13 @@ octeon_gpio_attach(device_t dev)
gpio_cfgx.s.int_en, gpio_cfgx.s.int_type ? "rising edge" : "level"); gpio_cfgx.s.int_en, gpio_cfgx.s.int_type ? "rising edge" : "level");
} }
} }
sc->busdev = gpiobus_attach_bus(dev);
if (sc->busdev == NULL) {
octeon_gpio_detach(dev);
return (ENXIO);
}
device_add_child(dev, "gpioc", -1); return (0);
device_add_child(dev, "gpiobus", -1);
return (bus_generic_attach(dev));
} }
static int static int
@ -457,7 +471,7 @@ octeon_gpio_detach(device_t dev)
bus_release_resource(dev, SYS_RES_IRQ, bus_release_resource(dev, SYS_RES_IRQ,
sc->gpio_irq_rid[i], sc->gpio_irq_res[i]); sc->gpio_irq_rid[i], sc->gpio_irq_res[i]);
} }
bus_generic_detach(dev); gpiobus_detach_bus(dev);
mtx_destroy(&sc->gpio_mtx); mtx_destroy(&sc->gpio_mtx);
return(0); return(0);
@ -470,6 +484,7 @@ static device_method_t octeon_gpio_methods[] = {
DEVMETHOD(device_detach, octeon_gpio_detach), DEVMETHOD(device_detach, octeon_gpio_detach),
/* GPIO protocol */ /* GPIO protocol */
DEVMETHOD(gpio_get_bus, octeon_gpio_get_bus),
DEVMETHOD(gpio_pin_max, octeon_gpio_pin_max), DEVMETHOD(gpio_pin_max, octeon_gpio_pin_max),
DEVMETHOD(gpio_pin_getname, octeon_gpio_pin_getname), DEVMETHOD(gpio_pin_getname, octeon_gpio_pin_getname),
DEVMETHOD(gpio_pin_getflags, octeon_gpio_pin_getflags), DEVMETHOD(gpio_pin_getflags, octeon_gpio_pin_getflags),

View File

@ -43,6 +43,7 @@
struct octeon_gpio_softc { struct octeon_gpio_softc {
device_t dev; device_t dev;
device_t busdev;
struct mtx gpio_mtx; struct mtx gpio_mtx;
struct resource *gpio_irq_res[OCTEON_GPIO_IRQS]; struct resource *gpio_irq_res[OCTEON_GPIO_IRQS];
int gpio_irq_rid[OCTEON_GPIO_IRQS]; int gpio_irq_rid[OCTEON_GPIO_IRQS];

View File

@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <mips/rt305x/rt305x_gpio.h> #include <mips/rt305x/rt305x_gpio.h>
#include <mips/rt305x/rt305x_gpiovar.h> #include <mips/rt305x/rt305x_gpiovar.h>
#include <mips/rt305x/rt305x_sysctlvar.h> #include <mips/rt305x/rt305x_sysctlvar.h>
#include <dev/gpio/gpiobusvar.h>
#include "gpio_if.h" #include "gpio_if.h"
@ -84,6 +85,7 @@ void rt305x_set_int_status(device_t, uint32_t);
/* /*
* GPIO interface * GPIO interface
*/ */
static device_t rt305x_gpio_get_bus(device_t);
static int rt305x_gpio_pin_max(device_t dev, int *maxpin); static int rt305x_gpio_pin_max(device_t dev, int *maxpin);
static int rt305x_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps); static int rt305x_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps);
static int rt305x_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t static int rt305x_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t
@ -157,6 +159,16 @@ rt305x_gpio_pin_configure(struct rt305x_gpio_softc *sc, struct gpio_pin *pin,
GPIO_UNLOCK(sc); GPIO_UNLOCK(sc);
} }
static device_t
rt305x_gpio_get_bus(device_t dev)
{
struct rt305x_gpio_softc *sc;
sc = device_get_softc(dev);
return (sc->busdev);
}
static int static int
rt305x_gpio_pin_max(device_t dev, int *maxpin) rt305x_gpio_pin_max(device_t dev, int *maxpin)
{ {
@ -501,11 +513,13 @@ rt305x_gpio_attach(device_t dev)
device_printf(dev, "\tUse reset_gpio %d\n", sc->reset_gpio); device_printf(dev, "\tUse reset_gpio %d\n", sc->reset_gpio);
} }
#endif #endif
sc->busdev = gpiobus_attach_bus(dev);
if (sc->busdev == NULL) {
rt305x_gpio_detach(dev);
return (ENXIO);
}
device_add_child(dev, "gpioc", -1); return (0);
device_add_child(dev, "gpiobus", -1);
return (bus_generic_attach(dev));
} }
static int static int
@ -515,7 +529,7 @@ rt305x_gpio_detach(device_t dev)
KASSERT(mtx_initialized(&sc->gpio_mtx), ("gpio mutex not initialized")); KASSERT(mtx_initialized(&sc->gpio_mtx), ("gpio mutex not initialized"));
bus_generic_detach(dev); gpiobus_detach_bus(dev);
if (sc->gpio_ih) if (sc->gpio_ih)
bus_teardown_intr(dev, sc->gpio_irq_res, sc->gpio_ih); bus_teardown_intr(dev, sc->gpio_irq_res, sc->gpio_ih);
if (sc->gpio_irq_res) if (sc->gpio_irq_res)
@ -589,6 +603,7 @@ static device_method_t rt305x_gpio_methods[] = {
DEVMETHOD(device_detach, rt305x_gpio_detach), DEVMETHOD(device_detach, rt305x_gpio_detach),
/* GPIO protocol */ /* GPIO protocol */
DEVMETHOD(gpio_get_bus, rt305x_gpio_get_bus),
DEVMETHOD(gpio_pin_max, rt305x_gpio_pin_max), DEVMETHOD(gpio_pin_max, rt305x_gpio_pin_max),
DEVMETHOD(gpio_pin_getname, rt305x_gpio_pin_getname), DEVMETHOD(gpio_pin_getname, rt305x_gpio_pin_getname),
DEVMETHOD(gpio_pin_getflags, rt305x_gpio_pin_getflags), DEVMETHOD(gpio_pin_getflags, rt305x_gpio_pin_getflags),

View File

@ -30,6 +30,7 @@
struct rt305x_gpio_softc { struct rt305x_gpio_softc {
device_t dev; device_t dev;
device_t busdev;
struct mtx gpio_mtx; struct mtx gpio_mtx;
struct resource *gpio_mem_res; struct resource *gpio_mem_res;
int gpio_mem_rid; int gpio_mem_rid;