diff options
author | Ulf Hansson <ulf.hansson@linaro.org> | 2014-03-17 08:56:19 -0400 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2014-05-12 06:52:35 -0400 |
commit | d2762090153053bca984ce5f8978953f63390401 (patch) | |
tree | b296837609fecca52cec1c544bffb444cfdbc3bb | |
parent | f3737fa388388bc864bc63b1c70e3679fe839a52 (diff) |
mmc: mmci: Convert to the mmc gpio API
To avoid duplication of code while handling card detect and write
protect GPIO pins/irqs, let's convert to use the mmc gpio API.
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-rw-r--r-- | drivers/mmc/host/mmci.c | 97 | ||||
-rw-r--r-- | drivers/mmc/host/mmci.h | 3 |
2 files changed, 15 insertions, 85 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index a40bf70170fd..ebe991628295 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/mmc/pm.h> | 23 | #include <linux/mmc/pm.h> |
24 | #include <linux/mmc/host.h> | 24 | #include <linux/mmc/host.h> |
25 | #include <linux/mmc/card.h> | 25 | #include <linux/mmc/card.h> |
26 | #include <linux/mmc/slot-gpio.h> | ||
26 | #include <linux/amba/bus.h> | 27 | #include <linux/amba/bus.h> |
27 | #include <linux/clk.h> | 28 | #include <linux/clk.h> |
28 | #include <linux/scatterlist.h> | 29 | #include <linux/scatterlist.h> |
@@ -1326,35 +1327,18 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1326 | pm_runtime_put_autosuspend(mmc_dev(mmc)); | 1327 | pm_runtime_put_autosuspend(mmc_dev(mmc)); |
1327 | } | 1328 | } |
1328 | 1329 | ||
1329 | static int mmci_get_ro(struct mmc_host *mmc) | ||
1330 | { | ||
1331 | struct mmci_host *host = mmc_priv(mmc); | ||
1332 | |||
1333 | if (host->gpio_wp == -ENOSYS) | ||
1334 | return -ENOSYS; | ||
1335 | |||
1336 | return gpio_get_value_cansleep(host->gpio_wp); | ||
1337 | } | ||
1338 | |||
1339 | static int mmci_get_cd(struct mmc_host *mmc) | 1330 | static int mmci_get_cd(struct mmc_host *mmc) |
1340 | { | 1331 | { |
1341 | struct mmci_host *host = mmc_priv(mmc); | 1332 | struct mmci_host *host = mmc_priv(mmc); |
1342 | struct mmci_platform_data *plat = host->plat; | 1333 | struct mmci_platform_data *plat = host->plat; |
1343 | unsigned int status; | 1334 | unsigned int status = mmc_gpio_get_cd(mmc); |
1344 | 1335 | ||
1345 | if (host->gpio_cd == -ENOSYS) { | 1336 | if (status == -ENOSYS) { |
1346 | if (!plat->status) | 1337 | if (!plat->status) |
1347 | return 1; /* Assume always present */ | 1338 | return 1; /* Assume always present */ |
1348 | 1339 | ||
1349 | status = plat->status(mmc_dev(host->mmc)); | 1340 | status = plat->status(mmc_dev(host->mmc)); |
1350 | } else | 1341 | } |
1351 | status = !!gpio_get_value_cansleep(host->gpio_cd) | ||
1352 | ^ plat->cd_invert; | ||
1353 | |||
1354 | /* | ||
1355 | * Use positive logic throughout - status is zero for no card, | ||
1356 | * non-zero for card inserted. | ||
1357 | */ | ||
1358 | return status; | 1342 | return status; |
1359 | } | 1343 | } |
1360 | 1344 | ||
@@ -1391,21 +1375,12 @@ static int mmci_sig_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1391 | return ret; | 1375 | return ret; |
1392 | } | 1376 | } |
1393 | 1377 | ||
1394 | static irqreturn_t mmci_cd_irq(int irq, void *dev_id) | ||
1395 | { | ||
1396 | struct mmci_host *host = dev_id; | ||
1397 | |||
1398 | mmc_detect_change(host->mmc, msecs_to_jiffies(500)); | ||
1399 | |||
1400 | return IRQ_HANDLED; | ||
1401 | } | ||
1402 | |||
1403 | static struct mmc_host_ops mmci_ops = { | 1378 | static struct mmc_host_ops mmci_ops = { |
1404 | .request = mmci_request, | 1379 | .request = mmci_request, |
1405 | .pre_req = mmci_pre_request, | 1380 | .pre_req = mmci_pre_request, |
1406 | .post_req = mmci_post_request, | 1381 | .post_req = mmci_post_request, |
1407 | .set_ios = mmci_set_ios, | 1382 | .set_ios = mmci_set_ios, |
1408 | .get_ro = mmci_get_ro, | 1383 | .get_ro = mmc_gpio_get_ro, |
1409 | .get_cd = mmci_get_cd, | 1384 | .get_cd = mmci_get_cd, |
1410 | .start_signal_voltage_switch = mmci_sig_volt_switch, | 1385 | .start_signal_voltage_switch = mmci_sig_volt_switch, |
1411 | }; | 1386 | }; |
@@ -1494,10 +1469,6 @@ static int mmci_probe(struct amba_device *dev, | |||
1494 | host = mmc_priv(mmc); | 1469 | host = mmc_priv(mmc); |
1495 | host->mmc = mmc; | 1470 | host->mmc = mmc; |
1496 | 1471 | ||
1497 | host->gpio_wp = -ENOSYS; | ||
1498 | host->gpio_cd = -ENOSYS; | ||
1499 | host->gpio_cd_irq = -1; | ||
1500 | |||
1501 | host->hw_designer = amba_manf(dev); | 1472 | host->hw_designer = amba_manf(dev); |
1502 | host->hw_revision = amba_rev(dev); | 1473 | host->hw_revision = amba_rev(dev); |
1503 | dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer); | 1474 | dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer); |
@@ -1568,6 +1539,9 @@ static int mmci_probe(struct amba_device *dev, | |||
1568 | 1539 | ||
1569 | mmc->caps = plat->capabilities; | 1540 | mmc->caps = plat->capabilities; |
1570 | mmc->caps2 = plat->capabilities2; | 1541 | mmc->caps2 = plat->capabilities2; |
1542 | if (!plat->cd_invert) | ||
1543 | mmc->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH; | ||
1544 | mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH; | ||
1571 | 1545 | ||
1572 | if (variant->busy_detect) { | 1546 | if (variant->busy_detect) { |
1573 | mmci_ops.card_busy = mmci_card_busy; | 1547 | mmci_ops.card_busy = mmci_card_busy; |
@@ -1621,49 +1595,23 @@ static int mmci_probe(struct amba_device *dev, | |||
1621 | goto err_gpio_cd; | 1595 | goto err_gpio_cd; |
1622 | } | 1596 | } |
1623 | if (gpio_is_valid(plat->gpio_cd)) { | 1597 | if (gpio_is_valid(plat->gpio_cd)) { |
1624 | ret = gpio_request(plat->gpio_cd, DRIVER_NAME " (cd)"); | 1598 | ret = mmc_gpio_request_cd(mmc, plat->gpio_cd, 0); |
1625 | if (ret == 0) | 1599 | if (ret) |
1626 | ret = gpio_direction_input(plat->gpio_cd); | ||
1627 | if (ret == 0) | ||
1628 | host->gpio_cd = plat->gpio_cd; | ||
1629 | else if (ret != -ENOSYS) | ||
1630 | goto err_gpio_cd; | 1600 | goto err_gpio_cd; |
1631 | |||
1632 | /* | ||
1633 | * A gpio pin that will detect cards when inserted and removed | ||
1634 | * will most likely want to trigger on the edges if it is | ||
1635 | * 0 when ejected and 1 when inserted (or mutatis mutandis | ||
1636 | * for the inverted case) so we request triggers on both | ||
1637 | * edges. | ||
1638 | */ | ||
1639 | ret = request_any_context_irq(gpio_to_irq(plat->gpio_cd), | ||
1640 | mmci_cd_irq, | ||
1641 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||
1642 | DRIVER_NAME " (cd)", host); | ||
1643 | if (ret >= 0) | ||
1644 | host->gpio_cd_irq = gpio_to_irq(plat->gpio_cd); | ||
1645 | } | 1601 | } |
1646 | if (plat->gpio_wp == -EPROBE_DEFER) { | 1602 | if (plat->gpio_wp == -EPROBE_DEFER) { |
1647 | ret = -EPROBE_DEFER; | 1603 | ret = -EPROBE_DEFER; |
1648 | goto err_gpio_wp; | 1604 | goto err_gpio_cd; |
1649 | } | 1605 | } |
1650 | if (gpio_is_valid(plat->gpio_wp)) { | 1606 | if (gpio_is_valid(plat->gpio_wp)) { |
1651 | ret = gpio_request(plat->gpio_wp, DRIVER_NAME " (wp)"); | 1607 | ret = mmc_gpio_request_ro(mmc, plat->gpio_wp); |
1652 | if (ret == 0) | 1608 | if (ret) |
1653 | ret = gpio_direction_input(plat->gpio_wp); | 1609 | goto err_gpio_cd; |
1654 | if (ret == 0) | ||
1655 | host->gpio_wp = plat->gpio_wp; | ||
1656 | else if (ret != -ENOSYS) | ||
1657 | goto err_gpio_wp; | ||
1658 | } | 1610 | } |
1659 | 1611 | ||
1660 | if ((host->plat->status || host->gpio_cd != -ENOSYS) | ||
1661 | && host->gpio_cd_irq < 0) | ||
1662 | mmc->caps |= MMC_CAP_NEEDS_POLL; | ||
1663 | |||
1664 | ret = request_irq(dev->irq[0], mmci_irq, IRQF_SHARED, DRIVER_NAME " (cmd)", host); | 1612 | ret = request_irq(dev->irq[0], mmci_irq, IRQF_SHARED, DRIVER_NAME " (cmd)", host); |
1665 | if (ret) | 1613 | if (ret) |
1666 | goto unmap; | 1614 | goto err_gpio_cd; |
1667 | 1615 | ||
1668 | if (!dev->irq[1]) | 1616 | if (!dev->irq[1]) |
1669 | host->singleirq = true; | 1617 | host->singleirq = true; |
@@ -1695,14 +1643,6 @@ static int mmci_probe(struct amba_device *dev, | |||
1695 | 1643 | ||
1696 | irq0_free: | 1644 | irq0_free: |
1697 | free_irq(dev->irq[0], host); | 1645 | free_irq(dev->irq[0], host); |
1698 | unmap: | ||
1699 | if (host->gpio_wp != -ENOSYS) | ||
1700 | gpio_free(host->gpio_wp); | ||
1701 | err_gpio_wp: | ||
1702 | if (host->gpio_cd_irq >= 0) | ||
1703 | free_irq(host->gpio_cd_irq, host); | ||
1704 | if (host->gpio_cd != -ENOSYS) | ||
1705 | gpio_free(host->gpio_cd); | ||
1706 | err_gpio_cd: | 1646 | err_gpio_cd: |
1707 | iounmap(host->base); | 1647 | iounmap(host->base); |
1708 | clk_disable: | 1648 | clk_disable: |
@@ -1741,13 +1681,6 @@ static int mmci_remove(struct amba_device *dev) | |||
1741 | if (!host->singleirq) | 1681 | if (!host->singleirq) |
1742 | free_irq(dev->irq[1], host); | 1682 | free_irq(dev->irq[1], host); |
1743 | 1683 | ||
1744 | if (host->gpio_wp != -ENOSYS) | ||
1745 | gpio_free(host->gpio_wp); | ||
1746 | if (host->gpio_cd_irq >= 0) | ||
1747 | free_irq(host->gpio_cd_irq, host); | ||
1748 | if (host->gpio_cd != -ENOSYS) | ||
1749 | gpio_free(host->gpio_cd); | ||
1750 | |||
1751 | iounmap(host->base); | 1684 | iounmap(host->base); |
1752 | clk_disable_unprepare(host->clk); | 1685 | clk_disable_unprepare(host->clk); |
1753 | 1686 | ||
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 58b1b8896bf2..8fc5814f938a 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h | |||
@@ -176,9 +176,6 @@ struct mmci_host { | |||
176 | struct mmc_data *data; | 176 | struct mmc_data *data; |
177 | struct mmc_host *mmc; | 177 | struct mmc_host *mmc; |
178 | struct clk *clk; | 178 | struct clk *clk; |
179 | int gpio_cd; | ||
180 | int gpio_wp; | ||
181 | int gpio_cd_irq; | ||
182 | bool singleirq; | 179 | bool singleirq; |
183 | 180 | ||
184 | spinlock_t lock; | 181 | spinlock_t lock; |