From patchwork Thu May 21 03:50:23 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 6452091 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 733C0C0432 for ; Thu, 21 May 2015 03:50:35 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 2C757203ED for ; Thu, 21 May 2015 03:50:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E919B20435 for ; Thu, 21 May 2015 03:50:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752915AbbEUDub (ORCPT ); Wed, 20 May 2015 23:50:31 -0400 Received: from relmlor3.renesas.com ([210.160.252.173]:39154 "EHLO relmlie2.idc.renesas.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753152AbbEUDua (ORCPT ); Wed, 20 May 2015 23:50:30 -0400 Received: from unknown (HELO relmlir4.idc.renesas.com) ([10.200.68.154]) by relmlie2.idc.renesas.com with ESMTP; 21 May 2015 12:50:29 +0900 Received: from relmlac4.idc.renesas.com (relmlac4.idc.renesas.com [10.200.69.24]) by relmlir4.idc.renesas.com (Postfix) with ESMTP id 135434ABA3; Thu, 21 May 2015 12:50:29 +0900 (JST) Received: by relmlac4.idc.renesas.com (Postfix, from userid 0) id C0A00480A3; Thu, 21 May 2015 12:50:28 +0900 (JST) Received: from relmlac4.idc.renesas.com (localhost [127.0.0.1]) by relmlac4.idc.renesas.com (Postfix) with ESMTP id BB8E7480A5; Thu, 21 May 2015 12:50:28 +0900 (JST) Received: from relmlii2.idc.renesas.com [10.200.68.66] by relmlac4.idc.renesas.com with ESMTP id NAB16217; Thu, 21 May 2015 12:50:28 +0900 X-IronPort-AV: E=Sophos;i="5.13,466,1427727600"; d="scan'208";a="187810377" Received: from mail-hk1lp0117.outbound.protection.outlook.com (HELO APAC01-HK1-obe.outbound.protection.outlook.com) ([207.46.51.117]) by relmlii2.idc.renesas.com with ESMTP/TLS/AES256-SHA; 21 May 2015 12:50:27 +0900 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=kuninori.morimoto.gx@renesas.com; Received: from morimoto-PC.renesas.com (211.11.155.132) by SIXPR06MB317.apcprd06.prod.outlook.com (10.141.125.143) with Microsoft SMTP Server (TLS) id 15.1.166.22; Thu, 21 May 2015 03:50:23 +0000 Message-ID: <87382qtwto.wl%kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto Subject: [PATCH 4/4 v2] ASoC: rsnd: spin lock for interrupt handler User-Agent: Wanderlust/2.15.9 Emacs/24.3 Mule/6.0 MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") To: Vinod Koul , Mark Brown CC: Simon , Nguyen Viet Dung , Magnus , Linux-SH , Linux-ALSA , Liam Girdwood , Laurent , Geert Uytterhoeven , Cao Minh Hiep , sakato , In-Reply-To: <878ucitwyh.wl%kuninori.morimoto.gx@renesas.com> References: <878ucitwyh.wl%kuninori.morimoto.gx@renesas.com> Date: Thu, 21 May 2015 03:50:23 +0000 X-Originating-IP: [211.11.155.132] X-ClientProxiedBy: TY1PR01CA0013.jpnprd01.prod.outlook.com (25.161.131.151) To SIXPR06MB317.apcprd06.prod.outlook.com (10.141.125.143) X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:SIXPR06MB317; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(5005006)(3002001); SRVR:SIXPR06MB317; BCL:0; PCL:0; RULEID:; SRVR:SIXPR06MB317; X-Forefront-PRVS: 0583A86C08 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(6009001)(199003)(189002)(66066001)(33646002)(83506001)(42186005)(101416001)(53416004)(64706001)(69596002)(47776003)(36756003)(105586002)(19580405001)(19580395003)(2950100001)(189998001)(46102003)(46406003)(106356001)(5001770100001)(5001830100001)(5001860100001)(50986999)(54356999)(76176999)(77096005)(68736005)(5001960100002)(50466002)(575784001)(229853001)(86362001)(77156002)(23726002)(62966003)(4001350100001)(92566002)(40100003)(4001540100001)(81156007)(122386002)(87976001)(97736004)(309714004); DIR:OUT; SFP:1102; SCL:1; SRVR:SIXPR06MB317; H:morimoto-PC.renesas.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; X-OriginatorOrg: renesas.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 May 2015 03:50:23.5447 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: SIXPR06MB317 Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Kuninori Morimoto Renesas R-Car driver interrupt handler was not locked before. But now, SSI/SRC interrupt handler calls restart function which should be called under spin lock. Below error might happen witout this patch. Unable to handle kernel NULL pointer dereference at virtual address 00000048 pgd = edfac000 [00000048] *pgd=6e0f0831, *pte=00000000, *ppte=00000000 Internal error: Oops: 17 [#1] SMP ARM CPU: 0 PID: 2009 Comm: aplay Not tainted 4.1.0-rc2-dirty #4 Hardware name: Generic R8A7790 (Flattened Device Tree) task: eeac9040 ti: eebe8000 task.ti: eebe8000 PC is at rsnd_get_adinr+0x28/0x60 LR is at rsnd_src_ssiu_start+0xdc/0x19c pc : [] lr : [] psr: a0000193 sp : eebe9e58 ip : eebe9e68 fp : eebe9e64 r10: c06ed9d0 r9 : ee919d10 r8 : 00000001 r7 : 00000001 r6 : ee1cb090 r5 : 00000000 r4 : edcaa418 r3 : 00000000 r2 : eea8ce00 r1 : 80000193 r0 : edcaa418 ... Reported-by: Cao Minh Hiep Signed-off-by: Kuninori Morimoto Tested-by: Keita Kobayashi Tested by: Cao Minh Hiep --- v1 -> v2 - no change, but added Hiep's Test-by sound/soc/sh/rcar/core.c | 12 ++++++++++-- sound/soc/sh/rcar/rsnd.h | 3 +-- sound/soc/sh/rcar/src.c | 11 ++++++++--- sound/soc/sh/rcar/ssi.c | 14 +++++++++++--- 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 2b7323c..d460d2a 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -170,6 +170,14 @@ void rsnd_mod_quit(struct rsnd_mod *mod) clk_unprepare(mod->clk); } +int rsnd_mod_is_working(struct rsnd_mod *mod) +{ + struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); + + /* see rsnd_dai_stream_init/quit() */ + return !!io->substream; +} + /* * settting function */ @@ -362,7 +370,7 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd, int ret; unsigned long flags; - rsnd_lock(priv, flags); + spin_lock_irqsave(&priv->lock, flags); switch (cmd) { case SNDRV_PCM_TRIGGER_START: @@ -400,7 +408,7 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd, } dai_trigger_end: - rsnd_unlock(priv, flags); + spin_unlock_irqrestore(&priv->lock, flags); return ret; } diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 4e6de68..03ff071 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -303,6 +303,7 @@ int rsnd_mod_init(struct rsnd_mod *mod, int id); void rsnd_mod_quit(struct rsnd_mod *mod); char *rsnd_mod_name(struct rsnd_mod *mod); +int rsnd_mod_is_working(struct rsnd_mod *mod); struct dma_chan *rsnd_mod_dma_req(struct rsnd_mod *mod); /* @@ -449,8 +450,6 @@ struct rsnd_priv { #define rsnd_priv_to_pdev(priv) ((priv)->pdev) #define rsnd_priv_to_dev(priv) (&(rsnd_priv_to_pdev(priv)->dev)) #define rsnd_priv_to_info(priv) ((priv)->info) -#define rsnd_lock(priv, flags) spin_lock_irqsave(&priv->lock, flags) -#define rsnd_unlock(priv, flags) spin_unlock_irqrestore(&priv->lock, flags) /* * rsnd_kctrl diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 3beb32e..fbe9166 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -673,10 +673,13 @@ static int _rsnd_src_stop_gen2(struct rsnd_mod *mod) static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data) { struct rsnd_mod *mod = data; - struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); + struct rsnd_priv *priv = rsnd_mod_to_priv(mod); + + spin_lock(&priv->lock); - if (!io) - return IRQ_NONE; + /* ignore all cases if not working */ + if (!rsnd_mod_is_working(mod)) + goto rsnd_src_interrupt_gen2_out; if (rsnd_src_error_record_gen2(mod)) { struct rsnd_priv *priv = rsnd_mod_to_priv(mod); @@ -692,6 +695,8 @@ static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data) else dev_warn(dev, "no more SRC restart\n"); } +rsnd_src_interrupt_gen2_out: + spin_unlock(&priv->lock); return IRQ_HANDLED; } diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 927ac52..50fa392 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -423,10 +423,15 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) struct rsnd_priv *priv = rsnd_mod_to_priv(mod); struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); int is_dma = rsnd_ssi_is_dma_mode(mod); - u32 status = rsnd_mod_read(mod, SSISR); + u32 status; + + spin_lock(&priv->lock); - if (!io) - return IRQ_NONE; + /* ignore all cases if not working */ + if (!rsnd_mod_is_working(mod)) + goto rsnd_ssi_interrupt_out; + + status = rsnd_mod_read(mod, SSISR); /* PIO only */ if (!is_dma && (status & DIRQ)) { @@ -466,6 +471,9 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) rsnd_ssi_record_error(ssi, status); +rsnd_ssi_interrupt_out: + spin_unlock(&priv->lock); + return IRQ_HANDLED; }