All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9 v4] mmc: cd-gpio: extend to handle more slot functions
@ 2012-06-22 13:23 ` Guennadi Liakhovetski
  0 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-06-22 13:23 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-mmc, Magnus Damm, Chris Ball

This patch series extends the cd-gpio helper module to handle further common 
slot functions, often implemented using GPIOs: CD polling and WP. It 
supersedes patches 1-8 and 10/10 from

http://thread.gmane.org/gmane.linux.kernel.mmc/14624/focus\x14644

Patch 9/10 from it is not needed any more, because the default polarity of 
CD and RO GPIOs is now active low, which is also what is used by all 
initial users. This makes updating them unnecessary and allows us to apply 
patch 10/10 (which now becomes 9/9) immediately without first having to 
wait for platform updates.

Thanks
Guennadi

Guennadi Liakhovetski (9):
  mmc: extend and rename cd-gpio helpers to handle more slot GPIO
    functions
  mmc: use a more generic name for slot function types and fields
  mmc: add two capability flags for CD and WP signal polarity
  mmc: add CD GPIO polling support to slot functions
  mmc: convert slot functions to managed allocation
  mmc: add WP pin handler to slot functions
  mmc: tmio: support caps2 flags
  mmc: sh_mobile_sdhi: support caps2 flags
  mmc: tmio: use generic GPIO CD and WP handlers

 drivers/mmc/core/Makefile          |    2 +-
 drivers/mmc/core/cd-gpio.c         |   83 ----------------
 drivers/mmc/core/host.c            |    4 +
 drivers/mmc/core/slot-gpio.c       |  188 ++++++++++++++++++++++++++++++++++++
 drivers/mmc/host/sh_mobile_sdhi.c  |    1 +
 drivers/mmc/host/tmio_mmc_pio.c    |   13 ++-
 include/linux/mfd/tmio.h           |    1 +
 include/linux/mmc/cd-gpio.h        |   18 ----
 include/linux/mmc/host.h           |   22 ++++-
 include/linux/mmc/sh_mobile_sdhi.h |    1 +
 include/linux/mmc/slot-gpio.h      |   24 +++++
 11 files changed, 249 insertions(+), 108 deletions(-)
 delete mode 100644 drivers/mmc/core/cd-gpio.c
 create mode 100644 drivers/mmc/core/slot-gpio.c
 delete mode 100644 include/linux/mmc/cd-gpio.h
 create mode 100644 include/linux/mmc/slot-gpio.h

-- 
1.7.2.5

---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

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

* [PATCH 0/9 v4] mmc: cd-gpio: extend to handle more slot functions
@ 2012-06-22 13:23 ` Guennadi Liakhovetski
  0 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-06-22 13:23 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-mmc, Magnus Damm, Chris Ball

This patch series extends the cd-gpio helper module to handle further common 
slot functions, often implemented using GPIOs: CD polling and WP. It 
supersedes patches 1-8 and 10/10 from

http://thread.gmane.org/gmane.linux.kernel.mmc/14624/focus=14644

Patch 9/10 from it is not needed any more, because the default polarity of 
CD and RO GPIOs is now active low, which is also what is used by all 
initial users. This makes updating them unnecessary and allows us to apply 
patch 10/10 (which now becomes 9/9) immediately without first having to 
wait for platform updates.

Thanks
Guennadi

Guennadi Liakhovetski (9):
  mmc: extend and rename cd-gpio helpers to handle more slot GPIO
    functions
  mmc: use a more generic name for slot function types and fields
  mmc: add two capability flags for CD and WP signal polarity
  mmc: add CD GPIO polling support to slot functions
  mmc: convert slot functions to managed allocation
  mmc: add WP pin handler to slot functions
  mmc: tmio: support caps2 flags
  mmc: sh_mobile_sdhi: support caps2 flags
  mmc: tmio: use generic GPIO CD and WP handlers

 drivers/mmc/core/Makefile          |    2 +-
 drivers/mmc/core/cd-gpio.c         |   83 ----------------
 drivers/mmc/core/host.c            |    4 +
 drivers/mmc/core/slot-gpio.c       |  188 ++++++++++++++++++++++++++++++++++++
 drivers/mmc/host/sh_mobile_sdhi.c  |    1 +
 drivers/mmc/host/tmio_mmc_pio.c    |   13 ++-
 include/linux/mfd/tmio.h           |    1 +
 include/linux/mmc/cd-gpio.h        |   18 ----
 include/linux/mmc/host.h           |   22 ++++-
 include/linux/mmc/sh_mobile_sdhi.h |    1 +
 include/linux/mmc/slot-gpio.h      |   24 +++++
 11 files changed, 249 insertions(+), 108 deletions(-)
 delete mode 100644 drivers/mmc/core/cd-gpio.c
 create mode 100644 drivers/mmc/core/slot-gpio.c
 delete mode 100644 include/linux/mmc/cd-gpio.h
 create mode 100644 include/linux/mmc/slot-gpio.h

-- 
1.7.2.5

---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

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

* [PATCH 1/9 v4] mmc: extend and rename cd-gpio helpers to handle more slot GPIO functions
  2012-06-22 13:23 ` Guennadi Liakhovetski
@ 2012-06-22 13:23   ` Guennadi Liakhovetski
  -1 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-06-22 13:23 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-mmc, Magnus Damm, Chris Ball

GPIOs can be used in MMC/SD-card slots not only for hotplug detection, but
also to implement the write-protection pin. Rename cd-gpio helpers to
slot-gpio to make addition of further slot GPIO functions possible.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/core/Makefile                    |    2 +-
 drivers/mmc/core/{cd-gpio.c => slot-gpio.c}  |   48 +++++++++++++-------------
 drivers/mmc/host/tmio_mmc_pio.c              |    6 ++--
 include/linux/mmc/{cd-gpio.h => slot-gpio.h} |    8 ++--
 4 files changed, 32 insertions(+), 32 deletions(-)
 rename drivers/mmc/core/{cd-gpio.c => slot-gpio.c} (53%)
 rename include/linux/mmc/{cd-gpio.h => slot-gpio.h} (68%)

diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
index dca4428..38ed210 100644
--- a/drivers/mmc/core/Makefile
+++ b/drivers/mmc/core/Makefile
@@ -7,6 +7,6 @@ mmc_core-y			:= core.o bus.o host.o \
 				   mmc.o mmc_ops.o sd.o sd_ops.o \
 				   sdio.o sdio_ops.o sdio_bus.o \
 				   sdio_cis.o sdio_io.o sdio_irq.o \
-				   quirks.o cd-gpio.o
+				   quirks.o slot-gpio.o
 
 mmc_core-$(CONFIG_DEBUG_FS)	+= debugfs.o
diff --git a/drivers/mmc/core/cd-gpio.c b/drivers/mmc/core/slot-gpio.c
similarity index 53%
rename from drivers/mmc/core/cd-gpio.c
rename to drivers/mmc/core/slot-gpio.c
index f13e38d..9796710 100644
--- a/drivers/mmc/core/cd-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -12,72 +12,72 @@
 #include <linux/gpio.h>
 #include <linux/interrupt.h>
 #include <linux/jiffies.h>
-#include <linux/mmc/cd-gpio.h>
 #include <linux/mmc/host.h>
+#include <linux/mmc/slot-gpio.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 
-struct mmc_cd_gpio {
-	unsigned int gpio;
-	char label[0];
+struct mmc_gpio {
+	unsigned int cd_gpio;
+	char cd_label[0];
 };
 
-static irqreturn_t mmc_cd_gpio_irqt(int irq, void *dev_id)
+static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
 {
 	/* Schedule a card detection after a debounce timeout */
 	mmc_detect_change(dev_id, msecs_to_jiffies(100));
 	return IRQ_HANDLED;
 }
 
-int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio)
+int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 {
 	size_t len = strlen(dev_name(host->parent)) + 4;
-	struct mmc_cd_gpio *cd;
+	struct mmc_gpio *ctx;
 	int irq = gpio_to_irq(gpio);
 	int ret;
 
 	if (irq < 0)
 		return irq;
 
-	cd = kmalloc(sizeof(*cd) + len, GFP_KERNEL);
-	if (!cd)
+	ctx = kmalloc(sizeof(*ctx) + len, GFP_KERNEL);
+	if (!ctx)
 		return -ENOMEM;
 
-	snprintf(cd->label, len, "%s cd", dev_name(host->parent));
+	snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent));
 
-	ret = gpio_request_one(gpio, GPIOF_DIR_IN, cd->label);
+	ret = gpio_request_one(gpio, GPIOF_DIR_IN, ctx->cd_label);
 	if (ret < 0)
 		goto egpioreq;
 
-	ret = request_threaded_irq(irq, NULL, mmc_cd_gpio_irqt,
-				   IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-				   cd->label, host);
+	ret = request_threaded_irq(irq, NULL, mmc_gpio_cd_irqt,
+			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+			ctx->cd_label, host);
 	if (ret < 0)
 		goto eirqreq;
 
-	cd->gpio = gpio;
+	ctx->cd_gpio = gpio;
 	host->hotplug.irq = irq;
-	host->hotplug.handler_priv = cd;
+	host->hotplug.handler_priv = ctx;
 
 	return 0;
 
 eirqreq:
 	gpio_free(gpio);
 egpioreq:
-	kfree(cd);
+	kfree(ctx);
 	return ret;
 }
-EXPORT_SYMBOL(mmc_cd_gpio_request);
+EXPORT_SYMBOL(mmc_gpio_request_cd);
 
-void mmc_cd_gpio_free(struct mmc_host *host)
+void mmc_gpio_free_cd(struct mmc_host *host)
 {
-	struct mmc_cd_gpio *cd = host->hotplug.handler_priv;
+	struct mmc_gpio *ctx = host->hotplug.handler_priv;
 
-	if (!cd)
+	if (!ctx)
 		return;
 
 	free_irq(host->hotplug.irq, host);
-	gpio_free(cd->gpio);
-	kfree(cd);
+	gpio_free(ctx->cd_gpio);
+	kfree(ctx);
 }
-EXPORT_SYMBOL(mmc_cd_gpio_free);
+EXPORT_SYMBOL(mmc_gpio_free_cd);
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index d68ae59..b204012f 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -34,9 +34,9 @@
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/mfd/tmio.h>
-#include <linux/mmc/cd-gpio.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/mmc.h>
+#include <linux/mmc/slot-gpio.h>
 #include <linux/mmc/tmio.h>
 #include <linux/module.h>
 #include <linux/pagemap.h>
@@ -1029,7 +1029,7 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
 	dev_pm_qos_expose_latency_limit(&pdev->dev, 100);
 
 	if (pdata->flags & TMIO_MMC_USE_GPIO_CD) {
-		ret = mmc_cd_gpio_request(mmc, pdata->cd_gpio);
+		ret = mmc_gpio_request_cd(mmc, pdata->cd_gpio);
 		if (ret < 0) {
 			tmio_mmc_host_remove(_host);
 			return ret;
@@ -1061,7 +1061,7 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host)
 		 * This means we can miss a card-eject, but this is anyway
 		 * possible, because of delayed processing of hotplug events.
 		 */
-		mmc_cd_gpio_free(mmc);
+		mmc_gpio_free_cd(mmc);
 
 	if (!host->native_hotplug)
 		pm_runtime_get_sync(&pdev->dev);
diff --git a/include/linux/mmc/cd-gpio.h b/include/linux/mmc/slot-gpio.h
similarity index 68%
rename from include/linux/mmc/cd-gpio.h
rename to include/linux/mmc/slot-gpio.h
index cefaba0..edfaa32 100644
--- a/include/linux/mmc/cd-gpio.h
+++ b/include/linux/mmc/slot-gpio.h
@@ -8,11 +8,11 @@
  * published by the Free Software Foundation.
  */
 
-#ifndef MMC_CD_GPIO_H
-#define MMC_CD_GPIO_H
+#ifndef MMC_SLOT_GPIO_H
+#define MMC_SLOT_GPIO_H
 
 struct mmc_host;
-int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio);
-void mmc_cd_gpio_free(struct mmc_host *host);
+int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio);
+void mmc_gpio_free_cd(struct mmc_host *host);
 
 #endif
-- 
1.7.2.5


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

* [PATCH 1/9 v4] mmc: extend and rename cd-gpio helpers to handle more slot GPIO functions
@ 2012-06-22 13:23   ` Guennadi Liakhovetski
  0 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-06-22 13:23 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-mmc, Magnus Damm, Chris Ball

GPIOs can be used in MMC/SD-card slots not only for hotplug detection, but
also to implement the write-protection pin. Rename cd-gpio helpers to
slot-gpio to make addition of further slot GPIO functions possible.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/core/Makefile                    |    2 +-
 drivers/mmc/core/{cd-gpio.c => slot-gpio.c}  |   48 +++++++++++++-------------
 drivers/mmc/host/tmio_mmc_pio.c              |    6 ++--
 include/linux/mmc/{cd-gpio.h => slot-gpio.h} |    8 ++--
 4 files changed, 32 insertions(+), 32 deletions(-)
 rename drivers/mmc/core/{cd-gpio.c => slot-gpio.c} (53%)
 rename include/linux/mmc/{cd-gpio.h => slot-gpio.h} (68%)

diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
index dca4428..38ed210 100644
--- a/drivers/mmc/core/Makefile
+++ b/drivers/mmc/core/Makefile
@@ -7,6 +7,6 @@ mmc_core-y			:= core.o bus.o host.o \
 				   mmc.o mmc_ops.o sd.o sd_ops.o \
 				   sdio.o sdio_ops.o sdio_bus.o \
 				   sdio_cis.o sdio_io.o sdio_irq.o \
-				   quirks.o cd-gpio.o
+				   quirks.o slot-gpio.o
 
 mmc_core-$(CONFIG_DEBUG_FS)	+= debugfs.o
diff --git a/drivers/mmc/core/cd-gpio.c b/drivers/mmc/core/slot-gpio.c
similarity index 53%
rename from drivers/mmc/core/cd-gpio.c
rename to drivers/mmc/core/slot-gpio.c
index f13e38d..9796710 100644
--- a/drivers/mmc/core/cd-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -12,72 +12,72 @@
 #include <linux/gpio.h>
 #include <linux/interrupt.h>
 #include <linux/jiffies.h>
-#include <linux/mmc/cd-gpio.h>
 #include <linux/mmc/host.h>
+#include <linux/mmc/slot-gpio.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 
-struct mmc_cd_gpio {
-	unsigned int gpio;
-	char label[0];
+struct mmc_gpio {
+	unsigned int cd_gpio;
+	char cd_label[0];
 };
 
-static irqreturn_t mmc_cd_gpio_irqt(int irq, void *dev_id)
+static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
 {
 	/* Schedule a card detection after a debounce timeout */
 	mmc_detect_change(dev_id, msecs_to_jiffies(100));
 	return IRQ_HANDLED;
 }
 
-int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio)
+int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 {
 	size_t len = strlen(dev_name(host->parent)) + 4;
-	struct mmc_cd_gpio *cd;
+	struct mmc_gpio *ctx;
 	int irq = gpio_to_irq(gpio);
 	int ret;
 
 	if (irq < 0)
 		return irq;
 
-	cd = kmalloc(sizeof(*cd) + len, GFP_KERNEL);
-	if (!cd)
+	ctx = kmalloc(sizeof(*ctx) + len, GFP_KERNEL);
+	if (!ctx)
 		return -ENOMEM;
 
-	snprintf(cd->label, len, "%s cd", dev_name(host->parent));
+	snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent));
 
-	ret = gpio_request_one(gpio, GPIOF_DIR_IN, cd->label);
+	ret = gpio_request_one(gpio, GPIOF_DIR_IN, ctx->cd_label);
 	if (ret < 0)
 		goto egpioreq;
 
-	ret = request_threaded_irq(irq, NULL, mmc_cd_gpio_irqt,
-				   IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-				   cd->label, host);
+	ret = request_threaded_irq(irq, NULL, mmc_gpio_cd_irqt,
+			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+			ctx->cd_label, host);
 	if (ret < 0)
 		goto eirqreq;
 
-	cd->gpio = gpio;
+	ctx->cd_gpio = gpio;
 	host->hotplug.irq = irq;
-	host->hotplug.handler_priv = cd;
+	host->hotplug.handler_priv = ctx;
 
 	return 0;
 
 eirqreq:
 	gpio_free(gpio);
 egpioreq:
-	kfree(cd);
+	kfree(ctx);
 	return ret;
 }
-EXPORT_SYMBOL(mmc_cd_gpio_request);
+EXPORT_SYMBOL(mmc_gpio_request_cd);
 
-void mmc_cd_gpio_free(struct mmc_host *host)
+void mmc_gpio_free_cd(struct mmc_host *host)
 {
-	struct mmc_cd_gpio *cd = host->hotplug.handler_priv;
+	struct mmc_gpio *ctx = host->hotplug.handler_priv;
 
-	if (!cd)
+	if (!ctx)
 		return;
 
 	free_irq(host->hotplug.irq, host);
-	gpio_free(cd->gpio);
-	kfree(cd);
+	gpio_free(ctx->cd_gpio);
+	kfree(ctx);
 }
-EXPORT_SYMBOL(mmc_cd_gpio_free);
+EXPORT_SYMBOL(mmc_gpio_free_cd);
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index d68ae59..b204012f 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -34,9 +34,9 @@
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/mfd/tmio.h>
-#include <linux/mmc/cd-gpio.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/mmc.h>
+#include <linux/mmc/slot-gpio.h>
 #include <linux/mmc/tmio.h>
 #include <linux/module.h>
 #include <linux/pagemap.h>
@@ -1029,7 +1029,7 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
 	dev_pm_qos_expose_latency_limit(&pdev->dev, 100);
 
 	if (pdata->flags & TMIO_MMC_USE_GPIO_CD) {
-		ret = mmc_cd_gpio_request(mmc, pdata->cd_gpio);
+		ret = mmc_gpio_request_cd(mmc, pdata->cd_gpio);
 		if (ret < 0) {
 			tmio_mmc_host_remove(_host);
 			return ret;
@@ -1061,7 +1061,7 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host)
 		 * This means we can miss a card-eject, but this is anyway
 		 * possible, because of delayed processing of hotplug events.
 		 */
-		mmc_cd_gpio_free(mmc);
+		mmc_gpio_free_cd(mmc);
 
 	if (!host->native_hotplug)
 		pm_runtime_get_sync(&pdev->dev);
diff --git a/include/linux/mmc/cd-gpio.h b/include/linux/mmc/slot-gpio.h
similarity index 68%
rename from include/linux/mmc/cd-gpio.h
rename to include/linux/mmc/slot-gpio.h
index cefaba0..edfaa32 100644
--- a/include/linux/mmc/cd-gpio.h
+++ b/include/linux/mmc/slot-gpio.h
@@ -8,11 +8,11 @@
  * published by the Free Software Foundation.
  */
 
-#ifndef MMC_CD_GPIO_H
-#define MMC_CD_GPIO_H
+#ifndef MMC_SLOT_GPIO_H
+#define MMC_SLOT_GPIO_H
 
 struct mmc_host;
-int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio);
-void mmc_cd_gpio_free(struct mmc_host *host);
+int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio);
+void mmc_gpio_free_cd(struct mmc_host *host);
 
 #endif
-- 
1.7.2.5


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

* [PATCH 2/9 v4] mmc: use a more generic name for slot function types and fields
  2012-06-22 13:23 ` Guennadi Liakhovetski
@ 2012-06-22 13:23   ` Guennadi Liakhovetski
  -1 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-06-22 13:23 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-mmc, Magnus Damm, Chris Ball

struct mmc_host::hotplug is becoming a generic hook for slot functions.
Rename it accordingly.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/core/host.c      |    2 ++
 drivers/mmc/core/slot-gpio.c |    8 ++++----
 include/linux/mmc/host.h     |   17 ++++++++++++++---
 3 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 91c84c7..b8c5290 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -327,6 +327,8 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
 
 	mmc_host_clk_init(host);
 
+	host->slot.cd_irq = -EINVAL;
+
 	spin_lock_init(&host->lock);
 	init_waitqueue_head(&host->wq);
 	INIT_DELAYED_WORK(&host->detect, mmc_rescan);
diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
index 9796710..468e5a0 100644
--- a/drivers/mmc/core/slot-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -56,8 +56,8 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 		goto eirqreq;
 
 	ctx->cd_gpio = gpio;
-	host->hotplug.irq = irq;
-	host->hotplug.handler_priv = ctx;
+	host->slot.cd_irq = irq;
+	host->slot.handler_priv = ctx;
 
 	return 0;
 
@@ -71,12 +71,12 @@ EXPORT_SYMBOL(mmc_gpio_request_cd);
 
 void mmc_gpio_free_cd(struct mmc_host *host)
 {
-	struct mmc_gpio *ctx = host->hotplug.handler_priv;
+	struct mmc_gpio *ctx = host->slot.handler_priv;
 
 	if (!ctx)
 		return;
 
-	free_irq(host->hotplug.irq, host);
+	free_irq(host->slot.cd_irq, host);
 	gpio_free(ctx->cd_gpio);
 	kfree(ctx);
 }
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 9deb725..90b6a38 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -150,8 +150,19 @@ struct mmc_async_req {
 	int (*err_check) (struct mmc_card *, struct mmc_async_req *);
 };
 
-struct mmc_hotplug {
-	unsigned int irq;
+/**
+ * struct mmc_slot - MMC slot functions
+ *
+ * @cd_irq:		MMC/SD-card slot hotplug detection IRQ or -EINVAL
+ * @handler_priv:	MMC/SD-card slot context
+ *
+ * Some MMC/SD host controllers implement slot-functions like card and
+ * write-protect detection natively. However, a large number of controllers
+ * leave these functions to the CPU. This struct provides a hook to attach
+ * such slot-function drivers.
+ */
+struct mmc_slot {
+	int cd_irq;
 	void *handler_priv;
 };
 
@@ -297,7 +308,7 @@ struct mmc_host {
 
 	struct delayed_work	detect;
 	int			detect_change;	/* card detect flag */
-	struct mmc_hotplug	hotplug;
+	struct mmc_slot		slot;
 
 	const struct mmc_bus_ops *bus_ops;	/* current bus driver */
 	unsigned int		bus_refs;	/* reference counter */
-- 
1.7.2.5


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

* [PATCH 2/9 v4] mmc: use a more generic name for slot function types and fields
@ 2012-06-22 13:23   ` Guennadi Liakhovetski
  0 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-06-22 13:23 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-mmc, Magnus Damm, Chris Ball

struct mmc_host::hotplug is becoming a generic hook for slot functions.
Rename it accordingly.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/core/host.c      |    2 ++
 drivers/mmc/core/slot-gpio.c |    8 ++++----
 include/linux/mmc/host.h     |   17 ++++++++++++++---
 3 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 91c84c7..b8c5290 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -327,6 +327,8 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
 
 	mmc_host_clk_init(host);
 
+	host->slot.cd_irq = -EINVAL;
+
 	spin_lock_init(&host->lock);
 	init_waitqueue_head(&host->wq);
 	INIT_DELAYED_WORK(&host->detect, mmc_rescan);
diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
index 9796710..468e5a0 100644
--- a/drivers/mmc/core/slot-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -56,8 +56,8 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 		goto eirqreq;
 
 	ctx->cd_gpio = gpio;
-	host->hotplug.irq = irq;
-	host->hotplug.handler_priv = ctx;
+	host->slot.cd_irq = irq;
+	host->slot.handler_priv = ctx;
 
 	return 0;
 
@@ -71,12 +71,12 @@ EXPORT_SYMBOL(mmc_gpio_request_cd);
 
 void mmc_gpio_free_cd(struct mmc_host *host)
 {
-	struct mmc_gpio *ctx = host->hotplug.handler_priv;
+	struct mmc_gpio *ctx = host->slot.handler_priv;
 
 	if (!ctx)
 		return;
 
-	free_irq(host->hotplug.irq, host);
+	free_irq(host->slot.cd_irq, host);
 	gpio_free(ctx->cd_gpio);
 	kfree(ctx);
 }
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 9deb725..90b6a38 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -150,8 +150,19 @@ struct mmc_async_req {
 	int (*err_check) (struct mmc_card *, struct mmc_async_req *);
 };
 
-struct mmc_hotplug {
-	unsigned int irq;
+/**
+ * struct mmc_slot - MMC slot functions
+ *
+ * @cd_irq:		MMC/SD-card slot hotplug detection IRQ or -EINVAL
+ * @handler_priv:	MMC/SD-card slot context
+ *
+ * Some MMC/SD host controllers implement slot-functions like card and
+ * write-protect detection natively. However, a large number of controllers
+ * leave these functions to the CPU. This struct provides a hook to attach
+ * such slot-function drivers.
+ */
+struct mmc_slot {
+	int cd_irq;
 	void *handler_priv;
 };
 
@@ -297,7 +308,7 @@ struct mmc_host {
 
 	struct delayed_work	detect;
 	int			detect_change;	/* card detect flag */
-	struct mmc_hotplug	hotplug;
+	struct mmc_slot		slot;
 
 	const struct mmc_bus_ops *bus_ops;	/* current bus driver */
 	unsigned int		bus_refs;	/* reference counter */
-- 
1.7.2.5


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

* [PATCH 3/9 v4] mmc: add two capability flags for CD and WP signal polarity
  2012-06-22 13:23 ` Guennadi Liakhovetski
@ 2012-06-22 13:23   ` Guennadi Liakhovetski
  -1 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-06-22 13:23 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-mmc, Magnus Damm, Chris Ball

To handle CD and WP SD/MMC slot pins we need generic flags to specify their
polarity.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v4:

1. MMC_CAP2_*_ACTIVE_HIGH inverted compared to v3

 include/linux/mmc/host.h |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 90b6a38..c1a03ee 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -256,6 +256,8 @@ struct mmc_host {
 #define MMC_CAP2_BROKEN_VOLTAGE	(1 << 7)	/* Use the broken voltage */
 #define MMC_CAP2_DETECT_ON_ERR	(1 << 8)	/* On I/O err check card removal */
 #define MMC_CAP2_HC_ERASE_SZ	(1 << 9)	/* High-capacity erase size */
+#define MMC_CAP2_CD_ACTIVE_HIGH	(1 << 10)	/* Card-detect signal active high */
+#define MMC_CAP2_RO_ACTIVE_HIGH	(1 << 11)	/* Write-protect signal active high */
 
 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
 	unsigned int        power_notify_type;
-- 
1.7.2.5


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

* [PATCH 3/9 v4] mmc: add two capability flags for CD and WP signal polarity
@ 2012-06-22 13:23   ` Guennadi Liakhovetski
  0 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-06-22 13:23 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-mmc, Magnus Damm, Chris Ball

To handle CD and WP SD/MMC slot pins we need generic flags to specify their
polarity.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v4:

1. MMC_CAP2_*_ACTIVE_HIGH inverted compared to v3

 include/linux/mmc/host.h |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 90b6a38..c1a03ee 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -256,6 +256,8 @@ struct mmc_host {
 #define MMC_CAP2_BROKEN_VOLTAGE	(1 << 7)	/* Use the broken voltage */
 #define MMC_CAP2_DETECT_ON_ERR	(1 << 8)	/* On I/O err check card removal */
 #define MMC_CAP2_HC_ERASE_SZ	(1 << 9)	/* High-capacity erase size */
+#define MMC_CAP2_CD_ACTIVE_HIGH	(1 << 10)	/* Card-detect signal active high */
+#define MMC_CAP2_RO_ACTIVE_HIGH	(1 << 11)	/* Write-protect signal active high */
 
 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
 	unsigned int        power_notify_type;
-- 
1.7.2.5


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

* [PATCH 4/9 v4] mmc: add CD GPIO polling support to slot functions
  2012-06-22 13:23 ` Guennadi Liakhovetski
@ 2012-06-22 13:23   ` Guennadi Liakhovetski
  -1 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-06-22 13:23 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-mmc, Magnus Damm, Chris Ball

A simple extension of mmc slot functions add support for CD GPIO polling
for cases, where the GPIO cannot produce interrupts or this is for some
reason not desired.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v4:

1. gpio variables are now signed
2. take care to mark gpio variables as invalid in hotplug context
3. MMC_CAP2_*_ACTIVE_HIGH inverted compared to v3

 drivers/mmc/core/slot-gpio.c  |   56 +++++++++++++++++++++++++++++++---------
 include/linux/mmc/slot-gpio.h |    2 +
 2 files changed, 45 insertions(+), 13 deletions(-)

diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
index 468e5a0..92cba02 100644
--- a/drivers/mmc/core/slot-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -18,7 +18,7 @@
 #include <linux/slab.h>
 
 struct mmc_gpio {
-	unsigned int cd_gpio;
+	int cd_gpio;
 	char cd_label[0];
 };
 
@@ -29,6 +29,18 @@ static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+int mmc_gpio_get_cd(struct mmc_host *host)
+{
+	struct mmc_gpio *ctx = host->slot.handler_priv;
+
+	if (!ctx || !gpio_is_valid(ctx->cd_gpio))
+		return -ENOSYS;
+
+	return !gpio_get_value_cansleep(ctx->cd_gpio) ^
+		!!(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH);
+}
+EXPORT_SYMBOL(mmc_gpio_get_cd);
+
 int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 {
 	size_t len = strlen(dev_name(host->parent)) + 4;
@@ -36,9 +48,6 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 	int irq = gpio_to_irq(gpio);
 	int ret;
 
-	if (irq < 0)
-		return irq;
-
 	ctx = kmalloc(sizeof(*ctx) + len, GFP_KERNEL);
 	if (!ctx)
 		return -ENOMEM;
@@ -49,20 +58,32 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 	if (ret < 0)
 		goto egpioreq;
 
-	ret = request_threaded_irq(irq, NULL, mmc_gpio_cd_irqt,
+	/*
+	 * Even if gpio_to_irq() returns a valid IRQ number, the platform might
+	 * still prefer to poll, e.g., because that IRQ number is already used
+	 * by another unit and cannot be shared.
+	 */
+	if (irq >= 0 && host->caps & MMC_CAP_NEEDS_POLL)
+		irq = -EINVAL;
+
+	if (irq >= 0) {
+		ret = request_threaded_irq(irq, NULL, mmc_gpio_cd_irqt,
 			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 			ctx->cd_label, host);
-	if (ret < 0)
-		goto eirqreq;
+		if (ret < 0)
+			irq = ret;
+	}
 
-	ctx->cd_gpio = gpio;
 	host->slot.cd_irq = irq;
+
+	if (irq < 0)
+		host->caps |= MMC_CAP_NEEDS_POLL;
+
+	ctx->cd_gpio = gpio;
 	host->slot.handler_priv = ctx;
 
 	return 0;
 
-eirqreq:
-	gpio_free(gpio);
 egpioreq:
 	kfree(ctx);
 	return ret;
@@ -72,12 +93,21 @@ EXPORT_SYMBOL(mmc_gpio_request_cd);
 void mmc_gpio_free_cd(struct mmc_host *host)
 {
 	struct mmc_gpio *ctx = host->slot.handler_priv;
+	int gpio;
 
-	if (!ctx)
+	if (!ctx || !gpio_is_valid(ctx->cd_gpio))
 		return;
 
-	free_irq(host->slot.cd_irq, host);
-	gpio_free(ctx->cd_gpio);
+	if (host->slot.cd_irq >= 0) {
+		free_irq(host->slot.cd_irq, host);
+		host->slot.cd_irq = -EINVAL;
+	}
+
+	gpio = ctx->cd_gpio;
+	ctx->cd_gpio = -EINVAL;
+
+	gpio_free(gpio);
+	host->slot.handler_priv = NULL;
 	kfree(ctx);
 }
 EXPORT_SYMBOL(mmc_gpio_free_cd);
diff --git a/include/linux/mmc/slot-gpio.h b/include/linux/mmc/slot-gpio.h
index edfaa32..1a977d7 100644
--- a/include/linux/mmc/slot-gpio.h
+++ b/include/linux/mmc/slot-gpio.h
@@ -12,6 +12,8 @@
 #define MMC_SLOT_GPIO_H
 
 struct mmc_host;
+
+int mmc_gpio_get_cd(struct mmc_host *host);
 int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio);
 void mmc_gpio_free_cd(struct mmc_host *host);
 
-- 
1.7.2.5


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

* [PATCH 4/9 v4] mmc: add CD GPIO polling support to slot functions
@ 2012-06-22 13:23   ` Guennadi Liakhovetski
  0 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-06-22 13:23 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-mmc, Magnus Damm, Chris Ball

A simple extension of mmc slot functions add support for CD GPIO polling
for cases, where the GPIO cannot produce interrupts or this is for some
reason not desired.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v4:

1. gpio variables are now signed
2. take care to mark gpio variables as invalid in hotplug context
3. MMC_CAP2_*_ACTIVE_HIGH inverted compared to v3

 drivers/mmc/core/slot-gpio.c  |   56 +++++++++++++++++++++++++++++++---------
 include/linux/mmc/slot-gpio.h |    2 +
 2 files changed, 45 insertions(+), 13 deletions(-)

diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
index 468e5a0..92cba02 100644
--- a/drivers/mmc/core/slot-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -18,7 +18,7 @@
 #include <linux/slab.h>
 
 struct mmc_gpio {
-	unsigned int cd_gpio;
+	int cd_gpio;
 	char cd_label[0];
 };
 
@@ -29,6 +29,18 @@ static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+int mmc_gpio_get_cd(struct mmc_host *host)
+{
+	struct mmc_gpio *ctx = host->slot.handler_priv;
+
+	if (!ctx || !gpio_is_valid(ctx->cd_gpio))
+		return -ENOSYS;
+
+	return !gpio_get_value_cansleep(ctx->cd_gpio) ^
+		!!(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH);
+}
+EXPORT_SYMBOL(mmc_gpio_get_cd);
+
 int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 {
 	size_t len = strlen(dev_name(host->parent)) + 4;
@@ -36,9 +48,6 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 	int irq = gpio_to_irq(gpio);
 	int ret;
 
-	if (irq < 0)
-		return irq;
-
 	ctx = kmalloc(sizeof(*ctx) + len, GFP_KERNEL);
 	if (!ctx)
 		return -ENOMEM;
@@ -49,20 +58,32 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 	if (ret < 0)
 		goto egpioreq;
 
-	ret = request_threaded_irq(irq, NULL, mmc_gpio_cd_irqt,
+	/*
+	 * Even if gpio_to_irq() returns a valid IRQ number, the platform might
+	 * still prefer to poll, e.g., because that IRQ number is already used
+	 * by another unit and cannot be shared.
+	 */
+	if (irq >= 0 && host->caps & MMC_CAP_NEEDS_POLL)
+		irq = -EINVAL;
+
+	if (irq >= 0) {
+		ret = request_threaded_irq(irq, NULL, mmc_gpio_cd_irqt,
 			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 			ctx->cd_label, host);
-	if (ret < 0)
-		goto eirqreq;
+		if (ret < 0)
+			irq = ret;
+	}
 
-	ctx->cd_gpio = gpio;
 	host->slot.cd_irq = irq;
+
+	if (irq < 0)
+		host->caps |= MMC_CAP_NEEDS_POLL;
+
+	ctx->cd_gpio = gpio;
 	host->slot.handler_priv = ctx;
 
 	return 0;
 
-eirqreq:
-	gpio_free(gpio);
 egpioreq:
 	kfree(ctx);
 	return ret;
@@ -72,12 +93,21 @@ EXPORT_SYMBOL(mmc_gpio_request_cd);
 void mmc_gpio_free_cd(struct mmc_host *host)
 {
 	struct mmc_gpio *ctx = host->slot.handler_priv;
+	int gpio;
 
-	if (!ctx)
+	if (!ctx || !gpio_is_valid(ctx->cd_gpio))
 		return;
 
-	free_irq(host->slot.cd_irq, host);
-	gpio_free(ctx->cd_gpio);
+	if (host->slot.cd_irq >= 0) {
+		free_irq(host->slot.cd_irq, host);
+		host->slot.cd_irq = -EINVAL;
+	}
+
+	gpio = ctx->cd_gpio;
+	ctx->cd_gpio = -EINVAL;
+
+	gpio_free(gpio);
+	host->slot.handler_priv = NULL;
 	kfree(ctx);
 }
 EXPORT_SYMBOL(mmc_gpio_free_cd);
diff --git a/include/linux/mmc/slot-gpio.h b/include/linux/mmc/slot-gpio.h
index edfaa32..1a977d7 100644
--- a/include/linux/mmc/slot-gpio.h
+++ b/include/linux/mmc/slot-gpio.h
@@ -12,6 +12,8 @@
 #define MMC_SLOT_GPIO_H
 
 struct mmc_host;
+
+int mmc_gpio_get_cd(struct mmc_host *host);
 int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio);
 void mmc_gpio_free_cd(struct mmc_host *host);
 
-- 
1.7.2.5


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

* [PATCH 5/9 v4] mmc: convert slot functions to managed allocation
  2012-06-22 13:23 ` Guennadi Liakhovetski
@ 2012-06-22 13:23   ` Guennadi Liakhovetski
  -1 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-06-22 13:23 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-mmc, Magnus Damm, Chris Ball

This prepares for the addition of further slot functions.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v4:

1. gpio variables are now signed
2. take care to mark gpio variables as invalid in hotplug context
3. MMC_CAP2_*_ACTIVE_HIGH inverted compared to v3

 drivers/mmc/core/host.c      |    2 +
 drivers/mmc/core/slot-gpio.c |   51 +++++++++++++++++++++++++++++++----------
 include/linux/mmc/host.h     |    3 ++
 3 files changed, 43 insertions(+), 13 deletions(-)

diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index b8c5290..74cf29a5 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -32,6 +32,7 @@
 static void mmc_host_classdev_release(struct device *dev)
 {
 	struct mmc_host *host = cls_dev_to_mmc_host(dev);
+	mutex_destroy(&host->slot.lock);
 	kfree(host);
 }
 
@@ -327,6 +328,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
 
 	mmc_host_clk_init(host);
 
+	mutex_init(&host->slot.lock);
 	host->slot.cd_irq = -EINVAL;
 
 	spin_lock_init(&host->lock);
diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
index 92cba02..41689da 100644
--- a/drivers/mmc/core/slot-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -29,6 +29,34 @@ static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static int mmc_gpio_alloc(struct mmc_host *host)
+{
+	size_t len = strlen(dev_name(host->parent)) + 4;
+	struct mmc_gpio *ctx;
+
+	mutex_lock(&host->slot.lock);
+
+	ctx = host->slot.handler_priv;
+	if (!ctx) {
+		/*
+		 * devm_kzalloc() can be called after device_initialize(), even
+		 * before device_add(), i.e., between mmc_alloc_host() and
+		 * mmc_add_host()
+		 */
+		ctx = devm_kzalloc(&host->class_dev, sizeof(*ctx) + len,
+				   GFP_KERNEL);
+		if (ctx) {
+			snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent));
+			ctx->cd_gpio = -EINVAL;
+			host->slot.handler_priv = ctx;
+		}
+	}
+
+	mutex_unlock(&host->slot.lock);
+
+	return ctx ? 0 : -ENOMEM;
+}
+
 int mmc_gpio_get_cd(struct mmc_host *host)
 {
 	struct mmc_gpio *ctx = host->slot.handler_priv;
@@ -43,20 +71,24 @@ EXPORT_SYMBOL(mmc_gpio_get_cd);
 
 int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 {
-	size_t len = strlen(dev_name(host->parent)) + 4;
 	struct mmc_gpio *ctx;
 	int irq = gpio_to_irq(gpio);
 	int ret;
 
-	ctx = kmalloc(sizeof(*ctx) + len, GFP_KERNEL);
-	if (!ctx)
-		return -ENOMEM;
+	ret = mmc_gpio_alloc(host);
+	if (ret < 0)
+		return ret;
 
-	snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent));
+	ctx = host->slot.handler_priv;
 
 	ret = gpio_request_one(gpio, GPIOF_DIR_IN, ctx->cd_label);
 	if (ret < 0)
-		goto egpioreq;
+		/*
+		 * don't bother freeing memory. It might still get used by other
+		 * slot functions, in any case it will be freed, when the device
+		 * is destroyed.
+		 */
+		return ret;
 
 	/*
 	 * Even if gpio_to_irq() returns a valid IRQ number, the platform might
@@ -80,13 +112,8 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 		host->caps |= MMC_CAP_NEEDS_POLL;
 
 	ctx->cd_gpio = gpio;
-	host->slot.handler_priv = ctx;
 
 	return 0;
-
-egpioreq:
-	kfree(ctx);
-	return ret;
 }
 EXPORT_SYMBOL(mmc_gpio_request_cd);
 
@@ -107,7 +134,5 @@ void mmc_gpio_free_cd(struct mmc_host *host)
 	ctx->cd_gpio = -EINVAL;
 
 	gpio_free(gpio);
-	host->slot.handler_priv = NULL;
-	kfree(ctx);
 }
 EXPORT_SYMBOL(mmc_gpio_free_cd);
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index c1a03ee..65c64ee 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -11,6 +11,7 @@
 #define LINUX_MMC_HOST_H
 
 #include <linux/leds.h>
+#include <linux/mutex.h>
 #include <linux/sched.h>
 #include <linux/device.h>
 #include <linux/fault-inject.h>
@@ -154,6 +155,7 @@ struct mmc_async_req {
  * struct mmc_slot - MMC slot functions
  *
  * @cd_irq:		MMC/SD-card slot hotplug detection IRQ or -EINVAL
+ * @lock:		protect the @handler_priv pointer
  * @handler_priv:	MMC/SD-card slot context
  *
  * Some MMC/SD host controllers implement slot-functions like card and
@@ -163,6 +165,7 @@ struct mmc_async_req {
  */
 struct mmc_slot {
 	int cd_irq;
+	struct mutex lock;
 	void *handler_priv;
 };
 
-- 
1.7.2.5


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

* [PATCH 5/9 v4] mmc: convert slot functions to managed allocation
@ 2012-06-22 13:23   ` Guennadi Liakhovetski
  0 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-06-22 13:23 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-mmc, Magnus Damm, Chris Ball

This prepares for the addition of further slot functions.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v4:

1. gpio variables are now signed
2. take care to mark gpio variables as invalid in hotplug context
3. MMC_CAP2_*_ACTIVE_HIGH inverted compared to v3

 drivers/mmc/core/host.c      |    2 +
 drivers/mmc/core/slot-gpio.c |   51 +++++++++++++++++++++++++++++++----------
 include/linux/mmc/host.h     |    3 ++
 3 files changed, 43 insertions(+), 13 deletions(-)

diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index b8c5290..74cf29a5 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -32,6 +32,7 @@
 static void mmc_host_classdev_release(struct device *dev)
 {
 	struct mmc_host *host = cls_dev_to_mmc_host(dev);
+	mutex_destroy(&host->slot.lock);
 	kfree(host);
 }
 
@@ -327,6 +328,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
 
 	mmc_host_clk_init(host);
 
+	mutex_init(&host->slot.lock);
 	host->slot.cd_irq = -EINVAL;
 
 	spin_lock_init(&host->lock);
diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
index 92cba02..41689da 100644
--- a/drivers/mmc/core/slot-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -29,6 +29,34 @@ static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static int mmc_gpio_alloc(struct mmc_host *host)
+{
+	size_t len = strlen(dev_name(host->parent)) + 4;
+	struct mmc_gpio *ctx;
+
+	mutex_lock(&host->slot.lock);
+
+	ctx = host->slot.handler_priv;
+	if (!ctx) {
+		/*
+		 * devm_kzalloc() can be called after device_initialize(), even
+		 * before device_add(), i.e., between mmc_alloc_host() and
+		 * mmc_add_host()
+		 */
+		ctx = devm_kzalloc(&host->class_dev, sizeof(*ctx) + len,
+				   GFP_KERNEL);
+		if (ctx) {
+			snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent));
+			ctx->cd_gpio = -EINVAL;
+			host->slot.handler_priv = ctx;
+		}
+	}
+
+	mutex_unlock(&host->slot.lock);
+
+	return ctx ? 0 : -ENOMEM;
+}
+
 int mmc_gpio_get_cd(struct mmc_host *host)
 {
 	struct mmc_gpio *ctx = host->slot.handler_priv;
@@ -43,20 +71,24 @@ EXPORT_SYMBOL(mmc_gpio_get_cd);
 
 int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 {
-	size_t len = strlen(dev_name(host->parent)) + 4;
 	struct mmc_gpio *ctx;
 	int irq = gpio_to_irq(gpio);
 	int ret;
 
-	ctx = kmalloc(sizeof(*ctx) + len, GFP_KERNEL);
-	if (!ctx)
-		return -ENOMEM;
+	ret = mmc_gpio_alloc(host);
+	if (ret < 0)
+		return ret;
 
-	snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent));
+	ctx = host->slot.handler_priv;
 
 	ret = gpio_request_one(gpio, GPIOF_DIR_IN, ctx->cd_label);
 	if (ret < 0)
-		goto egpioreq;
+		/*
+		 * don't bother freeing memory. It might still get used by other
+		 * slot functions, in any case it will be freed, when the device
+		 * is destroyed.
+		 */
+		return ret;
 
 	/*
 	 * Even if gpio_to_irq() returns a valid IRQ number, the platform might
@@ -80,13 +112,8 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 		host->caps |= MMC_CAP_NEEDS_POLL;
 
 	ctx->cd_gpio = gpio;
-	host->slot.handler_priv = ctx;
 
 	return 0;
-
-egpioreq:
-	kfree(ctx);
-	return ret;
 }
 EXPORT_SYMBOL(mmc_gpio_request_cd);
 
@@ -107,7 +134,5 @@ void mmc_gpio_free_cd(struct mmc_host *host)
 	ctx->cd_gpio = -EINVAL;
 
 	gpio_free(gpio);
-	host->slot.handler_priv = NULL;
-	kfree(ctx);
 }
 EXPORT_SYMBOL(mmc_gpio_free_cd);
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index c1a03ee..65c64ee 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -11,6 +11,7 @@
 #define LINUX_MMC_HOST_H
 
 #include <linux/leds.h>
+#include <linux/mutex.h>
 #include <linux/sched.h>
 #include <linux/device.h>
 #include <linux/fault-inject.h>
@@ -154,6 +155,7 @@ struct mmc_async_req {
  * struct mmc_slot - MMC slot functions
  *
  * @cd_irq:		MMC/SD-card slot hotplug detection IRQ or -EINVAL
+ * @lock:		protect the @handler_priv pointer
  * @handler_priv:	MMC/SD-card slot context
  *
  * Some MMC/SD host controllers implement slot-functions like card and
@@ -163,6 +165,7 @@ struct mmc_async_req {
  */
 struct mmc_slot {
 	int cd_irq;
+	struct mutex lock;
 	void *handler_priv;
 };
 
-- 
1.7.2.5


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

* [PATCH 6/9 v4] mmc: add WP pin handler to slot functions
  2012-06-22 13:23 ` Guennadi Liakhovetski
@ 2012-06-22 13:23   ` Guennadi Liakhovetski
  -1 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-06-22 13:23 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-mmc, Magnus Damm, Chris Ball

Card Write-Protect pin is often implemented, using a GPIO, which makes it
simple to provide a generic handler for it.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v4:

1. gpio variables are now signed
2. take care to mark gpio variables as invalid in hotplug context
3. MMC_CAP2_*_ACTIVE_HIGH inverted compared to v3

 drivers/mmc/core/slot-gpio.c  |   52 ++++++++++++++++++++++++++++++++++++++++-
 include/linux/mmc/slot-gpio.h |    4 +++
 2 files changed, 55 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
index 41689da..0582429 100644
--- a/drivers/mmc/core/slot-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -18,7 +18,9 @@
 #include <linux/slab.h>
 
 struct mmc_gpio {
+	int ro_gpio;
 	int cd_gpio;
+	char *ro_label;
 	char cd_label[0];
 };
 
@@ -43,11 +45,14 @@ static int mmc_gpio_alloc(struct mmc_host *host)
 		 * before device_add(), i.e., between mmc_alloc_host() and
 		 * mmc_add_host()
 		 */
-		ctx = devm_kzalloc(&host->class_dev, sizeof(*ctx) + len,
+		ctx = devm_kzalloc(&host->class_dev, sizeof(*ctx) + 2 * len,
 				   GFP_KERNEL);
 		if (ctx) {
+			ctx->ro_label = ctx->cd_label + len;
 			snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent));
+			snprintf(ctx->ro_label, len, "%s ro", dev_name(host->parent));
 			ctx->cd_gpio = -EINVAL;
+			ctx->ro_gpio = -EINVAL;
 			host->slot.handler_priv = ctx;
 		}
 	}
@@ -57,6 +62,18 @@ static int mmc_gpio_alloc(struct mmc_host *host)
 	return ctx ? 0 : -ENOMEM;
 }
 
+int mmc_gpio_get_ro(struct mmc_host *host)
+{
+	struct mmc_gpio *ctx = host->slot.handler_priv;
+
+	if (!ctx || !gpio_is_valid(ctx->ro_gpio))
+		return -ENOSYS;
+
+	return !gpio_get_value_cansleep(ctx->ro_gpio) ^
+		!!(host->caps2 & MMC_CAP2_RO_ACTIVE_HIGH);
+}
+EXPORT_SYMBOL(mmc_gpio_get_ro);
+
 int mmc_gpio_get_cd(struct mmc_host *host)
 {
 	struct mmc_gpio *ctx = host->slot.handler_priv;
@@ -69,6 +86,24 @@ int mmc_gpio_get_cd(struct mmc_host *host)
 }
 EXPORT_SYMBOL(mmc_gpio_get_cd);
 
+int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio)
+{
+	struct mmc_gpio *ctx;
+	int ret;
+
+	if (!gpio_is_valid(gpio))
+		return -EINVAL;
+
+	ret = mmc_gpio_alloc(host);
+	if (ret < 0)
+		return ret;
+
+	ctx = host->slot.handler_priv;
+
+	return gpio_request_one(gpio, GPIOF_DIR_IN, ctx->ro_label);
+}
+EXPORT_SYMBOL(mmc_gpio_request_ro);
+
 int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 {
 	struct mmc_gpio *ctx;
@@ -117,6 +152,21 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 }
 EXPORT_SYMBOL(mmc_gpio_request_cd);
 
+void mmc_gpio_free_ro(struct mmc_host *host)
+{
+	struct mmc_gpio *ctx = host->slot.handler_priv;
+	int gpio;
+
+	if (!ctx || !gpio_is_valid(ctx->ro_gpio))
+		return;
+
+	gpio = ctx->ro_gpio;
+	ctx->ro_gpio = -EINVAL;
+
+	gpio_free(gpio);
+}
+EXPORT_SYMBOL(mmc_gpio_free_ro);
+
 void mmc_gpio_free_cd(struct mmc_host *host)
 {
 	struct mmc_gpio *ctx = host->slot.handler_priv;
diff --git a/include/linux/mmc/slot-gpio.h b/include/linux/mmc/slot-gpio.h
index 1a977d7..7d88d27 100644
--- a/include/linux/mmc/slot-gpio.h
+++ b/include/linux/mmc/slot-gpio.h
@@ -13,6 +13,10 @@
 
 struct mmc_host;
 
+int mmc_gpio_get_ro(struct mmc_host *host);
+int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio);
+void mmc_gpio_free_ro(struct mmc_host *host);
+
 int mmc_gpio_get_cd(struct mmc_host *host);
 int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio);
 void mmc_gpio_free_cd(struct mmc_host *host);
-- 
1.7.2.5


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

* [PATCH 6/9 v4] mmc: add WP pin handler to slot functions
@ 2012-06-22 13:23   ` Guennadi Liakhovetski
  0 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-06-22 13:23 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-mmc, Magnus Damm, Chris Ball

Card Write-Protect pin is often implemented, using a GPIO, which makes it
simple to provide a generic handler for it.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

v4:

1. gpio variables are now signed
2. take care to mark gpio variables as invalid in hotplug context
3. MMC_CAP2_*_ACTIVE_HIGH inverted compared to v3

 drivers/mmc/core/slot-gpio.c  |   52 ++++++++++++++++++++++++++++++++++++++++-
 include/linux/mmc/slot-gpio.h |    4 +++
 2 files changed, 55 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
index 41689da..0582429 100644
--- a/drivers/mmc/core/slot-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -18,7 +18,9 @@
 #include <linux/slab.h>
 
 struct mmc_gpio {
+	int ro_gpio;
 	int cd_gpio;
+	char *ro_label;
 	char cd_label[0];
 };
 
@@ -43,11 +45,14 @@ static int mmc_gpio_alloc(struct mmc_host *host)
 		 * before device_add(), i.e., between mmc_alloc_host() and
 		 * mmc_add_host()
 		 */
-		ctx = devm_kzalloc(&host->class_dev, sizeof(*ctx) + len,
+		ctx = devm_kzalloc(&host->class_dev, sizeof(*ctx) + 2 * len,
 				   GFP_KERNEL);
 		if (ctx) {
+			ctx->ro_label = ctx->cd_label + len;
 			snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent));
+			snprintf(ctx->ro_label, len, "%s ro", dev_name(host->parent));
 			ctx->cd_gpio = -EINVAL;
+			ctx->ro_gpio = -EINVAL;
 			host->slot.handler_priv = ctx;
 		}
 	}
@@ -57,6 +62,18 @@ static int mmc_gpio_alloc(struct mmc_host *host)
 	return ctx ? 0 : -ENOMEM;
 }
 
+int mmc_gpio_get_ro(struct mmc_host *host)
+{
+	struct mmc_gpio *ctx = host->slot.handler_priv;
+
+	if (!ctx || !gpio_is_valid(ctx->ro_gpio))
+		return -ENOSYS;
+
+	return !gpio_get_value_cansleep(ctx->ro_gpio) ^
+		!!(host->caps2 & MMC_CAP2_RO_ACTIVE_HIGH);
+}
+EXPORT_SYMBOL(mmc_gpio_get_ro);
+
 int mmc_gpio_get_cd(struct mmc_host *host)
 {
 	struct mmc_gpio *ctx = host->slot.handler_priv;
@@ -69,6 +86,24 @@ int mmc_gpio_get_cd(struct mmc_host *host)
 }
 EXPORT_SYMBOL(mmc_gpio_get_cd);
 
+int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio)
+{
+	struct mmc_gpio *ctx;
+	int ret;
+
+	if (!gpio_is_valid(gpio))
+		return -EINVAL;
+
+	ret = mmc_gpio_alloc(host);
+	if (ret < 0)
+		return ret;
+
+	ctx = host->slot.handler_priv;
+
+	return gpio_request_one(gpio, GPIOF_DIR_IN, ctx->ro_label);
+}
+EXPORT_SYMBOL(mmc_gpio_request_ro);
+
 int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 {
 	struct mmc_gpio *ctx;
@@ -117,6 +152,21 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
 }
 EXPORT_SYMBOL(mmc_gpio_request_cd);
 
+void mmc_gpio_free_ro(struct mmc_host *host)
+{
+	struct mmc_gpio *ctx = host->slot.handler_priv;
+	int gpio;
+
+	if (!ctx || !gpio_is_valid(ctx->ro_gpio))
+		return;
+
+	gpio = ctx->ro_gpio;
+	ctx->ro_gpio = -EINVAL;
+
+	gpio_free(gpio);
+}
+EXPORT_SYMBOL(mmc_gpio_free_ro);
+
 void mmc_gpio_free_cd(struct mmc_host *host)
 {
 	struct mmc_gpio *ctx = host->slot.handler_priv;
diff --git a/include/linux/mmc/slot-gpio.h b/include/linux/mmc/slot-gpio.h
index 1a977d7..7d88d27 100644
--- a/include/linux/mmc/slot-gpio.h
+++ b/include/linux/mmc/slot-gpio.h
@@ -13,6 +13,10 @@
 
 struct mmc_host;
 
+int mmc_gpio_get_ro(struct mmc_host *host);
+int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio);
+void mmc_gpio_free_ro(struct mmc_host *host);
+
 int mmc_gpio_get_cd(struct mmc_host *host);
 int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio);
 void mmc_gpio_free_cd(struct mmc_host *host);
-- 
1.7.2.5


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

* [PATCH 7/9 v4] mmc: tmio: support caps2 flags
  2012-06-22 13:23 ` Guennadi Liakhovetski
@ 2012-06-22 13:23   ` Guennadi Liakhovetski
  -1 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-06-22 13:23 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-mmc, Magnus Damm, Chris Ball

Allow tmio mmc glue drivers pass mmc_host::caps2 flags down to the mmc
layer.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/tmio_mmc_pio.c |    1 +
 include/linux/mfd/tmio.h        |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index b204012f..f8df021 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -951,6 +951,7 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
 
 	mmc->ops = &tmio_mmc_ops;
 	mmc->caps = MMC_CAP_4_BIT_DATA | pdata->capabilities;
+	mmc->caps2 = pdata->capabilities2;
 	mmc->max_segs = 32;
 	mmc->max_blk_size = 512;
 	mmc->max_blk_count = (PAGE_CACHE_SIZE / mmc->max_blk_size) *
diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h
index b332c4c..d83af39 100644
--- a/include/linux/mfd/tmio.h
+++ b/include/linux/mfd/tmio.h
@@ -101,6 +101,7 @@ struct tmio_mmc_host;
 struct tmio_mmc_data {
 	unsigned int			hclk;
 	unsigned long			capabilities;
+	unsigned long			capabilities2;
 	unsigned long			flags;
 	u32				ocr_mask;	/* available voltages */
 	struct tmio_mmc_dma		*dma;
-- 
1.7.2.5


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

* [PATCH 7/9 v4] mmc: tmio: support caps2 flags
@ 2012-06-22 13:23   ` Guennadi Liakhovetski
  0 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-06-22 13:23 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-mmc, Magnus Damm, Chris Ball

Allow tmio mmc glue drivers pass mmc_host::caps2 flags down to the mmc
layer.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/tmio_mmc_pio.c |    1 +
 include/linux/mfd/tmio.h        |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index b204012f..f8df021 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -951,6 +951,7 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
 
 	mmc->ops = &tmio_mmc_ops;
 	mmc->caps = MMC_CAP_4_BIT_DATA | pdata->capabilities;
+	mmc->caps2 = pdata->capabilities2;
 	mmc->max_segs = 32;
 	mmc->max_blk_size = 512;
 	mmc->max_blk_count = (PAGE_CACHE_SIZE / mmc->max_blk_size) *
diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h
index b332c4c..d83af39 100644
--- a/include/linux/mfd/tmio.h
+++ b/include/linux/mfd/tmio.h
@@ -101,6 +101,7 @@ struct tmio_mmc_host;
 struct tmio_mmc_data {
 	unsigned int			hclk;
 	unsigned long			capabilities;
+	unsigned long			capabilities2;
 	unsigned long			flags;
 	u32				ocr_mask;	/* available voltages */
 	struct tmio_mmc_dma		*dma;
-- 
1.7.2.5


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

* [PATCH 8/9 v4] mmc: sh_mobile_sdhi: support caps2 flags
  2012-06-22 13:23 ` Guennadi Liakhovetski
@ 2012-06-22 13:23   ` Guennadi Liakhovetski
  -1 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-06-22 13:23 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-mmc, Magnus Damm, Chris Ball

Let SDHI platforms specify mmc_host::caps2 flags in their platform data.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/sh_mobile_sdhi.c  |    1 +
 include/linux/mmc/sh_mobile_sdhi.h |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 42f07fa..1e7c5c4 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -162,6 +162,7 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
 			mmc_data->write16_hook = sh_mobile_sdhi_write16_hook;
 		mmc_data->ocr_mask = p->tmio_ocr_mask;
 		mmc_data->capabilities |= p->tmio_caps;
+		mmc_data->capabilities2 |= p->tmio_caps2;
 		mmc_data->cd_gpio = p->cd_gpio;
 
 		if (p->dma_slave_tx > 0 && p->dma_slave_rx > 0) {
diff --git a/include/linux/mmc/sh_mobile_sdhi.h b/include/linux/mmc/sh_mobile_sdhi.h
index e94e620..b65679f 100644
--- a/include/linux/mmc/sh_mobile_sdhi.h
+++ b/include/linux/mmc/sh_mobile_sdhi.h
@@ -23,6 +23,7 @@ struct sh_mobile_sdhi_info {
 	int dma_slave_rx;
 	unsigned long tmio_flags;
 	unsigned long tmio_caps;
+	unsigned long tmio_caps2;
 	u32 tmio_ocr_mask;	/* available MMC voltages */
 	unsigned int cd_gpio;
 	struct tmio_mmc_data *pdata;
-- 
1.7.2.5


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

* [PATCH 8/9 v4] mmc: sh_mobile_sdhi: support caps2 flags
@ 2012-06-22 13:23   ` Guennadi Liakhovetski
  0 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-06-22 13:23 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-mmc, Magnus Damm, Chris Ball

Let SDHI platforms specify mmc_host::caps2 flags in their platform data.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/sh_mobile_sdhi.c  |    1 +
 include/linux/mmc/sh_mobile_sdhi.h |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 42f07fa..1e7c5c4 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -162,6 +162,7 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
 			mmc_data->write16_hook = sh_mobile_sdhi_write16_hook;
 		mmc_data->ocr_mask = p->tmio_ocr_mask;
 		mmc_data->capabilities |= p->tmio_caps;
+		mmc_data->capabilities2 |= p->tmio_caps2;
 		mmc_data->cd_gpio = p->cd_gpio;
 
 		if (p->dma_slave_tx > 0 && p->dma_slave_rx > 0) {
diff --git a/include/linux/mmc/sh_mobile_sdhi.h b/include/linux/mmc/sh_mobile_sdhi.h
index e94e620..b65679f 100644
--- a/include/linux/mmc/sh_mobile_sdhi.h
+++ b/include/linux/mmc/sh_mobile_sdhi.h
@@ -23,6 +23,7 @@ struct sh_mobile_sdhi_info {
 	int dma_slave_rx;
 	unsigned long tmio_flags;
 	unsigned long tmio_caps;
+	unsigned long tmio_caps2;
 	u32 tmio_ocr_mask;	/* available MMC voltages */
 	unsigned int cd_gpio;
 	struct tmio_mmc_data *pdata;
-- 
1.7.2.5


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

* [PATCH 9/9 v4] mmc: tmio: use generic GPIO CD and WP handlers
  2012-06-22 13:23 ` Guennadi Liakhovetski
@ 2012-06-22 13:23   ` Guennadi Liakhovetski
  -1 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-06-22 13:23 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-mmc, Magnus Damm, Chris Ball

The tmio-mmc driver is already using the generic GPIO CD handler in IRQ
mode. This patch adds support for CD polling mode and also checks for
availability of a WP GPIO.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/tmio_mmc_pio.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index f8df021..0d8a9bb 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -875,6 +875,9 @@ static int tmio_mmc_get_ro(struct mmc_host *mmc)
 {
 	struct tmio_mmc_host *host = mmc_priv(mmc);
 	struct tmio_mmc_data *pdata = host->pdata;
+	int ret = mmc_gpio_get_ro(mmc);
+	if (ret >= 0)
+		return ret;
 
 	return !((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) ||
 		 (sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT));
@@ -884,6 +887,9 @@ static int tmio_mmc_get_cd(struct mmc_host *mmc)
 {
 	struct tmio_mmc_host *host = mmc_priv(mmc);
 	struct tmio_mmc_data *pdata = host->pdata;
+	int ret = mmc_gpio_get_cd(mmc);
+	if (ret >= 0)
+		return ret;
 
 	if (!pdata->get_cd)
 		return -ENOSYS;
-- 
1.7.2.5


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

* [PATCH 9/9 v4] mmc: tmio: use generic GPIO CD and WP handlers
@ 2012-06-22 13:23   ` Guennadi Liakhovetski
  0 siblings, 0 replies; 20+ messages in thread
From: Guennadi Liakhovetski @ 2012-06-22 13:23 UTC (permalink / raw)
  To: linux-sh; +Cc: linux-mmc, Magnus Damm, Chris Ball

The tmio-mmc driver is already using the generic GPIO CD handler in IRQ
mode. This patch adds support for CD polling mode and also checks for
availability of a WP GPIO.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/mmc/host/tmio_mmc_pio.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index f8df021..0d8a9bb 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -875,6 +875,9 @@ static int tmio_mmc_get_ro(struct mmc_host *mmc)
 {
 	struct tmio_mmc_host *host = mmc_priv(mmc);
 	struct tmio_mmc_data *pdata = host->pdata;
+	int ret = mmc_gpio_get_ro(mmc);
+	if (ret >= 0)
+		return ret;
 
 	return !((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) ||
 		 (sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT));
@@ -884,6 +887,9 @@ static int tmio_mmc_get_cd(struct mmc_host *mmc)
 {
 	struct tmio_mmc_host *host = mmc_priv(mmc);
 	struct tmio_mmc_data *pdata = host->pdata;
+	int ret = mmc_gpio_get_cd(mmc);
+	if (ret >= 0)
+		return ret;
 
 	if (!pdata->get_cd)
 		return -ENOSYS;
-- 
1.7.2.5


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

end of thread, other threads:[~2012-06-22 13:23 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-22 13:23 [PATCH 0/9 v4] mmc: cd-gpio: extend to handle more slot functions Guennadi Liakhovetski
2012-06-22 13:23 ` Guennadi Liakhovetski
2012-06-22 13:23 ` [PATCH 1/9 v4] mmc: extend and rename cd-gpio helpers to handle more slot GPIO functions Guennadi Liakhovetski
2012-06-22 13:23   ` Guennadi Liakhovetski
2012-06-22 13:23 ` [PATCH 2/9 v4] mmc: use a more generic name for slot function types and fields Guennadi Liakhovetski
2012-06-22 13:23   ` Guennadi Liakhovetski
2012-06-22 13:23 ` [PATCH 3/9 v4] mmc: add two capability flags for CD and WP signal polarity Guennadi Liakhovetski
2012-06-22 13:23   ` Guennadi Liakhovetski
2012-06-22 13:23 ` [PATCH 4/9 v4] mmc: add CD GPIO polling support to slot functions Guennadi Liakhovetski
2012-06-22 13:23   ` Guennadi Liakhovetski
2012-06-22 13:23 ` [PATCH 5/9 v4] mmc: convert slot functions to managed allocation Guennadi Liakhovetski
2012-06-22 13:23   ` Guennadi Liakhovetski
2012-06-22 13:23 ` [PATCH 6/9 v4] mmc: add WP pin handler to slot functions Guennadi Liakhovetski
2012-06-22 13:23   ` Guennadi Liakhovetski
2012-06-22 13:23 ` [PATCH 7/9 v4] mmc: tmio: support caps2 flags Guennadi Liakhovetski
2012-06-22 13:23   ` Guennadi Liakhovetski
2012-06-22 13:23 ` [PATCH 8/9 v4] mmc: sh_mobile_sdhi: " Guennadi Liakhovetski
2012-06-22 13:23   ` Guennadi Liakhovetski
2012-06-22 13:23 ` [PATCH 9/9 v4] mmc: tmio: use generic GPIO CD and WP handlers Guennadi Liakhovetski
2012-06-22 13:23   ` Guennadi Liakhovetski

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.