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: Douglas Anderson X-Patchwork-Id: 5528741 Return-Path: X-Original-To: patchwork-linux-rockchip@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id E3CFE9F1CD for ; Mon, 22 Dec 2014 18:48:03 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id F2F42201B9 for ; Mon, 22 Dec 2014 18:48:02 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 248BD201B4 for ; Mon, 22 Dec 2014 18:48:02 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Y381Q-0005zc-7V; Mon, 22 Dec 2014 18:48:00 +0000 Received: from mail-ie0-x22e.google.com ([2607:f8b0:4001:c03::22e]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Y381O-0005xI-R4 for linux-rockchip@lists.infradead.org; Mon, 22 Dec 2014 18:47:59 +0000 Received: by mail-ie0-f174.google.com with SMTP id at20so4662233iec.5 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=eC3U77ZSJIHPYCMt4EEasrIh51hMpfc4GUSrrOdk8jB3BxXA7yDB9rocfQPGBGvvJL 7tN3C1hA1b6uWKgXq4wnB45oZm3O6//usKPpTl1uwcTP1xon9TrmW0fuvoF46DDhpGy7 i1pUABTVHxWtUW5EhfEjwc5nS+d3E/No2TRI9GPo0c5QTNRj57vkqWN51U4t4Pgh31PS EjQ8KreNHlt51CHCpuqWupf1U6BoJ1Aw/tOiZzrNbEdX4en8LWnE9x78g2FOU9XqVyVz c167NrsClGZ5LnTW1NuSykrLGircWkKMrJsqOoYMC+62w9+JAgl1Oo1r4G/+u6mLDHHz uRBQ== X-Gm-Message-State: ALoCoQkD746CqEBvfxR+937NhP6LMHkDfsr4FWIu0L1Pc2Em6lvvVfFXIemKqT+EbSMuslmgvWy5 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 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 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20141222_104758_943238_0FCE64D8 X-CRM114-Status: GOOD ( 12.93 ) X-Spam-Score: -0.8 (/) Cc: Alexandru Stan , linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Doug Anderson , linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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);