--- zzzz-none-000/linux-3.10.107/drivers/mmc/host/omap.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/mmc/host/omap.c 2021-02-04 17:41:59.000000000 +0000 @@ -22,9 +22,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -90,17 +92,6 @@ #define OMAP_MMC_CMDTYPE_AC 2 #define OMAP_MMC_CMDTYPE_ADTC 3 -#define OMAP_DMA_MMC_TX 21 -#define OMAP_DMA_MMC_RX 22 -#define OMAP_DMA_MMC2_TX 54 -#define OMAP_DMA_MMC2_RX 55 - -#define OMAP24XX_DMA_MMC2_TX 47 -#define OMAP24XX_DMA_MMC2_RX 48 -#define OMAP24XX_DMA_MMC1_TX 61 -#define OMAP24XX_DMA_MMC1_RX 62 - - #define DRIVER_NAME "mmci-omap" /* Specifies how often in millisecs to poll for card status changes @@ -128,7 +119,6 @@ struct mmc_omap_host { int initialized; - int suspended; struct mmc_request * mrq; struct mmc_command * cmd; struct mmc_data * data; @@ -141,7 +131,6 @@ u32 dma_rx_burst; struct dma_chan *dma_tx; u32 dma_tx_burst; - struct resource *mem_res; void __iomem *virt_base; unsigned int phys_base; int irq; @@ -164,7 +153,6 @@ u32 total_bytes_left; unsigned features; - unsigned use_dma:1; unsigned brs_received:1, dma_done:1; unsigned dma_in_use:1; spinlock_t dma_lock; @@ -189,7 +177,7 @@ unsigned long tick_ns; if (slot != NULL && slot->host->fclk_enabled && slot->fclk_freq > 0) { - tick_ns = (1000000000 + slot->fclk_freq - 1) / slot->fclk_freq; + tick_ns = DIV_ROUND_UP(NSEC_PER_SEC, slot->fclk_freq); ndelay(8 * tick_ns); } } @@ -349,6 +337,7 @@ u32 cmdreg; u32 resptype; u32 cmdtype; + u16 irq_mask; host->cmd = cmd; @@ -401,12 +390,14 @@ OMAP_MMC_WRITE(host, CTO, 200); OMAP_MMC_WRITE(host, ARGL, cmd->arg & 0xffff); OMAP_MMC_WRITE(host, ARGH, cmd->arg >> 16); - OMAP_MMC_WRITE(host, IE, - OMAP_MMC_STAT_A_EMPTY | OMAP_MMC_STAT_A_FULL | - OMAP_MMC_STAT_CMD_CRC | OMAP_MMC_STAT_CMD_TOUT | - OMAP_MMC_STAT_DATA_CRC | OMAP_MMC_STAT_DATA_TOUT | - OMAP_MMC_STAT_END_OF_CMD | OMAP_MMC_STAT_CARD_ERR | - OMAP_MMC_STAT_END_OF_DATA); + irq_mask = OMAP_MMC_STAT_A_EMPTY | OMAP_MMC_STAT_A_FULL | + OMAP_MMC_STAT_CMD_CRC | OMAP_MMC_STAT_CMD_TOUT | + OMAP_MMC_STAT_DATA_CRC | OMAP_MMC_STAT_DATA_TOUT | + OMAP_MMC_STAT_END_OF_CMD | OMAP_MMC_STAT_CARD_ERR | + OMAP_MMC_STAT_END_OF_DATA; + if (cmd->opcode == MMC_ERASE) + irq_mask &= ~OMAP_MMC_STAT_DATA_TOUT; + OMAP_MMC_WRITE(host, IE, irq_mask); OMAP_MMC_WRITE(host, CMD, cmdreg); } @@ -444,7 +435,7 @@ struct mmc_data *data = host->stop_data; unsigned long tick_ns; - tick_ns = (1000000000 + slot->fclk_freq - 1)/slot->fclk_freq; + tick_ns = DIV_ROUND_UP(NSEC_PER_SEC, slot->fclk_freq); ndelay(8*tick_ns); mmc_omap_start_command(host, data->stop); @@ -486,7 +477,7 @@ u16 stat = 0; /* Sending abort takes 80 clocks. Have some extra and round up */ - timeout = (120*1000000 + slot->fclk_freq - 1)/slot->fclk_freq; + timeout = DIV_ROUND_UP(120 * USEC_PER_SEC, slot->fclk_freq); restarts = 0; while (restarts < maxloops) { OMAP_MMC_WRITE(host, STAT, 0xFFFF); @@ -686,8 +677,8 @@ if (n > host->buffer_bytes_left) n = host->buffer_bytes_left; - nwords = n / 2; - nwords += n & 1; /* handle odd number of bytes to transfer */ + /* Round up to handle odd number of bytes to transfer */ + nwords = DIV_ROUND_UP(n, 2); host->buffer_bytes_left -= n; host->total_bytes_left -= n; @@ -956,7 +947,8 @@ mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req) { struct mmc_data *data = req->data; - int i, use_dma, block_size; + int i, use_dma = 1, block_size; + struct scatterlist *sg; unsigned sg_len; host->data = data; @@ -981,13 +973,10 @@ sg_len = (data->blocks == 1) ? 1 : data->sg_len; /* Only do DMA for entire blocks */ - use_dma = host->use_dma; - if (use_dma) { - for (i = 0; i < sg_len; i++) { - if ((data->sg[i].length % block_size) != 0) { - use_dma = 0; - break; - } + for_each_sg(data->sg, sg, sg_len, i) { + if ((sg->length % block_size) != 0) { + use_dma = 0; + break; } } @@ -1250,7 +1239,7 @@ mmc->caps = 0; if (host->pdata->slots[id].wires >= 4) - mmc->caps |= MMC_CAP_4_BIT_DATA; + mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_ERASE; mmc->ops = &mmc_omap_ops; mmc->f_min = 400000; @@ -1273,6 +1262,13 @@ mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; mmc->max_seg_size = mmc->max_req_size; + if (slot->pdata->get_cover_state != NULL) { + setup_timer(&slot->cover_timer, mmc_omap_cover_timer, + (unsigned long)slot); + tasklet_init(&slot->cover_tasklet, mmc_omap_cover_handler, + (unsigned long)slot); + } + r = mmc_add_host(mmc); if (r < 0) goto err_remove_host; @@ -1289,11 +1285,6 @@ &dev_attr_cover_switch); if (r < 0) goto err_remove_slot_name; - - setup_timer(&slot->cover_timer, mmc_omap_cover_timer, - (unsigned long)slot); - tasklet_init(&slot->cover_tasklet, mmc_omap_cover_handler, - (unsigned long)slot); tasklet_schedule(&slot->cover_tasklet); } @@ -1331,7 +1322,7 @@ struct mmc_omap_host *host = NULL; struct resource *res; dma_cap_mask_t mask; - unsigned sig; + unsigned sig = 0; int i, ret = 0; int irq; @@ -1341,24 +1332,22 @@ } if (pdata->nr_slots == 0) { dev_err(&pdev->dev, "no slots\n"); - return -ENXIO; + return -EPROBE_DEFER; } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + host = devm_kzalloc(&pdev->dev, sizeof(struct mmc_omap_host), + GFP_KERNEL); + if (host == NULL) + return -ENOMEM; + irq = platform_get_irq(pdev, 0); - if (res == NULL || irq < 0) + if (irq < 0) return -ENXIO; - res = request_mem_region(res->start, resource_size(res), - pdev->name); - if (res == NULL) - return -EBUSY; - - host = kzalloc(sizeof(struct mmc_omap_host), GFP_KERNEL); - if (host == NULL) { - ret = -ENOMEM; - goto err_free_mem_region; - } + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + host->virt_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(host->virt_base)) + return PTR_ERR(host->virt_base); INIT_WORK(&host->slot_release_work, mmc_omap_slot_release_work); INIT_WORK(&host->send_stop_work, mmc_omap_send_stop_work); @@ -1380,20 +1369,11 @@ platform_set_drvdata(pdev, host); host->id = pdev->id; - host->mem_res = res; - host->irq = irq; - host->use_dma = 1; host->irq = irq; - host->phys_base = host->mem_res->start; - host->virt_base = ioremap(res->start, resource_size(res)); - if (!host->virt_base) - goto err_ioremap; - + host->phys_base = res->start; host->iclk = clk_get(&pdev->dev, "ick"); - if (IS_ERR(host->iclk)) { - ret = PTR_ERR(host->iclk); - goto err_free_mmc_host; - } + if (IS_ERR(host->iclk)) + return PTR_ERR(host->iclk); clk_enable(host->iclk); host->fclk = clk_get(&pdev->dev, "fck"); @@ -1408,38 +1388,23 @@ host->dma_tx_burst = -1; host->dma_rx_burst = -1; - if (mmc_omap2()) - sig = host->id == 0 ? OMAP24XX_DMA_MMC1_TX : OMAP24XX_DMA_MMC2_TX; - else - sig = host->id == 0 ? OMAP_DMA_MMC_TX : OMAP_DMA_MMC2_TX; - host->dma_tx = dma_request_channel(mask, omap_dma_filter_fn, &sig); -#if 0 - if (!host->dma_tx) { - dev_err(host->dev, "unable to obtain TX DMA engine channel %u\n", - sig); - goto err_dma; - } -#else + res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx"); + if (res) + sig = res->start; + host->dma_tx = dma_request_slave_channel_compat(mask, + omap_dma_filter_fn, &sig, &pdev->dev, "tx"); if (!host->dma_tx) dev_warn(host->dev, "unable to obtain TX DMA engine channel %u\n", sig); -#endif - if (mmc_omap2()) - sig = host->id == 0 ? OMAP24XX_DMA_MMC1_RX : OMAP24XX_DMA_MMC2_RX; - else - sig = host->id == 0 ? OMAP_DMA_MMC_RX : OMAP_DMA_MMC2_RX; - host->dma_rx = dma_request_channel(mask, omap_dma_filter_fn, &sig); -#if 0 - if (!host->dma_rx) { - dev_err(host->dev, "unable to obtain RX DMA engine channel %u\n", - sig); - goto err_dma; - } -#else + + res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx"); + if (res) + sig = res->start; + host->dma_rx = dma_request_slave_channel_compat(mask, + omap_dma_filter_fn, &sig, &pdev->dev, "rx"); if (!host->dma_rx) dev_warn(host->dev, "unable to obtain RX DMA engine channel %u\n", sig); -#endif ret = request_irq(host->irq, mmc_omap_irq, 0, DRIVER_NAME, host); if (ret) @@ -1455,8 +1420,10 @@ host->reg_shift = (mmc_omap7xx() ? 1 : 2); host->mmc_omap_wq = alloc_workqueue("mmc_omap", 0, 0); - if (!host->mmc_omap_wq) + if (!host->mmc_omap_wq) { + ret = -ENOMEM; goto err_plat_cleanup; + } for (i = 0; i < pdata->nr_slots; i++) { ret = mmc_omap_new_slot(host, i); @@ -1486,12 +1453,6 @@ err_free_iclk: clk_disable(host->iclk); clk_put(host->iclk); -err_free_mmc_host: - iounmap(host->virt_base); -err_ioremap: - kfree(host); -err_free_mem_region: - release_mem_region(res->start, resource_size(res)); return ret; } @@ -1500,8 +1461,6 @@ struct mmc_omap_host *host = platform_get_drvdata(pdev); int i; - platform_set_drvdata(pdev, NULL); - BUG_ON(host == NULL); for (i = 0; i < host->nr_slots; i++) @@ -1521,74 +1480,25 @@ if (host->dma_rx) dma_release_channel(host->dma_rx); - iounmap(host->virt_base); - release_mem_region(pdev->resource[0].start, - pdev->resource[0].end - pdev->resource[0].start + 1); destroy_workqueue(host->mmc_omap_wq); - kfree(host); - return 0; } -#ifdef CONFIG_PM -static int mmc_omap_suspend(struct platform_device *pdev, pm_message_t mesg) -{ - int i, ret = 0; - struct mmc_omap_host *host = platform_get_drvdata(pdev); - - if (host == NULL || host->suspended) - return 0; - - for (i = 0; i < host->nr_slots; i++) { - struct mmc_omap_slot *slot; - - slot = host->slots[i]; - ret = mmc_suspend_host(slot->mmc); - if (ret < 0) { - while (--i >= 0) { - slot = host->slots[i]; - mmc_resume_host(slot->mmc); - } - return ret; - } - } - host->suspended = 1; - return 0; -} - -static int mmc_omap_resume(struct platform_device *pdev) -{ - int i, ret = 0; - struct mmc_omap_host *host = platform_get_drvdata(pdev); - - if (host == NULL || !host->suspended) - return 0; - - for (i = 0; i < host->nr_slots; i++) { - struct mmc_omap_slot *slot; - slot = host->slots[i]; - ret = mmc_resume_host(slot->mmc); - if (ret < 0) - return ret; - - host->suspended = 0; - } - return 0; -} -#else -#define mmc_omap_suspend NULL -#define mmc_omap_resume NULL +#if IS_BUILTIN(CONFIG_OF) +static const struct of_device_id mmc_omap_match[] = { + { .compatible = "ti,omap2420-mmc", }, + { }, +}; +MODULE_DEVICE_TABLE(of, mmc_omap_match); #endif static struct platform_driver mmc_omap_driver = { .probe = mmc_omap_probe, .remove = mmc_omap_remove, - .suspend = mmc_omap_suspend, - .resume = mmc_omap_resume, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, + .of_match_table = of_match_ptr(mmc_omap_match), }, };