|
@@ -38,6 +38,7 @@
|
|
#include <linux/mmc/host.h>
|
|
#include <linux/mmc/host.h>
|
|
#include <linux/mmc/mmc.h>
|
|
#include <linux/mmc/mmc.h>
|
|
#include <linux/mmc/sdio.h>
|
|
#include <linux/mmc/sdio.h>
|
|
|
|
+#include <linux/mmc/slot-gpio.h>
|
|
#include <linux/gpio.h>
|
|
#include <linux/gpio.h>
|
|
#include <linux/regulator/consumer.h>
|
|
#include <linux/regulator/consumer.h>
|
|
#include <linux/module.h>
|
|
#include <linux/module.h>
|
|
@@ -69,26 +70,8 @@ struct mxs_mmc_host {
|
|
unsigned char bus_width;
|
|
unsigned char bus_width;
|
|
spinlock_t lock;
|
|
spinlock_t lock;
|
|
int sdio_irq_en;
|
|
int sdio_irq_en;
|
|
- int wp_gpio;
|
|
|
|
- bool wp_inverted;
|
|
|
|
};
|
|
};
|
|
|
|
|
|
-static int mxs_mmc_get_ro(struct mmc_host *mmc)
|
|
|
|
-{
|
|
|
|
- struct mxs_mmc_host *host = mmc_priv(mmc);
|
|
|
|
- int ret;
|
|
|
|
-
|
|
|
|
- if (!gpio_is_valid(host->wp_gpio))
|
|
|
|
- return -EINVAL;
|
|
|
|
-
|
|
|
|
- ret = gpio_get_value(host->wp_gpio);
|
|
|
|
-
|
|
|
|
- if (host->wp_inverted)
|
|
|
|
- ret = !ret;
|
|
|
|
-
|
|
|
|
- return ret;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static int mxs_mmc_get_cd(struct mmc_host *mmc)
|
|
static int mxs_mmc_get_cd(struct mmc_host *mmc)
|
|
{
|
|
{
|
|
struct mxs_mmc_host *host = mmc_priv(mmc);
|
|
struct mxs_mmc_host *host = mmc_priv(mmc);
|
|
@@ -551,7 +534,7 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
|
|
|
|
|
|
static const struct mmc_host_ops mxs_mmc_ops = {
|
|
static const struct mmc_host_ops mxs_mmc_ops = {
|
|
.request = mxs_mmc_request,
|
|
.request = mxs_mmc_request,
|
|
- .get_ro = mxs_mmc_get_ro,
|
|
|
|
|
|
+ .get_ro = mmc_gpio_get_ro,
|
|
.get_cd = mxs_mmc_get_cd,
|
|
.get_cd = mxs_mmc_get_cd,
|
|
.set_ios = mxs_mmc_set_ios,
|
|
.set_ios = mxs_mmc_set_ios,
|
|
.enable_sdio_irq = mxs_mmc_enable_sdio_irq,
|
|
.enable_sdio_irq = mxs_mmc_enable_sdio_irq,
|
|
@@ -585,7 +568,7 @@ static int mxs_mmc_probe(struct platform_device *pdev)
|
|
struct mxs_mmc_host *host;
|
|
struct mxs_mmc_host *host;
|
|
struct mmc_host *mmc;
|
|
struct mmc_host *mmc;
|
|
struct resource *iores;
|
|
struct resource *iores;
|
|
- int ret = 0, irq_err;
|
|
|
|
|
|
+ int ret = 0, irq_err, gpio;
|
|
struct regulator *reg_vmmc;
|
|
struct regulator *reg_vmmc;
|
|
enum of_gpio_flags flags;
|
|
enum of_gpio_flags flags;
|
|
struct mxs_ssp *ssp;
|
|
struct mxs_ssp *ssp;
|
|
@@ -659,9 +642,14 @@ static int mxs_mmc_probe(struct platform_device *pdev)
|
|
mmc->caps |= MMC_CAP_NEEDS_POLL;
|
|
mmc->caps |= MMC_CAP_NEEDS_POLL;
|
|
if (of_property_read_bool(np, "non-removable"))
|
|
if (of_property_read_bool(np, "non-removable"))
|
|
mmc->caps |= MMC_CAP_NONREMOVABLE;
|
|
mmc->caps |= MMC_CAP_NONREMOVABLE;
|
|
- host->wp_gpio = of_get_named_gpio_flags(np, "wp-gpios", 0, &flags);
|
|
|
|
- if (flags & OF_GPIO_ACTIVE_LOW)
|
|
|
|
- host->wp_inverted = 1;
|
|
|
|
|
|
+ gpio = of_get_named_gpio_flags(np, "wp-gpios", 0, &flags);
|
|
|
|
+ if (gpio_is_valid(gpio)) {
|
|
|
|
+ ret = mmc_gpio_request_ro(mmc, gpio);
|
|
|
|
+ if (ret)
|
|
|
|
+ goto out_clk_disable;
|
|
|
|
+ if (!(flags & OF_GPIO_ACTIVE_LOW))
|
|
|
|
+ mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
|
|
|
|
+ }
|
|
|
|
|
|
if (of_property_read_bool(np, "cd-inverted"))
|
|
if (of_property_read_bool(np, "cd-inverted"))
|
|
mmc->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
|
|
mmc->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
|