From c728b350d165094df1dcac6a1052c60340694edf Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 1 May 2012 16:59:38 +0200 Subject: [PATCH] --- yaml --- r: 312827 b: refs/heads/master c: 5aa7dad305594ea30d21e23b3036565042adf50c h: refs/heads/master i: 312825: ca93142b6dac3cef164197686236d5a16e5a63de 312823: 95d1642a10df582e1b8df7382ae9eca33a11d37f v: v3 --- [refs] | 2 +- trunk/drivers/mmc/core/slot-gpio.c | 52 ++++++++++++++++++++++++++++- trunk/include/linux/mmc/slot-gpio.h | 4 +++ 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index da53cfcb9ef7..e8ff2f273125 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: a7d1a1ebd8f5858a812ac3d5fbbc178b4959a63b +refs/heads/master: 5aa7dad305594ea30d21e23b3036565042adf50c diff --git a/trunk/drivers/mmc/core/slot-gpio.c b/trunk/drivers/mmc/core/slot-gpio.c index 41689da14b8d..058242916cef 100644 --- a/trunk/drivers/mmc/core/slot-gpio.c +++ b/trunk/drivers/mmc/core/slot-gpio.c @@ -18,7 +18,9 @@ #include 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/trunk/include/linux/mmc/slot-gpio.h b/trunk/include/linux/mmc/slot-gpio.h index 1a977d7ba3ba..7d88d27bfafa 100644 --- a/trunk/include/linux/mmc/slot-gpio.h +++ b/trunk/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);