Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys FDT: Interrupts -- add support for interrupt maps
details: https://anonhg.NetBSD.org/src/rev/e25b90488511
branches: trunk
changeset: 812843:e25b90488511
user: marty <marty%NetBSD.org@localhost>
date: Tue Jan 05 21:53:48 2016 +0000
description:
FDT: Interrupts -- add support for interrupt maps
The mct on exynos uses an interrupt map so we add support now. Devices
represent their interrupts either through a combination of interrupt-parent
and interrupts properties, where the 'interrupts' property is an array of
one or more interrupt specifiers; or through a combination of an
interrupt-parent that points to an interrupt-map, where the interrupt-map
contains 2 or more entries consisting of an index, a pointer to an
interrupt-controller, and a specifier for that controller.
This code adds the ability to walk the interrupt-map and return a specifier.
Unfortunately, the addition requires changing the interface to the
interrupt-controllers' _establish and _intstr functions, so this check in
contains a rototill of the three existing fdt interrupt controllers to use
the new interface.
diffstat:
sys/arch/arm/fdt/gic_fdt.c | 85 ++-----------
sys/arch/arm/nvidia/tegra_lic.c | 79 +-----------
sys/arch/arm/samsung/exynos_combiner.c | 78 ++----------
sys/arch/arm/samsung/mct.c | 24 +--
sys/arch/evbarm/conf/EXYNOS | 5 +-
sys/dev/fdt/fdt_intr.c | 202 ++++++++++++++++++++++++++++++--
sys/dev/fdt/fdtvar.h | 6 +-
7 files changed, 240 insertions(+), 239 deletions(-)
diffs (truncated from 786 to 300 lines):
diff -r 6278ff48efc4 -r e25b90488511 sys/arch/arm/fdt/gic_fdt.c
--- a/sys/arch/arm/fdt/gic_fdt.c Tue Jan 05 18:44:34 2016 +0000
+++ b/sys/arch/arm/fdt/gic_fdt.c Tue Jan 05 21:53:48 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: gic_fdt.c,v 1.1 2015/12/13 17:45:37 jmcneill Exp $ */
+/* $NetBSD: gic_fdt.c,v 1.2 2016/01/05 21:53:48 marty Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gic_fdt.c,v 1.1 2015/12/13 17:45:37 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gic_fdt.c,v 1.2 2016/01/05 21:53:48 marty Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -44,10 +44,10 @@
static int gic_fdt_match(device_t, cfdata_t, void *);
static void gic_fdt_attach(device_t, device_t, void *);
-static void * gic_fdt_establish(device_t, int, u_int, int, int,
+static void * gic_fdt_establish(device_t, u_int *, int, int,
int (*)(void *), void *);
static void gic_fdt_disestablish(device_t, void *);
-static bool gic_fdt_intrstr(device_t, int, u_int, char *, size_t);
+static bool gic_fdt_intrstr(device_t, u_int *, char *, size_t);
struct fdtbus_interrupt_controller_func gic_fdt_funcs = {
.establish = gic_fdt_establish,
@@ -100,49 +100,21 @@
}
static void *
-gic_fdt_establish(device_t dev, int phandle, u_int index, int ipl, int flags,
+gic_fdt_establish(device_t dev, u_int *specifier, int ipl, int flags,
int (*func)(void *), void *arg)
{
- struct gic_fdt_softc * const sc = device_private(dev);
int iflags = (flags & FDT_INTR_MPSAFE) ? IST_MPSAFE : 0;
- u_int *interrupts;
- int interrupt_cells, len;
-
- len = OF_getprop(sc->sc_phandle, "#interrupt-cells", &interrupt_cells,
- sizeof(interrupt_cells));
- if (len != sizeof(interrupt_cells) || interrupt_cells <= 0)
- return NULL;
- interrupt_cells = be32toh(interrupt_cells);
-
- len = OF_getproplen(phandle, "interrupts");
- if (len <= 0)
- return NULL;
-
- const u_int clen = interrupt_cells * 4;
- const u_int nintr = len / interrupt_cells;
-
- if (index >= nintr)
- return NULL;
-
- interrupts = kmem_alloc(len, KM_SLEEP);
-
- if (OF_getprop(phandle, "interrupts", interrupts, len) != len) {
- kmem_free(interrupts, len);
- return NULL;
- }
/* 1st cell is the interrupt type; 0 is SPI, 1 is PPI */
/* 2nd cell is the interrupt number */
/* 3rd cell is flags */
- const u_int type = be32toh(interrupts[index * clen + 0]);
- const u_int intr = be32toh(interrupts[index * clen + 1]);
+ const u_int type = be32toh(specifier[0]);
+ const u_int intr = be32toh(specifier[1]);
const u_int irq = type == 0 ? IRQ_SPI(intr) : IRQ_PPI(intr);
- const u_int trig = be32toh(interrupts[index * clen + 2]) & 0xf;
+ const u_int trig = be32toh(specifier[2]) & 0xf;
const u_int level = (trig & 0x3) ? IST_EDGE : IST_LEVEL;
- kmem_free(interrupts, len);
-
return intr_establish(irq, ipl, level | iflags, func, arg);
}
@@ -153,49 +125,18 @@
}
static bool
-gic_fdt_intrstr(device_t dev, int phandle, u_int index, char *buf,
- size_t buflen)
+gic_fdt_intrstr(device_t dev, u_int *specifier, char *buf, size_t buflen)
{
- struct gic_fdt_softc * const sc = device_private(dev);
- u_int *interrupts;
- int interrupt_cells, len;
-
- len = OF_getprop(sc->sc_phandle, "#interrupt-cells", &interrupt_cells,
- sizeof(interrupt_cells));
- if (len != sizeof(interrupt_cells) || interrupt_cells <= 0) {
- return false;
- }
- interrupt_cells = be32toh(interrupt_cells);
-
- len = OF_getproplen(phandle, "interrupts");
- if (len <= 0) {
- return false;
- }
-
- const u_int clen = interrupt_cells * 4;
- const u_int nintr = len / interrupt_cells;
-
- if (index >= nintr) {
- return false;
- }
-
- interrupts = kmem_alloc(len, KM_SLEEP);
-
- if (OF_getprop(phandle, "interrupts", interrupts, len) != len) {
- kmem_free(interrupts, len);
- return false;
- }
-
/* 1st cell is the interrupt type; 0 is SPI, 1 is PPI */
/* 2nd cell is the interrupt number */
/* 3rd cell is flags */
- const u_int type = be32toh(interrupts[index * clen + 0]);
- const u_int intr = be32toh(interrupts[index * clen + 1]);
+ if (!specifier)
+ return false;
+ const u_int type = be32toh(specifier[0]);
+ const u_int intr = be32toh(specifier[1]);
const u_int irq = type == 0 ? IRQ_SPI(intr) : IRQ_PPI(intr);
- kmem_free(interrupts, len);
-
snprintf(buf, buflen, "GIC irq %d", irq);
return true;
diff -r 6278ff48efc4 -r e25b90488511 sys/arch/arm/nvidia/tegra_lic.c
--- a/sys/arch/arm/nvidia/tegra_lic.c Tue Jan 05 18:44:34 2016 +0000
+++ b/sys/arch/arm/nvidia/tegra_lic.c Tue Jan 05 21:53:48 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_lic.c,v 1.2 2015/12/16 19:46:55 jmcneill Exp $ */
+/* $NetBSD: tegra_lic.c,v 1.3 2016/01/05 21:53:48 marty Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_lic.c,v 1.2 2015/12/16 19:46:55 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_lic.c,v 1.3 2016/01/05 21:53:48 marty Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -47,10 +47,10 @@
static int tegra_lic_match(device_t, cfdata_t, void *);
static void tegra_lic_attach(device_t, device_t, void *);
-static void * tegra_lic_establish(device_t, int, u_int, int, int,
+static void * tegra_lic_establish(device_t, u_int *, int, int,
int (*)(void *), void *);
static void tegra_lic_disestablish(device_t, void *);
-static bool tegra_lic_intrstr(device_t, int, u_int, char *, size_t);
+static bool tegra_lic_intrstr(device_t, u_int *, char *, size_t);
struct fdtbus_interrupt_controller_func tegra_lic_funcs = {
.establish = tegra_lic_establish,
@@ -97,48 +97,21 @@
}
static void *
-tegra_lic_establish(device_t dev, int phandle, u_int index, int ipl, int flags,
+tegra_lic_establish(device_t dev, u_int *specifier, int ipl, int flags,
int (*func)(void *), void *arg)
{
- struct tegra_lic_softc * const sc = device_private(dev);
int iflags = (flags & FDT_INTR_MPSAFE) ? IST_MPSAFE : 0;
- u_int *interrupts;
- int interrupt_cells, len;
-
- if (of_getprop_uint32(sc->sc_phandle, "#interrupt-cells",
- &interrupt_cells)) {
- return NULL;
- }
-
- len = OF_getproplen(phandle, "interrupts");
- if (len <= 0)
- return NULL;
-
- const u_int clen = interrupt_cells * 4;
- const u_int nintr = len / interrupt_cells;
-
- if (index >= nintr)
- return NULL;
-
- interrupts = kmem_alloc(len, KM_SLEEP);
-
- if (OF_getprop(phandle, "interrupts", interrupts, len) != len) {
- kmem_free(interrupts, len);
- return NULL;
- }
/* 1st cell is the interrupt type; 0 is SPI, 1 is PPI */
/* 2nd cell is the interrupt number */
/* 3rd cell is flags */
- const u_int type = be32toh(interrupts[index * clen + 0]);
- const u_int intr = be32toh(interrupts[index * clen + 1]);
+ const u_int type = be32toh(specifier[0]);
+ const u_int intr = be32toh(specifier[1]);
const u_int irq = type == 0 ? IRQ_SPI(intr) : IRQ_PPI(intr);
- const u_int trig = be32toh(interrupts[index * clen + 2]) & 0xf;
+ const u_int trig = be32toh(specifier[2]) & 0xf;
const u_int level = (trig & 0x3) ? IST_EDGE : IST_LEVEL;
- kmem_free(interrupts, len);
-
return intr_establish(irq, ipl, level | iflags, func, arg);
}
@@ -149,47 +122,17 @@
}
static bool
-tegra_lic_intrstr(device_t dev, int phandle, u_int index, char *buf,
+tegra_lic_intrstr(device_t dev, u_int *specifier, char *buf,
size_t buflen)
{
- struct tegra_lic_softc * const sc = device_private(dev);
- u_int *interrupts;
- int interrupt_cells, len;
-
- if (of_getprop_uint32(sc->sc_phandle, "#interrupt-cells",
- &interrupt_cells)) {
- return false;
- }
-
- len = OF_getproplen(phandle, "interrupts");
- if (len <= 0) {
- return false;
- }
-
- const u_int clen = interrupt_cells * 4;
- const u_int nintr = len / interrupt_cells;
-
- if (index >= nintr) {
- return false;
- }
-
- interrupts = kmem_alloc(len, KM_SLEEP);
-
- if (OF_getprop(phandle, "interrupts", interrupts, len) != len) {
- kmem_free(interrupts, len);
- return false;
- }
-
/* 1st cell is the interrupt type; 0 is SPI, 1 is PPI */
/* 2nd cell is the interrupt number */
/* 3rd cell is flags */
- const u_int type = be32toh(interrupts[index * clen + 0]);
- const u_int intr = be32toh(interrupts[index * clen + 1]);
+ const u_int type = be32toh(specifier[0]);
+ const u_int intr = be32toh(specifier[1]);
const u_int irq = type == 0 ? IRQ_SPI(intr) : IRQ_PPI(intr);
- kmem_free(interrupts, len);
-
snprintf(buf, buflen, "LIC irq %d", irq);
return true;
diff -r 6278ff48efc4 -r e25b90488511 sys/arch/arm/samsung/exynos_combiner.c
--- a/sys/arch/arm/samsung/exynos_combiner.c Tue Jan 05 18:44:34 2016 +0000
+++ b/sys/arch/arm/samsung/exynos_combiner.c Tue Jan 05 21:53:48 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: exynos_combiner.c,v 1.5 2016/01/03 04:10:58 marty Exp $ */
+/* $NetBSD: exynos_combiner.c,v 1.6 2016/01/05 21:53:48 marty Exp $ */
/*-
* Copyright (c) 2015 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
#include "gpio.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: exynos_combiner.c,v 1.5 2016/01/03 04:10:58 marty Exp $");
+__KERNEL_RCSID(1, "$NetBSD: exynos_combiner.c,v 1.6 2016/01/05 21:53:48 marty Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -86,10 +86,11 @@
static int exynos_combiner_match(device_t, cfdata_t, void *);
static void exynos_combiner_attach(device_t, device_t, void *);
-static void * exynos_combiner_establish(device_t, int, u_int, int, int,
+static void * exynos_combiner_establish(device_t, u_int *, int, int,
int (*)(void *), void *);
Home |
Main Index |
Thread Index |
Old Index