diff options
Diffstat (limited to 'drivers/mmc/host/dw_mmc.c')
-rw-r--r-- | drivers/mmc/host/dw_mmc.c | 62 |
1 files changed, 34 insertions, 28 deletions
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index c2828f35c3b8..c0667c8af2bd 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c | |||
@@ -232,6 +232,7 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) | |||
232 | { | 232 | { |
233 | struct mmc_data *data; | 233 | struct mmc_data *data; |
234 | struct dw_mci_slot *slot = mmc_priv(mmc); | 234 | struct dw_mci_slot *slot = mmc_priv(mmc); |
235 | struct dw_mci_drv_data *drv_data = slot->host->drv_data; | ||
235 | u32 cmdr; | 236 | u32 cmdr; |
236 | cmd->error = -EINPROGRESS; | 237 | cmd->error = -EINPROGRESS; |
237 | 238 | ||
@@ -261,8 +262,8 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) | |||
261 | cmdr |= SDMMC_CMD_DAT_WR; | 262 | cmdr |= SDMMC_CMD_DAT_WR; |
262 | } | 263 | } |
263 | 264 | ||
264 | if (slot->host->drv_data->prepare_command) | 265 | if (drv_data && drv_data->prepare_command) |
265 | slot->host->drv_data->prepare_command(slot->host, &cmdr); | 266 | drv_data->prepare_command(slot->host, &cmdr); |
266 | 267 | ||
267 | return cmdr; | 268 | return cmdr; |
268 | } | 269 | } |
@@ -434,7 +435,7 @@ static int dw_mci_idmac_init(struct dw_mci *host) | |||
434 | return 0; | 435 | return 0; |
435 | } | 436 | } |
436 | 437 | ||
437 | static struct dw_mci_dma_ops dw_mci_idmac_ops = { | 438 | static const struct dw_mci_dma_ops dw_mci_idmac_ops = { |
438 | .init = dw_mci_idmac_init, | 439 | .init = dw_mci_idmac_init, |
439 | .start = dw_mci_idmac_start_dma, | 440 | .start = dw_mci_idmac_start_dma, |
440 | .stop = dw_mci_idmac_stop_dma, | 441 | .stop = dw_mci_idmac_stop_dma, |
@@ -772,6 +773,7 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
772 | static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 773 | static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
773 | { | 774 | { |
774 | struct dw_mci_slot *slot = mmc_priv(mmc); | 775 | struct dw_mci_slot *slot = mmc_priv(mmc); |
776 | struct dw_mci_drv_data *drv_data = slot->host->drv_data; | ||
775 | u32 regs; | 777 | u32 regs; |
776 | 778 | ||
777 | /* set default 1 bit mode */ | 779 | /* set default 1 bit mode */ |
@@ -807,8 +809,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
807 | slot->clock = ios->clock; | 809 | slot->clock = ios->clock; |
808 | } | 810 | } |
809 | 811 | ||
810 | if (slot->host->drv_data->set_ios) | 812 | if (drv_data && drv_data->set_ios) |
811 | slot->host->drv_data->set_ios(slot->host, ios); | 813 | drv_data->set_ios(slot->host, ios); |
812 | 814 | ||
813 | switch (ios->power_mode) { | 815 | switch (ios->power_mode) { |
814 | case MMC_POWER_UP: | 816 | case MMC_POWER_UP: |
@@ -1815,6 +1817,7 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) | |||
1815 | { | 1817 | { |
1816 | struct mmc_host *mmc; | 1818 | struct mmc_host *mmc; |
1817 | struct dw_mci_slot *slot; | 1819 | struct dw_mci_slot *slot; |
1820 | struct dw_mci_drv_data *drv_data = host->drv_data; | ||
1818 | int ctrl_id, ret; | 1821 | int ctrl_id, ret; |
1819 | u8 bus_width; | 1822 | u8 bus_width; |
1820 | 1823 | ||
@@ -1854,8 +1857,8 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) | |||
1854 | } else { | 1857 | } else { |
1855 | ctrl_id = to_platform_device(host->dev)->id; | 1858 | ctrl_id = to_platform_device(host->dev)->id; |
1856 | } | 1859 | } |
1857 | if (host->drv_data && host->drv_data->caps) | 1860 | if (drv_data && drv_data->caps) |
1858 | mmc->caps |= host->drv_data->caps[ctrl_id]; | 1861 | mmc->caps |= drv_data->caps[ctrl_id]; |
1859 | 1862 | ||
1860 | if (host->pdata->caps2) | 1863 | if (host->pdata->caps2) |
1861 | mmc->caps2 = host->pdata->caps2; | 1864 | mmc->caps2 = host->pdata->caps2; |
@@ -1867,10 +1870,10 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) | |||
1867 | else | 1870 | else |
1868 | bus_width = 1; | 1871 | bus_width = 1; |
1869 | 1872 | ||
1870 | if (host->drv_data->setup_bus) { | 1873 | if (drv_data && drv_data->setup_bus) { |
1871 | struct device_node *slot_np; | 1874 | struct device_node *slot_np; |
1872 | slot_np = dw_mci_of_find_slot_node(host->dev, slot->id); | 1875 | slot_np = dw_mci_of_find_slot_node(host->dev, slot->id); |
1873 | ret = host->drv_data->setup_bus(host, slot_np, bus_width); | 1876 | ret = drv_data->setup_bus(host, slot_np, bus_width); |
1874 | if (ret) | 1877 | if (ret) |
1875 | goto err_setup_bus; | 1878 | goto err_setup_bus; |
1876 | } | 1879 | } |
@@ -1968,7 +1971,7 @@ static void dw_mci_init_dma(struct dw_mci *host) | |||
1968 | /* Determine which DMA interface to use */ | 1971 | /* Determine which DMA interface to use */ |
1969 | #ifdef CONFIG_MMC_DW_IDMAC | 1972 | #ifdef CONFIG_MMC_DW_IDMAC |
1970 | host->dma_ops = &dw_mci_idmac_ops; | 1973 | host->dma_ops = &dw_mci_idmac_ops; |
1971 | dev_info(&host->dev, "Using internal DMA controller.\n"); | 1974 | dev_info(host->dev, "Using internal DMA controller.\n"); |
1972 | #endif | 1975 | #endif |
1973 | 1976 | ||
1974 | if (!host->dma_ops) | 1977 | if (!host->dma_ops) |
@@ -2035,6 +2038,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) | |||
2035 | struct dw_mci_board *pdata; | 2038 | struct dw_mci_board *pdata; |
2036 | struct device *dev = host->dev; | 2039 | struct device *dev = host->dev; |
2037 | struct device_node *np = dev->of_node; | 2040 | struct device_node *np = dev->of_node; |
2041 | struct dw_mci_drv_data *drv_data = host->drv_data; | ||
2038 | int idx, ret; | 2042 | int idx, ret; |
2039 | 2043 | ||
2040 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | 2044 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); |
@@ -2062,8 +2066,8 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) | |||
2062 | 2066 | ||
2063 | of_property_read_u32(np, "card-detect-delay", &pdata->detect_delay_ms); | 2067 | of_property_read_u32(np, "card-detect-delay", &pdata->detect_delay_ms); |
2064 | 2068 | ||
2065 | if (host->drv_data->parse_dt) { | 2069 | if (drv_data && drv_data->parse_dt) { |
2066 | ret = host->drv_data->parse_dt(host); | 2070 | ret = drv_data->parse_dt(host); |
2067 | if (ret) | 2071 | if (ret) |
2068 | return ERR_PTR(ret); | 2072 | return ERR_PTR(ret); |
2069 | } | 2073 | } |
@@ -2080,6 +2084,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) | |||
2080 | 2084 | ||
2081 | int dw_mci_probe(struct dw_mci *host) | 2085 | int dw_mci_probe(struct dw_mci *host) |
2082 | { | 2086 | { |
2087 | struct dw_mci_drv_data *drv_data = host->drv_data; | ||
2083 | int width, i, ret = 0; | 2088 | int width, i, ret = 0; |
2084 | u32 fifo_size; | 2089 | u32 fifo_size; |
2085 | int init_slots = 0; | 2090 | int init_slots = 0; |
@@ -2127,8 +2132,8 @@ int dw_mci_probe(struct dw_mci *host) | |||
2127 | else | 2132 | else |
2128 | host->bus_hz = clk_get_rate(host->ciu_clk); | 2133 | host->bus_hz = clk_get_rate(host->ciu_clk); |
2129 | 2134 | ||
2130 | if (host->drv_data->setup_clock) { | 2135 | if (drv_data && drv_data->setup_clock) { |
2131 | ret = host->drv_data->setup_clock(host); | 2136 | ret = drv_data->setup_clock(host); |
2132 | if (ret) { | 2137 | if (ret) { |
2133 | dev_err(host->dev, | 2138 | dev_err(host->dev, |
2134 | "implementation specific clock setup failed\n"); | 2139 | "implementation specific clock setup failed\n"); |
@@ -2228,6 +2233,21 @@ int dw_mci_probe(struct dw_mci *host) | |||
2228 | else | 2233 | else |
2229 | host->num_slots = ((mci_readl(host, HCON) >> 1) & 0x1F) + 1; | 2234 | host->num_slots = ((mci_readl(host, HCON) >> 1) & 0x1F) + 1; |
2230 | 2235 | ||
2236 | /* | ||
2237 | * Enable interrupts for command done, data over, data empty, card det, | ||
2238 | * receive ready and error such as transmit, receive timeout, crc error | ||
2239 | */ | ||
2240 | mci_writel(host, RINTSTS, 0xFFFFFFFF); | ||
2241 | mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | | ||
2242 | SDMMC_INT_TXDR | SDMMC_INT_RXDR | | ||
2243 | DW_MCI_ERROR_FLAGS | SDMMC_INT_CD); | ||
2244 | mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */ | ||
2245 | |||
2246 | dev_info(host->dev, "DW MMC controller at irq %d, " | ||
2247 | "%d bit host data width, " | ||
2248 | "%u deep fifo\n", | ||
2249 | host->irq, width, fifo_size); | ||
2250 | |||
2231 | /* We need at least one slot to succeed */ | 2251 | /* We need at least one slot to succeed */ |
2232 | for (i = 0; i < host->num_slots; i++) { | 2252 | for (i = 0; i < host->num_slots; i++) { |
2233 | ret = dw_mci_init_slot(host, i); | 2253 | ret = dw_mci_init_slot(host, i); |
@@ -2257,20 +2277,6 @@ int dw_mci_probe(struct dw_mci *host) | |||
2257 | else | 2277 | else |
2258 | host->data_offset = DATA_240A_OFFSET; | 2278 | host->data_offset = DATA_240A_OFFSET; |
2259 | 2279 | ||
2260 | /* | ||
2261 | * Enable interrupts for command done, data over, data empty, card det, | ||
2262 | * receive ready and error such as transmit, receive timeout, crc error | ||
2263 | */ | ||
2264 | mci_writel(host, RINTSTS, 0xFFFFFFFF); | ||
2265 | mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | | ||
2266 | SDMMC_INT_TXDR | SDMMC_INT_RXDR | | ||
2267 | DW_MCI_ERROR_FLAGS | SDMMC_INT_CD); | ||
2268 | mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */ | ||
2269 | |||
2270 | dev_info(host->dev, "DW MMC controller at irq %d, " | ||
2271 | "%d bit host data width, " | ||
2272 | "%u deep fifo\n", | ||
2273 | host->irq, width, fifo_size); | ||
2274 | if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO) | 2280 | if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO) |
2275 | dev_info(host->dev, "Internal DMAC interrupt fix enabled.\n"); | 2281 | dev_info(host->dev, "Internal DMAC interrupt fix enabled.\n"); |
2276 | 2282 | ||