All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 2/2] Make cmdq_en attribute writeable
@ 2021-02-15  0:32 Luca Porzio
  2021-02-15 13:49   ` Dan Carpenter
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Luca Porzio @ 2021-02-15  0:32 UTC (permalink / raw)
  To: linux-mmc; +Cc: Zhan Liu, Luca Porzio

cmdq_en attribute in sysfs now can now be written.
When 0 is written:
  CMDQ is disabled and kept disabled across device reboots.
When 1 is written:
  CMDQ mode is instantly reneabled (if supported).

Signed-off-by: Luca Porzio <lporzio@micron.com>
Signed-off-by: Zhan Liu <zliua@micron.com>
---
 drivers/mmc/core/mmc.c   | 152 ++++++++++++++++++++++++++++++---------
 include/linux/mmc/card.h |   1 +
 2 files changed, 118 insertions(+), 35 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 0d80b72ddde8..5c7d5bac5c00 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -794,7 +794,120 @@ MMC_DEV_ATTR(enhanced_rpmb_supported, "%#x\n",
 MMC_DEV_ATTR(rel_sectors, "%#x\n", card->ext_csd.rel_sectors);
 MMC_DEV_ATTR(ocr, "0x%08x\n", card->ocr);
 MMC_DEV_ATTR(rca, "0x%04x\n", card->rca);
-MMC_DEV_ATTR(cmdq_en, "%d\n", card->ext_csd.cmdq_en);
+
+
+/* Setup command queue mode and CQE if underling hw supports it
+ * and assuming force_disable_cmdq has not been set.
+ */
+static int mmc_cmdq_setup(struct mmc_host *host, struct mmc_card *card)
+{
+	int err;
+
+	/* Check HW support */
+	if (!card->ext_csd.cmdq_support || !(host->caps2 & MMC_CAP2_CQE))
+		card->force_disable_cmdq = true;
+
+	/* Enable/Disable  CMDQ mode */
+	if (!card->ext_csd.cmdq_en && !card->force_disable_cmdq) {
+		err = mmc_cmdq_enable(card);
+		if (err && err != -EBADMSG)
+			return err;
+		if (err) {
+			pr_warn("%s: Enabling CMDQ failed\n",
+			    mmc_hostname(card->host));
+			card->ext_csd.cmdq_support = false;
+			card->ext_csd.cmdq_depth = 0;
+		}
+
+	} else if (card->ext_csd.cmdq_en && card->force_disable_cmdq) {
+		err = mmc_cmdq_disable(card);
+		if (err) {
+			pr_warn("%s: Disabling CMDQ failed, error %d\n",
+			    mmc_hostname(card->host), err);
+			err = 0;
+		}
+	}
+
+	/*
+	 * In some cases (e.g. RPMB or mmc_test), the Command Queue must be
+	 * disabled for a time, so a flag is needed to indicate to re-enable the
+	 * Command Queue.
+	 */
+	card->reenable_cmdq = card->ext_csd.cmdq_en;
+
+	/* Enable/Disable Host CQE */
+	if (!card->force_disable_cmdq) {
+
+		if (host->cqe_ops && !host->cqe_enabled) {
+			err = host->cqe_ops->cqe_enable(host, card);
+			if (!err) {
+				host->cqe_enabled = true;
+
+				if (card->ext_csd.cmdq_en) {
+					pr_info("%s: Command Queue Engine enabled\n",
+					    mmc_hostname(host));
+				} else {
+					host->hsq_enabled = true;
+					pr_info("%s: Host Software Queue enabled\n",
+					    mmc_hostname(host));
+				}
+			}
+		}
+
+	} else {
+
+		if (host->cqe_enabled) {
+			host->cqe_ops->cqe_disable(host);
+			host->cqe_enabled = false;
+			pr_info("%s: Command Queue Engine disabled\n",
+			    mmc_hostname(host));
+		}
+
+		host->hsq_enabled = false;
+		err = 0;
+	}
+
+	return err;
+}
+
+
+static ssize_t cmdq_en_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct mmc_card *card = mmc_dev_to_card(dev);
+
+	return sprintf(buf, "%d\n", card->ext_csd.cmdq_en);
+}
+
+static ssize_t cmdq_en_store(struct device *dev, struct device_attribute *attr,
+				 const char *buf, size_t count)
+{
+	struct mmc_card *card = mmc_dev_to_card(dev);
+	struct mmc_host *host = card->host;
+	unsigned long enable;
+	int err;
+
+	if (!card || kstrtoul(buf, 0, &enable))
+		return -EINVAL;
+	if (!card->ext_csd.cmdq_support)
+		return -EOPNOTSUPP;
+
+	enable = !!enable;
+	if (enable == card->ext_csd.cmdq_en)
+		return count;
+
+	mmc_get_card(card, NULL);
+	card->force_disable_cmdq = !enable;
+	err = mmc_cmdq_setup(host, card);
+	mmc_put_card(card, NULL);
+
+	if (err)
+		return err;
+	else
+		return count;
+}
+
+static DEVICE_ATTR_RW(cmdq_en);
+
 
 static ssize_t mmc_fwrev_show(struct device *dev,
 			      struct device_attribute *attr,
@@ -1838,40 +1951,9 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
 	 * Enable Command Queue if supported. Note that Packed Commands cannot
 	 * be used with Command Queue.
 	 */
-	card->ext_csd.cmdq_en = false;
-	if (card->ext_csd.cmdq_support && host->caps2 & MMC_CAP2_CQE) {
-		err = mmc_cmdq_enable(card);
-		if (err && err != -EBADMSG)
-			goto free_card;
-		if (err) {
-			pr_warn("%s: Enabling CMDQ failed\n",
-				mmc_hostname(card->host));
-			card->ext_csd.cmdq_support = false;
-			card->ext_csd.cmdq_depth = 0;
-		}
-	}
-	/*
-	 * In some cases (e.g. RPMB or mmc_test), the Command Queue must be
-	 * disabled for a time, so a flag is needed to indicate to re-enable the
-	 * Command Queue.
-	 */
-	card->reenable_cmdq = card->ext_csd.cmdq_en;
-
-	if (host->cqe_ops && !host->cqe_enabled) {
-		err = host->cqe_ops->cqe_enable(host, card);
-		if (!err) {
-			host->cqe_enabled = true;
-
-			if (card->ext_csd.cmdq_en) {
-				pr_info("%s: Command Queue Engine enabled\n",
-					mmc_hostname(host));
-			} else {
-				host->hsq_enabled = true;
-				pr_info("%s: Host Software Queue enabled\n",
-					mmc_hostname(host));
-			}
-		}
-	}
+	err = mmc_cmdq_setup(host, card);
+	if (err)
+		goto free_card;
 
 	if (host->caps2 & MMC_CAP2_AVOID_3_3V &&
 	    host->ios.signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index f9ad35dd6012..e554bb0cf722 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -272,6 +272,7 @@ struct mmc_card {
 #define MMC_QUIRK_BROKEN_HPI	(1<<13)		/* Disable broken HPI support */
 
 	bool			reenable_cmdq;	/* Re-enable Command Queue */
+	bool			force_disable_cmdq; /* Keep Command Queue disabled */
 
 	unsigned int		erase_size;	/* erase size in sectors */
  	unsigned int		erase_shift;	/* if erase unit is power 2 */
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2021-03-15  7:12 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-15  0:32 [RFC PATCH 2/2] Make cmdq_en attribute writeable Luca Porzio
2021-02-15 13:49 ` Dan Carpenter
2021-02-15 13:49   ` Dan Carpenter
2021-02-17 13:04 ` kernel test robot
2021-03-02 10:46 ` Ulf Hansson
2021-03-10  8:54   ` Adrian Hunter
2021-03-14 22:33     ` [EXT] " Luca Porzio (lporzio)
2021-03-15  7:11       ` Adrian Hunter
2021-03-08 17:05 ` Ulf Hansson
     [not found]   ` <CABhGgDPpUXPHJ49E_ku5N-fO=GWZKTdQQUGugAruG6y2=J1YgA@mail.gmail.com>
2021-03-09 15:47     ` Ulf Hansson
2021-03-14 22:26       ` [EXT] " Luca Porzio (lporzio)

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.