From patchwork Tue May 9 08:27:26 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 98884 Delivered-To: patches@linaro.org Received: by 10.140.96.100 with SMTP id j91csp1708398qge; Tue, 9 May 2017 01:27:38 -0700 (PDT) X-Received: by 10.223.153.181 with SMTP id y50mr41687560wrb.41.1494318458459; Tue, 09 May 2017 01:27:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1494318458; cv=none; d=google.com; s=arc-20160816; b=xcWYi2am/OSnqjHtsiDIVEbIga5m9ty3uXKqftB+p2subPD3v6eD2sAV9KQ7kNQXSo wykdAnzj4RttnaESK9Y68mUGtg0OBn4Y1L1/BjKwjHllLQ+AQSKM2ayY5rvCUUgNIJ+L dyLIzKwa9BgNv2HnLCp0yNcWwIEzfZRCSJihpuxTiVjDL/5pCWbtt1h+HmIwmGYbflnK o9xxpN/tf95Oll3CQlGMONiQnku9H/VXnYeAdELebCoKi/JbS2iJ8rg10LbuezoO6KBO fHJ9Y4Ua+Ny/5zuCfeNkuzq+zY+oLiCQoKF9wTLQDDcZqxfv875a/QCAZQa8bvwuS9G/ gEIA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=Y2wVdM/0OSvHBpF88xlr+DwnSL9iobLDisyXyd8fAqo=; b=wXykJekQ4u7QcnBzNj8u/KEDnZbKeYmyLM1bkiEa6FkC7quQ30sJpayu1XiZWljHhb U4aF9EruRxym5sMunS85cJLciDa+nDu3P9k7Uyx5+afOC8ov9T9C96JPJzXWMIN0c9Kq OrhlMJnZ52ioBdLFVbQ3JOAsnauADhZxCKBOAcxidAmdNClSVkPycwAfxvV+A+Nqtrx4 uTKq+Fd7nof2qUpon7UIhPvAUaeJAzODfogzd40h4B+0VD9KczI/3wE+zSd8hjwmJ4A9 aEmWCUykrrn+euZ0iA2iGfbqwQCTzIueIXMo2WARGr0QCn2VKKLPqa6hE3NBJh8LOPZQ ALsA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: domain of ulf.hansson@linaro.org designates 2a00:1450:400c:c0c::235 as permitted sender) smtp.mailfrom=ulf.hansson@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from mail-wr0-x235.google.com (mail-wr0-x235.google.com. [2a00:1450:400c:c0c::235]) by mx.google.com with ESMTPS id u31si17426590wrc.200.2017.05.09.01.27.38 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 May 2017 01:27:38 -0700 (PDT) Received-SPF: pass (google.com: domain of ulf.hansson@linaro.org designates 2a00:1450:400c:c0c::235 as permitted sender) client-ip=2a00:1450:400c:c0c::235; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: domain of ulf.hansson@linaro.org designates 2a00:1450:400c:c0c::235 as permitted sender) smtp.mailfrom=ulf.hansson@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: by mail-wr0-x235.google.com with SMTP id l50so63260792wrc.3 for ; Tue, 09 May 2017 01:27:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Y2wVdM/0OSvHBpF88xlr+DwnSL9iobLDisyXyd8fAqo=; b=GeHfn/MXs/U1DbMVucN9GUUFSFxHkQnoTCs/T4x82iYbhYVjK0dX5pvOzi3wYSuUSH Yi0MykZtTOD+Ncln+b+neQ/atO1NnzAXiOWFtvsiQCDoSm9/BDxFAorsNIYFzlcjez/r UOQIDLF3bOvLiGAeTL552FYbmx+gTUURgsZIE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Y2wVdM/0OSvHBpF88xlr+DwnSL9iobLDisyXyd8fAqo=; b=k65c1/rihEUOOSu2rLl0BHAAECDM68GS+ScfkSLzm2v1vAhwJ6IBWXPlKScEDuG3Lg CLmoy3vBscPWQL5gIjzZnRlesr9YfZqAFlXtepbPloDOEGmBqOP3dC1s4ILImiKTsdTJ SKjd9R5kfuh7RZNRjp0EwaO5nViKxYhGJyDZXg4d/AmQ6EANI8d0XXMtp+rVs/thyaPk xGKdLtGBximDwYtiW+UBuvJqzPL4OBwPeru3ueD4mgC77IcJo/Iv2E3nQoKF4g5wJpXU 3+UIDIgqIhlyoAatBt940mkoG8JHfiPjsXpZZOCzNkGH07amVV8GLTM2fhnTTjN/5kc1 3eZQ== X-Gm-Message-State: AODbwcAduR6EsOaDmIFdqw+EeBAE+9hIk28dyKWqX/BtAQoc38Xzlhc3 KL+HBLqDmuoiXSmrmko= X-Received: by 10.46.83.82 with SMTP id t18mr6046890ljd.70.1494318458014; Tue, 09 May 2017 01:27:38 -0700 (PDT) Return-Path: Received: from localhost.localdomain (h-155-4-221-67.na.cust.bahnhof.se. [155.4.221.67]) by smtp.gmail.com with ESMTPSA id o21sm3151108lfo.34.2017.05.09.01.27.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 09 May 2017 01:27:37 -0700 (PDT) From: Ulf Hansson To: linux-mmc@vger.kernel.org, Ulf Hansson Cc: Jaehoon Chung , Adrian Hunter , Brian Norris , Shawn Lin , Doug Anderson Subject: [PATCH v3 2/5] mmc: sdio: Add API to manage SDIO IRQs from a workqueue Date: Tue, 9 May 2017 10:27:26 +0200 Message-Id: <1494318449-2591-3-git-send-email-ulf.hansson@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1494318449-2591-1-git-send-email-ulf.hansson@linaro.org> References: <1494318449-2591-1-git-send-email-ulf.hansson@linaro.org> For hosts not supporting MMC_CAP2_SDIO_IRQ_NOTHREAD but MMC_CAP_SDIO_IRQ, the SDIO IRQs are processed from a dedicated kernel thread. For these cases, the host calls mmc_signal_sdio_irq() from its ISR to signal a new SDIO IRQ. Signaling an SDIO IRQ makes the host's ->enable_sdio_irq() callback to be invoked to temporary disable the IRQs, before the kernel thread is woken up to process it. When processing of the IRQs are completed, they are re-enabled by the kernel thread, again via invoking the host's ->enable_sdio_irq(). The observation from this, is that the execution path is being unnecessary complex, as the host driver already knows that it needs to temporary disable the IRQs before signaling a new one. Moreover, replacing the kernel thread with a work/workqueue would not only greatly simplify the code, but also make it more robust. To address the above problems, let's continue to build upon the support for MMC_CAP2_SDIO_IRQ_NOTHREAD, as it already implements SDIO IRQs to be processed without using the clumsy kernel thread and without the ping-pong calls of the host's ->enable_sdio_irq() callback for each processed IRQ. Therefore, let's add new API sdio_signal_irq(), which enables hosts to signal/process SDIO IRQs by using a work/workqueue, rather than using the kernel thread. Add also a new host callback ->ack_sdio_irq(), which the work invokes when the SDIO IRQs have been processed. This informs the host about when it shall re-enable the SDIO IRQs. Potentially, we could re-use the existing ->enable_sdio_irq() callback instead of adding a new one, however it has turned out that it's more convenient for hosts to get this information via a separate callback. Hosts that wants to use this new method to signal/process SDIO IRQs, must enable MMC_CAP2_SDIO_IRQ_NOTHREAD and implement the ->ack_sdio_irq() callback. Signed-off-by: Ulf Hansson Tested-by: Douglas Anderson Reviewed-by: Douglas Anderson --- Changes in v3: - Switched to use system_wq, as system_freezable_wq doesn't work. - Use a delayed_work instead of a regular work. It's needed in next step when implementing SDIO IRQ polling. --- drivers/mmc/core/host.c | 2 ++ drivers/mmc/core/sdio_irq.c | 16 ++++++++++++++++ drivers/mmc/core/sdio_ops.h | 2 ++ include/linux/mmc/host.h | 3 +++ 4 files changed, 23 insertions(+) -- 2.7.4 diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 3f8c85d..8823c97 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -30,6 +30,7 @@ #include "host.h" #include "slot-gpio.h" #include "pwrseq.h" +#include "sdio_ops.h" #define cls_dev_to_mmc_host(d) container_of(d, struct mmc_host, class_dev) @@ -379,6 +380,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) spin_lock_init(&host->lock); init_waitqueue_head(&host->wq); INIT_DELAYED_WORK(&host->detect, mmc_rescan); + INIT_DELAYED_WORK(&host->sdio_irq_work, sdio_irq_work); setup_timer(&host->retune_timer, mmc_retune_timer, (unsigned long)host); /* diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c index 44d9c86..c771843 100644 --- a/drivers/mmc/core/sdio_irq.c +++ b/drivers/mmc/core/sdio_irq.c @@ -98,11 +98,27 @@ void sdio_run_irqs(struct mmc_host *host) if (host->sdio_irqs) { host->sdio_irq_pending = true; process_sdio_pending_irqs(host); + if (host->ops->ack_sdio_irq) + host->ops->ack_sdio_irq(host); } mmc_release_host(host); } EXPORT_SYMBOL_GPL(sdio_run_irqs); +void sdio_irq_work(struct work_struct *work) +{ + struct mmc_host *host = + container_of(work, struct mmc_host, sdio_irq_work.work); + + sdio_run_irqs(host); +} + +void sdio_signal_irq(struct mmc_host *host) +{ + queue_delayed_work(system_wq, &host->sdio_irq_work, 0); +} +EXPORT_SYMBOL_GPL(sdio_signal_irq); + static int sdio_irq_thread(void *_host) { struct mmc_host *host = _host; diff --git a/drivers/mmc/core/sdio_ops.h b/drivers/mmc/core/sdio_ops.h index ee35cb4..96945ca 100644 --- a/drivers/mmc/core/sdio_ops.h +++ b/drivers/mmc/core/sdio_ops.h @@ -17,6 +17,7 @@ struct mmc_host; struct mmc_card; +struct work_struct; int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr); int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, @@ -25,6 +26,7 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz); int sdio_reset(struct mmc_host *host); unsigned int mmc_align_data_size(struct mmc_card *card, unsigned int sz); +void sdio_irq_work(struct work_struct *work); static inline bool sdio_is_io_busy(u32 opcode, u32 arg) { diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 21385ac..f186b26 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -130,6 +130,7 @@ struct mmc_host_ops { int (*get_cd)(struct mmc_host *host); void (*enable_sdio_irq)(struct mmc_host *host, int enable); + void (*ack_sdio_irq)(struct mmc_host *host); /* optional callback for HC quirks */ void (*init_card)(struct mmc_host *host, struct mmc_card *card); @@ -358,6 +359,7 @@ struct mmc_host { unsigned int sdio_irqs; struct task_struct *sdio_irq_thread; + struct delayed_work sdio_irq_work; bool sdio_irq_pending; atomic_t sdio_irq_thread_abort; @@ -428,6 +430,7 @@ static inline void mmc_signal_sdio_irq(struct mmc_host *host) } void sdio_run_irqs(struct mmc_host *host); +void sdio_signal_irq(struct mmc_host *host); #ifdef CONFIG_REGULATOR int mmc_regulator_get_ocrmask(struct regulator *supply);