From patchwork Wed Feb 6 21:31:20 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 14643 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 825FF23E92 for ; Wed, 6 Feb 2013 21:31:40 +0000 (UTC) Received: from mail-ve0-f171.google.com (mail-ve0-f171.google.com [209.85.128.171]) by fiordland.canonical.com (Postfix) with ESMTP id F2F89A19180 for ; Wed, 6 Feb 2013 21:31:39 +0000 (UTC) Received: by mail-ve0-f171.google.com with SMTP id b10so1686959vea.30 for ; Wed, 06 Feb 2013 13:31:39 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:x-forwarded-to:x-forwarded-for:delivered-to:x-received :received-spf:from:to:cc:subject:date:message-id:x-mailer :mime-version:content-type:x-gm-message-state; bh=2hy+ksUnUQ6GftJ2k2Q1OuZC1GX0EtGqNxApcxPjazE=; b=ViwT6GIbm/HqIcPL+SyPh7brgUKbRuyW244y1zN9JOoLMdPSamYt9g3b9YtqzgmHXd IEr0UlUX65GZ1cnJJvd/4+unXPwQxIyW4enZM7UFKF/z1KQXcdc56SaO+bH7Jcd4wECN HG9EXn9wlG84yt7rzNZP9szoScCdj+/ftnRtjylOrgk9To0uUKY85gHusVVyftUV6F1m 3nSx6JOH4aVlzKqNGslFkPiMhCB9ByJ7nYuuFx0k27YAdWi4XbIz/USCOn1bAxghP55n dxvClfb3uJbMeaaIzTJih4mxhxdknrn6xRiv6pRNipqNNzjHYoZz6QnPQBPn4FSIuF+2 ENIg== X-Received: by 10.52.27.50 with SMTP id q18mr31036104vdg.20.1360186299470; Wed, 06 Feb 2013 13:31:39 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.58.252.8 with SMTP id zo8csp53270vec; Wed, 6 Feb 2013 13:31:38 -0800 (PST) X-Received: by 10.14.213.131 with SMTP id a3mr67942750eep.24.1360186297807; Wed, 06 Feb 2013 13:31:37 -0800 (PST) Received: from eu1sys200aog110.obsmtp.com (eu1sys200aog110.obsmtp.com [207.126.144.129]) by mx.google.com with SMTP id v1si3698141eel.250.2013.02.06.13.31.30 (version=TLSv1 cipher=RC4-SHA bits=128/128); Wed, 06 Feb 2013 13:31:37 -0800 (PST) Received-SPF: neutral (google.com: 207.126.144.129 is neither permitted nor denied by best guess record for domain of linus.walleij@stericsson.com) client-ip=207.126.144.129; Authentication-Results: mx.google.com; spf=neutral (google.com: 207.126.144.129 is neither permitted nor denied by best guess record for domain of linus.walleij@stericsson.com) smtp.mail=linus.walleij@stericsson.com Received: from beta.dmz-us.st.com ([167.4.1.35]) (using TLSv1) by eu1sys200aob110.postini.com ([207.126.147.11]) with SMTP ID DSNKURLLsoGMlTujv4zV9G6+RzuFCYa2fEv1@postini.com; Wed, 06 Feb 2013 21:31:37 UTC Received: from zeta.dmz-us.st.com (ns4.st.com [167.4.16.71]) by beta.dmz-us.st.com (STMicroelectronics) with ESMTP id 99C4E55; Wed, 6 Feb 2013 21:30:43 +0000 (GMT) Received: from relay1.stm.gmessaging.net (unknown [10.230.100.17]) by zeta.dmz-us.st.com (STMicroelectronics) with ESMTP id 4198979; Wed, 6 Feb 2013 15:37:45 +0000 (GMT) Received: from exdcvycastm004.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm004", Issuer "exdcvycastm004" (not verified)) by relay1.stm.gmessaging.net (Postfix) with ESMTPS id DBD1E24C07C; Wed, 6 Feb 2013 22:31:16 +0100 (CET) Received: from steludxu4075.lud.stericsson.com (10.230.100.153) by smtp.stericsson.com (10.230.100.2) with Microsoft SMTP Server (TLS) id 8.3.83.0; Wed, 6 Feb 2013 22:31:26 +0100 From: Linus Walleij To: Samuel Ortiz , Cc: Anmar Oueja , Linus Walleij , Lee Jones Subject: [PATCH] mfd: ab8500: actually handle the AB8500 GPIO IRQs correctly Date: Wed, 6 Feb 2013 22:31:20 +0100 Message-ID: <1360186280-6883-1-git-send-email-linus.walleij@stericsson.com> X-Mailer: git-send-email 1.7.11.3 MIME-Version: 1.0 X-Gm-Message-State: ALoCoQma7amFDWezG7LfzNVBbgj5KYixCshViFy0RLhqXZbGZ5mHMOXZjMN+YpGjsrdoyJVYdgQ5 The patch: "mfd: ab8500: prepare to handle AB8500 GPIO's IRQs correctly" altered the AB8500 IRQ mask/unmask functions such that they would handle masking on/off the falling edge IRQ if this was requested by the consumer. However the bit mask for hwirqs 43 and 44 was shifting the bit mask incorrectly, resulting in the wrong IRQ being mased/unmasked. Further while the patch would mask/unmask the correct line, when the interrupt actually came in, it would still be treated as a valid hwirq. The offsetting applied when masking/unmasking was not applied when handling the IRQ, i.e. the falling edge lines were not routed back to the rising edge lines. This fixes both cases. The end result has been tested with the SIM detect IRQ, GPIO12, hwirq 46 and 62. Cc: Samuel Ortiz Cc: Lee Jones Signed-off-by: Linus Walleij --- Sam, requesting an ACK for this as well. It goes on top of the previous series for the AB8500 GPIO IRQ business from Lee Jones, basically it repairs one of the patches in that series. --- drivers/mfd/ab8500-core.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index a0a3f72..f67106a 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -374,7 +374,8 @@ static void ab8500_irq_mask(struct irq_data *data) if (offset >= AB9540_INT_GPIO50R && offset <= AB9540_INT_GPIO54R) ab8500->mask[index + 1] |= mask; if (offset == AB8540_INT_GPIO43R || offset == AB8540_INT_GPIO44R) - ab8500->mask[index] |= (mask >> 1); + /* Here the falling IRQ is one bit lower */ + ab8500->mask[index] |= (mask << 1); } static void ab8500_irq_unmask(struct irq_data *data) @@ -390,17 +391,20 @@ static void ab8500_irq_unmask(struct irq_data *data) /* The AB8500 GPIOs have two interrupts each (rising & falling). */ if (type & IRQ_TYPE_EDGE_FALLING) { + pr_info("AB8500 IRQ: unmask falling IRQ %d, index %d, mask %08x\n", offset, index, mask); if (offset >= AB8500_INT_GPIO6R && offset <= AB8500_INT_GPIO41R) ab8500->mask[index + 2] &= ~mask; else if (offset >= AB9540_INT_GPIO50R && offset <= AB9540_INT_GPIO54R) ab8500->mask[index + 1] &= ~mask; else if (offset == AB8540_INT_GPIO43R || offset == AB8540_INT_GPIO44R) - ab8500->mask[index] &= ~(mask >> 1); + /* Here the falling IRQ is one bit lower */ + ab8500->mask[index] &= ~(mask << 1); else ab8500->mask[index] &= ~mask; - } else + } else { /* Satisfies the case where type is not set. */ ab8500->mask[index] &= ~mask; + } } static int ab8500_irq_set_type(struct irq_data *data, unsigned int type) @@ -440,6 +444,19 @@ static int ab8500_handle_hierarchical_line(struct ab8500 *ab8500, line = (i << 3) + int_bit; latch_val &= ~(1 << int_bit); + /* + * This handles the falling edge hwirqs from the GPIO + * lines. Route them back to the line registered for the + * rising IRQ, as this is merely a flag for the same IRQ + * in linux terms. + */ + if (line >= AB8500_INT_GPIO6F && line <= AB8500_INT_GPIO41F) + line -= 16; + if (line >= AB9540_INT_GPIO50F && line <= AB9540_INT_GPIO54F) + line -= 8; + if (line == AB8540_INT_GPIO43F || line == AB8540_INT_GPIO44F) + line += 1; + handle_nested_irq(ab8500->irq_base + line); } while (latch_val);