From owner-svn-src-head@FreeBSD.ORG Thu May 8 17:20:46 2014 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 3FCE8371; Thu, 8 May 2014 17:20:46 +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 205C8B2D; Thu, 8 May 2014 17:20:46 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s48HKjK2034673; Thu, 8 May 2014 17:20:45 GMT (envelope-from ian@svn.freebsd.org) Received: (from ian@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s48HKjCM034671; Thu, 8 May 2014 17:20:45 GMT (envelope-from ian@svn.freebsd.org) Message-Id: <201405081720.s48HKjCM034671@svn.freebsd.org> From: Ian Lepore Date: Thu, 8 May 2014 17:20:45 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r265690 - head/sys/arm/xilinx 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 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: Thu, 08 May 2014 17:20:46 -0000 Author: ian Date: Thu May 8 17:20:45 2014 New Revision: 265690 URL: http://svnweb.freebsd.org/changeset/base/265690 Log: Use edge-triggered interrupts rather than polling loops to avoid missing transitions of the INIT_B line. Also, release the mutex during uiomove(). Submitted by: Thomas Skibo Modified: head/sys/arm/xilinx/zy7_devcfg.c Modified: head/sys/arm/xilinx/zy7_devcfg.c ============================================================================== --- head/sys/arm/xilinx/zy7_devcfg.c Thu May 8 16:59:36 2014 (r265689) +++ head/sys/arm/xilinx/zy7_devcfg.c Thu May 8 17:20:45 2014 (r265690) @@ -267,24 +267,35 @@ zy7_devcfg_reset_pl(struct zy7_devcfg_so devcfg_ctl = RD4(sc, ZY7_DEVCFG_CTRL); + /* Clear sticky bits and set up INIT signal positive edge interrupt. */ + WR4(sc, ZY7_DEVCFG_INT_STATUS, ZY7_DEVCFG_INT_ALL); + WR4(sc, ZY7_DEVCFG_INT_MASK, ~ZY7_DEVCFG_INT_PCFG_INIT_PE); + /* Deassert PROG_B (active low). */ devcfg_ctl |= ZY7_DEVCFG_CTRL_PCFG_PROG_B; WR4(sc, ZY7_DEVCFG_CTRL, devcfg_ctl); - /* Wait for INIT_B deasserted (active low). */ - tries = 0; - while ((RD4(sc, ZY7_DEVCFG_STATUS) & - ZY7_DEVCFG_STATUS_PCFG_INIT) == 0) { - if (++tries >= 100) - return (EIO); - DELAY(5); + /* + * Wait for INIT to assert. If it is already asserted, we may not get + * an edge interrupt so cancel it and continue. + */ + if ((RD4(sc, ZY7_DEVCFG_STATUS) & + ZY7_DEVCFG_STATUS_PCFG_INIT) != 0) { + /* Already asserted. Cancel interrupt. */ + WR4(sc, ZY7_DEVCFG_INT_MASK, ~0); + } + else { + /* Wait for positive edge interrupt. */ + err = mtx_sleep(sc, &sc->sc_mtx, PCATCH, "zy7i1", hz); + if (err != 0) + return (err); } - - /* Reassert PROG_B. */ + + /* Reassert PROG_B (active low). */ devcfg_ctl &= ~ZY7_DEVCFG_CTRL_PCFG_PROG_B; WR4(sc, ZY7_DEVCFG_CTRL, devcfg_ctl); - /* Wait for INIT_B asserted. */ + /* Wait for INIT deasserted. This happens almost instantly. */ tries = 0; while ((RD4(sc, ZY7_DEVCFG_STATUS) & ZY7_DEVCFG_STATUS_PCFG_INIT) != 0) { @@ -293,7 +304,7 @@ zy7_devcfg_reset_pl(struct zy7_devcfg_so DELAY(5); } - /* Clear sticky bits and set up INIT_B positive edge interrupt. */ + /* Clear sticky bits and set up INIT positive edge interrupt. */ WR4(sc, ZY7_DEVCFG_INT_STATUS, ZY7_DEVCFG_INT_ALL); WR4(sc, ZY7_DEVCFG_INT_MASK, ~ZY7_DEVCFG_INT_PCFG_INIT_PE); @@ -301,11 +312,11 @@ zy7_devcfg_reset_pl(struct zy7_devcfg_so devcfg_ctl |= ZY7_DEVCFG_CTRL_PCFG_PROG_B; WR4(sc, ZY7_DEVCFG_CTRL, devcfg_ctl); - /* Wait for INIT_B deasserted indicating FPGA internal initialization - * is complete. This takes much longer than the previous waits for - * INIT_B transition (on the order of 700us). + /* + * Wait for INIT asserted indicating FPGA internal initialization + * is complete. */ - err = mtx_sleep(sc, &sc->sc_mtx, PCATCH, "zy7in", hz); + err = mtx_sleep(sc, &sc->sc_mtx, PCATCH, "zy7i2", hz); if (err != 0) return (err); @@ -404,7 +415,9 @@ zy7_devcfg_write(struct cdev *dev, struc /* uiomove the data from user buffer to our dma map. */ segsz = MIN(PAGE_SIZE, uio->uio_resid); + DEVCFG_SC_UNLOCK(sc); err = uiomove(dma_mem, segsz, uio); + DEVCFG_SC_LOCK(sc); if (err != 0) break;