From patchwork Wed Jul 18 08:38:55 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Girish K S X-Patchwork-Id: 10111 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 689DB23F4C for ; Wed, 18 Jul 2012 08:39:16 +0000 (UTC) Received: from mail-gh0-f180.google.com (mail-gh0-f180.google.com [209.85.160.180]) by fiordland.canonical.com (Postfix) with ESMTP id 0D0F6A18151 for ; Wed, 18 Jul 2012 08:39:15 +0000 (UTC) Received: by ghbz12 with SMTP id z12so1417406ghb.11 for ; Wed, 18 Jul 2012 01:39:15 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:from:to:cc :subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=3ctO4qpfKrUoxKfcI9rY3CO1ZABYs2mFzENGkbPHUs8=; b=hM+NOsWJhLQnvKreWDfpa29y8v8QKsLhN0oubUoGg/0Gwkgbcd+r5TXIUTTc2vXnna 4Nku25FCe0yMKPtgBU19NKs+GQheR7+pcAW6qVCROk5viAg72wIBoFFRvDeingitygl/ j3mmfSEIGeJlZ+b0ScrimeKuJsNjsNJSyLI7T3fGF+3WGjWNbZ4M7V1h+NS6TQKPe8Zi SYv4k8Rgk5dk/LDc4CoZZJZopQHh5ZkmhJh+S1cZ8IEAjlw/SbMgZH5+ferZ8frVxIC8 Lrc2NVbg37Wo63QQiAZFI+3gFs+ugz5NO71iaBHuzvKSfMAgjdoMQ9jkSptH+9tIK6Mu 9PEQ== Received: by 10.50.57.167 with SMTP id j7mr1129687igq.53.1342600755240; Wed, 18 Jul 2012 01:39:15 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.241.2 with SMTP id lc2csp29008ibb; Wed, 18 Jul 2012 01:39:14 -0700 (PDT) Received: by 10.68.190.168 with SMTP id gr8mr6116893pbc.157.1342600754068; Wed, 18 Jul 2012 01:39:14 -0700 (PDT) Received: from mail-pb0-f50.google.com (mail-pb0-f50.google.com [209.85.160.50]) by mx.google.com with ESMTPS id qd2si28870901pbb.57.2012.07.18.01.39.13 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 18 Jul 2012 01:39:14 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.160.50 is neither permitted nor denied by best guess record for domain of girish.shivananjappa@linaro.org) client-ip=209.85.160.50; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.160.50 is neither permitted nor denied by best guess record for domain of girish.shivananjappa@linaro.org) smtp.mail=girish.shivananjappa@linaro.org Received: by mail-pb0-f50.google.com with SMTP id rr4so2684175pbb.37 for ; Wed, 18 Jul 2012 01:39:13 -0700 (PDT) Received: by 10.68.225.231 with SMTP id rn7mr6125051pbc.13.1342600753617; Wed, 18 Jul 2012 01:39:13 -0700 (PDT) Received: from localhost.localdomain ([115.113.119.130]) by mx.google.com with ESMTPS id ku7sm15785816pbc.31.2012.07.18.01.39.09 (version=SSLv3 cipher=OTHER); Wed, 18 Jul 2012 01:39:13 -0700 (PDT) From: Girish K S To: linux-mmc@vger.kernel.org Cc: cjb@laptop.org, will.newton@imgtec.com, patches@linaro.org, linux-samsung-soc@vger.kernel.org, shashidharh@vayavyalabs.com, thomas.abraham@linaro.org, jh80.chung@samsung.com, Girish K S Subject: [PATCH V1] mmc: dwmmc: Add quirk for broken Hardware Config Date: Wed, 18 Jul 2012 14:08:55 +0530 Message-Id: <1342600735-7855-2-git-send-email-girish.shivananjappa@linaro.org> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1342600735-7855-1-git-send-email-girish.shivananjappa@linaro.org> References: <1342600735-7855-1-git-send-email-girish.shivananjappa@linaro.org> X-Gm-Message-State: ALoCoQldecSOu3TSSf/uswwz6k2jHJxR8p5gFifIn9BmoW76QnmAJqSZ8Xbgxj8AWQS1okpeoTKI In some Soc'S that integrate Designware mmc host controllers, the HCON register is broken. The hardware configuration is not updated. One specific usecase is the IDMAC. In Exysons5 SoC there exist a internal DMA, but the HCON register's DMA_INTERFACE field is not set to indicate its existance. This quirk can be used in such case to force the existance broken HCON field. changes in v1: -modified the caps2 field access per controller index.Reported by Jaehoon Chung . -replaced the pointer to device with the pointer to platform device in struct dw_mci. -updated driver data for all 4 mmc controllers of exynos5 SoC. -added non device-tree support for ctrl_id access. Signed-off-by: Girish K S --- drivers/mmc/host/dw_mmc-pltfm.c | 10 +++- drivers/mmc/host/dw_mmc.c | 150 ++++++++++++++++++++++++--------------- drivers/mmc/host/dw_mmc.h | 1 + include/linux/mmc/dw_mmc.h | 2 +- include/linux/mmc/host.h | 1 + 5 files changed, 106 insertions(+), 58 deletions(-) diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c index 900f412..c8eb573 100644 --- a/drivers/mmc/host/dw_mmc-pltfm.c +++ b/drivers/mmc/host/dw_mmc-pltfm.c @@ -35,9 +35,17 @@ static unsigned long exynos5250_dwmmc_caps[4] = { MMC_CAP_CMD23, }; +static unsigned long exynos5250_dwmmc_caps2[4] = { + MMC_CAP2_CONFIG_BROKEN, + MMC_CAP2_CONFIG_BROKEN, + MMC_CAP2_CONFIG_BROKEN, + MMC_CAP2_CONFIG_BROKEN, +}; + static struct dw_mci_drv_data exynos5250_drv_data = { .ctrl_type = DW_MCI_TYPE_EXYNOS5250, .caps = exynos5250_dwmmc_caps, + .caps2 = exynos5250_dwmmc_caps2, }; static const struct of_device_id dw_mci_pltfm_match[] = { @@ -74,7 +82,7 @@ static int dw_mci_pltfm_probe(struct platform_device *pdev) goto err_free; } - host->dev = &pdev->dev; + host->pdev = pdev; host->irq_flags = 0; host->pdata = pdev->dev.platform_data; ret = -ENOMEM; diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 000da16..fd9233d 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -283,8 +283,10 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) static void dw_mci_start_command(struct dw_mci *host, struct mmc_command *cmd, u32 cmd_flags) { + struct device *dev = &host->pdev->dev; + host->cmd = cmd; - dev_vdbg(host->dev, + dev_vdbg(dev, "start command: ARGR=0x%08x CMDR=0x%08x\n", cmd->arg, cmd_flags); @@ -323,10 +325,11 @@ static int dw_mci_get_dma_dir(struct mmc_data *data) static void dw_mci_dma_cleanup(struct dw_mci *host) { struct mmc_data *data = host->data; + struct device *dev = &host->pdev->dev; if (data) if (!data->host_cookie) - dma_unmap_sg(host->dev, + dma_unmap_sg(dev, data->sg, data->sg_len, dw_mci_get_dma_dir(data)); @@ -351,8 +354,9 @@ static void dw_mci_idmac_stop_dma(struct dw_mci *host) static void dw_mci_idmac_complete_dma(struct dw_mci *host) { struct mmc_data *data = host->data; + struct device *dev = &host->pdev->dev; - dev_vdbg(host->dev, "DMA complete\n"); + dev_vdbg(dev, "DMA complete\n"); host->dma_ops->cleanup(host); @@ -420,10 +424,27 @@ static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len) mci_writel(host, PLDMND, 1); } +static int dw_get_platform_device_id(struct dw_mci *host) +{ + int ctrl_id; + struct device *dev = &host->pdev->dev; + + if (dev->of_node) + ctrl_id = of_alias_get_id(dev->of_node, "mshc"); + else + ctrl_id = host->pdev->id; + + if (ctrl_id < 0) + ctrl_id = 0; + + return ctrl_id; +} + static int dw_mci_idmac_init(struct dw_mci *host) { struct idmac_desc *p; - int i, dma_support; + int i, dma_support, ctrl_id; + struct device *dev = &host->pdev->dev; /* Number of descriptors in the ring buffer */ host->ring_size = PAGE_SIZE / sizeof(struct idmac_desc); @@ -431,14 +452,23 @@ static int dw_mci_idmac_init(struct dw_mci *host) /* Check if Hardware Configuration Register has support for DMA */ dma_support = (mci_readl(host, HCON) >> 16) & 0x3; - if (!dma_support || dma_support > 2) { - dev_err(&host->dev, + /* + * In Some of the Soc's the HCON Register is broken. Even though the + * Soc's has a internal DMA the HCON register's DMA field doesnt + * show it. So additional quirk is added for such Soc's + */ + ctrl_id = dw_get_platform_device_id(host); + + if ((!dma_support || dma_support > 2) && + host->drv_data && host->drv_data->caps2 && + !(host->drv_data->caps2[ctrl_id] & MMC_CAP2_CONFIG_BROKEN)) { + dev_err(dev, "Host Controller does not support IDMA Tx.\n"); host->dma_ops = NULL; return -ENODEV; } - dev_info(&host->dev, "Using internal DMA controller.\n"); + dev_info(dev, "Using internal DMA controller.\n"); /* Forward link the descriptor list */ for (i = 0, p = host->sg_cpu; i < host->ring_size - 1; i++, p++) @@ -474,6 +504,7 @@ static int dw_mci_pre_dma_transfer(struct dw_mci *host, { struct scatterlist *sg; unsigned int i, sg_len; + struct device *dev = &host->pdev->dev; if (!next && data->host_cookie) return data->host_cookie; @@ -494,7 +525,7 @@ static int dw_mci_pre_dma_transfer(struct dw_mci *host, return -EINVAL; } - sg_len = dma_map_sg(host->dev, + sg_len = dma_map_sg(dev, data->sg, data->sg_len, dw_mci_get_dma_dir(data)); @@ -532,12 +563,13 @@ static void dw_mci_post_req(struct mmc_host *mmc, { struct dw_mci_slot *slot = mmc_priv(mmc); struct mmc_data *data = mrq->data; + struct device *dev = &slot->host->pdev->dev; if (!slot->host->use_dma || !data) return; if (data->host_cookie) - dma_unmap_sg(slot->host->dev, + dma_unmap_sg(dev, data->sg, data->sg_len, dw_mci_get_dma_dir(data)); @@ -548,6 +580,7 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data) { int sg_len; u32 temp; + struct device *dev = &host->pdev->dev; host->using_dma = 0; @@ -563,7 +596,7 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data) host->using_dma = 1; - dev_vdbg(host->dev, + dev_vdbg(dev, "sd sg_cpu: %#lx sg_dma: %#lx sg_len: %d\n", (unsigned long)host->sg_cpu, (unsigned long)host->sg_dma, sg_len); @@ -928,6 +961,7 @@ static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq) { struct dw_mci_slot *slot; struct mmc_host *prev_mmc = host->cur_slot->mmc; + struct device *dev = &host->pdev->dev; WARN_ON(host->cmd || host->data); @@ -937,12 +971,12 @@ static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq) slot = list_entry(host->queue.next, struct dw_mci_slot, queue_node); list_del(&slot->queue_node); - dev_vdbg(host->dev, "list not empty: %s is next\n", + dev_vdbg(dev, "list not empty: %s is next\n", mmc_hostname(slot->mmc)); host->state = STATE_SENDING_CMD; dw_mci_start_request(host, slot); } else { - dev_vdbg(host->dev, "list empty\n"); + dev_vdbg(dev, "list empty\n"); host->state = STATE_IDLE; } @@ -1081,7 +1115,7 @@ static void dw_mci_tasklet_func(unsigned long priv) data->bytes_xfered = 0; data->error = -ETIMEDOUT; } else { - dev_err(host->dev, + dev_err(&host->pdev->dev, "data FIFO error " "(status=%08x)\n", status); @@ -1829,7 +1863,8 @@ static u32 dw_mci_of_get_bus_wd(struct device *dev, u8 slot) static int dw_mci_of_setup_bus(struct dw_mci *host, u8 slot, u32 bus_wd) { - struct device_node *np = dw_mci_of_find_slot_node(host->dev, slot); + struct device *dev = &host->pdev->dev; + struct device_node *np = dw_mci_of_find_slot_node(dev, slot); int idx, gpio, ret; if (!np) @@ -1838,13 +1873,13 @@ static int dw_mci_of_setup_bus(struct dw_mci *host, u8 slot, u32 bus_wd) for (idx = 0; idx < NUM_PINS(bus_wd); idx++) { gpio = of_get_gpio(np, idx); if (!gpio_is_valid(gpio)) { - dev_err(host->dev, "invalid gpio: %d\n", gpio); + dev_err(dev, "invalid gpio: %d\n", gpio); return -EINVAL; } - ret = devm_gpio_request(host->dev, gpio, "dw-mci-bus"); + ret = devm_gpio_request(dev, gpio, "dw-mci-bus"); if (ret) { - dev_err(host->dev, "gpio [%d] request failed\n", gpio); + dev_err(dev, "gpio [%d] request failed\n", gpio); return -EBUSY; } } @@ -1852,11 +1887,11 @@ static int dw_mci_of_setup_bus(struct dw_mci *host, u8 slot, u32 bus_wd) host->slot[slot]->wp_gpio = -1; gpio = of_get_named_gpio(np, "wp-gpios", 0); if (!gpio_is_valid(gpio)) { - dev_info(host->dev, "wp gpio not available"); + dev_info(dev, "wp gpio not available"); } else { - ret = devm_gpio_request(host->dev, gpio, "dw-mci-wp"); + ret = devm_gpio_request(dev, gpio, "dw-mci-wp"); if (ret) - dev_info(host->dev, "gpio [%d] request failed\n", + dev_info(dev, "gpio [%d] request failed\n", gpio); else host->slot[slot]->wp_gpio = gpio; @@ -1865,11 +1900,11 @@ static int dw_mci_of_setup_bus(struct dw_mci *host, u8 slot, u32 bus_wd) host->slot[slot]->cd_gpio = -1; gpio = of_get_named_gpio(np, "cd-gpios", 0); if (!gpio_is_valid(gpio)) { - dev_info(host->dev, "cd gpio not available"); + dev_info(dev, "cd gpio not available"); } else { - ret = devm_gpio_request(host->dev, gpio, "dw-mci-cd"); + ret = devm_gpio_request(dev, gpio, "dw-mci-cd"); if (ret) - dev_err(host->dev, "gpio [%d] request failed\n", gpio); + dev_err(dev, "gpio [%d] request failed\n", gpio); else host->slot[slot]->cd_gpio = gpio; } @@ -1893,8 +1928,9 @@ static int __init dw_mci_init_slot(struct dw_mci *host, unsigned int id) struct mmc_host *mmc; struct dw_mci_slot *slot; int ctrl_id, ret; + struct device *dev = &host->pdev->dev; - mmc = mmc_alloc_host(sizeof(struct dw_mci_slot), host->dev); + mmc = mmc_alloc_host(sizeof(struct dw_mci_slot), dev); if (!mmc) return -ENOMEM; @@ -1923,23 +1959,23 @@ static int __init dw_mci_init_slot(struct dw_mci *host, unsigned int id) if (host->pdata->caps) mmc->caps = host->pdata->caps; - if (host->dev->of_node) { - ctrl_id = of_alias_get_id(host->dev->of_node, "mshc"); - if (ctrl_id < 0) - ctrl_id = 0; - } + ctrl_id = dw_get_platform_device_id(host); + if (host->drv_data->caps) mmc->caps |= host->drv_data->caps[ctrl_id]; if (host->pdata->caps2) mmc->caps2 = host->pdata->caps2; + if (host->drv_data->caps2) + mmc->caps2 |= host->drv_data->caps2[ctrl_id]; + if (host->pdata->get_bus_wd) { if (host->pdata->get_bus_wd(slot->id) >= 4) mmc->caps |= MMC_CAP_4_BIT_DATA; - } else if (host->dev->of_node) { + } else if (dev->of_node) { unsigned int bus_width; - bus_width = dw_mci_of_get_bus_wd(host->dev, slot->id); + bus_width = dw_mci_of_get_bus_wd(dev, slot->id); switch (bus_width) { case 8: mmc->caps |= MMC_CAP_8_BIT_DATA; @@ -2030,11 +2066,12 @@ static void dw_mci_cleanup_slot(struct dw_mci_slot *slot, unsigned int id) static void dw_mci_init_dma(struct dw_mci *host) { + struct device *dev = &host->pdev->dev; /* Alloc memory for sg translation */ - host->sg_cpu = dma_alloc_coherent(host->dev, PAGE_SIZE, + host->sg_cpu = dma_alloc_coherent(dev, PAGE_SIZE, &host->sg_dma, GFP_KERNEL); if (!host->sg_cpu) { - dev_err(host->dev, "%s: could not alloc DMA memory\n", + dev_err(dev, "%s: could not alloc DMA memory\n", __func__); goto no_dma; } @@ -2050,12 +2087,12 @@ static void dw_mci_init_dma(struct dw_mci *host) if (host->dma_ops->init && host->dma_ops->start && host->dma_ops->stop && host->dma_ops->cleanup) { if (host->dma_ops->init(host)) { - dev_err(host->dev, "%s: Unable to initialize " + dev_err(dev, "%s: Unable to initialize " "DMA Controller.\n", __func__); goto no_dma; } } else { - dev_err(host->dev, "DMA initialization not found.\n"); + dev_err(dev, "DMA initialization not found.\n"); goto no_dma; } @@ -2063,7 +2100,7 @@ static void dw_mci_init_dma(struct dw_mci *host) return; no_dma: - dev_info(host->dev, "Using PIO mode.\n"); + dev_info(dev, "Using PIO mode.\n"); host->use_dma = 0; return; } @@ -2109,7 +2146,7 @@ static struct dw_mci_of_quirks { static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) { struct dw_mci_board *pdata; - struct device *dev = host->dev; + struct device *dev = &host->pdev->dev; struct device_node *np = dev->of_node; u32 timing[3]; int idx, cnt; @@ -2169,30 +2206,31 @@ int dw_mci_probe(struct dw_mci *host) int width, i, ret = 0; u32 fifo_size; int init_slots = 0; + struct device *dev = &host->pdev->dev; if (!host->pdata) { host->pdata = dw_mci_parse_dt(host); if (IS_ERR(host->pdata)) { - dev_err(host->dev, "platform data not available\n"); + dev_err(dev, "platform data not available\n"); return -EINVAL; } } if (!host->pdata->select_slot && host->pdata->num_slots > 1) { - dev_err(host->dev, + dev_err(dev, "Platform data must supply select_slot function\n"); return -ENODEV; } - host->biu_clk = clk_get(host->dev, "biu"); + host->biu_clk = clk_get(dev, "biu"); if (IS_ERR(host->biu_clk)) - dev_dbg(host->dev, "biu clock not available\n"); + dev_dbg(dev, "biu clock not available\n"); else clk_prepare_enable(host->biu_clk); - host->ciu_clk = clk_get(host->dev, "ciu"); + host->ciu_clk = clk_get(dev, "ciu"); if (IS_ERR(host->ciu_clk)) - dev_dbg(host->dev, "ciu clock not available\n"); + dev_dbg(dev, "ciu clock not available\n"); else clk_prepare_enable(host->ciu_clk); @@ -2202,7 +2240,7 @@ int dw_mci_probe(struct dw_mci *host) host->bus_hz = clk_get_rate(host->ciu_clk); if (!host->bus_hz) { - dev_err(host->dev, + dev_err(dev, "Platform data must supply bus speed\n"); ret = -ENODEV; goto err_clk; @@ -2243,7 +2281,7 @@ int dw_mci_probe(struct dw_mci *host) } /* Reset all blocks */ - if (!mci_wait_reset(host->dev, host)) + if (!mci_wait_reset(dev, host)) return -ENODEV; host->dma_ops = host->pdata->dma_ops; @@ -2300,15 +2338,15 @@ int dw_mci_probe(struct dw_mci *host) for (i = 0; i < host->num_slots; i++) { ret = dw_mci_init_slot(host, i); if (ret) - dev_dbg(host->dev, "slot %d init failed\n", i); + dev_dbg(dev, "slot %d init failed\n", i); else init_slots++; } if (init_slots) { - dev_info(host->dev, "%d slots initialized\n", init_slots); + dev_info(dev, "%d slots initialized\n", init_slots); } else { - dev_dbg(host->dev, "attempted to initialize %d slots, " + dev_dbg(dev, "attempted to initialize %d slots, " "but failed on all\n", host->num_slots); goto err_init_slot; } @@ -2318,7 +2356,7 @@ int dw_mci_probe(struct dw_mci *host) * Need to check the version-id and set data-offset for DATA register. */ host->verid = SDMMC_GET_VERID(mci_readl(host, VERID)); - dev_info(host->dev, "Version ID is %04x\n", host->verid); + dev_info(dev, "Version ID is %04x\n", host->verid); if (host->verid < DW_MMC_240A) host->data_offset = DATA_OFFSET; @@ -2335,12 +2373,12 @@ int dw_mci_probe(struct dw_mci *host) DW_MCI_ERROR_FLAGS | SDMMC_INT_CD); mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */ - dev_info(host->dev, "DW MMC controller at irq %d, " + dev_info(dev, "DW MMC controller at irq %d, " "%d bit host data width, " "%u deep fifo\n", host->irq, width, fifo_size); if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO) - dev_info(host->dev, "Internal DMAC interrupt fix enabled.\n"); + dev_info(dev, "Internal DMAC interrupt fix enabled.\n"); return 0; @@ -2353,7 +2391,7 @@ err_workqueue: err_dmaunmap: if (host->use_dma && host->dma_ops->exit) host->dma_ops->exit(host); - dma_free_coherent(host->dev, PAGE_SIZE, + dma_free_coherent(dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); if (host->vmmc) { @@ -2377,23 +2415,23 @@ EXPORT_SYMBOL(dw_mci_probe); void dw_mci_remove(struct dw_mci *host) { int i; + struct device *dev = &host->pdev->dev; mci_writel(host, RINTSTS, 0xFFFFFFFF); mci_writel(host, INTMASK, 0); /* disable all mmc interrupt first */ for (i = 0; i < host->num_slots; i++) { - dev_dbg(host->dev, "remove slot %d\n", i); + dev_dbg(dev, "remove slot %d\n", i); if (host->slot[i]) dw_mci_cleanup_slot(host->slot[i], i); } - /* disable clock to CIU */ mci_writel(host, CLKENA, 0); mci_writel(host, CLKSRC, 0); free_irq(host->irq, host); destroy_workqueue(host->card_workqueue); - dma_free_coherent(host->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); + dma_free_coherent(dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); if (host->use_dma && host->dma_ops->exit) host->dma_ops->exit(host); @@ -2451,7 +2489,7 @@ int dw_mci_resume(struct dw_mci *host) if (host->vmmc) regulator_enable(host->vmmc); - if (!mci_wait_reset(host->dev, host)) { + if (!mci_wait_reset(&host->pdev->dev, host)) { ret = -ENODEV; return ret; } diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h index 6c17282..8c4810a 100644 --- a/drivers/mmc/host/dw_mmc.h +++ b/drivers/mmc/host/dw_mmc.h @@ -203,6 +203,7 @@ extern int dw_mci_resume(struct dw_mci *host); struct dw_mci_drv_data { unsigned long ctrl_type; unsigned long *caps; + unsigned long *caps2; }; #endif /* _DW_MMC_H_ */ diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h index 32c778f..71de160 100644 --- a/include/linux/mmc/dw_mmc.h +++ b/include/linux/mmc/dw_mmc.h @@ -161,7 +161,7 @@ struct dw_mci { u32 fifoth_val; u16 verid; u16 data_offset; - struct device *dev; + struct platform_device *pdev; struct dw_mci_board *pdata; struct dw_mci_drv_data *drv_data; struct clk *biu_clk; diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 79d8921..b3e35fd 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -273,6 +273,7 @@ struct mmc_host { #define MMC_CAP2_PACKED_WR (1 << 21) /* Allow packed write */ #define MMC_CAP2_PACKED_CMD (MMC_CAP2_PACKED_RD | \ MMC_CAP2_PACKED_WR) /* Allow packed commands */ +#define MMC_CAP2_CONFIG_BROKEN (1 << 22) /* Broken Config Register */ mmc_pm_flag_t pm_caps; /* supported pm features */ unsigned int power_notify_type;