Author: jmallett
Date: Wed Dec  1 05:24:29 2010
New Revision: 216092
URL: http://svn.freebsd.org/changeset/base/216092

Log:
  Add interrupt describing and binding to CIU.

Modified:
  head/sys/mips/cavium/ciu.c

Modified: head/sys/mips/cavium/ciu.c
==============================================================================
--- head/sys/mips/cavium/ciu.c  Wed Dec  1 03:51:06 2010        (r216091)
+++ head/sys/mips/cavium/ciu.c  Wed Dec  1 05:24:29 2010        (r216092)
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/module.h>
 #include <sys/rman.h>
 #include <sys/malloc.h>
+#include <sys/smp.h>
 
 #include <machine/bus.h>
 #include <machine/intr_machdep.h>
@@ -80,13 +81,24 @@ static int          ciu_setup_intr(device_t, dev
                                       void *, void **);
 static int             ciu_teardown_intr(device_t, device_t,
                                          struct resource *, void *);
+static int             ciu_bind_intr(device_t, device_t, struct resource *,
+                                     int);
+static int             ciu_describe_intr(device_t, device_t,
+                                         struct resource *, void *,
+                                         const char *);
 static void            ciu_hinted_child(device_t, const char *, int);
 
 static void            ciu_en0_intr_mask(void *);
 static void            ciu_en0_intr_unmask(void *);
+#ifdef SMP
+static int             ciu_en0_intr_bind(void *, u_char);
+#endif
 
 static void            ciu_en1_intr_mask(void *);
 static void            ciu_en1_intr_unmask(void *);
+#ifdef SMP
+static int             ciu_en1_intr_bind(void *, u_char);
+#endif
 
 static int             ciu_intr(void *);
 
@@ -196,6 +208,7 @@ ciu_setup_intr(device_t bus, device_t ch
        struct intr_event *event, **eventp;
        void (*mask_func)(void *);
        void (*unmask_func)(void *);
+       int (*bind_func)(void *, u_char);
        mips_intrcnt_t intrcnt;
        int error;
        int irq;
@@ -206,16 +219,25 @@ ciu_setup_intr(device_t bus, device_t ch
                intrcnt = ciu_en0_intrcnt[irq - CIU_IRQ_EN0_BEGIN];
                mask_func = ciu_en0_intr_mask;
                unmask_func = ciu_en0_intr_unmask;
+#ifdef SMP
+               bind_func = ciu_en0_intr_bind;
+#endif
        } else {
                eventp = &ciu_en1_intr_events[irq - CIU_IRQ_EN1_BEGIN];
                intrcnt = ciu_en1_intrcnt[irq - CIU_IRQ_EN1_BEGIN];
                mask_func = ciu_en1_intr_mask;
                unmask_func = ciu_en1_intr_unmask;
+#ifdef SMP
+               bind_func = ciu_en1_intr_bind;
+#endif
        }
+#if !defined(SMP)
+       bind_func = NULL;
+#endif
 
        if ((event = *eventp) == NULL) {
                error = intr_event_create(eventp, (void *)(uintptr_t)irq, 0,
-                   irq, mask_func, unmask_func, NULL, NULL, "int%d", irq);
+                   irq, mask_func, unmask_func, NULL, bind_func, "int%d", irq);
                if (error != 0)
                        return (error);
 
@@ -245,6 +267,50 @@ ciu_teardown_intr(device_t bus, device_t
        return (0);
 }
 
+#ifdef SMP
+static int
+ciu_bind_intr(device_t bus, device_t child, struct resource *res, int cpu)
+{
+       struct intr_event *event;
+       int irq;
+       
+       irq = rman_get_start(res);
+       if (irq <= CIU_IRQ_EN0_END)
+               event = ciu_en0_intr_events[irq - CIU_IRQ_EN0_BEGIN];
+       else
+               event = ciu_en1_intr_events[irq - CIU_IRQ_EN1_BEGIN];
+
+       return (intr_event_bind(event, cpu));
+}
+#endif
+
+static int
+ciu_describe_intr(device_t bus, device_t child, struct resource *res,
+                 void *cookie, const char *descr)
+{
+       struct intr_event *event;
+       mips_intrcnt_t intrcnt;
+       int error;
+       int irq;
+       
+       irq = rman_get_start(res);
+       if (irq <= CIU_IRQ_EN0_END) {
+               event = ciu_en0_intr_events[irq - CIU_IRQ_EN0_BEGIN];
+               intrcnt = ciu_en0_intrcnt[irq - CIU_IRQ_EN0_BEGIN];
+       } else {
+               event = ciu_en1_intr_events[irq - CIU_IRQ_EN1_BEGIN];
+               intrcnt = ciu_en1_intrcnt[irq - CIU_IRQ_EN1_BEGIN];
+       }
+
+       error = intr_event_describe_handler(event, cookie, descr);
+       if (error != 0)
+               return (error);
+
+       mips_intrcnt_setname(intrcnt, event->ie_fullname);
+
+       return (0);
+}
+
 static void
 ciu_hinted_child(device_t bus, const char *dname, int dunit)
 {
@@ -275,6 +341,28 @@ ciu_en0_intr_unmask(void *arg)
        cvmx_write_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num()*2), mask);
 }
 
+#ifdef SMP
+static int
+ciu_en0_intr_bind(void *arg, u_char target)
+{
+       uint64_t mask;
+       int core;
+       int irq;
+
+       irq = (uintptr_t)arg;
+       CPU_FOREACH(core) {
+               mask = cvmx_read_csr(CVMX_CIU_INTX_EN0(core*2));
+               if (core == target)
+                       mask |= 1ull << (irq - CIU_IRQ_EN0_BEGIN);
+               else
+                       mask &= ~(1ull << (irq - CIU_IRQ_EN0_BEGIN));
+               cvmx_write_csr(CVMX_CIU_INTX_EN0(core*2), mask);
+       }
+
+       return (0);
+}
+#endif
+
 static void
 ciu_en1_intr_mask(void *arg)
 {
@@ -299,6 +387,28 @@ ciu_en1_intr_unmask(void *arg)
        cvmx_write_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num()*2), mask);
 }
 
+#ifdef SMP
+static int
+ciu_en1_intr_bind(void *arg, u_char target)
+{
+       uint64_t mask;
+       int core;
+       int irq;
+
+       irq = (uintptr_t)arg;
+       CPU_FOREACH(core) {
+               mask = cvmx_read_csr(CVMX_CIU_INTX_EN1(core*2));
+               if (core == target)
+                       mask |= 1ull << (irq - CIU_IRQ_EN1_BEGIN);
+               else
+                       mask &= ~(1ull << (irq - CIU_IRQ_EN1_BEGIN));
+               cvmx_write_csr(CVMX_CIU_INTX_EN1(core*2), mask);
+       }
+
+       return (0);
+}
+#endif
+
 static int
 ciu_intr(void *arg)
 {
@@ -358,6 +468,10 @@ static device_method_t ciu_methods[] = {
        DEVMETHOD(bus_activate_resource,bus_generic_activate_resource),
        DEVMETHOD(bus_setup_intr,       ciu_setup_intr),
        DEVMETHOD(bus_teardown_intr,    ciu_teardown_intr),
+#ifdef SMP
+       DEVMETHOD(bus_bind_intr,        ciu_bind_intr),
+#endif
+       DEVMETHOD(bus_describe_intr,    ciu_describe_intr),
 
        DEVMETHOD(bus_add_child,        bus_generic_add_child),
        DEVMETHOD(bus_hinted_child,     ciu_hinted_child),
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to