From owner-svn-src-all@FreeBSD.ORG Wed Dec 1 05:25:20 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2E8DA1065F43; Wed, 1 Dec 2010 05:24:30 +0000 (UTC) (envelope-from jmallett@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 1CBBE8FC19; Wed, 1 Dec 2010 05:24:30 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id oB15OUwG071154; Wed, 1 Dec 2010 05:24:30 GMT (envelope-from jmallett@svn.freebsd.org) Received: (from jmallett@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id oB15OTYD071153; Wed, 1 Dec 2010 05:24:29 GMT (envelope-from jmallett@svn.freebsd.org) Message-Id: <201012010524.oB15OTYD071153@svn.freebsd.org> From: Juli Mallett Date: Wed, 1 Dec 2010 05:24:29 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r216092 - head/sys/mips/cavium X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 01 Dec 2010 05:25:20 -0000 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 #include #include +#include #include #include @@ -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),