From patchwork Tue Dec 2 12:02:41 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Asutosh Das (asd)" X-Patchwork-Id: 5419501 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 55CB79F6FA for ; Tue, 2 Dec 2014 12:02:51 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 618882024F for ; Tue, 2 Dec 2014 12:02:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 68674202A1 for ; Tue, 2 Dec 2014 12:02:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932774AbaLBMCq (ORCPT ); Tue, 2 Dec 2014 07:02:46 -0500 Received: from sabertooth01.qualcomm.com ([65.197.215.72]:14682 "EHLO sabertooth01.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932473AbaLBMCp (ORCPT ); Tue, 2 Dec 2014 07:02:45 -0500 X-IronPort-AV: E=McAfee;i="5600,1067,7639"; a="79184516" Received: from ironmsg02-l.qualcomm.com ([172.30.48.16]) by sabertooth01.qualcomm.com with ESMTP/TLS/DHE-RSA-AES256-SHA; 02 Dec 2014 04:02:45 -0800 X-IronPort-AV: E=Sophos;i="5.07,500,1413270000"; d="scan'208";a="396976050" Received: from asutoshd-ics.in.qualcomm.com ([10.44.83.79]) by ironmsg02-L.qualcomm.com with ESMTP/TLS/DHE-RSA-AES256-SHA; 02 Dec 2014 04:02:44 -0800 Received: (from asutoshd@localhost) by asutoshd-ics.in.qualcomm.com (8.14.2/8.14.5/Submit) id sB2C2fr3027713; Tue, 2 Dec 2014 17:32:41 +0530 Date: Tue, 2 Dec 2014 17:32:41 +0530 From: Asutosh Das To: linux-mmc@vger.kernel.org Cc: linux-arm-msm@vger.kernel.org Subject: [PATCH 5/5] mmc: sdhci: add command queue support to sdhci Message-ID: <20141202120241.GA27704@asutoshd-ics.in.qualcomm.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@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 Adds command-queue support to SDHCi compliant drivers. Signed-off-by: Asutosh Das Signed-off-by: Konstantin Dorfman --- drivers/mmc/host/sdhci.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci.h | 2 ++ include/linux/mmc/sdhci.h | 1 + 3 files changed, 92 insertions(+) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 9a79fc4..66d537e 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -25,6 +25,7 @@ #include +#include #include #include #include @@ -2422,6 +2423,20 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) } } +#ifdef CONFIG_MMC_CQ_HCI +static irqreturn_t sdhci_cmdq_irq(struct mmc_host *mmc, u32 intmask) +{ + return cmdq_irq(mmc, intmask); +} + +#else +static irqreturn_t sdhci_cmdq_irq(struct mmc_host *mmc, u32 intmask) +{ + pr_err("%s: rxd cmdq-irq when disabled !!!!\n", mmc_hostname(mmc)); + return IRQ_NONE; +} +#endif + static irqreturn_t sdhci_irq(int irq, void *dev_id) { irqreturn_t result; @@ -2443,6 +2458,12 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id) goto out; } + if (host->mmc->card && mmc_card_cmdq(host->mmc->card)) { + pr_debug("*** %s: cmdq intr: 0x%08x\n", mmc_hostname(host->mmc), + intmask); + result = sdhci_cmdq_irq(host->mmc, intmask); + goto out; + } again: DBG("*** %s got interrupt: 0x%08x\n", mmc_hostname(host->mmc), intmask); @@ -2769,6 +2790,64 @@ struct sdhci_host *sdhci_alloc_host(struct device *dev, EXPORT_SYMBOL_GPL(sdhci_alloc_host); +#ifdef CONFIG_MMC_CQ_HCI +static void sdhci_cmdq_clear_set_irqs(struct mmc_host *mmc, u32 clear, u32 set) +{ + struct sdhci_host *host = mmc_priv(mmc); + + sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, + SDHCI_INT_CMDQ_EN | SDHCI_INT_ERROR_MASK); +} + +static void sdhci_cmdq_set_data_timeout(struct mmc_host *mmc, u32 val) +{ + struct sdhci_host *host = mmc_priv(mmc); + + sdhci_writeb(host, val, SDHCI_TIMEOUT_CONTROL); +} + +static void sdhci_cmdq_dump_vendor_regs(struct mmc_host *mmc) +{ + struct sdhci_host *host = mmc_priv(mmc); + + sdhci_dumpregs(host); +} + +static int sdhci_cmdq_init(struct sdhci_host *host, struct mmc_host *mmc, + bool dma64) +{ + return cmdq_init(host->cq_host, mmc, dma64); +} +#else +static void sdhci_cmdq_clear_set_irqs(struct mmc_host *mmc, u32 clear, u32 set) +{ + +} + +static void sdhci_cmdq_set_data_timeout(struct mmc_host *mmc, u32 val) +{ + +} + +static void sdhci_cmdq_dump_vendor_regs(struct mmc_host *mmc) +{ + +} + +static int sdhci_cmdq_init(struct sdhci_host *host, struct mmc_host *mmc, + bool dma64) +{ + return -ENOSYS; +} + +#endif + +static const struct cmdq_host_ops sdhci_cmdq_ops = { + .clear_set_irqs = sdhci_cmdq_clear_set_irqs, + .set_data_timeout = sdhci_cmdq_set_data_timeout, + .dump_vendor_regs = sdhci_cmdq_dump_vendor_regs, +}; + int sdhci_add_host(struct sdhci_host *host) { struct mmc_host *mmc; @@ -3259,6 +3338,16 @@ int sdhci_add_host(struct sdhci_host *host) #endif mmiowb(); + if (mmc->caps2 & MMC_CAP2_CMD_QUEUE) { + bool dma64 = (host->flags & SDHCI_USE_ADMA_64BIT) ? + true : false; + ret = sdhci_cmdq_init(host, mmc, dma64); + if (ret) + pr_err("%s: CMDQ init: failed (%d)\n", + mmc_hostname(host->mmc), ret); + else + host->cq_host->ops = &sdhci_cmdq_ops; + } mmc_add_host(mmc); diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 0a3ed01..c1a9fa8 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -149,6 +149,8 @@ SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \ SDHCI_INT_DATA_END_BIT | SDHCI_INT_ADMA_ERROR | \ SDHCI_INT_BLK_GAP) + +#define SDHCI_INT_CMDQ_EN (0x1 << 14) #define SDHCI_INT_ALL_MASK ((unsigned int)-1) #define SDHCI_ACMD12_ERR 0x3C diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index 7be12b8..dd9fe0d 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h @@ -184,6 +184,7 @@ struct sdhci_host { unsigned int tuning_mode; /* Re-tuning mode supported by host */ #define SDHCI_TUNING_MODE_1 0 struct timer_list tuning_timer; /* Timer for tuning */ + struct cmdq_host *cq_host; unsigned long private[0] ____cacheline_aligned; };