Changeset View
Changeset View
Standalone View
Standalone View
sys/arm/arm/gic_fdt.c
Show First 20 Lines • Show All 123 Lines • ▼ Show 20 Lines | gic_fdt_probe(device_t dev) | ||||
device_set_desc(dev, "ARM Generic Interrupt Controller"); | device_set_desc(dev, "ARM Generic Interrupt Controller"); | ||||
return (BUS_PROBE_DEFAULT); | return (BUS_PROBE_DEFAULT); | ||||
} | } | ||||
static int | static int | ||||
gic_fdt_attach(device_t dev) | gic_fdt_attach(device_t dev) | ||||
{ | { | ||||
struct arm_gic_fdt_softc *sc = device_get_softc(dev); | struct arm_gic_fdt_softc *sc = device_get_softc(dev); | ||||
phandle_t pxref; | phandle_t pxref = ofw_bus_find_iparent(ofw_bus_get_node(dev)); | ||||
intptr_t xref; | intptr_t xref = OF_xref_from_node(ofw_bus_get_node(dev)); | ||||
int err; | int err; | ||||
sc->base.is_root = false; | |||||
/* | |||||
* Controller is root if: | |||||
* - doesn't have interrupt parent | |||||
* - his interrupt parent is this controller | |||||
*/ | |||||
if (pxref == 0 || xref == pxref) | |||||
sc->base.is_root = true; | |||||
sc->base.gic_bus = GIC_BUS_FDT; | sc->base.gic_bus = GIC_BUS_FDT; | ||||
err = arm_gic_attach(dev); | err = arm_gic_attach(dev); | ||||
if (err != 0) | if (err != 0) | ||||
return (err); | return (err); | ||||
xref = OF_xref_from_node(ofw_bus_get_node(dev)); | |||||
/* | /* | ||||
* Now, when everything is initialized, it's right time to | * Now, when everything is initialized, it's right time to | ||||
* register interrupt controller to interrupt framefork. | * register interrupt controller to interrupt framefork. | ||||
*/ | */ | ||||
if (intr_pic_register(dev, xref) == NULL) { | if (intr_pic_register(dev, xref) == NULL) { | ||||
device_printf(dev, "could not register PIC\n"); | device_printf(dev, "could not register PIC\n"); | ||||
goto cleanup; | goto cleanup; | ||||
} | } | ||||
/* | if (sc->base.is_root) { | ||||
* Controller is root if: | |||||
* - doesn't have interrupt parent | |||||
* - his interrupt parent is this controller | |||||
*/ | |||||
pxref = ofw_bus_find_iparent(ofw_bus_get_node(dev)); | |||||
if (pxref == 0 || xref == pxref) { | |||||
if (intr_pic_claim_root(dev, xref, arm_gic_intr, sc, | if (intr_pic_claim_root(dev, xref, arm_gic_intr, sc, | ||||
GIC_LAST_SGI - GIC_FIRST_SGI + 1) != 0) { | GIC_LAST_SGI - GIC_FIRST_SGI + 1) != 0) { | ||||
device_printf(dev, "could not set PIC as a root\n"); | device_printf(dev, "could not set PIC as a root\n"); | ||||
intr_pic_deregister(dev, xref); | intr_pic_deregister(dev, xref); | ||||
goto cleanup; | goto cleanup; | ||||
} | } | ||||
} else { | } else { | ||||
if (sc->base.gic_res[2] == NULL) { | if (sc->base.gic_res[INTRNG_RES_IDX] == NULL) { | ||||
device_printf(dev, | device_printf(dev, | ||||
"not root PIC must have defined interrupt\n"); | "not root PIC must have defined interrupt\n"); | ||||
intr_pic_deregister(dev, xref); | intr_pic_deregister(dev, xref); | ||||
goto cleanup; | goto cleanup; | ||||
} | } | ||||
if (bus_setup_intr(dev, sc->base.gic_res[2], INTR_TYPE_CLK, | if (bus_setup_intr(dev, sc->base.gic_res[INTRNG_RES_IDX], INTR_TYPE_CLK, | ||||
arm_gic_intr, NULL, sc, &sc->base.gic_intrhand)) { | arm_gic_intr, NULL, sc, &sc->base.gic_intrhand)) { | ||||
device_printf(dev, "could not setup irq handler\n"); | device_printf(dev, "could not setup irq handler\n"); | ||||
intr_pic_deregister(dev, xref); | intr_pic_deregister(dev, xref); | ||||
goto cleanup; | goto cleanup; | ||||
} | } | ||||
} | } | ||||
OF_device_register_xref(xref, dev); | OF_device_register_xref(xref, dev); | ||||
Show All 12 Lines | |||||
} | } | ||||
static struct resource_list * | static struct resource_list * | ||||
gic_fdt_get_resource_list(device_t bus, device_t child) | gic_fdt_get_resource_list(device_t bus, device_t child) | ||||
{ | { | ||||
struct arm_gic_devinfo *di; | struct arm_gic_devinfo *di; | ||||
di = device_get_ivars(child); | di = device_get_ivars(child); | ||||
KASSERT(di != NULL, ("gic_fdt_get_resource_list: No devinfo")); | |||||
return (&di->rl); | return di ? (&di->rl) : (NULL); | ||||
} | } | ||||
static int | static int | ||||
arm_gic_fill_ranges(phandle_t node, struct arm_gic_fdt_softc *sc) | arm_gic_fill_ranges(phandle_t node, struct arm_gic_fdt_softc *sc) | ||||
{ | { | ||||
pcell_t host_cells; | pcell_t host_cells; | ||||
cell_t *base_ranges; | cell_t *base_ranges; | ||||
ssize_t nbase_ranges; | ssize_t nbase_ranges; | ||||
▲ Show 20 Lines • Show All 151 Lines • Show Last 20 Lines |