]> git.ipfire.org Git - people/ms/u-boot.git/blobdiff - drivers/mmc/pci_mmc.c
mmc: use mmc modes to select the correct bus speed
[people/ms/u-boot.git] / drivers / mmc / pci_mmc.c
index e39b476834e650d187cfa25278ac48e7cfe87232..05c0044a7a001148fc8e3183a2229fc171ed6b33 100644 (file)
@@ -6,37 +6,66 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <errno.h>
 #include <malloc.h>
+#include <mapmem.h>
 #include <sdhci.h>
 #include <asm/pci.h>
 
-int pci_mmc_init(const char *name, struct pci_device_id *mmc_supported)
+struct pci_mmc_plat {
+       struct mmc_config cfg;
+       struct mmc mmc;
+};
+
+struct pci_mmc_priv {
+       struct sdhci_host host;
+       void *base;
+};
+
+static int pci_mmc_probe(struct udevice *dev)
 {
-       struct sdhci_host *mmc_host;
-       u32 iobase;
+       struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+       struct pci_mmc_plat *plat = dev_get_platdata(dev);
+       struct pci_mmc_priv *priv = dev_get_priv(dev);
+       struct sdhci_host *host = &priv->host;
+       u32 ioaddr;
        int ret;
-       int i;
-
-       for (i = 0; ; i++) {
-               struct udevice *dev;
-
-               ret = pci_find_device_id(mmc_supported, i, &dev);
-               if (ret)
-                       return ret;
-               mmc_host = malloc(sizeof(struct sdhci_host));
-               if (!mmc_host)
-                       return -ENOMEM;
-
-               mmc_host->name = name;
-               dm_pci_read_config32(dev, PCI_BASE_ADDRESS_0, &iobase);
-               mmc_host->ioaddr = (void *)(ulong)iobase;
-               mmc_host->quirks = 0;
-               mmc_host->max_clk = 0;
-               ret = add_sdhci(mmc_host, 0, 0);
-               if (ret)
-                       return ret;
-       }
-
-       return 0;
+
+       dm_pci_read_config32(dev, PCI_BASE_ADDRESS_0, &ioaddr);
+       host->ioaddr = map_sysmem(ioaddr, 0);
+       host->name = dev->name;
+       ret = sdhci_setup_cfg(&plat->cfg, host, 0, 0);
+       if (ret)
+               return ret;
+       host->mmc = &plat->mmc;
+       host->mmc->priv = &priv->host;
+       host->mmc->dev = dev;
+       upriv->mmc = host->mmc;
+
+       return sdhci_probe(dev);
 }
+
+static int pci_mmc_bind(struct udevice *dev)
+{
+       struct pci_mmc_plat *plat = dev_get_platdata(dev);
+
+       return sdhci_bind(dev, &plat->mmc, &plat->cfg);
+}
+
+U_BOOT_DRIVER(pci_mmc) = {
+       .name   = "pci_mmc",
+       .id     = UCLASS_MMC,
+       .bind   = pci_mmc_bind,
+       .probe  = pci_mmc_probe,
+       .ops    = &sdhci_ops,
+       .priv_auto_alloc_size = sizeof(struct pci_mmc_priv),
+       .platdata_auto_alloc_size = sizeof(struct pci_mmc_plat),
+};
+
+static struct pci_device_id mmc_supported[] = {
+       { PCI_DEVICE_CLASS(PCI_CLASS_SYSTEM_SDHCI << 8, 0xffff00) },
+       {},
+};
+
+U_BOOT_PCI_DEVICE(pci_mmc, mmc_supported);