]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/mmc/host/davinci_mmc.c
mmc: sd: Meet alignment requirements for raw_ssr DMA
[karo-tx-linux.git] / drivers / mmc / host / davinci_mmc.c
index a56373c7598315b8ddef5580b4a7e749958a9983..36b5af8eadb88eae79e74cad782259ba100b9910 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/mmc/mmc.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/mmc/slot-gpio.h>
 
 #include <linux/platform_data/mmc-davinci.h>
 
@@ -1029,9 +1030,10 @@ static int mmc_davinci_get_cd(struct mmc_host *mmc)
        struct platform_device *pdev = to_platform_device(mmc->parent);
        struct davinci_mmc_config *config = pdev->dev.platform_data;
 
-       if (!config || !config->get_cd)
-               return -ENOSYS;
-       return config->get_cd(pdev->id);
+       if (config && config->get_cd)
+               return config->get_cd(pdev->id);
+
+       return mmc_gpio_get_cd(mmc);
 }
 
 static int mmc_davinci_get_ro(struct mmc_host *mmc)
@@ -1039,9 +1041,10 @@ static int mmc_davinci_get_ro(struct mmc_host *mmc)
        struct platform_device *pdev = to_platform_device(mmc->parent);
        struct davinci_mmc_config *config = pdev->dev.platform_data;
 
-       if (!config || !config->get_ro)
-               return -ENOSYS;
-       return config->get_ro(pdev->id);
+       if (config && config->get_ro)
+               return config->get_ro(pdev->id);
+
+       return mmc_gpio_get_ro(mmc);
 }
 
 static void mmc_davinci_enable_sdio_irq(struct mmc_host *mmc, int enable)
@@ -1159,49 +1162,53 @@ static const struct of_device_id davinci_mmc_dt_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, davinci_mmc_dt_ids);
 
-static struct davinci_mmc_config
-       *mmc_parse_pdata(struct platform_device *pdev)
+static int mmc_davinci_parse_pdata(struct mmc_host *mmc)
 {
-       struct device_node *np;
+       struct platform_device *pdev = to_platform_device(mmc->parent);
        struct davinci_mmc_config *pdata = pdev->dev.platform_data;
-       const struct of_device_id *match =
-               of_match_device(davinci_mmc_dt_ids, &pdev->dev);
-       u32 data;
-
-       np = pdev->dev.of_node;
-       if (!np)
-               return pdata;
-
-       pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
-       if (!pdata) {
-               dev_err(&pdev->dev, "Failed to allocate memory for struct davinci_mmc_config\n");
-               goto nodata;
-       }
+       struct mmc_davinci_host *host;
+       int ret;
 
-       if (match)
-               pdev->id_entry = match->data;
+       if (!pdata)
+               return -EINVAL;
 
-       if (of_property_read_u32(np, "max-frequency", &pdata->max_freq))
-               dev_info(&pdev->dev, "'max-frequency' property not specified, defaulting to 25MHz\n");
+       host = mmc_priv(mmc);
+       if (!host)
+               return -EINVAL;
 
-       of_property_read_u32(np, "bus-width", &data);
-       switch (data) {
-       case 1:
-       case 4:
-       case 8:
-               pdata->wires = data;
-               break;
-       default:
-               pdata->wires = 1;
-               dev_info(&pdev->dev, "Unsupported buswidth, defaulting to 1 bit\n");
-       }
-nodata:
-       return pdata;
+       if (pdata && pdata->nr_sg)
+               host->nr_sg = pdata->nr_sg - 1;
+
+       if (pdata && (pdata->wires == 4 || pdata->wires == 0))
+               mmc->caps |= MMC_CAP_4_BIT_DATA;
+
+       if (pdata && (pdata->wires == 8))
+               mmc->caps |= (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA);
+
+       mmc->f_min = 312500;
+       mmc->f_max = 25000000;
+       if (pdata && pdata->max_freq)
+               mmc->f_max = pdata->max_freq;
+       if (pdata && pdata->caps)
+               mmc->caps |= pdata->caps;
+
+       /* Register a cd gpio, if there is not one, enable polling */
+       ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0, NULL);
+       if (ret == -EPROBE_DEFER)
+               return ret;
+       else if (ret)
+               mmc->caps |= MMC_CAP_NEEDS_POLL;
+
+       ret = mmc_gpiod_request_ro(mmc, "wp", 0, false, 0, NULL);
+       if (ret == -EPROBE_DEFER)
+               return ret;
+
+       return 0;
 }
 
 static int __init davinci_mmcsd_probe(struct platform_device *pdev)
 {
-       struct davinci_mmc_config *pdata = NULL;
+       const struct of_device_id *match;
        struct mmc_davinci_host *host = NULL;
        struct mmc_host *mmc = NULL;
        struct resource *r, *mem = NULL;
@@ -1209,16 +1216,12 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
        size_t mem_size;
        const struct platform_device_id *id_entry;
 
-       pdata = mmc_parse_pdata(pdev);
-       if (pdata == NULL) {
-               dev_err(&pdev->dev, "Couldn't get platform data\n");
-               return -ENOENT;
-       }
-
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       irq = platform_get_irq(pdev, 0);
-       if (!r || irq == NO_IRQ)
+       if (!r)
                return -ENODEV;
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0)
+               return irq;
 
        mem_size = resource_size(r);
        mem = devm_request_mem_region(&pdev->dev, r->start, mem_size,
@@ -1251,14 +1254,28 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
 
        host->mmc_input_clk = clk_get_rate(host->clk);
 
-       init_mmcsd_host(host);
-
-       if (pdata->nr_sg)
-               host->nr_sg = pdata->nr_sg - 1;
+       match = of_match_device(davinci_mmc_dt_ids, &pdev->dev);
+       if (match) {
+               pdev->id_entry = match->data;
+               ret = mmc_of_parse(mmc);
+               if (ret) {
+                       dev_err(&pdev->dev,
+                               "could not parse of data: %d\n", ret);
+                       goto parse_fail;
+               }
+       } else {
+               ret = mmc_davinci_parse_pdata(mmc);
+               if (ret) {
+                       dev_err(&pdev->dev,
+                               "could not parse platform data: %d\n", ret);
+                       goto parse_fail;
+       }       }
 
        if (host->nr_sg > MAX_NR_SG || !host->nr_sg)
                host->nr_sg = MAX_NR_SG;
 
+       init_mmcsd_host(host);
+
        host->use_dma = use_dma;
        host->mmc_irq = irq;
        host->sdio_irq = platform_get_irq(pdev, 1);
@@ -1271,27 +1288,13 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev)
                        host->use_dma = 0;
        }
 
-       /* REVISIT:  someday, support IRQ-driven card detection.  */
-       mmc->caps |= MMC_CAP_NEEDS_POLL;
        mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY;
 
-       if (pdata && (pdata->wires == 4 || pdata->wires == 0))
-               mmc->caps |= MMC_CAP_4_BIT_DATA;
-
-       if (pdata && (pdata->wires == 8))
-               mmc->caps |= (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA);
-
        id_entry = platform_get_device_id(pdev);
        if (id_entry)
                host->version = id_entry->driver_data;
 
        mmc->ops = &mmc_davinci_ops;
-       mmc->f_min = 312500;
-       mmc->f_max = 25000000;
-       if (pdata && pdata->max_freq)
-               mmc->f_max = pdata->max_freq;
-       if (pdata && pdata->caps)
-               mmc->caps |= pdata->caps;
        mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
 
        /* With no iommu coalescing pages, each phys_seg is a hw_seg.
@@ -1352,6 +1355,7 @@ mmc_add_host_fail:
        mmc_davinci_cpufreq_deregister(host);
 cpu_freq_fail:
        davinci_release_dma_channels(host);
+parse_fail:
 dma_probe_defer:
        clk_disable_unprepare(host->clk);
 clk_prepare_enable_fail: