From owner-svn-src-head@FreeBSD.ORG Fri Feb 27 00:57:10 2015 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id C3222517; Fri, 27 Feb 2015 00:57:10 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A2A57322; Fri, 27 Feb 2015 00:57:10 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t1R0vA7U029330; Fri, 27 Feb 2015 00:57:10 GMT (envelope-from jchandra@FreeBSD.org) Received: (from jchandra@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t1R0v95Z029327; Fri, 27 Feb 2015 00:57:09 GMT (envelope-from jchandra@FreeBSD.org) Message-Id: <201502270057.t1R0v95Z029327@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: jchandra set sender to jchandra@FreeBSD.org using -f From: "Jayachandran C." Date: Fri, 27 Feb 2015 00:57:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r279341 - head/sys/mips/nlm X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 27 Feb 2015 00:57:10 -0000 Author: jchandra Date: Fri Feb 27 00:57:09 2015 New Revision: 279341 URL: https://svnweb.freebsd.org/changeset/base/279341 Log: Improve additional interrupt ACK for Broadcom XLP Handling some interrupts in XLP (like PCIe and SATA) involves writing to vendor specific registers as part of interrupt acknowledgement. This was earlier done with xlp_establish_intr(), but a better solution is to provide a function xlp_set_bus_ack() that can be used with cpu_establish_hardintr(). This will allow platform initialization code to setup these ACKs without changing the standrard drivers. Modified: head/sys/mips/nlm/interrupt.h head/sys/mips/nlm/intr_machdep.c head/sys/mips/nlm/xlp_pci.c Modified: head/sys/mips/nlm/interrupt.h ============================================================================== --- head/sys/mips/nlm/interrupt.h Fri Feb 27 00:54:53 2015 (r279340) +++ head/sys/mips/nlm/interrupt.h Fri Feb 27 00:57:09 2015 (r279341) @@ -68,9 +68,7 @@ * XLR needs custom pre and post handlers for PCI/PCI-e interrupts * XXX: maybe follow i386 intsrc model */ -void xlp_establish_intr(const char *name, driver_filter_t filt, - driver_intr_t handler, void *arg, int irq, int flags, - void **cookiep, void (*busack)(int)); void xlp_enable_irq(int irq); +void xlp_set_bus_ack(int irq, void (*ack)(int, void *), void *arg); #endif /* _RMI_INTERRUPT_H_ */ Modified: head/sys/mips/nlm/intr_machdep.c ============================================================================== --- head/sys/mips/nlm/intr_machdep.c Fri Feb 27 00:54:53 2015 (r279340) +++ head/sys/mips/nlm/intr_machdep.c Fri Feb 27 00:57:09 2015 (r279341) @@ -58,7 +58,8 @@ __FBSDID("$FreeBSD$"); #include struct xlp_intrsrc { - void (*busack)(int); /* Additional ack */ + void (*bus_ack)(int, void *); /* Additional ack */ + void *bus_ack_arg; /* arg for additional ack */ struct intr_event *ie; /* event corresponding to intr */ int irq; int irt; @@ -119,23 +120,13 @@ cpu_establish_softintr(const char *name, panic("Soft interrupts unsupported!\n"); } -void -cpu_establish_hardintr(const char *name, driver_filter_t * filt, - void (*handler) (void *), void *arg, int irq, int flags, - void **cookiep) -{ - - xlp_establish_intr(name, filt, handler, arg, irq, flags, - cookiep, NULL); -} - static void xlp_post_filter(void *source) { struct xlp_intrsrc *src = source; - if (src->busack) - src->busack(src->irq); + if (src->bus_ack) + src->bus_ack(src->irq, src->bus_ack_arg); nlm_pic_ack(xlp_pic_base, src->irt); } @@ -144,8 +135,8 @@ xlp_pre_ithread(void *source) { struct xlp_intrsrc *src = source; - if (src->busack) - src->busack(src->irq); + if (src->bus_ack) + src->bus_ack(src->irq, src->bus_ack_arg); } static void @@ -157,19 +148,35 @@ xlp_post_ithread(void *source) } void -xlp_establish_intr(const char *name, driver_filter_t filt, - driver_intr_t handler, void *arg, int irq, int flags, - void **cookiep, void (*busack)(int)) +xlp_set_bus_ack(int irq, void (*ack)(int, void *), void *arg) +{ + struct xlp_intrsrc *src; + + KASSERT(irq > 0 && irq <= XLR_MAX_INTR, + ("%s called for bad hard intr %d", __func__, irq)); + + /* no locking needed - this will called early in boot */ + src = &xlp_interrupts[irq]; + KASSERT(src->ie != NULL, + ("%s called after IRQ enable for %d.", __func__, irq)); + src->bus_ack_arg = arg; + src->bus_ack = ack; +} + +void +cpu_establish_hardintr(const char *name, driver_filter_t * filt, + void (*handler) (void *), void *arg, int irq, int flags, + void **cookiep) { struct intr_event *ie; /* descriptor for the IRQ */ struct xlp_intrsrc *src = NULL; int errcode; - if (irq < 0 || irq > XLR_MAX_INTR) - panic("%s called for unknown hard intr %d", __func__, irq); + KASSERT(irq > 0 && irq <= XLR_MAX_INTR , + ("%s called for bad hard intr %d", __func__, irq)); /* - * FIXME locking - not needed now, because we do this only on + * Locking - not needed now, because we do this only on * startup from CPU0 */ src = &xlp_interrupts[irq]; @@ -194,7 +201,6 @@ xlp_establish_intr(const char *name, dri return; } src->irq = irq; - src->busack = busack; src->ie = ie; } if (XLP_IRQ_IS_PICINTR(irq)) { Modified: head/sys/mips/nlm/xlp_pci.c ============================================================================== --- head/sys/mips/nlm/xlp_pci.c Fri Feb 27 00:54:53 2015 (r279340) +++ head/sys/mips/nlm/xlp_pci.c Fri Feb 27 00:57:09 2015 (r279341) @@ -561,7 +561,7 @@ xlp_map_msi(device_t pcib, device_t dev, } static void -bridge_pcie_ack(int irq) +bridge_pcie_ack(int irq, void *arg) { uint32_t node,reg; uint64_t base; @@ -597,7 +597,6 @@ mips_platform_pcib_setup_intr(device_t d { int error = 0; int xlpirq; - void *extra_ack; error = rman_activate_resource(irq); if (error) @@ -656,12 +655,11 @@ mips_platform_pcib_setup_intr(device_t d xlpirq = PIC_PCIE_IRQ(link); } - if (xlpirq >= PIC_PCIE_0_IRQ && xlpirq <= PIC_PCIE_3_IRQ) - extra_ack = bridge_pcie_ack; - else - extra_ack = NULL; - xlp_establish_intr(device_get_name(child), filt, - intr, arg, xlpirq, flags, cookiep, extra_ack); + /* if it is for real PCIe, we need to ack at bridge too */ + if (xlpirq >= PIC_PCIE_IRQ(0) && xlpirq <= PIC_PCIE_IRQ(3)) + xlp_set_bus_ack(xlpirq, bridge_pcie_ack, NULL); + cpu_establish_hardintr(device_get_name(child), filt, intr, arg, + xlpirq, flags, cookiep); return (0); }