mirror of https://gitee.com/openkylin/linux.git
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: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
parent
7fb2bbf4d9
commit
8900144692
|
@ -21,6 +21,7 @@
|
|||
#include <linux/amba/bus.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/div64.h>
|
||||
|
@ -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 = {
|
||||
.request = mmci_request,
|
||||
.set_ios = mmci_set_ios,
|
||||
.get_ro = mmci_get_ro,
|
||||
.get_cd = mmci_get_cd,
|
||||
};
|
||||
|
||||
static void mmci_check_status(unsigned long 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)
|
||||
mmc_detect_change(host->mmc, 0);
|
||||
|
||||
|
@ -516,6 +541,9 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
|
|||
host = mmc_priv(mmc);
|
||||
host->mmc = mmc;
|
||||
|
||||
host->gpio_wp = -ENOSYS;
|
||||
host->gpio_cd = -ENOSYS;
|
||||
|
||||
host->hw_designer = amba_manf(dev);
|
||||
host->hw_revision = amba_rev(dev);
|
||||
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)
|
|||
writel(0, host->base + MMCIMASK1);
|
||||
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);
|
||||
if (ret)
|
||||
goto unmap;
|
||||
|
@ -602,6 +649,7 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
|
|||
writel(MCI_IRQENABLE, host->base + MMCIMASK0);
|
||||
|
||||
amba_set_drvdata(dev, mmc);
|
||||
host->oldstat = mmci_get_cd(host->mmc);
|
||||
|
||||
mmc_add_host(mmc);
|
||||
|
||||
|
@ -620,6 +668,12 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
|
|||
irq0_free:
|
||||
free_irq(dev->irq[0], host);
|
||||
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);
|
||||
clk_disable:
|
||||
clk_disable(host->clk);
|
||||
|
@ -655,6 +709,11 @@ static int __devexit mmci_remove(struct amba_device *dev)
|
|||
free_irq(dev->irq[0], 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);
|
||||
clk_disable(host->clk);
|
||||
clk_put(host->clk);
|
||||
|
|
|
@ -151,6 +151,8 @@ struct mmci_host {
|
|||
struct mmc_data *data;
|
||||
struct mmc_host *mmc;
|
||||
struct clk *clk;
|
||||
int gpio_cd;
|
||||
int gpio_wp;
|
||||
|
||||
unsigned int data_xfered;
|
||||
|
||||
|
|
Loading…
Reference in New Issue