From patchwork Mon Mar 9 13:59:02 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 45538 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 36691214BF for ; Mon, 9 Mar 2015 13:59:09 +0000 (UTC) Received: by labhs14 with SMTP id hs14sf38762820lab.0 for ; Mon, 09 Mar 2015 06:59:08 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:mime-version:in-reply-to:references :date:message-id:subject:from:to:cc:content-type:sender:precedence :list-id:x-original-sender:x-original-authentication-results :mailing-list:list-post:list-help:list-archive:list-unsubscribe; bh=fXdMtECOTJkuKiQcdJ6SazV9SX23TFqtepE/aSafGJw=; b=R+JpbWW7iYg9anUOqXuntQjx9yjCunoFNgwQtt1ow4D76lBNZ489Uo6kEqjGQCgYi5 wFgs9liXh+4ZnWoNWfwhb8pyQqwdG2ZE4FqUP0b7KLQM3f68oJoXL91HKrYSNPY5afy/ /AXcEVLJTu9sPNZzZVeF4eXmrUi5W3vr7DDfEvdxE6qhLYe7vOsCfJQzuCXSqaY5GhjS V7+dV22PHx8WYc1BiM0w0e+f1ME3b0XIjBgqfpn7gLPCfMFhIJqXFV7baxcJ5guKLnum TKZOAcbVSmNkKdY1yCv3ChY4qm9Y+pHlfOZEoyoq/SzwRWd3oZrL+Efm7gURzzBIwZr1 hOBw== X-Gm-Message-State: ALoCoQnuXJ8PCyr+NCmpv9LVxBEEIkaw5yAQHVeGm/LAr2AsQ5nLautqnA9zLVFNV0jiUBEzU98T X-Received: by 10.112.9.65 with SMTP id x1mr4029169lba.16.1425909548092; Mon, 09 Mar 2015 06:59:08 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.179.4 with SMTP id dc4ls310341lac.73.gmail; Mon, 09 Mar 2015 06:59:07 -0700 (PDT) X-Received: by 10.152.7.212 with SMTP id l20mr14324964laa.68.1425909547944; Mon, 09 Mar 2015 06:59:07 -0700 (PDT) Received: from mail-la0-f49.google.com (mail-la0-f49.google.com. [209.85.215.49]) by mx.google.com with ESMTPS id aw3si12198972lbc.140.2015.03.09.06.59.07 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 09 Mar 2015 06:59:07 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.49 as permitted sender) client-ip=209.85.215.49; Received: by labhs14 with SMTP id hs14so71111696lab.4 for ; Mon, 09 Mar 2015 06:59:07 -0700 (PDT) X-Received: by 10.152.26.201 with SMTP id n9mr25606793lag.29.1425909547645; Mon, 09 Mar 2015 06:59:07 -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.35.133 with SMTP id h5csp1498500lbj; Mon, 9 Mar 2015 06:59:06 -0700 (PDT) X-Received: by 10.66.146.100 with SMTP id tb4mr21049576pab.104.1425909545122; Mon, 09 Mar 2015 06:59:05 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a1si9015497pdb.148.2015.03.09.06.59.04 for ; Mon, 09 Mar 2015 06:59:05 -0700 (PDT) Received-SPF: none (google.com: linux-gpio-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753580AbbCIN7D (ORCPT ); Mon, 9 Mar 2015 09:59:03 -0400 Received: from mail-oi0-f45.google.com ([209.85.218.45]:37870 "EHLO mail-oi0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753857AbbCIN7C (ORCPT ); Mon, 9 Mar 2015 09:59:02 -0400 Received: by oigi138 with SMTP id i138so29331646oig.4 for ; Mon, 09 Mar 2015 06:59:02 -0700 (PDT) MIME-Version: 1.0 X-Received: by 10.202.79.23 with SMTP id d23mr20375324oib.45.1425909542169; Mon, 09 Mar 2015 06:59:02 -0700 (PDT) Received: by 10.182.132.45 with HTTP; Mon, 9 Mar 2015 06:59:02 -0700 (PDT) In-Reply-To: <1425372461-17859-1-git-send-email-abrodkin@synopsys.com> References: <1425372461-17859-1-git-send-email-abrodkin@synopsys.com> Date: Mon, 9 Mar 2015 14:59:02 +0100 Message-ID: Subject: Re: [PATCH] gpio-dwapb: reset mask register on probe From: Linus Walleij To: Alexey Brodkin Cc: "linux-gpio@vger.kernel.org" , "linux-kernel@vger.kernel.org" , Vineet Gupta , Alexandre Courbot Sender: linux-gpio-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-gpio@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: linus.walleij@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.215.49 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 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , On Tue, Mar 3, 2015 at 9:47 AM, Alexey Brodkin wrote: > It's possible that boot-loader that worked on CPU before Linux kernel > made some changes in GPIO controller registers. For example interrupts > could be all masked. > > Current implementation of DW GPIO driver relies on default values in > mask register. > > This is especially problematic in this DW GPIO driver because it sets 2 > pairs of methods: .irq_eable/.irq_disable and .irq_mask/.irq_unmask. In > this case generic "irq_enable" function will use only > .irq_enable call-back and mask register will be never modified so > required interrupts will be finally unmasked. > > To troubleshoot described problem on driver probe we just need to make > sure mask register is zeroed. > > Signed-off-by: Alexey Brodkin > Cc: Vineet Gupta > Cc: Linus Walleij > Cc: Alexandre Courbot Wait. > +++ b/drivers/gpio/gpio-dwapb.c > @@ -370,6 +370,9 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio, > irq_create_mapping(gpio->domain, hwirq); > > port->bgc.gc.to_irq = dwapb_gpio_to_irq; > + > + /* Reset mask register */ > + dwapb_write(gpio, GPIO_INTMASK, 0); I don't get this. This looks like you just enable all interrupts. The driver also contains this in .suspend(): /* Mask out interrupts */ dwapb_write(gpio, GPIO_INTMASK, 0xffffffff); If *anything* the probe should *mask* all interrupts so that the .unmask() callback can enable them selectively. The real problem I think is that struct irq_chip contains mask()/unmask() callbacks that are not implemented by this driver. Can you please test the below (untested) patch instead: From: Linus Walleij Date: Mon, 9 Mar 2015 14:56:18 +0100 Subject: [PATCH] RFC: gpio: dwapb: handle mask/unmask properly This implements the callbacks for masking/unmasking IRQs in the special IRQ mask/unmask register of the DWAPB GPIO block. Previously these mask bits were unhandled and relied on boot-up defaults. Reported-by: Alexey Brodkin Signed-off-by: Linus Walleij --- drivers/gpio/gpio-dwapb.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d); @@ -302,6 +326,10 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio, struct irq_chip_type *ct; int err, i; + /* Mask out and disable all interrupts */ + dwapb_write(gpio, GPIO_INTMASK, 0xffffffff); + dwapb_write(gpio, GPIO_INTEN, 0); + gpio->domain = irq_domain_add_linear(node, ngpio, &irq_generic_chip_ops, gpio); if (!gpio->domain) @@ -334,6 +362,8 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio, ct->chip.irq_mask = irq_gc_mask_set_bit; ct->chip.irq_unmask = irq_gc_mask_clr_bit; ct->chip.irq_set_type = dwapb_irq_set_type; + ct->chip.irq_mask = dwapb_irq_mask; + ct->chip.irq_unmask = dwapb_irq_unmask; ct->chip.irq_enable = dwapb_irq_enable; ct->chip.irq_disable = dwapb_irq_disable; ct->chip.irq_request_resources = dwapb_irq_reqres; diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c index 58faf04fce5d..1396f26bac5d 100644 --- a/drivers/gpio/gpio-dwapb.c +++ b/drivers/gpio/gpio-dwapb.c @@ -158,6 +158,30 @@ static void dwapb_irq_handler(u32 irq, struct irq_desc *desc) chip->irq_eoi(irq_desc_get_irq_data(desc)); } +static void dwapb_irq_mask(struct irq_data *d) +{ + struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d); + struct dwapb_gpio *gpio = igc->private; + + spin_lock_irqsave(&bgc->lock, flags); + val = dwapb_read(gpio, GPIO_INTMASK); + val |= BIT(d->hwirq); + dwapb_write(gpio, GPIO_INTMASK, val); + spin_unlock_irqrestore(&bgc->lock, flags); +} + +static void dwapb_irq_unmask(struct irq_data *d) +{ + struct irq_chip_generic *igc = irq_data_get_irq_chip_data(d); + struct dwapb_gpio *gpio = igc->private; + + spin_lock_irqsave(&bgc->lock, flags); + val = dwapb_read(gpio, GPIO_INTMASK); + val &= ~BIT(d->hwirq); + dwapb_write(gpio, GPIO_INTMASK, val); + spin_unlock_irqrestore(&bgc->lock, flags); +} + static void dwapb_irq_enable(struct irq_data *d) {