From patchwork Sun Mar 31 19:54:20 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergei Shtylyov X-Patchwork-Id: 2368661 Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 87F093FC8C for ; Sun, 31 Mar 2013 19:55:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756014Ab3CaTzm (ORCPT ); Sun, 31 Mar 2013 15:55:42 -0400 Received: from mail-la0-f42.google.com ([209.85.215.42]:63687 "EHLO mail-la0-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755993Ab3CaTzm (ORCPT ); Sun, 31 Mar 2013 15:55:42 -0400 Received: by mail-la0-f42.google.com with SMTP id fe20so1664743lab.15 for ; Sun, 31 Mar 2013 12:55:40 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:to:subject:cc:from:organization:date:mime-version :content-type:content-transfer-encoding:message-id :x-gm-message-state; bh=vDDmpRaFSvp4rlD10aBknhFRcasyIlPpBZlhxiUsiZk=; b=pYIwzEkwkdeIpPgqUxF+gOV58Z9X+X7mH3YZY92dlA7R+ggQ1oX3u2Zg025MZ/F4Mz 2TCTWO7kvqWoBh+Dq8zj16fcW0GnPjVcDHkNezeu+ytMOoRELhAiCVjyk46u677mKPqH FRWlk2XAMITzkzGYIsxNOa8s9+5GarwCblT9y3xLCqojcrKTovgZT4z16wIEIdh7jFlT wBuV3WqH8BGXFOqiHGPLr1tubEd2lRUHINcJqIap2nxrWdZVN1OMrEgDtQ/ehFCLqfvv zLpX2FloDl8IRHuqaBjljQGlz9aTYhTsSWAzu93Lmbjgi5ppkhSD8IBq5HpsbcZwNdWk /LlA== X-Received: by 10.152.28.3 with SMTP id x3mr4522612lag.27.1364759740337; Sun, 31 Mar 2013 12:55:40 -0700 (PDT) Received: from wasted.dev.rtsoft.ru (ppp91-79-90-168.pppoe.mtu-net.ru. [91.79.90.168]) by mx.google.com with ESMTPS id go12sm4489353lab.3.2013.03.31.12.55.38 (version=TLSv1 cipher=RC4-SHA bits=128/128); Sun, 31 Mar 2013 12:55:39 -0700 (PDT) To: netdev@vger.kernel.org Subject: [PATCH 2/2] sh_eth: workaround for spurious ECI interrupt Cc: nobuhiro.iwamatsu.yj@renesas.com, linux-sh@vger.kernel.org From: Sergei Shtylyov Organization: Cogent Embedded Date: Sun, 31 Mar 2013 23:54:20 +0400 MIME-Version: 1.0 Message-Id: <201303312354.20695.sergei.shtylyov@cogentembedded.com> X-Gm-Message-State: ALoCoQnAkhZJza0Hwy9qDMJgWm7i202bZB6imIpUYId5p1LeEGp7Xh4f0bw7JgcMcAAb6nPi/Bja Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org At least on Renesas R8A7778, EESR.ECI interrupt seems to fire regardless of its mask in EESIPR register. I can 100% reproduce it with the following scenario: target is booted with 'ip=on' option, and so IP-Config opens SoC Ether device but doesn't get a proper reply and then succeeds with on-board SMC chip; then I login and try to bring up the SoC Ether device with 'ifconfig', and I get an ECI interrupt once request_irq() is called by sh_eth_open() (while interrupt mask in EESIPR register is all 0), if that interrupt is accompanied by a pending EESR.FRC (frame receive completion) interrupt, I get kernel oops in sh_eth_rx() because sh_eth_ring_init() hasn't been called yet! The solution I worked out is the following: in sh_eth_interrupt(), mask the interrupt status from EESR register with the interrupt mask from EESIPR register in order not to handle the disabled interrupts -- but forcing EESIPR.M_ECI bit in this mask set because we always need to fully handle EESR.ECI interrupt in sh_eth_error() in order to quench it (as it doesn't get cleared by just writing 1 to the this bit as all the other interrupts). While at it, remove unneeded initializer for 'intr_status' variable and give it *unsigned long* type, matching the type of sh_eth_read()'s result; fix comment. Signed-off-by: Sergei Shtylyov Reviewed-by: Max Filippov --- The patch is against the David Miller's 'net.git' repo, however I'm not sure if it needs to be applied to it and not to 'net-next.git' (it should apply there with line offsets) since R8A7778 support is not upstream yet. drivers/net/ethernet/renesas/sh_eth.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) -- 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 Index: net/drivers/net/ethernet/renesas/sh_eth.c =================================================================== --- net.orig/drivers/net/ethernet/renesas/sh_eth.c +++ net/drivers/net/ethernet/renesas/sh_eth.c @@ -1324,12 +1324,18 @@ static irqreturn_t sh_eth_interrupt(int struct sh_eth_private *mdp = netdev_priv(ndev); struct sh_eth_cpu_data *cd = mdp->cd; irqreturn_t ret = IRQ_NONE; - u32 intr_status = 0; + unsigned long intr_status; spin_lock(&mdp->lock); - /* Get interrpt stat */ + /* Get interrupt status */ intr_status = sh_eth_read(ndev, EESR); + /* Mask it with the interrupt mask, forcing ECI interrupt to be always + * enabled since it's the one that comes thru regardless of the mask, + * and we need to fully handle it in sh_eth_error() in order to quench + * it as it doesn't get cleared by just writing 1 to the ECI bit... + */ + intr_status &= sh_eth_read(ndev, EESIPR) | DMAC_M_ECI; /* Clear interrupt */ if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF | EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF |