summaryrefslogtreecommitdiff
path: root/drivers/mmc/host/omap_hsmmc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-13 14:53:03 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-13 14:53:03 -0700
commit8d9095c667a185c8e2449632343a2b6c65ae58f1 (patch)
tree738cdc0e1e5c96738c31ea327ac0d741349d3757 /drivers/mmc/host/omap_hsmmc.c
parent1a370f4cd95e056d55ef5bf1a183880e70195e59 (diff)
parent69f0fb2a592fc9ebc5e3e55178055d1cff31d479 (diff)
Merge tag 'mmc-v4.1' of git://git.linaro.org/people/ulf.hansson/mmc
Pull MMC updates from Ulf Hansson: "MMC core: - Add support for marking HPI as broken through devicetree - Enable runtime PM management of host devices - Remove the ->enable|disable() callbacks - Restructure code and cleanups - Refreshed some of the MMC sections in MAINTAINERS MMC host: - dw_mmc: HS400 mode support - dw_mmc: Add the cmd11 timer to detect a timeout - dw_mmc: Endian agnostic IO accessors - dw_mmc: Bugfixes - sh_mmcif: Add exclusion between cmd and interrupt - omap_hsmmc: Hibernation support - omap_hsmmc: Rework and simplify cover/card detect - omap_hsmmc: Stop using ->enable|disable() callbacks - atmel-mci: Endian agnostic IO - sunxi: Enable MMC_CAP_SDIO_IRQ - sdhci-st: Add support for the stih407 family silicon - sdhci-st: UHS card support in SDR104 mode - sdhci-st: HS200 mode support - sdhci-esdhc-imx: Use common mmc DT parser - sdhci-of-arasan: Use common mmc DT parser - sdhci-iproc: Add new driver for Broadcom IPROC SDHCI controller - sdhci-tegra: Convert to GPIO descriptors - sdhci-tegra: Optmize write_w path for tegra114 and later - sdhci-sirf: Update tuning procedure - sdhci: Fix card presence logic - sdhci: Cleanups and consolidation" * tag 'mmc-v4.1' of git://git.linaro.org/people/ulf.hansson/mmc: (79 commits) mmc: sdhci-st: Update ST SDHCI binding documentation. mmc: sdhci-st: Update the quirks for this controller. mmc: sdhci-st: Add sdhci_st_set_uhs_signaling function. mmc: sdhci-st: Add st_mmcss_cconfig function to configure mmcss glue registers. mmc: sdhci-st: Add delay management functions for top registers (eMMC). mmc: sdhci-st: Add support for de-asserting reset signal and top regs resource mmc: sdhci-st: Add macros for register offsets and bitfields for mmcss glue regs mmc: sdhci-esdhc-imx: Call mmc_of_parse() mmc: dw_mmc: Add locking around cmd11 timer mmc: dw_mmc: Add a return in an unexpected cmd11 timeout mmc: dw_mmc: Increase cmd11 timeout to 500ms mmc: dw_mmc: fix fifo ordering in big endian mmc: dw_mmc: change idmac descriptor files to __le32 mmc: dw_mmc: make IO accessors endian agnostic mmc: core: Convert the error field in struct mmc_command|data into an int mmc: sdhci-of-arasan: Call OF parsing for MMC mmc: sdhci-pci: fix 64 BIT DMA quirks for rtsx mmc: Add support for marking hpi as broken through devicetree mmc: sdhci-tegra: convert to use GPIO descriptors mmc: omap_hsmmc: use generic slot-gpio isr to manage card detect pin ...
Diffstat (limited to 'drivers/mmc/host/omap_hsmmc.c')
-rw-r--r--drivers/mmc/host/omap_hsmmc.c119
1 files changed, 32 insertions, 87 deletions
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index f84cfb01716d..9df2b6801f76 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -222,10 +222,6 @@ struct omap_hsmmc_host {
struct omap_hsmmc_next next_data;
struct omap_hsmmc_platform_data *pdata;
- /* To handle board related suspend/resume functionality for MMC */
- int (*suspend)(struct device *dev);
- int (*resume)(struct device *dev);
-
/* return MMC cover switch state, can be NULL if not supported.
*
* possible return values:
@@ -234,12 +230,7 @@ struct omap_hsmmc_host {
*/
int (*get_cover_state)(struct device *dev);
- /* Card detection IRQs */
- int card_detect_irq;
-
int (*card_detect)(struct device *dev);
- int (*get_ro)(struct device *dev);
-
};
struct omap_mmc_of_data {
@@ -256,13 +247,6 @@ static int omap_hsmmc_card_detect(struct device *dev)
return mmc_gpio_get_cd(host->mmc);
}
-static int omap_hsmmc_get_wp(struct device *dev)
-{
- struct omap_hsmmc_host *host = dev_get_drvdata(dev);
-
- return mmc_gpio_get_ro(host->mmc);
-}
-
static int omap_hsmmc_get_cover_state(struct device *dev)
{
struct omap_hsmmc_host *host = dev_get_drvdata(dev);
@@ -434,7 +418,7 @@ static inline int omap_hsmmc_have_reg(void)
#endif
-static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id);
+static irqreturn_t omap_hsmmc_cover_irq(int irq, void *dev_id);
static int omap_hsmmc_gpio_init(struct mmc_host *mmc,
struct omap_hsmmc_host *host,
@@ -442,29 +426,25 @@ static int omap_hsmmc_gpio_init(struct mmc_host *mmc,
{
int ret;
- if (gpio_is_valid(pdata->switch_pin)) {
- if (pdata->cover)
- host->get_cover_state =
- omap_hsmmc_get_cover_state;
- else
- host->card_detect = omap_hsmmc_card_detect;
- host->card_detect_irq =
- gpio_to_irq(pdata->switch_pin);
- mmc_gpio_set_cd_isr(mmc, omap_hsmmc_detect);
- ret = mmc_gpio_request_cd(mmc, pdata->switch_pin, 0);
+ if (gpio_is_valid(pdata->gpio_cod)) {
+ ret = mmc_gpio_request_cd(mmc, pdata->gpio_cod, 0);
if (ret)
return ret;
- } else {
- pdata->switch_pin = -EINVAL;
+
+ host->get_cover_state = omap_hsmmc_get_cover_state;
+ mmc_gpio_set_cd_isr(mmc, omap_hsmmc_cover_irq);
+ } else if (gpio_is_valid(pdata->gpio_cd)) {
+ ret = mmc_gpio_request_cd(mmc, pdata->gpio_cd, 0);
+ if (ret)
+ return ret;
+
+ host->card_detect = omap_hsmmc_card_detect;
}
if (gpio_is_valid(pdata->gpio_wp)) {
- host->get_ro = omap_hsmmc_get_wp;
ret = mmc_gpio_request_ro(mmc, pdata->gpio_wp);
if (ret)
return ret;
- } else {
- pdata->gpio_wp = -EINVAL;
}
return 0;
@@ -882,6 +862,8 @@ static void omap_hsmmc_request_done(struct omap_hsmmc_host *host, struct mmc_req
return;
host->mrq = NULL;
mmc_request_done(host->mmc, mrq);
+ pm_runtime_mark_last_busy(host->dev);
+ pm_runtime_put_autosuspend(host->dev);
}
/*
@@ -1252,26 +1234,16 @@ static void omap_hsmmc_protect_card(struct omap_hsmmc_host *host)
}
/*
- * irq handler to notify the core about card insertion/removal
+ * irq handler when (cell-phone) cover is mounted/removed
*/
-static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id)
+static irqreturn_t omap_hsmmc_cover_irq(int irq, void *dev_id)
{
struct omap_hsmmc_host *host = dev_id;
- int carddetect;
sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch");
- if (host->card_detect)
- carddetect = host->card_detect(host->dev);
- else {
- omap_hsmmc_protect_card(host);
- carddetect = -ENOSYS;
- }
-
- if (carddetect)
- mmc_detect_change(host->mmc, (HZ * 200) / 1000);
- else
- mmc_detect_change(host->mmc, (HZ * 50) / 1000);
+ omap_hsmmc_protect_card(host);
+ mmc_detect_change(host->mmc, (HZ * 200) / 1000);
return IRQ_HANDLED;
}
@@ -1305,6 +1277,8 @@ static void omap_hsmmc_dma_callback(void *param)
host->mrq = NULL;
mmc_request_done(host->mmc, mrq);
+ pm_runtime_mark_last_busy(host->dev);
+ pm_runtime_put_autosuspend(host->dev);
}
}
@@ -1537,6 +1511,7 @@ static void omap_hsmmc_request(struct mmc_host *mmc, struct mmc_request *req)
BUG_ON(host->req_in_progress);
BUG_ON(host->dma_ch != -1);
+ pm_runtime_get_sync(host->dev);
if (host->protect_card) {
if (host->reqs_blocked < 3) {
/*
@@ -1553,6 +1528,8 @@ static void omap_hsmmc_request(struct mmc_host *mmc, struct mmc_request *req)
req->data->error = -EBADF;
req->cmd->retries = 0;
mmc_request_done(mmc, req);
+ pm_runtime_mark_last_busy(host->dev);
+ pm_runtime_put_autosuspend(host->dev);
return;
} else if (host->reqs_blocked)
host->reqs_blocked = 0;
@@ -1566,6 +1543,8 @@ static void omap_hsmmc_request(struct mmc_host *mmc, struct mmc_request *req)
req->data->error = err;
host->mrq = NULL;
mmc_request_done(mmc, req);
+ pm_runtime_mark_last_busy(host->dev);
+ pm_runtime_put_autosuspend(host->dev);
return;
}
if (req->sbc && !(host->flags & AUTO_CMD23)) {
@@ -1641,15 +1620,6 @@ static int omap_hsmmc_get_cd(struct mmc_host *mmc)
return host->card_detect(host->dev);
}
-static int omap_hsmmc_get_ro(struct mmc_host *mmc)
-{
- struct omap_hsmmc_host *host = mmc_priv(mmc);
-
- if (!host->get_ro)
- return -ENOSYS;
- return host->get_ro(host->dev);
-}
-
static void omap_hsmmc_init_card(struct mmc_host *mmc, struct mmc_card *card)
{
struct omap_hsmmc_host *host = mmc_priv(mmc);
@@ -1778,25 +1748,6 @@ static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host)
set_sd_bus_power(host);
}
-static int omap_hsmmc_enable_fclk(struct mmc_host *mmc)
-{
- struct omap_hsmmc_host *host = mmc_priv(mmc);
-
- pm_runtime_get_sync(host->dev);
-
- return 0;
-}
-
-static int omap_hsmmc_disable_fclk(struct mmc_host *mmc)
-{
- struct omap_hsmmc_host *host = mmc_priv(mmc);
-
- pm_runtime_mark_last_busy(host->dev);
- pm_runtime_put_autosuspend(host->dev);
-
- return 0;
-}
-
static int omap_hsmmc_multi_io_quirk(struct mmc_card *card,
unsigned int direction, int blk_size)
{
@@ -1808,14 +1759,12 @@ static int omap_hsmmc_multi_io_quirk(struct mmc_card *card,
}
static struct mmc_host_ops omap_hsmmc_ops = {
- .enable = omap_hsmmc_enable_fclk,
- .disable = omap_hsmmc_disable_fclk,
.post_req = omap_hsmmc_post_req,
.pre_req = omap_hsmmc_pre_req,
.request = omap_hsmmc_request,
.set_ios = omap_hsmmc_set_ios,
.get_cd = omap_hsmmc_get_cd,
- .get_ro = omap_hsmmc_get_ro,
+ .get_ro = mmc_gpio_get_ro,
.init_card = omap_hsmmc_init_card,
.enable_sdio_irq = omap_hsmmc_enable_sdio_irq,
};
@@ -1937,7 +1886,8 @@ static struct omap_hsmmc_platform_data *of_get_hsmmc_pdata(struct device *dev)
if (of_find_property(np, "ti,dual-volt", NULL))
pdata->controller_flags |= OMAP_HSMMC_SUPPORTS_DUAL_VOLT;
- pdata->switch_pin = -EINVAL;
+ pdata->gpio_cd = -EINVAL;
+ pdata->gpio_cod = -EINVAL;
pdata->gpio_wp = -EINVAL;
if (of_find_property(np, "ti,non-removable", NULL)) {
@@ -2179,9 +2129,9 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
if (ret < 0)
goto err_slot_name;
}
- if (host->card_detect_irq && host->get_cover_state) {
+ if (host->get_cover_state) {
ret = device_create_file(&mmc->class_dev,
- &dev_attr_cover_switch);
+ &dev_attr_cover_switch);
if (ret < 0)
goto err_slot_name;
}
@@ -2236,7 +2186,7 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int omap_hsmmc_suspend(struct device *dev)
{
struct omap_hsmmc_host *host = dev_get_drvdata(dev);
@@ -2292,10 +2242,6 @@ static int omap_hsmmc_resume(struct device *dev)
pm_runtime_put_autosuspend(host->dev);
return 0;
}
-
-#else
-#define omap_hsmmc_suspend NULL
-#define omap_hsmmc_resume NULL
#endif
static int omap_hsmmc_runtime_suspend(struct device *dev)
@@ -2376,8 +2322,7 @@ static int omap_hsmmc_runtime_resume(struct device *dev)
}
static struct dev_pm_ops omap_hsmmc_dev_pm_ops = {
- .suspend = omap_hsmmc_suspend,
- .resume = omap_hsmmc_resume,
+ SET_SYSTEM_SLEEP_PM_OPS(omap_hsmmc_suspend, omap_hsmmc_resume)
.runtime_suspend = omap_hsmmc_runtime_suspend,
.runtime_resume = omap_hsmmc_runtime_resume,
};