From patchwork Fri Sep 12 13:23:34 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 37319 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f71.google.com (mail-la0-f71.google.com [209.85.215.71]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 27E3D203EE for ; Fri, 12 Sep 2014 13:35:39 +0000 (UTC) Received: by mail-la0-f71.google.com with SMTP id mc6sf490872lab.6 for ; Fri, 12 Sep 2014 06:35:38 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:date :message-id:in-reply-to:references:subject:precedence:list-id :list-unsubscribe:list-archive:list-post:list-help:list-subscribe :errors-to:sender:x-original-sender :x-original-authentication-results:mailing-list; bh=s/5zUuDwcfHuNs9d0wGsD0t1CLqWTZqwg0zPTyp9rBg=; b=UDajM2SU9BZpVkapJPmk7ZMWgZo25vQZbFiQJSyLT9cB0BlBU0itEQPLqq6Wj3s7aM 3BSHp2ZC+lEHGyIr416TkYULPfLYXsTFPkyOQsZ0SHze/x7mI4w7z3Zhk8tAYvqHpWVi f3HN3JcAAQuJj+g0TlBPhKwQUlgkHeYKMHsgqcLp0d2tpZkrzUorK13h89Z/bIifqYnv bDCRkWlNBBY8Yhp2AZg6xicFzr7IZgWvaee72UEJAe+qVDPOzADVArdJ3IsQoEh9yMFx LWJ9ovZr6iSC0l4ljHuQMbwXo1nrKC7vHnW/mqPKj0I6kuY1e8k/pEhk/rtmqUHx7E15 4ZGw== X-Gm-Message-State: ALoCoQmMdn3Ag1dk6O0c8wOF1YsZZ1/5quxTYGPdif05mx9WzEPMU3XsXP55Kqb+XPPlKxiRGPkK X-Received: by 10.180.81.226 with SMTP id d2mr661382wiy.5.1410528937921; Fri, 12 Sep 2014 06:35:37 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.25.134 with SMTP id c6ls158459lag.37.gmail; Fri, 12 Sep 2014 06:35:37 -0700 (PDT) X-Received: by 10.112.60.33 with SMTP id e1mr8437964lbr.36.1410528937645; Fri, 12 Sep 2014 06:35:37 -0700 (PDT) Received: from mail-lb0-f176.google.com (mail-lb0-f176.google.com [209.85.217.176]) by mx.google.com with ESMTPS id lk1si6656817lac.4.2014.09.12.06.35.37 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 12 Sep 2014 06:35:37 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.176 as permitted sender) client-ip=209.85.217.176; Received: by mail-lb0-f176.google.com with SMTP id z11so921215lbi.35 for ; Fri, 12 Sep 2014 06:35:37 -0700 (PDT) X-Received: by 10.112.62.200 with SMTP id a8mr8558171lbs.34.1410528937537; Fri, 12 Sep 2014 06:35:37 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.141.42 with SMTP id rl10csp732709lbb; Fri, 12 Sep 2014 06:35:36 -0700 (PDT) X-Received: by 10.229.212.66 with SMTP id gr2mr11953609qcb.27.1410528936244; Fri, 12 Sep 2014 06:35:36 -0700 (PDT) Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id p34si5586718qga.126.2014.09.12.06.35.35 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Fri, 12 Sep 2014 06:35:36 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Received: from localhost ([::1]:45026 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XSR0h-0002Xv-BG for patch@linaro.org; Fri, 12 Sep 2014 09:35:35 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57011) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XSQpb-0006q7-CV for qemu-devel@nongnu.org; Fri, 12 Sep 2014 09:24:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XSQpT-00040I-4B for qemu-devel@nongnu.org; Fri, 12 Sep 2014 09:24:07 -0400 Received: from mnementh.archaic.org.uk ([81.2.115.146]:46961) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XSQpS-0003xi-SO for qemu-devel@nongnu.org; Fri, 12 Sep 2014 09:23:59 -0400 Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1XSQpO-0003X8-HO for qemu-devel@nongnu.org; Fri, 12 Sep 2014 14:23:54 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 12 Sep 2014 14:23:34 +0100 Message-Id: <1410528234-13545-4-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1410528234-13545-1-git-send-email-peter.maydell@linaro.org> References: <1410528234-13545-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 81.2.115.146 Subject: [Qemu-devel] [PULL 03/23] pl061: implement input interrupt logic X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: peter.maydell@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.176 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 From: Colin Leitner This patch adds the missing input interrupt logic to the pl061 GPIO device. To keep the floating output pins to stay high, the old state variable had to be split into two separate ones for input and output - which brings the vmstate version to 3. Edge level interrupts and I/O were tested under Linux 3.14. Level interrupt handling hasn't been tested. Signed-off-by: Colin Leitner Message-id: 54024FD2.9080204@gmail.com Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/gpio/pl061.c | 59 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c index dd4ea29..bd03e99 100644 --- a/hw/gpio/pl061.c +++ b/hw/gpio/pl061.c @@ -37,7 +37,8 @@ typedef struct PL061State { MemoryRegion iomem; uint32_t locked; uint32_t data; - uint32_t old_data; + uint32_t old_out_data; + uint32_t old_in_data; uint32_t dir; uint32_t isense; uint32_t ibe; @@ -63,12 +64,13 @@ typedef struct PL061State { static const VMStateDescription vmstate_pl061 = { .name = "pl061", - .version_id = 2, - .minimum_version_id = 1, + .version_id = 3, + .minimum_version_id = 3, .fields = (VMStateField[]) { VMSTATE_UINT32(locked, PL061State), VMSTATE_UINT32(data, PL061State), - VMSTATE_UINT32(old_data, PL061State), + VMSTATE_UINT32(old_out_data, PL061State), + VMSTATE_UINT32(old_in_data, PL061State), VMSTATE_UINT32(dir, PL061State), VMSTATE_UINT32(isense, PL061State), VMSTATE_UINT32(ibe, PL061State), @@ -98,23 +100,52 @@ static void pl061_update(PL061State *s) uint8_t out; int i; + DPRINTF("dir = %d, data = %d\n", s->dir, s->data); + /* Outputs float high. */ /* FIXME: This is board dependent. */ out = (s->data & s->dir) | ~s->dir; - changed = s->old_data ^ out; - if (!changed) - return; + changed = s->old_out_data ^ out; + if (changed) { + s->old_out_data = out; + for (i = 0; i < 8; i++) { + mask = 1 << i; + if (changed & mask) { + DPRINTF("Set output %d = %d\n", i, (out & mask) != 0); + qemu_set_irq(s->out[i], (out & mask) != 0); + } + } + } - s->old_data = out; - for (i = 0; i < 8; i++) { - mask = 1 << i; - if (changed & mask) { - DPRINTF("Set output %d = %d\n", i, (out & mask) != 0); - qemu_set_irq(s->out[i], (out & mask) != 0); + /* Inputs */ + changed = (s->old_in_data ^ s->data) & ~s->dir; + if (changed) { + s->old_in_data = s->data; + for (i = 0; i < 8; i++) { + mask = 1 << i; + if (changed & mask) { + DPRINTF("Changed input %d = %d\n", i, (s->data & mask) != 0); + + if (!(s->isense & mask)) { + /* Edge interrupt */ + if (s->ibe & mask) { + /* Any edge triggers the interrupt */ + s->istate |= mask; + } else { + /* Edge is selected by IEV */ + s->istate |= ~(s->data ^ s->iev) & mask; + } + } + } } } - /* FIXME: Implement input interrupts. */ + /* Level interrupt */ + s->istate |= ~(s->data ^ s->iev) & s->isense; + + DPRINTF("istate = %02X\n", s->istate); + + qemu_set_irq(s->irq, (s->istate & s->im) != 0); } static uint64_t pl061_read(void *opaque, hwaddr offset,