Commit 89001446 authored by Russell King's avatar Russell King Committed by Russell King

MMC: MMCI: use gpiolib for card detect/write protect

Use gpiolib where available (and when valid GPIOs are provided) for
write protect/card detect status reporting.  We fall back to the old
'status' method where gpiolib support is not available.
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 7fb2bbf4
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/amba/bus.h> #include <linux/amba/bus.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <linux/gpio.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/div64.h> #include <asm/div64.h>
...@@ -472,17 +473,41 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) ...@@ -472,17 +473,41 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
} }
} }
static int mmci_get_ro(struct mmc_host *mmc)
{
struct mmci_host *host = mmc_priv(mmc);
if (host->gpio_wp == -ENOSYS)
return -ENOSYS;
return gpio_get_value(host->gpio_wp);
}
static int mmci_get_cd(struct mmc_host *mmc)
{
struct mmci_host *host = mmc_priv(mmc);
unsigned int status;
if (host->gpio_cd == -ENOSYS)
status = host->plat->status(mmc_dev(host->mmc));
else
status = gpio_get_value(host->gpio_cd);
return !status;
}
static const struct mmc_host_ops mmci_ops = { static const struct mmc_host_ops mmci_ops = {
.request = mmci_request, .request = mmci_request,
.set_ios = mmci_set_ios, .set_ios = mmci_set_ios,
.get_ro = mmci_get_ro,
.get_cd = mmci_get_cd,
}; };
static void mmci_check_status(unsigned long data) static void mmci_check_status(unsigned long data)
{ {
struct mmci_host *host = (struct mmci_host *)data; struct mmci_host *host = (struct mmci_host *)data;
unsigned int status; unsigned int status = mmci_get_cd(host->mmc);
status = host->plat->status(mmc_dev(host->mmc));
if (status ^ host->oldstat) if (status ^ host->oldstat)
mmc_detect_change(host->mmc, 0); mmc_detect_change(host->mmc, 0);
...@@ -516,6 +541,9 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) ...@@ -516,6 +541,9 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
host = mmc_priv(mmc); host = mmc_priv(mmc);
host->mmc = mmc; host->mmc = mmc;
host->gpio_wp = -ENOSYS;
host->gpio_cd = -ENOSYS;
host->hw_designer = amba_manf(dev); host->hw_designer = amba_manf(dev);
host->hw_revision = amba_rev(dev); host->hw_revision = amba_rev(dev);
DBG(host, "designer ID = 0x%02x\n", host->hw_designer); DBG(host, "designer ID = 0x%02x\n", host->hw_designer);
...@@ -591,6 +619,25 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) ...@@ -591,6 +619,25 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
writel(0, host->base + MMCIMASK1); writel(0, host->base + MMCIMASK1);
writel(0xfff, host->base + MMCICLEAR); writel(0xfff, host->base + MMCICLEAR);
if (gpio_is_valid(plat->gpio_cd)) {
ret = gpio_request(plat->gpio_cd, DRIVER_NAME " (cd)");
if (ret == 0)
ret = gpio_direction_input(plat->gpio_cd);
if (ret == 0)
host->gpio_cd = plat->gpio_cd;
else if (ret != -ENOSYS)
goto err_gpio_cd;
}
if (gpio_is_valid(plat->gpio_wp)) {
ret = gpio_request(plat->gpio_wp, DRIVER_NAME " (wp)");
if (ret == 0)
ret = gpio_direction_input(plat->gpio_wp);
if (ret == 0)
host->gpio_wp = plat->gpio_wp;
else if (ret != -ENOSYS)
goto err_gpio_wp;
}
ret = request_irq(dev->irq[0], mmci_irq, IRQF_SHARED, DRIVER_NAME " (cmd)", host); ret = request_irq(dev->irq[0], mmci_irq, IRQF_SHARED, DRIVER_NAME " (cmd)", host);
if (ret) if (ret)
goto unmap; goto unmap;
...@@ -602,6 +649,7 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) ...@@ -602,6 +649,7 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
writel(MCI_IRQENABLE, host->base + MMCIMASK0); writel(MCI_IRQENABLE, host->base + MMCIMASK0);
amba_set_drvdata(dev, mmc); amba_set_drvdata(dev, mmc);
host->oldstat = mmci_get_cd(host->mmc);
mmc_add_host(mmc); mmc_add_host(mmc);
...@@ -620,6 +668,12 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) ...@@ -620,6 +668,12 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
irq0_free: irq0_free:
free_irq(dev->irq[0], host); free_irq(dev->irq[0], host);
unmap: unmap:
if (host->gpio_wp != -ENOSYS)
gpio_free(host->gpio_wp);
err_gpio_wp:
if (host->gpio_cd != -ENOSYS)
gpio_free(host->gpio_cd);
err_gpio_cd:
iounmap(host->base); iounmap(host->base);
clk_disable: clk_disable:
clk_disable(host->clk); clk_disable(host->clk);
...@@ -655,6 +709,11 @@ static int __devexit mmci_remove(struct amba_device *dev) ...@@ -655,6 +709,11 @@ static int __devexit mmci_remove(struct amba_device *dev)
free_irq(dev->irq[0], host); free_irq(dev->irq[0], host);
free_irq(dev->irq[1], host); free_irq(dev->irq[1], host);
if (host->gpio_wp != -ENOSYS)
gpio_free(host->gpio_wp);
if (host->gpio_cd != -ENOSYS)
gpio_free(host->gpio_cd);
iounmap(host->base); iounmap(host->base);
clk_disable(host->clk); clk_disable(host->clk);
clk_put(host->clk); clk_put(host->clk);
......
...@@ -151,6 +151,8 @@ struct mmci_host { ...@@ -151,6 +151,8 @@ struct mmci_host {
struct mmc_data *data; struct mmc_data *data;
struct mmc_host *mmc; struct mmc_host *mmc;
struct clk *clk; struct clk *clk;
int gpio_cd;
int gpio_wp;
unsigned int data_xfered; unsigned int data_xfered;
......
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