From patchwork Sun Nov 18 00:55:53 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Heiko_St=C3=BCbner?= X-Patchwork-Id: 1760151 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id BF56EDF2A2 for ; Sun, 18 Nov 2012 00:58:02 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TZtB8-0003GZ-Ff; Sun, 18 Nov 2012 00:56:06 +0000 Received: from gloria.sntech.de ([95.129.55.99]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1TZtAy-0003DA-HO for linux-arm-kernel@lists.infradead.org; Sun, 18 Nov 2012 00:55:58 +0000 Received: from 146-52-59-5-dynip.superkabel.de ([146.52.59.5] helo=marty.localnet) by gloria.sntech.de with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.72) (envelope-from ) id 1TZtAx-0006Nh-4m; Sun, 18 Nov 2012 01:55:55 +0100 From: Heiko =?utf-8?q?St=C3=BCbner?= To: Kukjin Kim Subject: [PATCH 07/10] ARM: S3C24XX: assimilate second s3c2416 interrupt into new structure Date: Sun, 18 Nov 2012 01:55:53 +0100 User-Agent: KMail/1.13.7 (Linux/3.2.0-3-686-pae; KDE/4.8.4; i686; ; ) References: <201211180151.01029.heiko@sntech.de> In-Reply-To: <201211180151.01029.heiko@sntech.de> MIME-Version: 1.0 Message-Id: <201211180155.53448.heiko@sntech.de> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20121117_195557_124594_78655F2A X-CRM114-Status: GOOD ( 19.13 ) X-Spam-Score: -2.6 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Ben Dooks X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org The interrupt ack,mask and unmask functions for the main interrupt register are also able to handle the second one of the s3c2416. Signed-off-by: Heiko Stuebner --- arch/arm/plat-s3c24xx/irq.c | 118 ++++++++++++++++--------------------------- 1 files changed, 43 insertions(+), 75 deletions(-) diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c index ace7e34..675a5f9 100644 --- a/arch/arm/plat-s3c24xx/irq.c +++ b/arch/arm/plat-s3c24xx/irq.c @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -54,6 +55,9 @@ /* s3c_irqext_chip + edge handler */ #define S3C_IRQTYPE_SUBEINT 6 +/* s3c2416_irq2_chip + edge handler */ +#define S3C_IRQTYPE_S3C2416 7 + struct s3c_irq_data { unsigned int type; unsigned long parent_irq; @@ -164,6 +168,13 @@ struct irq_chip s3c_irq_chip = { .irq_set_wake = s3c_irq_wake }; +struct irq_chip s3c2416_irq_second = { + .name = "s3c2416", + .irq_ack = s3c_irq_ack, + .irq_mask = s3c_irq_mask, + .irq_unmask = s3c_irq_unmask, +}; + static void s3c_irqext_ack(struct irq_data *data) { struct s3c_irq_intc *intc = data->domain->host_data; @@ -516,6 +527,11 @@ static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq, set_irq_flags(virq, IRQF_VALID); attach_to_parent = true; break; + case S3C_IRQTYPE_S3C2416: + irq_set_chip_and_handler(virq, &s3c2416_irq_second, + handle_edge_irq); + set_irq_flags(virq, IRQF_VALID); + break; default: pr_err("irq-s3c24xx: unsupported irqtype %d\n", irq_data->type); return -EINVAL; @@ -800,80 +816,6 @@ struct s3c_irq_data init_s3c2443base[32] = { #endif #ifdef CONFIG_CPU_S3C2416 - -/* second interrupt register */ - -static inline void s3c2416_irq_ack_second(struct irq_data *data) -{ - unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D); - - __raw_writel(bitval, S3C2416_SRCPND2); - __raw_writel(bitval, S3C2416_INTPND2); -} - -static void s3c2416_irq_mask_second(struct irq_data *data) -{ - unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D); - unsigned long mask; - - mask = __raw_readl(S3C2416_INTMSK2); - mask |= bitval; - __raw_writel(mask, S3C2416_INTMSK2); -} - -static void s3c2416_irq_unmask_second(struct irq_data *data) -{ - unsigned long bitval = 1UL << (data->irq - IRQ_S3C2416_2D); - unsigned long mask; - - mask = __raw_readl(S3C2416_INTMSK2); - mask &= ~bitval; - __raw_writel(mask, S3C2416_INTMSK2); -} - -struct irq_chip s3c2416_irq_second = { - .irq_ack = s3c2416_irq_ack_second, - .irq_mask = s3c2416_irq_mask_second, - .irq_unmask = s3c2416_irq_unmask_second, -}; - - -static void s3c2416_irq_add_second(void) -{ - unsigned long pend; - unsigned long last; - int irqno; - int i; - - /* first, clear all interrupts pending... */ - last = 0; - for (i = 0; i < 4; i++) { - pend = __raw_readl(S3C2416_INTPND2); - - if (pend == 0 || pend == last) - break; - - __raw_writel(pend, S3C2416_SRCPND2); - __raw_writel(pend, S3C2416_INTPND2); - printk(KERN_INFO "irq: clearing pending status %08x\n", - (int)pend); - last = pend; - } - - for (irqno = IRQ_S3C2416_2D; irqno <= IRQ_S3C2416_I2S1; irqno++) { - switch (irqno) { - case IRQ_S3C2416_RESERVED2: - case IRQ_S3C2416_RESERVED3: - /* no IRQ here */ - break; - default: - irq_set_chip_and_handler(irqno, &s3c2416_irq_second, - handle_edge_irq); - set_irq_flags(irqno, IRQF_VALID); - } - } -} - struct s3c_irq_data init_s3c2416subint[32] = { { .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 28 }, /* UART0-RX */ { .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 28 }, /* UART0-TX */ @@ -906,8 +848,21 @@ struct s3c_irq_data init_s3c2416subint[32] = { { .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 9 }, /* AC97 */ }; +struct s3c_irq_data init_s3c2416_second[32] = { + { .type = S3C_IRQTYPE_S3C2416 }, /* 2D */ + { .type = S3C_IRQTYPE_S3C2416 }, /* IIC1 */ + { .type = S3C_IRQTYPE_NONE }, /* reserved */ + { .type = S3C_IRQTYPE_NONE }, /* reserved */ + { .type = S3C_IRQTYPE_S3C2416 }, /* PCM0 */ + { .type = S3C_IRQTYPE_S3C2416 }, /* PCM1 */ + { .type = S3C_IRQTYPE_S3C2416 }, /* I2S0 */ + { .type = S3C_IRQTYPE_S3C2416 }, /* I2S1 */ +}; + void __init s3c2416_init_irq(void) { + struct s3c_irq_intc *s3c_intc2; + /* override irq data */ s3c_intc[0].irqs = &init_s3c2443base[0]; s3c_intc[2].irqs = &init_s3c2416subint[0]; @@ -916,7 +871,20 @@ void __init s3c2416_init_irq(void) s3c24xx_init_irq(); - s3c2416_irq_add_second(); + s3c_intc2 = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL); + if (!s3c_intc2) { + pr_err("irq: failed to allocate memory for second controller\n"); + return; + } + + s3c_intc2->reg_pending = S3C2416_SRCPND2, + s3c_intc2->reg_intpnd = S3C2416_INTPND2, + s3c_intc2->reg_mask = S3C2416_INTMSK2, + s3c_intc2->irqs = &init_s3c2416_second[0], + + s3c24xx_clear_intc(s3c_intc2); + s3c_intc2->domain = irq_domain_add_legacy(NULL, 8, IRQ_S3C2416_2D, 0, + &s3c24xx_irq_ops, s3c_intc2); } #ifdef CONFIG_PM