dm: core: Update lists_bind_fdt() to use ofnode
[oweals/u-boot.git] / drivers / mmc / uniphier-sd.c
index 40a5c85e373f2df34a60020d19a89ea2d4c7779c..3c462bd5835e9e4efae745791fdaaff80a4c2af5 100644 (file)
@@ -9,7 +9,7 @@
 #include <clk.h>
 #include <fdtdec.h>
 #include <mmc.h>
-#include <dm/device.h>
+#include <dm.h>
 #include <linux/compat.h>
 #include <linux/io.h>
 #include <linux/sizes.h>
@@ -119,9 +119,12 @@ DECLARE_GLOBAL_DATA_PTR;
 /* alignment required by the DMA engine of this controller */
 #define UNIPHIER_SD_DMA_MINALIGN       0x10
 
-struct uniphier_sd_priv {
+struct uniphier_sd_plat {
        struct mmc_config cfg;
-       struct mmc *mmc;
+       struct mmc mmc;
+};
+
+struct uniphier_sd_priv {
        void __iomem *regbase;
        unsigned long mclk;
        unsigned int version;
@@ -571,6 +574,9 @@ static void uniphier_sd_set_clk_rate(struct uniphier_sd_priv *priv,
                val = UNIPHIER_SD_CLKCTL_DIV1024;
 
        tmp = readl(priv->regbase + UNIPHIER_SD_CLKCTL);
+       if (tmp & UNIPHIER_SD_CLKCTL_SCLKEN &&
+           (tmp & UNIPHIER_SD_CLKCTL_DIV_MASK) == val)
+               return;
 
        /* stop the clock before changing its rate to avoid a glitch signal */
        tmp &= ~UNIPHIER_SD_CLKCTL_SCLKEN;
@@ -582,6 +588,8 @@ static void uniphier_sd_set_clk_rate(struct uniphier_sd_priv *priv,
 
        tmp |= UNIPHIER_SD_CLKCTL_SCLKEN;
        writel(tmp, priv->regbase + UNIPHIER_SD_CLKCTL);
+
+       udelay(1000);
 }
 
 static int uniphier_sd_set_ios(struct udevice *dev)
@@ -599,8 +607,6 @@ static int uniphier_sd_set_ios(struct udevice *dev)
        uniphier_sd_set_ddr_mode(priv, mmc);
        uniphier_sd_set_clk_rate(priv, mmc);
 
-       udelay(1000);
-
        return 0;
 }
 
@@ -651,15 +657,23 @@ static void uniphier_sd_host_init(struct uniphier_sd_priv *priv)
        }
 }
 
+static int uniphier_sd_bind(struct udevice *dev)
+{
+       struct uniphier_sd_plat *plat = dev_get_platdata(dev);
+
+       return mmc_bind(dev, &plat->mmc, &plat->cfg);
+}
+
 static int uniphier_sd_probe(struct udevice *dev)
 {
+       struct uniphier_sd_plat *plat = dev_get_platdata(dev);
        struct uniphier_sd_priv *priv = dev_get_priv(dev);
        struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
        fdt_addr_t base;
        struct clk clk;
        int ret;
 
-       base = dev_get_addr(dev);
+       base = devfdt_get_addr(dev);
        if (base == FDT_ADDR_T_NONE)
                return -EINVAL;
 
@@ -688,15 +702,16 @@ static int uniphier_sd_probe(struct udevice *dev)
                return ret;
        }
 
-       priv->cfg.name = dev->name;
-       priv->cfg.host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS;
+       plat->cfg.name = dev->name;
+       plat->cfg.host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS;
 
-       switch (fdtdec_get_int(gd->fdt_blob, dev->of_offset, "bus-width", 1)) {
+       switch (fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "bus-width",
+                              1)) {
        case 8:
-               priv->cfg.host_caps |= MMC_MODE_8BIT;
+               plat->cfg.host_caps |= MMC_MODE_8BIT;
                break;
        case 4:
-               priv->cfg.host_caps |= MMC_MODE_4BIT;
+               plat->cfg.host_caps |= MMC_MODE_4BIT;
                break;
        case 1:
                break;
@@ -705,7 +720,7 @@ static int uniphier_sd_probe(struct udevice *dev)
                return -EINVAL;
        }
 
-       if (fdt_get_property(gd->fdt_blob, dev->of_offset, "non-removable",
+       if (fdt_get_property(gd->fdt_blob, dev_of_offset(dev), "non-removable",
                             NULL))
                priv->caps |= UNIPHIER_SD_CAP_NONREMOVABLE;
 
@@ -719,27 +734,13 @@ static int uniphier_sd_probe(struct udevice *dev)
 
        uniphier_sd_host_init(priv);
 
-       priv->cfg.voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34;
-       priv->cfg.f_min = priv->mclk /
+       plat->cfg.voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34;
+       plat->cfg.f_min = priv->mclk /
                        (priv->caps & UNIPHIER_SD_CAP_DIV1024 ? 1024 : 512);
-       priv->cfg.f_max = priv->mclk;
-       priv->cfg.b_max = U32_MAX; /* max value of UNIPHIER_SD_SECCNT */
-
-       priv->mmc = mmc_create(&priv->cfg, priv);
-       if (!priv->mmc)
-               return -EIO;
-
-       upriv->mmc = priv->mmc;
-       priv->mmc->dev = dev;
-
-       return 0;
-}
-
-static int uniphier_sd_remove(struct udevice *dev)
-{
-       struct uniphier_sd_priv *priv = dev_get_priv(dev);
+       plat->cfg.f_max = priv->mclk;
+       plat->cfg.b_max = U32_MAX; /* max value of UNIPHIER_SD_SECCNT */
 
-       mmc_destroy(priv->mmc);
+       upriv->mmc = &plat->mmc;
 
        return 0;
 }
@@ -753,8 +754,9 @@ U_BOOT_DRIVER(uniphier_mmc) = {
        .name = "uniphier-mmc",
        .id = UCLASS_MMC,
        .of_match = uniphier_sd_match,
+       .bind = uniphier_sd_bind,
        .probe = uniphier_sd_probe,
-       .remove = uniphier_sd_remove,
        .priv_auto_alloc_size = sizeof(struct uniphier_sd_priv),
+       .platdata_auto_alloc_size = sizeof(struct uniphier_sd_plat),
        .ops = &uniphier_sd_ops,
 };