From patchwork Thu Jul 14 16:39:10 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guennadi Liakhovetski X-Patchwork-Id: 975462 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p6EGdAKT031666 for ; Thu, 14 Jul 2011 16:39:18 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932093Ab1GNQjS (ORCPT ); Thu, 14 Jul 2011 12:39:18 -0400 Received: from moutng.kundenserver.de ([212.227.126.171]:49291 "EHLO moutng.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932076Ab1GNQjR (ORCPT ); Thu, 14 Jul 2011 12:39:17 -0400 Received: from axis700.grange (dslb-178-006-253-037.pools.arcor-ip.net [178.6.253.37]) by mrelayeu.kundenserver.de (node=mrbap4) with ESMTP (Nemesis) id 0Lm4C9-1RGSZr3Lof-00Zhui; Thu, 14 Jul 2011 18:39:10 +0200 Received: by axis700.grange (Postfix, from userid 1000) id 7E0EF189B6E; Thu, 14 Jul 2011 18:39:10 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by axis700.grange (Postfix) with ESMTP id 7B02E189B6D; Thu, 14 Jul 2011 18:39:10 +0200 (CEST) Date: Thu, 14 Jul 2011 18:39:10 +0200 (CEST) From: Guennadi Liakhovetski X-X-Sender: lyakh@axis700.grange To: linux-mmc@vger.kernel.org cc: linux-sh@vger.kernel.org, Magnus Damm , "Rafael J. Wysocki" , Chris Ball , Ian Molton , Simon Horman Subject: [PATCH 2/2] mmc: tmio: fix a deadlock In-Reply-To: Message-ID: References: MIME-Version: 1.0 X-Provags-ID: V02:K0:YUSQJG9SQw6f5/qkP2nOZGyFNYLUMfAh3xlZNRdPeGc 9xHQK2HtikZs0QpwRkLInOUG90D0VwSp+IkN0MDaTB8VcHAEff JO5ADbPU4JlamJMhBVSt1fBSL41Ycm6zT0jcqHHjYLt1cRk1Uz X6LJ5nuZ1byOpmMoPSSgxu5YbvEzGeI2heIF0FsepGsWgGiS1j 7fMnsdI0wgHB7BtxNy3Rfem/1LfyTWUH+t5yKGRpiE= Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Thu, 14 Jul 2011 16:39:18 +0000 (UTC) Currently the tmio-mmc driver contains a recursive runtime PM method invocation, which leads to a deadlock on a mutex. Avoid it by taking care not to request DMA too early. Signed-off-by: Guennadi Liakhovetski --- drivers/mmc/host/tmio_mmc.h | 5 +++++ drivers/mmc/host/tmio_mmc_dma.c | 5 ++++- drivers/mmc/host/tmio_mmc_pio.c | 4 ++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index 551d1ef..60ba335 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h @@ -109,6 +109,7 @@ static inline void tmio_mmc_kunmap_atomic(struct scatterlist *sg, #if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) void tmio_mmc_start_dma(struct tmio_mmc_host *host, struct mmc_data *data); +void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable); void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdata); void tmio_mmc_release_dma(struct tmio_mmc_host *host); #else @@ -117,6 +118,10 @@ static inline void tmio_mmc_start_dma(struct tmio_mmc_host *host, { } +static inline void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable) +{ +} + static inline void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdata) { diff --git a/drivers/mmc/host/tmio_mmc_dma.c b/drivers/mmc/host/tmio_mmc_dma.c index 7e86662..2aa616d 100644 --- a/drivers/mmc/host/tmio_mmc_dma.c +++ b/drivers/mmc/host/tmio_mmc_dma.c @@ -22,8 +22,11 @@ #define TMIO_MMC_MIN_DMA_LEN 8 -static void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable) +void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable) { + if (!host->chan_tx || !host->chan_rx) + return; + #if defined(CONFIG_SUPERH) || defined(CONFIG_ARCH_SHMOBILE) /* Switch DMA mode on or off - SuperH specific? */ sd_ctrl_write16(host, CTL_DMA_ENABLE, enable ? 2 : 0); diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c index 221ffb7..1f16357 100644 --- a/drivers/mmc/host/tmio_mmc_pio.c +++ b/drivers/mmc/host/tmio_mmc_pio.c @@ -984,7 +984,7 @@ int tmio_mmc_host_resume(struct device *dev) if (host->pm_global) { /* Runtime PM resume callback didn't run */ tmio_mmc_reset(host); - tmio_mmc_request_dma(host, host->pdata); + tmio_mmc_enable_dma(host, true); host->pm_global = false; } @@ -1007,7 +1007,7 @@ int tmio_mmc_host_runtime_resume(struct device *dev) struct tmio_mmc_data *pdata = host->pdata; tmio_mmc_reset(host); - tmio_mmc_request_dma(host, host->pdata); + tmio_mmc_enable_dma(host, true); if (pdata->power) { /* Only entered after a card-insert interrupt */