From patchwork Tue Apr 17 07:30:49 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 7885 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 460E823E4C for ; Tue, 17 Apr 2012 07:31:05 +0000 (UTC) Received: from mail-iy0-f180.google.com (mail-iy0-f180.google.com [209.85.210.180]) by fiordland.canonical.com (Postfix) with ESMTP id 0EF23A1877B for ; Tue, 17 Apr 2012 07:31:04 +0000 (UTC) Received: by mail-iy0-f180.google.com with SMTP id e36so11751811iag.11 for ; Tue, 17 Apr 2012 00:31:04 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:from:to:cc :subject:date:message-id:x-mailer:mime-version:content-type :x-gm-message-state; bh=wh4lAskbDpHJfDh6DtvE6ygfJjDT6/wszVya819A0uY=; b=dcyMVQmIgQtlJGieifI9KXNMKdjTeXe8HKPYMVT8RbbaEWbR+9yxkTJtK3P8weZHpd HQuH585LyQiEgWgG3agTCNMgysSM5Z4ATDiIsD+qIG3D4JUmY1e59WHewdUmVu14iC0F leEiJW/eDvSbLXtgdrhFjatkkyd7ItHVrVuzV1zWieiCayxwBe859dYXpL2z6zOSI5Cg ZPWIA3crSfNRMDEG+epXVs/6QbgqtCtHYYGwdqzn40OqDcatFOJcwp63WlbKzfi6uoQh uOQp/ag6tMeWv56M4zy2QC10iSvCgrCfISqaLi1/Uykv0kfSM4timRipqf7P1XVc0Q4W SiIg== Received: by 10.43.52.74 with SMTP id vl10mr9075861icb.55.1334647864752; Tue, 17 Apr 2012 00:31:04 -0700 (PDT) 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.231.137.198 with SMTP id x6csp130025ibt; Tue, 17 Apr 2012 00:31:03 -0700 (PDT) Received: by 10.213.10.69 with SMTP id o5mr1037870ebo.91.1334647862923; Tue, 17 Apr 2012 00:31:02 -0700 (PDT) Received: from eu1sys200aog111.obsmtp.com (eu1sys200aog111.obsmtp.com. [207.126.144.131]) by mx.google.com with SMTP id v8si5733305eem.10.2012.04.17.00.30.58 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 17 Apr 2012 00:31:02 -0700 (PDT) Received-SPF: neutral (google.com: 207.126.144.131 is neither permitted nor denied by best guess record for domain of linus.walleij@stericsson.com) client-ip=207.126.144.131; Authentication-Results: mx.google.com; spf=neutral (google.com: 207.126.144.131 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 eu1sys200aob111.postini.com ([207.126.147.11]) with SMTP ID DSNKT40cMu/ohTYi8rTVy+av4reyQ3iuiEdL@postini.com; Tue, 17 Apr 2012 07:31:02 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 71C9164; Tue, 17 Apr 2012 07:30:36 +0000 (GMT) Received: from relay2.stm.gmessaging.net (unknown [10.230.100.18]) by zeta.dmz-us.st.com (STMicroelectronics) with ESMTP id 784A975; Tue, 17 Apr 2012 05:26:14 +0000 (GMT) Received: from exdcvycastm022.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm022", Issuer "exdcvycastm022" (not verified)) by relay2.stm.gmessaging.net (Postfix) with ESMTPS id C1049A8065; Tue, 17 Apr 2012 09:30:48 +0200 (CEST) Received: from steludxu4075.lud.stericsson.com (10.230.100.153) by smtp.stericsson.com (10.230.100.30) with Microsoft SMTP Server (TLS) id 8.3.83.0; Tue, 17 Apr 2012 09:30:51 +0200 From: Linus Walleij To: Samuel Ortiz , Cc: Michel JAOUEN , Maxime Coquelin , Linus Walleij Subject: [PATCH 5/6] mfd/ab8500: support of hierachical interrupt Date: Tue, 17 Apr 2012 09:30:49 +0200 Message-ID: <1334647849-1773-1-git-send-email-linus.walleij@stericsson.com> X-Mailer: git-send-email 1.7.9.2 MIME-Version: 1.0 X-Gm-Message-State: ALoCoQkhviAp+r2OjmfwC3XuRL4YS92nyEIhJJ3T+fmktbzUW5EaVL36wPc/xHlDaqoXpL7r+qfy From: Michel JAOUEN Hierarchical interrupt is supported since ab8500 V2. However, it is not implemented in ab8500-core driver. With curent implementation, when an ab9540 interrupt occurs, 17 Latch registers are read through i2c. With hierarchical interrupt implementation, there is only 4 i2c accesses. Signed-off-by: Maxime Coquelin Tested-by: Michel Jaouen Signed-off-by: Linus Walleij --- drivers/mfd/ab8500-core.c | 85 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 3 deletions(-) diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 9781e1e..8e56fd1 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -91,6 +91,15 @@ #define AB8500_IT_MASK23_REG 0x56 #define AB8500_IT_MASK24_REG 0x57 +/* + * latch hierarchy registers + */ +#define AB8500_IT_LATCHHIER1_REG 0x60 +#define AB8500_IT_LATCHHIER2_REG 0x61 +#define AB8500_IT_LATCHHIER3_REG 0x62 + +#define AB8500_IT_LATCHHIER_NUM 3 + #define AB8500_REV_REG 0x80 #define AB8500_IC_NAME_REG 0x82 #define AB8500_SWITCH_OFF_STATUS 0x00 @@ -337,6 +346,67 @@ static struct irq_chip ab8500_irq_chip = { .irq_unmask = ab8500_irq_unmask, }; +static irqreturn_t ab8500_hierarchical_irq(int irq, void *dev) +{ + struct ab8500 *ab8500 = dev; + int i; + + dev_vdbg(ab8500->dev, "interrupt\n"); + + /* Hierarchical interrupt version */ + for (i = 0; i < AB8500_IT_LATCHHIER_NUM; i++) { + int status; + u8 hier_val; + + status = get_register_interruptible(ab8500, AB8500_INTERRUPT, + AB8500_IT_LATCHHIER1_REG + i, &hier_val); + if (status < 0 || hier_val == 0) + continue; + + do { + int latch_bit = __ffs(hier_val); + u8 offset = i * 8 + latch_bit; + u8 latch_val; + + /* Fix inconsistent ITFromLatch25 bit mapping... */ + if (unlikely(offset == 17)) + offset = 24; + + status = get_register_interruptible(ab8500, + AB8500_INTERRUPT, + AB8500_IT_LATCH1_REG + offset, + &latch_val); + if (status < 0 || latch_val == 0) + goto discard; + + do { + int int_bit = __ffs(latch_val); + int line; + int j; + + for (j = 0; j < ab8500->mask_size; j++) + if (ab8500->irq_reg_offset[j] == offset) + break; + + if (j >= ab8500->mask_size) { + dev_err(ab8500->dev, + "Register offset 0x%2x not declared\n", + offset); + return IRQ_HANDLED; + } + + line = j * 8 + int_bit; + + handle_nested_irq(ab8500->irq_base + line); + latch_val &= ~(1 << int_bit); + } while (latch_val); +discard: + hier_val &= ~(1 << latch_bit); + } while (hier_val); + } + return IRQ_HANDLED; +} + static irqreturn_t ab8500_irq(int irq, void *dev) { struct ab8500 *ab8500 = dev; @@ -1196,9 +1266,18 @@ int __devinit ab8500_init(struct ab8500 *ab8500, enum ab8500_version version) if (ret) goto out_freeoldmask; - ret = request_threaded_irq(ab8500->irq, NULL, ab8500_irq, - IRQF_ONESHOT | IRQF_NO_SUSPEND, - "ab8500", ab8500); + /* Activate this feature only in ab9540 */ + /* till tests are done on ab8500 1p2 or later*/ + if (is_ab9540(ab8500)) + ret = request_threaded_irq(ab8500->irq, NULL, + ab8500_hierarchical_irq, + IRQF_ONESHOT | IRQF_NO_SUSPEND, + "ab8500", ab8500); + else + ret = request_threaded_irq(ab8500->irq, NULL, + ab8500_irq, + IRQF_ONESHOT | IRQF_NO_SUSPEND, + "ab8500", ab8500); if (ret) goto out_removeirq; }