From patchwork Mon Apr 28 07:40:57 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Fenkart X-Patchwork-Id: 4075581 Return-Path: X-Original-To: patchwork-linux-omap@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 903B89FA35 for ; Mon, 28 Apr 2014 07:42:32 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B0E5C2028D for ; Mon, 28 Apr 2014 07:42:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BB3552026D for ; Mon, 28 Apr 2014 07:42:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753569AbaD1Hm2 (ORCPT ); Mon, 28 Apr 2014 03:42:28 -0400 Received: from mail-ee0-f50.google.com ([74.125.83.50]:49666 "EHLO mail-ee0-f50.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751808AbaD1Hm0 (ORCPT ); Mon, 28 Apr 2014 03:42:26 -0400 Received: by mail-ee0-f50.google.com with SMTP id c13so4483636eek.23 for ; Mon, 28 Apr 2014 00:42:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Ulsb2NbbIG6b3kh4tXr+GkCkpsZiHgHBmF3uFut+Cr0=; b=UDgKagJXD4Lcq5d9uk0YcQtG2bI5u+hbGVFT78DY5eIwF5vrxX3/GcxmBNFhmCGQPX 0/+fMM4hKHBrH742iQPUDp9es18HPoIjPCPRGE7JIOHFPqp5uOVZfv0yGCdGcnfaMVG2 SB9M6G/SuALjZcgdlQBHya36PbS7a9CuS7hVA7IBT0lel+izq78LHnRwcKkJ51iaQSTu fGwWYLGCMLcToUIWddVKxzppj5R92ZmONB9bu6lza1fFJchbhToJKD1UquZMLF04qHEb CUIhlx1tCer5/3AMCDubaIWxqpvu3MMuEM+so/8mlSrCBc8xeDkURqVOQeAJLY56aHwH loxw== X-Received: by 10.15.36.6 with SMTP id h6mr2188518eev.54.1398670945314; Mon, 28 Apr 2014 00:42:25 -0700 (PDT) Received: from localhost (ip-89-176-190-91.net.upcbroadband.cz. [89.176.190.91]) by mx.google.com with ESMTPSA id y51sm48065256eeu.0.2014.04.28.00.42.23 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Mon, 28 Apr 2014 00:42:24 -0700 (PDT) From: Andreas Fenkart To: Tony Lindgren Cc: Chris Ball , Grant Likely , Felipe Balbi , Balaji T K , zonque@gmail.com, galak@codeaurora.org, linux-doc@vger.kernel.org, linux-mmc@vger.kernel.org, linux-omap@vger.kernel.org, Andreas Fenkart Subject: [PATCH v10 2/5] mmc: omap_hsmmc: bug: abort runtime suspend if pending sdio irq detected Date: Mon, 28 Apr 2014 09:40:57 +0200 Message-Id: <1398670860-30695-3-git-send-email-afenkart@gmail.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1398670860-30695-1-git-send-email-afenkart@gmail.com> References: <1398670860-30695-1-git-send-email-afenkart@gmail.com> Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Spam-Status: No, score=-7.4 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, 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 on multicores, an sdio irq handler could be running in parallel to runtime suspend. In the worst case it could be waiting for the spinlock held by the runtime suspend. When runtime suspend is complete and the functional clock (fclk) turned off, the irq handler will continue and cause a SIGBUS on the first register access. Signed-off-by: Andreas Fenkart diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 700fb91..e675042 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -56,6 +56,7 @@ #define OMAP_HSMMC_RSP54 0x0118 #define OMAP_HSMMC_RSP76 0x011C #define OMAP_HSMMC_DATA 0x0120 +#define OMAP_HSMMC_PSTATE 0x0124 #define OMAP_HSMMC_HCTL 0x0128 #define OMAP_HSMMC_SYSCTL 0x012C #define OMAP_HSMMC_STAT 0x0130 @@ -2400,6 +2401,7 @@ static int omap_hsmmc_runtime_suspend(struct device *dev) { struct omap_hsmmc_host *host; unsigned long flags; + int ret = 0; host = platform_get_drvdata(to_platform_device(dev)); omap_hsmmc_context_save(host); @@ -2411,14 +2413,29 @@ static int omap_hsmmc_runtime_suspend(struct device *dev) /* disable sdio irq handling to prevent race */ OMAP_HSMMC_WRITE(host->base, ISE, 0); OMAP_HSMMC_WRITE(host->base, IE, 0); - OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR); + + if (!(OMAP_HSMMC_READ(host->base, PSTATE) & BIT(21))) { + /* + * dat1 line low, pending sdio irq + * race condition: possible irq handler running on + * multi-core, abort + */ + dev_dbg(dev, "pending sdio irq, abort suspend\n"); + OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR); + OMAP_HSMMC_WRITE(host->base, ISE, CIRQ_EN); + OMAP_HSMMC_WRITE(host->base, IE, CIRQ_EN); + pm_runtime_mark_last_busy(dev); + ret = -EBUSY; + goto abort; + } WARN_ON(host->flags & HSMMC_WAKE_IRQ_ENABLED); enable_irq(host->wake_irq); host->flags |= HSMMC_WAKE_IRQ_ENABLED; } +abort: spin_unlock_irqrestore(&host->irq_lock, flags); - return 0; + return ret; } static int omap_hsmmc_runtime_resume(struct device *dev)