From patchwork Fri Mar 20 02:08:22 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rafael Ignacio Zurita X-Patchwork-Id: 13197 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 n2K2F9EI010485 for ; Fri, 20 Mar 2009 02:15:09 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752448AbZCTCPJ (ORCPT ); Thu, 19 Mar 2009 22:15:09 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1752746AbZCTCPJ (ORCPT ); Thu, 19 Mar 2009 22:15:09 -0400 Received: from smtp110.prem.mail.ac4.yahoo.com ([76.13.13.93]:42184 "HELO smtp110.prem.mail.ac4.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1752448AbZCTCPI (ORCPT ); Thu, 19 Mar 2009 22:15:08 -0400 X-Greylist: delayed 401 seconds by postgrey-1.27 at vger.kernel.org; Thu, 19 Mar 2009 22:15:07 EDT Received: (qmail 94152 invoked from network); 20 Mar 2009 02:08:24 -0000 DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=s1024; d=yahoo.com; h=Received:X-YMail-OSG:X-Yahoo-Newman-Property:Date:From:To:Cc:Subject:Message-ID:Reply-To:MIME-Version:Content-Type:Content-Disposition:Sender:User-Agent; b=tGWws/8xKCtwZ3Im9WIlQsCBBkenaAA5o91wSOYjNTnbyc/cg9YxkyNrTBw16/SNcdZlmawOJYGLynRl9NUBn5gt1CQJXu8WwFOHRkpsWA+K86N6nZRRKX1rh14/MwDbD/2PhSod5Er0N7YP/77fHxdt4JNKqpLijbXLrJlT2Ok= ; Received: from unknown (HELO localhost) (rizurita@200.123.158.181 with login) by smtp110.prem.mail.ac4.yahoo.com with SMTP; 20 Mar 2009 02:08:24 -0000 X-YMail-OSG: 3U6bzC8VM1nchNll5pxcXrIbcwC_6qB3LKIALj22Amlc6tMzalpT7qcCSFJsM_.1BoUTEEn7nUIQSl7_CuwUsSvYJWNTz.0ir4XTtvwoeyzglVLp79eeUfB9fWZIYdIa1P579bPvfuRJ2s.BRncP3OKO4CUs0AC9kP3MyKc.VAjWVWckOgGJW72CGKrw9IFWGrhOYpKijWGgvfNMGY.SkzAKRJiD X-Yahoo-Newman-Property: ymail-3 Date: Thu, 19 Mar 2009 23:08:22 -0300 From: Rafael Ignacio Zurita To: linux-sh@vger.kernel.org Cc: lethal@linux-sh.org Subject: [PATCH] sh: fix the HD64461 level-triggered interrupts handling Message-ID: <20090320020822.GA17555@rafazurita.homelinux.net> Reply-To: Rafael Ignacio Zurita MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.18 (2008-05-17) Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org Rework the hd64461 demuxer code to fix the HD64461 level-triggered interrupts handling, using handle_level_irq() as needed. Signed-off-by: Rafael Ignacio Zurita --- arch/sh/boards/mach-hp6xx/setup.c | 1 - arch/sh/cchips/hd6446x/hd64461.c | 30 +++++++++++++++++------------- arch/sh/include/asm/hd64461.h | 1 - 3 files changed, 17 insertions(+), 15 deletions(-) --- a/arch/sh/boards/mach-hp6xx/setup.c +++ b/arch/sh/boards/mach-hp6xx/setup.c @@ -115,7 +115,6 @@ static struct sh_machine_vector mv_hp6xx __initmv = { .mv_setup = hp6xx_setup, /* IRQ's : CPU(64) + CCHIP(16) + FREE_TO_USE(6) */ .mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM + 6, - .mv_irq_demux = hd64461_irq_demux, /* Enable IRQ0 -> IRQ3 in IRQ_MODE */ .mv_init_irq = hp6xx_init_irq, }; --- a/arch/sh/cchips/hd6446x/hd64461.c +++ b/arch/sh/cchips/hd6446x/hd64461.c @@ -53,21 +53,22 @@ static struct irq_chip hd64461_irq_chip = { .unmask = hd64461_unmask_irq, }; -int hd64461_irq_demux(int irq) +static void hd64461_irq_demux(unsigned int irq, struct irq_desc *desc) { - if (irq == CONFIG_HD64461_IRQ) { - unsigned short bit; - unsigned short nirr = inw(HD64461_NIRR); - unsigned short nimr = inw(HD64461_NIMR); - int i; - - nirr &= ~nimr; - for (bit = 1, i = 0; i < 16; bit <<= 1, i++) - if (nirr & bit) - break; - irq = HD64461_IRQBASE + i; + unsigned short intv = ctrl_inw(HD64461_NIRR); + struct irq_desc *ext_desc; + unsigned int ext_irq = HD64461_IRQBASE; + + intv &= (1 << HD64461_IRQ_NUM) - 1; + + while (intv) { + if (intv & 1) { + ext_desc = irq_desc + ext_irq; + handle_level_irq(ext_irq, ext_desc); + } + intv >>= 1; + ext_irq++; } - return irq; } int __init setup_hd64461(void) @@ -93,6 +94,9 @@ int __init setup_hd64461(void) set_irq_chip_and_handler(i, &hd64461_irq_chip, handle_level_irq); + set_irq_chained_handler(CONFIG_HD64461_IRQ, hd64461_irq_demux); + set_irq_type(CONFIG_HD64461_IRQ, IRQ_TYPE_LEVEL_LOW); + #ifdef CONFIG_HD64461_ENABLER printk(KERN_INFO "HD64461: enabling PCMCIA devices\n"); __raw_writeb(0x4c, HD64461_PCC1CSCIER); --- a/arch/sh/include/asm/hd64461.h +++ b/arch/sh/include/asm/hd64461.h @@ -242,7 +242,6 @@ #include /* arch/sh/cchips/hd6446x/hd64461/setup.c */ -int hd64461_irq_demux(int irq); void hd64461_register_irq_demux(int irq, int (*demux) (int irq, void *dev), void *dev); void hd64461_unregister_irq_demux(int irq);