From patchwork Mon Dec 22 18:47:29 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 423483 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id BD45F1400B7 for ; Tue, 23 Dec 2014 05:47:39 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754597AbaLVSri (ORCPT ); Mon, 22 Dec 2014 13:47:38 -0500 Received: from mail-ie0-f175.google.com ([209.85.223.175]:56908 "EHLO mail-ie0-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754295AbaLVSrh (ORCPT ); Mon, 22 Dec 2014 13:47:37 -0500 Received: by mail-ie0-f175.google.com with SMTP id x19so4836003ier.34 for ; Mon, 22 Dec 2014 10:47:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id; bh=M/kj16Wxa+lyijGtz+WZZfKITHGvPRla2OZkX+I9vpk=; b=lwrxmhqw1dfH+LX7UyHwY//BxniaP/k/5GfAJpJgU73djSgqMVwehCeJoTwp7NjrAa h5a0P9+QTHjaObYVjSV4yHGLl4VCep3q0KQe1B7h9NPhraSBH2lgkr158NydiAGz8EjG ABJIUNy447R8QsbuhEqyRcwdLlM3qMOjcLr+M= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=M/kj16Wxa+lyijGtz+WZZfKITHGvPRla2OZkX+I9vpk=; b=cK4UZq4vOWwvTbDp8M/TvAeGK5KodKO06EvZGzAdlPguDwywS8b7+FubCuBz1PCw+q x5d938U3vMmk5OqvnzjxzAPokceDkTzIPhwVSgPe4z1Ry8DRUo1vj6ERzZ3XgRxKWRiW elqUFoJ64/HyyZ15TWrSnK7mLnL9b+xa+0PBNjmCi4JlA4pgRrJfUL8AXnkopO6p9e+F MdQhLbAOVkjBgyk6PJ9adQ3e9GoBFNWpAdYhfengRyxD6+IDtztrYubJcEdlt7QOMhAR Pm0rUXRZ6DwsKLlV41ZcFWd0WAu7L3qqffAgV23gEFEdffpEQJxvVodfngZ5qqtXVKGm ZxEA== X-Gm-Message-State: ALoCoQkWPX7VgtoXOKHqCHYSB7Jhp/MBRl7/4YOG9Xqt1v2mYU50mYiglY+fMt4iqPm3CaYY+uKB X-Received: by 10.42.151.67 with SMTP id d3mr18624554icw.56.1419274057088; Mon, 22 Dec 2014 10:47:37 -0800 (PST) Received: from tictac.mtv.corp.google.com ([172.22.65.76]) by mx.google.com with ESMTPSA id uw1sm5222338igb.19.2014.12.22.10.47.35 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 22 Dec 2014 10:47:36 -0800 (PST) From: Doug Anderson To: Linus Walleij , Heiko Stuebner Cc: Alexandru Stan , linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org, Doug Anderson , linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] pinctrl: rockchip: Avoid losing interrupts when supporting both edges Date: Mon, 22 Dec 2014 10:47:29 -0800 Message-Id: <1419274049-5069-1-git-send-email-dianders@chromium.org> X-Mailer: git-send-email 2.2.0.rc0.207.ga3a616c Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org I was seeing cases where I was losing interrupts when inserting and removing SD cards. Sometimes the card would get "stuck" in the inserted state. I believe that the problem was related to the code to handle the case where we needed both rising and falling edges. This code would disable the interrupt as the polarity was switched. If an interrupt came at the wrong time it could be lost. We'll match what the gpio-dwapb.c driver does upstream and change the interrupt polarity without disabling things. Signed-off-by: Doug Anderson Reviewed-by: Heiko Stuebner Tested-by: Heiko Stuebner --- drivers/pinctrl/pinctrl-rockchip.c | 45 +++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 3c22dbe..43eacc9 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -1398,10 +1398,7 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) { struct irq_chip *chip = irq_get_chip(irq); struct rockchip_pin_bank *bank = irq_get_handler_data(irq); - u32 polarity = 0, data = 0; u32 pend; - bool edge_changed = false; - unsigned long flags; dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name); @@ -1409,12 +1406,6 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) pend = readl_relaxed(bank->reg_base + GPIO_INT_STATUS); - if (bank->toggle_edge_mode) { - polarity = readl_relaxed(bank->reg_base + - GPIO_INT_POLARITY); - data = readl_relaxed(bank->reg_base + GPIO_EXT_PORT); - } - while (pend) { unsigned int virq; @@ -1434,27 +1425,31 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) * needs manual intervention. */ if (bank->toggle_edge_mode & BIT(irq)) { - if (data & BIT(irq)) - polarity &= ~BIT(irq); - else - polarity |= BIT(irq); + u32 data, data_old, polarity; + unsigned long flags; - edge_changed = true; - } + data = readl_relaxed(bank->reg_base + GPIO_EXT_PORT); + do { + spin_lock_irqsave(&bank->slock, flags); - generic_handle_irq(virq); - } + polarity = readl_relaxed(bank->reg_base + + GPIO_INT_POLARITY); + if (data & BIT(irq)) + polarity &= ~BIT(irq); + else + polarity |= BIT(irq); + writel(polarity, + bank->reg_base + GPIO_INT_POLARITY); - if (bank->toggle_edge_mode && edge_changed) { - /* Interrupt params should only be set with ints disabled */ - spin_lock_irqsave(&bank->slock, flags); + spin_unlock_irqrestore(&bank->slock, flags); - data = readl_relaxed(bank->reg_base + GPIO_INTEN); - writel_relaxed(0, bank->reg_base + GPIO_INTEN); - writel(polarity, bank->reg_base + GPIO_INT_POLARITY); - writel(data, bank->reg_base + GPIO_INTEN); + data_old = data; + data = readl_relaxed(bank->reg_base + + GPIO_EXT_PORT); + } while ((data & BIT(irq)) != (data_old & BIT(irq))); + } - spin_unlock_irqrestore(&bank->slock, flags); + generic_handle_irq(virq); } chained_irq_exit(chip, desc);