From patchwork Sun May 11 11:28:56 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Fenkart X-Patchwork-Id: 4150301 Return-Path: X-Original-To: patchwork-linux-mmc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 7E638BFF02 for ; Sun, 11 May 2014 11:30:26 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B6C69202F0 for ; Sun, 11 May 2014 11:30:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C52192028D for ; Sun, 11 May 2014 11:30:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932133AbaEKLaX (ORCPT ); Sun, 11 May 2014 07:30:23 -0400 Received: from mail-ve0-f178.google.com ([209.85.128.178]:46362 "EHLO mail-ve0-f178.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932092AbaEKLaW (ORCPT ); Sun, 11 May 2014 07:30:22 -0400 Received: by mail-ve0-f178.google.com with SMTP id sa20so7410452veb.37 for ; Sun, 11 May 2014 04:30:21 -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=sV1eXzuyEhm2kxZRwYSVurczVLthUt4ShB9nJHVLqi8=; b=CiEY+qCLV1ZqOO4O8uFffJSSPo7R25ucM3UKpWRFh3ocmpoKC/i5m9gIaVDJ+PNaTJ WmwzDlgorgAQlbBlFzWt7c+8e/PSWfDNAX9N4/vJmx/iohazydow1kPnz8mhinNe+6BD SJggdFdmfTKQVb0Xhv7kAHqFtmisVL8joQEP1QduTMUeIs6+GTDHg1dnlzdeA5IOhOjT I0jsPtToOnJKd2qeF6qGXf7beBC151jDBCQ2ni7R9BBXqtHJeLarc651m47poDEqp297 7zcJveMAjOtNph/pdlPTLylgwYw3WbOMmWOzRBj+O7Cl4rwW+umwNRgEFlPOvPYzcZ7S TY/A== X-Received: by 10.58.228.163 with SMTP id sj3mr98602vec.28.1399807821302; Sun, 11 May 2014 04:30:21 -0700 (PDT) Received: from localhost (ip-89-176-190-91.net.upcbroadband.cz. [89.176.190.91]) by mx.google.com with ESMTPSA id 10sm17284190vdu.9.2014.05.11.04.30.18 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Sun, 11 May 2014 04:30:20 -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 v11 4/6] mmc: omap_hsmmc: abort runtime suspend if pending sdio irq detected Date: Sun, 11 May 2014 13:28:56 +0200 Message-Id: <1399807738-32223-5-git-send-email-afenkart@gmail.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1399807738-32223-1-git-send-email-afenkart@gmail.com> References: <1399807738-32223-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 1a9d31f..30365f5 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) @@ -2423,6 +2426,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); @@ -2434,14 +2438,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)