svn commit: r216092 - head/sys/mips/cavium

Juli Mallett jmallett at FreeBSD.org
Wed Dec 1 05:25:20 UTC 2010


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),


More information about the svn-src-all mailing list