Commit 5aa7dad3 authored by Guennadi Liakhovetski's avatar Guennadi Liakhovetski Committed by Chris Ball

mmc: core: add WP pin handler to slot functions

Card Write-Protect pin is often implemented, using a GPIO, which makes
it simple to provide a generic handler for it.
Signed-off-by: default avatarGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: default avatarChris Ball <cjb@laptop.org>
parent a7d1a1eb
...@@ -18,7 +18,9 @@ ...@@ -18,7 +18,9 @@
#include <linux/slab.h> #include <linux/slab.h>
struct mmc_gpio { struct mmc_gpio {
int ro_gpio;
int cd_gpio; int cd_gpio;
char *ro_label;
char cd_label[0]; char cd_label[0];
}; };
...@@ -43,11 +45,14 @@ static int mmc_gpio_alloc(struct mmc_host *host) ...@@ -43,11 +45,14 @@ static int mmc_gpio_alloc(struct mmc_host *host)
* before device_add(), i.e., between mmc_alloc_host() and * before device_add(), i.e., between mmc_alloc_host() and
* mmc_add_host() * mmc_add_host()
*/ */
ctx = devm_kzalloc(&host->class_dev, sizeof(*ctx) + len, ctx = devm_kzalloc(&host->class_dev, sizeof(*ctx) + 2 * len,
GFP_KERNEL); GFP_KERNEL);
if (ctx) { if (ctx) {
ctx->ro_label = ctx->cd_label + len;
snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent)); 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->cd_gpio = -EINVAL;
ctx->ro_gpio = -EINVAL;
host->slot.handler_priv = ctx; host->slot.handler_priv = ctx;
} }
} }
...@@ -57,6 +62,18 @@ static int mmc_gpio_alloc(struct mmc_host *host) ...@@ -57,6 +62,18 @@ static int mmc_gpio_alloc(struct mmc_host *host)
return ctx ? 0 : -ENOMEM; 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) int mmc_gpio_get_cd(struct mmc_host *host)
{ {
struct mmc_gpio *ctx = host->slot.handler_priv; struct mmc_gpio *ctx = host->slot.handler_priv;
...@@ -69,6 +86,24 @@ int mmc_gpio_get_cd(struct mmc_host *host) ...@@ -69,6 +86,24 @@ int mmc_gpio_get_cd(struct mmc_host *host)
} }
EXPORT_SYMBOL(mmc_gpio_get_cd); 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) int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
{ {
struct mmc_gpio *ctx; struct mmc_gpio *ctx;
...@@ -117,6 +152,21 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio) ...@@ -117,6 +152,21 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
} }
EXPORT_SYMBOL(mmc_gpio_request_cd); 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) void mmc_gpio_free_cd(struct mmc_host *host)
{ {
struct mmc_gpio *ctx = host->slot.handler_priv; struct mmc_gpio *ctx = host->slot.handler_priv;
......
...@@ -13,6 +13,10 @@ ...@@ -13,6 +13,10 @@
struct mmc_host; 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_get_cd(struct mmc_host *host);
int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio); int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio);
void mmc_gpio_free_cd(struct mmc_host *host); void mmc_gpio_free_cd(struct mmc_host *host);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment