From patchwork Tue Feb 24 13:58:57 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Magnus Damm X-Patchwork-Id: 8592 X-Patchwork-Delegate: lethal@linux-sh.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n1OE1DIi032435 for ; Tue, 24 Feb 2009 14:01:13 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754459AbZBXOBN (ORCPT ); Tue, 24 Feb 2009 09:01:13 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754140AbZBXOBN (ORCPT ); Tue, 24 Feb 2009 09:01:13 -0500 Received: from rv-out-0506.google.com ([209.85.198.232]:64825 "EHLO rv-out-0506.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754459AbZBXOBM (ORCPT ); Tue, 24 Feb 2009 09:01:12 -0500 Received: by rv-out-0506.google.com with SMTP id g37so2492616rvb.1 for ; Tue, 24 Feb 2009 06:01:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:date:message-id :subject; bh=sRySBMGBHFnlbnjKnXcpRb8fgC7K+5bySrriJlUbTQg=; b=ckqCVCJ6HR7wyHUOsCxpFQbuUT/jX/7lIOWYZNr8KJEQ7b8ywbu0q6ydAcAgEE04X8 r8PcLRxSWwR+frtIf6Qr6USeqPObkcOamMPF2QVGP5RwMZ9pWMUXBPF11/0GR4oGN7WA cr4WrRy924eJmuZyqSzAZWVQx+hXu/Ql1u7Hs= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:date:message-id:subject; b=nztFa3mvJQcnyBcCivpWGQRsZ09p9cM2nrB1632n5pVtXgBE3bSqmgE2PLFroONx3S jgeSCODYTbfBXF5RS1hl76m++wmxQ5g4hS6ZRppzF5O0sF/ejKFQFdwfqd1jm67NRI9o jCpyYgUFMin47u87B57isON+/+H7CcsT0CAqE= Received: by 10.141.168.2 with SMTP id v2mr2622772rvo.47.1235484070894; Tue, 24 Feb 2009 06:01:10 -0800 (PST) Received: from rx1.opensource.se (114.8.221.202.ts.2iij.net [202.221.8.114]) by mx.google.com with ESMTPS id l31sm16621856rvb.5.2009.02.24.06.01.09 (version=TLSv1/SSLv3 cipher=RC4-MD5); Tue, 24 Feb 2009 06:01:10 -0800 (PST) From: Magnus Damm To: linux-sh@vger.kernel.org Cc: Magnus Damm , lethal@linux-sh.org Date: Tue, 24 Feb 2009 22:58:57 +0900 Message-Id: <20090224135857.12058.3261.sendpatchset@rx1.opensource.se> Subject: [PATCH 01/04] sh: multiple vectors per irq - base Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org From: Magnus Damm Instead of keeping the single vector -> single linux irq mapping we extend the intc code to support merging of vectors to a single linux irq. This helps processors such as sh7750, sh7780 and sh7785 which have more vectors than masking ability. With this patch in place we can modify the intc tables to use one irq per maskable irq source. Please note the following: - If multiple vectors share the same enum then only the first vector will be available as a linux irq. - Drivers may need to be rewritten to get pending irq source from the hardware block instead of irq number. This patch together with the sh7785 specific intc tables solves DMA controller irq issues related to buggy interrupt masking. Signed-off-by: Magnus Damm Reported-by: Yoshihiro Shimoda --- arch/sh/kernel/irq.c | 2 +- drivers/sh/intc.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/sh_intc.h | 1 + 3 files changed, 49 insertions(+), 1 deletion(-) -- To unsubscribe from this list: send the line "unsubscribe linux-sh" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html --- 0001/arch/sh/kernel/irq.c +++ work/arch/sh/kernel/irq.c 2009-02-24 14:52:49.000000000 +0900 @@ -106,7 +106,7 @@ asmlinkage int do_IRQ(unsigned int irq, } #endif - irq = irq_demux(evt2irq(irq)); + irq = irq_demux(intc_evt2irq(irq)); #ifdef CONFIG_IRQSTACKS curctx = (union irq_ctx *)current_thread_info(); --- 0001/drivers/sh/intc.c +++ work/drivers/sh/intc.c 2009-02-24 14:52:49.000000000 +0900 @@ -568,6 +568,10 @@ static void __init intc_register_irq(str if (!data[0] && data[1]) primary = 1; + if (!data[0] && !data[1]) + pr_warning("intc: missing unique irq mask for 0x%04x\n", + irq2evt(irq)); + data[0] = data[0] ? data[0] : intc_mask_data(desc, d, enum_id, 1); data[1] = data[1] ? data[1] : intc_prio_data(desc, d, enum_id, 1); @@ -641,6 +645,17 @@ static unsigned int __init save_reg(stru return 0; } +static unsigned char *intc_evt2irq_table; + +unsigned int intc_evt2irq(unsigned int vector) +{ + unsigned int irq = evt2irq(vector); + + if (intc_evt2irq_table && intc_evt2irq_table[irq]) + irq = intc_evt2irq_table[irq]; + + return irq; +} void __init register_intc_controller(struct intc_desc *desc) { @@ -705,8 +720,40 @@ void __init register_intc_controller(str BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */ + /* keep the first vector only if same enum is used multiple times */ for (i = 0; i < desc->nr_vectors; i++) { struct intc_vect *vect = desc->vectors + i; + int first_irq = evt2irq(vect->vect); + + if (!vect->enum_id) + continue; + + for (k = i + 1; k < desc->nr_vectors; k++) { + struct intc_vect *vect2 = desc->vectors + k; + + if (vect->enum_id != vect2->enum_id) + continue; + + vect2->enum_id = 0; + + if (!intc_evt2irq_table) + intc_evt2irq_table = alloc_bootmem(NR_IRQS); + + if (!intc_evt2irq_table) { + pr_warning("intc: cannot allocate evt2irq!\n"); + continue; + } + + intc_evt2irq_table[evt2irq(vect2->vect)] = first_irq; + } + } + + /* register the vectors one by one */ + for (i = 0; i < desc->nr_vectors; i++) { + struct intc_vect *vect = desc->vectors + i; + + if (!vect->enum_id) + continue; intc_register_irq(desc, d, vect->enum_id, evt2irq(vect->vect)); } --- 0001/include/linux/sh_intc.h +++ work/include/linux/sh_intc.h 2009-02-24 14:52:49.000000000 +0900 @@ -85,6 +85,7 @@ struct intc_desc symbol __initdata = { } #endif +unsigned int intc_evt2irq(unsigned int vector); void __init register_intc_controller(struct intc_desc *desc); int intc_set_priority(unsigned int irq, unsigned int prio);