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