From patchwork Mon Aug 20 09:39:23 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yoshihiro Shimoda X-Patchwork-Id: 1347881 Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 42BE7DFF0F for ; Mon, 20 Aug 2012 09:40:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752753Ab2HTJko (ORCPT ); Mon, 20 Aug 2012 05:40:44 -0400 Received: from relmlor1.renesas.com ([210.160.252.171]:44584 "EHLO relmlor1.renesas.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751606Ab2HTJkn (ORCPT ); Mon, 20 Aug 2012 05:40:43 -0400 Received: from relmlir2.idc.renesas.com ([10.200.68.152]) by relmlor1.idc.renesas.com ( SJSMS) with ESMTP id <0M91000CES5NXA30@relmlor1.idc.renesas.com>; Mon, 20 Aug 2012 18:39:23 +0900 (JST) Received: from relmlac2.idc.renesas.com ([10.200.69.22]) by relmlir2.idc.renesas.com ( SJSMS) with ESMTP id <0M91004F9S5NUC10@relmlir2.idc.renesas.com>; Mon, 20 Aug 2012 18:39:23 +0900 (JST) Received: by relmlac2.idc.renesas.com (Postfix, from userid 0) id C8C07280A3; Mon, 20 Aug 2012 18:39:23 +0900 (JST) Received: from relmlac2.idc.renesas.com (localhost [127.0.0.1]) by relmlac2.idc.renesas.com (Postfix) with ESMTP id C34B8280A1; Mon, 20 Aug 2012 18:39:23 +0900 (JST) Received: from relmlii1.idc.renesas.com [10.200.68.65] by relmlac2.idc.renesas.com with ESMTP id UAC13316; Mon, 20 Aug 2012 18:39:23 +0900 X-IronPort-AV: E=Sophos; i="4.77,796,1336316400"; d="scan'208"; a="94545099" Received: from unknown (HELO [172.30.8.157]) ([172.30.8.157]) by relmlii1.idc.renesas.com with ESMTP; Mon, 20 Aug 2012 18:39:23 +0900 Message-id: <503205CB.5010109@renesas.com> Date: Mon, 20 Aug 2012 18:39:23 +0900 From: "Shimoda, Yoshihiro" User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:14.0) Gecko/20120713 Thunderbird/14.0 MIME-version: 1.0 To: balbi@ti.com Cc: USB list , SH-Linux , Kuninori Morimoto Subject: [PATCH] usb: renesas_usbhs: modify the irq handler for sharing irq Content-type: text/plain; charset=ISO-8859-1 Content-transfer-encoding: 7bit Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org When IORESOURCE_IRQ_SHAREABLE is set, the irq handler may be called even if the interupt of the USB module doesn't happen. So, it may clear the interrupt flags by mistake. This patch fixes it. Signed-off-by: Yoshihiro Shimoda --- drivers/usb/renesas_usbhs/mod.c | 25 ++++++++++++++++++++++--- 1 files changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c index 82a628f..35c5208 100644 --- a/drivers/usb/renesas_usbhs/mod.c +++ b/drivers/usb/renesas_usbhs/mod.c @@ -209,14 +209,18 @@ int usbhs_status_get_ctrl_stage(struct usbhs_irq_state *irq_state) return (int)irq_state->intsts0 & CTSQ_MASK; } -static void usbhs_status_get_each_irq(struct usbhs_priv *priv, - struct usbhs_irq_state *state) +static int usbhs_status_get_each_irq(struct usbhs_priv *priv, + struct usbhs_irq_state *state) { struct usbhs_mod *mod = usbhs_mod_get_current(priv); + u16 intenb0, intenb1; state->intsts0 = usbhs_read(priv, INTSTS0); state->intsts1 = usbhs_read(priv, INTSTS1); + intenb0 = usbhs_read(priv, INTENB0); + intenb1 = usbhs_read(priv, INTENB1); + /* mask */ if (mod) { state->brdysts = usbhs_read(priv, BRDYSTS); @@ -226,6 +230,20 @@ static void usbhs_status_get_each_irq(struct usbhs_priv *priv, state->bempsts &= mod->irq_bempsts; state->brdysts &= mod->irq_brdysts; } + + /* + * Check whether the irq enable registers and the irq status are set + * when IRQF_SHARED is set. + */ + if (priv->irqflags & IRQF_SHARED) { + if (!(intenb0 & state->intsts0) && + !(intenb1 & state->intsts1) && + !(state->bempsts) && + !(state->brdysts)) + return -EIO; + } + + return 0; } /* @@ -238,7 +256,8 @@ static irqreturn_t usbhs_interrupt(int irq, void *data) struct usbhs_priv *priv = data; struct usbhs_irq_state irq_state; - usbhs_status_get_each_irq(priv, &irq_state); + if (usbhs_status_get_each_irq(priv, &irq_state) < 0) + return IRQ_NONE; /* * clear interrupt