From patchwork Fri May 23 08:30:32 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Fenkart X-Patchwork-Id: 4228971 Return-Path: X-Original-To: patchwork-linux-mmc@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 369D99F32B for ; Fri, 23 May 2014 08:31:58 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 74B7520386 for ; Fri, 23 May 2014 08:31:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9CDCC20383 for ; Fri, 23 May 2014 08:31:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751885AbaEWIbw (ORCPT ); Fri, 23 May 2014 04:31:52 -0400 Received: from mail-ee0-f47.google.com ([74.125.83.47]:59218 "EHLO mail-ee0-f47.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751573AbaEWIbu (ORCPT ); Fri, 23 May 2014 04:31:50 -0400 Received: by mail-ee0-f47.google.com with SMTP id c13so3313036eek.6 for ; Fri, 23 May 2014 01:31:48 -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=5UcoqcSST8mZXcRcbVoiCVPb7BZn0c9/IlTlnhR22EE=; b=KukYk45ol1bcFNWqB3F43TPvD7ECYXniTs7EjjzkbLP1Ef+GOydCE2GWDqagopeYn1 0UDKI+V9AOu+VbWD5no+jN4XO/SxVF002iegm3m5qNczo4ewGuYkURuQsJ9XwyjSf+vs 0TShCKKFbQuJ93Pk3+KHwDjg5J2u4nVXPxvzIg9sc6k71q2s+tM9PCnxebKN5O7E19Wh uUwOz44KzWZUveDOHJewpEsBJKAMWLNug+1Bf6H9uDLq+/FE7doIOS9I2BXY4KILtZB+ uCyS7ANyPPJ3XLAM5J09gdmlDNMxi2dNJOK+SoeZPAVovbDs2MrgCQhSOpSIMKBvul2Y Dxnw== X-Received: by 10.14.172.201 with SMTP id t49mr5770055eel.9.1400833908470; Fri, 23 May 2014 01:31:48 -0700 (PDT) Received: from localhost (ip-89-176-190-91.net.upcbroadband.cz. [89.176.190.91]) by mx.google.com with ESMTPSA id o49sm6569734eep.33.2014.05.23.01.31.46 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Fri, 23 May 2014 01:31:47 -0700 (PDT) From: Andreas Fenkart To: Tony Lindgren Cc: Chris Ball , Grant Likely , Felipe Balbi , Balaji T K , Andreas Mueller , Sebastian Reichel , 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 v13 5/7] mmc: omap_hsmmc: abort runtime suspend if pending sdio irq detected Date: Fri, 23 May 2014 10:30:32 +0200 Message-Id: <1400833834-15893-6-git-send-email-afenkart@gmail.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1400833834-15893-1-git-send-email-afenkart@gmail.com> References: <1400833834-15893-1-git-send-email-afenkart@gmail.com> Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@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. Acked-by: Balaji T K Signed-off-by: Andreas Fenkart diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index dfc593e..aafef29 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -107,6 +107,9 @@ #define SRD (1 << 26) #define SOFTRESET (1 << 1) +/* PSTATE */ +#define DLEV_DAT(x) (1 << (20 + (x))) + /* Interrupt masks for IE and ISE register */ #define CC_EN (1 << 0) #define TC_EN (1 << 1) @@ -2432,6 +2435,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); @@ -2443,14 +2447,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) & DLEV_DAT(1))) { + /* + * 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)