linux/drivers/mmc/host/sdhci-st.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Support for SDHCI on STMicroelectronics SoCs
   4 *
   5 * Copyright (C) 2014 STMicroelectronics Ltd
   6 * Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
   7 * Contributors: Peter Griffin <peter.griffin@linaro.org>
   8 *
   9 * Based on sdhci-cns3xxx.c
  10 */
  11
  12#include <linux/io.h>
  13#include <linux/of.h>
  14#include <linux/module.h>
  15#include <linux/err.h>
  16#include <linux/mmc/host.h>
  17#include <linux/reset.h>
  18#include "sdhci-pltfm.h"
  19
  20struct st_mmc_platform_data {
  21        struct  reset_control *rstc;
  22        struct  clk *icnclk;
  23        void __iomem *top_ioaddr;
  24};
  25
  26/* MMCSS glue logic to setup the HC on some ST SoCs (e.g. STiH407 family) */
  27
  28#define ST_MMC_CCONFIG_REG_1            0x400
  29#define ST_MMC_CCONFIG_TIMEOUT_CLK_UNIT BIT(24)
  30#define ST_MMC_CCONFIG_TIMEOUT_CLK_FREQ BIT(12)
  31#define ST_MMC_CCONFIG_TUNING_COUNT_DEFAULT     BIT(8)
  32#define ST_MMC_CCONFIG_ASYNC_WAKEUP     BIT(0)
  33#define ST_MMC_CCONFIG_1_DEFAULT        \
  34                                ((ST_MMC_CCONFIG_TIMEOUT_CLK_UNIT) | \
  35                                 (ST_MMC_CCONFIG_TIMEOUT_CLK_FREQ) | \
  36                                 (ST_MMC_CCONFIG_TUNING_COUNT_DEFAULT))
  37
  38#define ST_MMC_CCONFIG_REG_2            0x404
  39#define ST_MMC_CCONFIG_HIGH_SPEED       BIT(28)
  40#define ST_MMC_CCONFIG_ADMA2            BIT(24)
  41#define ST_MMC_CCONFIG_8BIT             BIT(20)
  42#define ST_MMC_CCONFIG_MAX_BLK_LEN      16
  43#define  MAX_BLK_LEN_1024               1
  44#define  MAX_BLK_LEN_2048               2
  45#define BASE_CLK_FREQ_200               0xc8
  46#define BASE_CLK_FREQ_100               0x64
  47#define BASE_CLK_FREQ_50                0x32
  48#define ST_MMC_CCONFIG_2_DEFAULT \
  49        (ST_MMC_CCONFIG_HIGH_SPEED | ST_MMC_CCONFIG_ADMA2 | \
  50         ST_MMC_CCONFIG_8BIT | \
  51         (MAX_BLK_LEN_1024 << ST_MMC_CCONFIG_MAX_BLK_LEN))
  52
  53#define ST_MMC_CCONFIG_REG_3                    0x408
  54#define ST_MMC_CCONFIG_EMMC_SLOT_TYPE           BIT(28)
  55#define ST_MMC_CCONFIG_64BIT                    BIT(24)
  56#define ST_MMC_CCONFIG_ASYNCH_INTR_SUPPORT      BIT(20)
  57#define ST_MMC_CCONFIG_1P8_VOLT                 BIT(16)
  58#define ST_MMC_CCONFIG_3P0_VOLT                 BIT(12)
  59#define ST_MMC_CCONFIG_3P3_VOLT                 BIT(8)
  60#define ST_MMC_CCONFIG_SUSP_RES_SUPPORT         BIT(4)
  61#define ST_MMC_CCONFIG_SDMA                     BIT(0)
  62#define ST_MMC_CCONFIG_3_DEFAULT        \
  63                         (ST_MMC_CCONFIG_ASYNCH_INTR_SUPPORT    | \
  64                          ST_MMC_CCONFIG_3P3_VOLT               | \
  65                          ST_MMC_CCONFIG_SUSP_RES_SUPPORT       | \
  66                          ST_MMC_CCONFIG_SDMA)
  67
  68#define ST_MMC_CCONFIG_REG_4    0x40c
  69#define ST_MMC_CCONFIG_D_DRIVER BIT(20)
  70#define ST_MMC_CCONFIG_C_DRIVER BIT(16)
  71#define ST_MMC_CCONFIG_A_DRIVER BIT(12)
  72#define ST_MMC_CCONFIG_DDR50    BIT(8)
  73#define ST_MMC_CCONFIG_SDR104   BIT(4)
  74#define ST_MMC_CCONFIG_SDR50    BIT(0)
  75#define ST_MMC_CCONFIG_4_DEFAULT        0
  76
  77#define ST_MMC_CCONFIG_REG_5            0x410
  78#define ST_MMC_CCONFIG_TUNING_FOR_SDR50 BIT(8)
  79#define RETUNING_TIMER_CNT_MAX          0xf
  80#define ST_MMC_CCONFIG_5_DEFAULT        0
  81
  82/* I/O configuration for Arasan IP */
  83#define ST_MMC_GP_OUTPUT        0x450
  84#define ST_MMC_GP_OUTPUT_CD     BIT(12)
  85
  86#define ST_MMC_STATUS_R         0x460
  87
  88#define ST_TOP_MMC_DLY_FIX_OFF(x)       (x - 0x8)
  89
  90/* TOP config registers to manage static and dynamic delay */
  91#define ST_TOP_MMC_TX_CLK_DLY                   ST_TOP_MMC_DLY_FIX_OFF(0x8)
  92#define ST_TOP_MMC_RX_CLK_DLY                   ST_TOP_MMC_DLY_FIX_OFF(0xc)
  93/* MMC delay control register */
  94#define ST_TOP_MMC_DLY_CTRL                     ST_TOP_MMC_DLY_FIX_OFF(0x18)
  95#define ST_TOP_MMC_DLY_CTRL_DLL_BYPASS_CMD      BIT(0)
  96#define ST_TOP_MMC_DLY_CTRL_DLL_BYPASS_PH_SEL   BIT(1)
  97#define ST_TOP_MMC_DLY_CTRL_TX_DLL_ENABLE       BIT(8)
  98#define ST_TOP_MMC_DLY_CTRL_RX_DLL_ENABLE       BIT(9)
  99#define ST_TOP_MMC_DLY_CTRL_ATUNE_NOT_CFG_DLY   BIT(10)
 100#define ST_TOP_MMC_START_DLL_LOCK               BIT(11)
 101
 102/* register to provide the phase-shift value for DLL */
 103#define ST_TOP_MMC_TX_DLL_STEP_DLY              ST_TOP_MMC_DLY_FIX_OFF(0x1c)
 104#define ST_TOP_MMC_RX_DLL_STEP_DLY              ST_TOP_MMC_DLY_FIX_OFF(0x20)
 105#define ST_TOP_MMC_RX_CMD_STEP_DLY              ST_TOP_MMC_DLY_FIX_OFF(0x24)
 106
 107/* phase shift delay on the tx clk 2.188ns */
 108#define ST_TOP_MMC_TX_DLL_STEP_DLY_VALID        0x6
 109
 110#define ST_TOP_MMC_DLY_MAX                      0xf
 111
 112#define ST_TOP_MMC_DYN_DLY_CONF \
 113                (ST_TOP_MMC_DLY_CTRL_TX_DLL_ENABLE | \
 114                 ST_TOP_MMC_DLY_CTRL_ATUNE_NOT_CFG_DLY | \
 115                 ST_TOP_MMC_START_DLL_LOCK)
 116
 117/*
 118 * For clock speeds greater than 90MHz, we need to check that the
 119 * DLL procedure has finished before switching to ultra-speed modes.
 120 */
 121#define CLK_TO_CHECK_DLL_LOCK   90000000
 122
 123static inline void st_mmcss_set_static_delay(void __iomem *ioaddr)
 124{
 125        if (!ioaddr)
 126                return;
 127
 128        writel_relaxed(0x0, ioaddr + ST_TOP_MMC_DLY_CTRL);
 129        writel_relaxed(ST_TOP_MMC_DLY_MAX,
 130                        ioaddr + ST_TOP_MMC_TX_CLK_DLY);
 131}
 132
 133/**
 134 * st_mmcss_cconfig: configure the Arasan HC inside the flashSS.
 135 * @np: dt device node.
 136 * @host: sdhci host
 137 * Description: this function is to configure the Arasan host controller.
 138 * On some ST SoCs, i.e. STiH407 family, the MMC devices inside a dedicated
 139 * flashSS sub-system which needs to be configured to be compliant to eMMC 4.5
 140 * or eMMC4.3.  This has to be done before registering the sdhci host.
 141 */
 142static void st_mmcss_cconfig(struct device_node *np, struct sdhci_host *host)
 143{
 144        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 145        struct mmc_host *mhost = host->mmc;
 146        u32 cconf2, cconf3, cconf4, cconf5;
 147
 148        if (!of_device_is_compatible(np, "st,sdhci-stih407"))
 149                return;
 150
 151        cconf2 = ST_MMC_CCONFIG_2_DEFAULT;
 152        cconf3 = ST_MMC_CCONFIG_3_DEFAULT;
 153        cconf4 = ST_MMC_CCONFIG_4_DEFAULT;
 154        cconf5 = ST_MMC_CCONFIG_5_DEFAULT;
 155
 156        writel_relaxed(ST_MMC_CCONFIG_1_DEFAULT,
 157                        host->ioaddr + ST_MMC_CCONFIG_REG_1);
 158
 159        /* Set clock frequency, default to 50MHz if max-frequency is not
 160         * provided */
 161
 162        switch (mhost->f_max) {
 163        case 200000000:
 164                clk_set_rate(pltfm_host->clk, mhost->f_max);
 165                cconf2 |= BASE_CLK_FREQ_200;
 166                break;
 167        case 100000000:
 168                clk_set_rate(pltfm_host->clk, mhost->f_max);
 169                cconf2 |= BASE_CLK_FREQ_100;
 170                break;
 171        default:
 172                clk_set_rate(pltfm_host->clk, 50000000);
 173                cconf2 |= BASE_CLK_FREQ_50;
 174        }
 175
 176        writel_relaxed(cconf2, host->ioaddr + ST_MMC_CCONFIG_REG_2);
 177
 178        if (!mmc_card_is_removable(mhost))
 179                cconf3 |= ST_MMC_CCONFIG_EMMC_SLOT_TYPE;
 180        else
 181                /* CARD _D ET_CTRL */
 182                writel_relaxed(ST_MMC_GP_OUTPUT_CD,
 183                                host->ioaddr + ST_MMC_GP_OUTPUT);
 184
 185        if (mhost->caps & MMC_CAP_UHS_SDR50) {
 186                /* use 1.8V */
 187                cconf3 |= ST_MMC_CCONFIG_1P8_VOLT;
 188                cconf4 |= ST_MMC_CCONFIG_SDR50;
 189                /* Use tuning */
 190                cconf5 |= ST_MMC_CCONFIG_TUNING_FOR_SDR50;
 191                /* Max timeout for retuning */
 192                cconf5 |= RETUNING_TIMER_CNT_MAX;
 193        }
 194
 195        if (mhost->caps & MMC_CAP_UHS_SDR104) {
 196                /*
 197                 * SDR104 implies the HC can support HS200 mode, so
 198                 * it's mandatory to use 1.8V
 199                 */
 200                cconf3 |= ST_MMC_CCONFIG_1P8_VOLT;
 201                cconf4 |= ST_MMC_CCONFIG_SDR104;
 202                /* Max timeout for retuning */
 203                cconf5 |= RETUNING_TIMER_CNT_MAX;
 204        }
 205
 206        if (mhost->caps & MMC_CAP_UHS_DDR50)
 207                cconf4 |= ST_MMC_CCONFIG_DDR50;
 208
 209        writel_relaxed(cconf3, host->ioaddr + ST_MMC_CCONFIG_REG_3);
 210        writel_relaxed(cconf4, host->ioaddr + ST_MMC_CCONFIG_REG_4);
 211        writel_relaxed(cconf5, host->ioaddr + ST_MMC_CCONFIG_REG_5);
 212}
 213
 214static inline void st_mmcss_set_dll(void __iomem *ioaddr)
 215{
 216        if (!ioaddr)
 217                return;
 218
 219        writel_relaxed(ST_TOP_MMC_DYN_DLY_CONF, ioaddr + ST_TOP_MMC_DLY_CTRL);
 220        writel_relaxed(ST_TOP_MMC_TX_DLL_STEP_DLY_VALID,
 221                        ioaddr + ST_TOP_MMC_TX_DLL_STEP_DLY);
 222}
 223
 224static int st_mmcss_lock_dll(void __iomem *ioaddr)
 225{
 226        unsigned long curr, value;
 227        unsigned long finish = jiffies + HZ;
 228
 229        /* Checks if the DLL procedure is finished */
 230        do {
 231                curr = jiffies;
 232                value = readl(ioaddr + ST_MMC_STATUS_R);
 233                if (value & 0x1)
 234                        return 0;
 235
 236                cpu_relax();
 237        } while (!time_after_eq(curr, finish));
 238
 239        return -EBUSY;
 240}
 241
 242static int sdhci_st_set_dll_for_clock(struct sdhci_host *host)
 243{
 244        int ret = 0;
 245        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 246        struct st_mmc_platform_data *pdata = sdhci_pltfm_priv(pltfm_host);
 247
 248        if (host->clock > CLK_TO_CHECK_DLL_LOCK) {
 249                st_mmcss_set_dll(pdata->top_ioaddr);
 250                ret = st_mmcss_lock_dll(host->ioaddr);
 251        }
 252
 253        return ret;
 254}
 255
 256static void sdhci_st_set_uhs_signaling(struct sdhci_host *host,
 257                                        unsigned int uhs)
 258{
 259        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 260        struct st_mmc_platform_data *pdata = sdhci_pltfm_priv(pltfm_host);
 261        u16 ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
 262        int ret = 0;
 263
 264        /* Select Bus Speed Mode for host */
 265        ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
 266        switch (uhs) {
 267        /*
 268         * Set V18_EN -- UHS modes do not work without this.
 269         * does not change signaling voltage
 270         */
 271
 272        case MMC_TIMING_UHS_SDR12:
 273                st_mmcss_set_static_delay(pdata->top_ioaddr);
 274                ctrl_2 |= SDHCI_CTRL_UHS_SDR12 | SDHCI_CTRL_VDD_180;
 275                break;
 276        case MMC_TIMING_UHS_SDR25:
 277                st_mmcss_set_static_delay(pdata->top_ioaddr);
 278                ctrl_2 |= SDHCI_CTRL_UHS_SDR25 | SDHCI_CTRL_VDD_180;
 279                break;
 280        case MMC_TIMING_UHS_SDR50:
 281                st_mmcss_set_static_delay(pdata->top_ioaddr);
 282                ctrl_2 |= SDHCI_CTRL_UHS_SDR50 | SDHCI_CTRL_VDD_180;
 283                ret = sdhci_st_set_dll_for_clock(host);
 284                break;
 285        case MMC_TIMING_UHS_SDR104:
 286        case MMC_TIMING_MMC_HS200:
 287                st_mmcss_set_static_delay(pdata->top_ioaddr);
 288                ctrl_2 |= SDHCI_CTRL_UHS_SDR104 | SDHCI_CTRL_VDD_180;
 289                ret =  sdhci_st_set_dll_for_clock(host);
 290                break;
 291        case MMC_TIMING_UHS_DDR50:
 292        case MMC_TIMING_MMC_DDR52:
 293                st_mmcss_set_static_delay(pdata->top_ioaddr);
 294                ctrl_2 |= SDHCI_CTRL_UHS_DDR50 | SDHCI_CTRL_VDD_180;
 295                break;
 296        }
 297
 298        if (ret)
 299                dev_warn(mmc_dev(host->mmc), "Error setting dll for clock "
 300                                                "(uhs %d)\n", uhs);
 301
 302        dev_dbg(mmc_dev(host->mmc), "uhs %d, ctrl_2 %04X\n", uhs, ctrl_2);
 303
 304        sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
 305}
 306
 307static u32 sdhci_st_readl(struct sdhci_host *host, int reg)
 308{
 309        u32 ret;
 310
 311        switch (reg) {
 312        case SDHCI_CAPABILITIES:
 313                ret = readl_relaxed(host->ioaddr + reg);
 314                /* Support 3.3V and 1.8V */
 315                ret &= ~SDHCI_CAN_VDD_300;
 316                break;
 317        default:
 318                ret = readl_relaxed(host->ioaddr + reg);
 319        }
 320        return ret;
 321}
 322
 323static const struct sdhci_ops sdhci_st_ops = {
 324        .get_max_clock = sdhci_pltfm_clk_get_max_clock,
 325        .set_clock = sdhci_set_clock,
 326        .set_bus_width = sdhci_set_bus_width,
 327        .read_l = sdhci_st_readl,
 328        .reset = sdhci_reset,
 329        .set_uhs_signaling = sdhci_st_set_uhs_signaling,
 330};
 331
 332static const struct sdhci_pltfm_data sdhci_st_pdata = {
 333        .ops = &sdhci_st_ops,
 334        .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC |
 335                SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
 336                SDHCI_QUIRK_NO_HISPD_BIT,
 337        .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
 338                SDHCI_QUIRK2_STOP_WITH_TC,
 339};
 340
 341
 342static int sdhci_st_probe(struct platform_device *pdev)
 343{
 344        struct device_node *np = pdev->dev.of_node;
 345        struct sdhci_host *host;
 346        struct st_mmc_platform_data *pdata;
 347        struct sdhci_pltfm_host *pltfm_host;
 348        struct clk *clk, *icnclk;
 349        int ret = 0;
 350        u16 host_version;
 351        struct resource *res;
 352        struct reset_control *rstc;
 353
 354        clk =  devm_clk_get(&pdev->dev, "mmc");
 355        if (IS_ERR(clk)) {
 356                dev_err(&pdev->dev, "Peripheral clk not found\n");
 357                return PTR_ERR(clk);
 358        }
 359
 360        /* ICN clock isn't compulsory, but use it if it's provided. */
 361        icnclk = devm_clk_get(&pdev->dev, "icn");
 362        if (IS_ERR(icnclk))
 363                icnclk = NULL;
 364
 365        rstc = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
 366        if (IS_ERR(rstc))
 367                return PTR_ERR(rstc);
 368        reset_control_deassert(rstc);
 369
 370        host = sdhci_pltfm_init(pdev, &sdhci_st_pdata, sizeof(*pdata));
 371        if (IS_ERR(host)) {
 372                dev_err(&pdev->dev, "Failed sdhci_pltfm_init\n");
 373                ret = PTR_ERR(host);
 374                goto err_pltfm_init;
 375        }
 376
 377        pltfm_host = sdhci_priv(host);
 378        pdata = sdhci_pltfm_priv(pltfm_host);
 379        pdata->rstc = rstc;
 380
 381        ret = mmc_of_parse(host->mmc);
 382        if (ret) {
 383                dev_err(&pdev->dev, "Failed mmc_of_parse\n");
 384                goto err_of;
 385        }
 386
 387        ret = clk_prepare_enable(clk);
 388        if (ret) {
 389                dev_err(&pdev->dev, "Failed to prepare clock\n");
 390                goto err_of;
 391        }
 392
 393        ret = clk_prepare_enable(icnclk);
 394        if (ret) {
 395                dev_err(&pdev->dev, "Failed to prepare icn clock\n");
 396                goto err_icnclk;
 397        }
 398
 399        /* Configure the FlashSS Top registers for setting eMMC TX/RX delay */
 400        res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 401                                           "top-mmc-delay");
 402        pdata->top_ioaddr = devm_ioremap_resource(&pdev->dev, res);
 403        if (IS_ERR(pdata->top_ioaddr))
 404                pdata->top_ioaddr = NULL;
 405
 406        pltfm_host->clk = clk;
 407        pdata->icnclk = icnclk;
 408
 409        /* Configure the Arasan HC inside the flashSS */
 410        st_mmcss_cconfig(np, host);
 411
 412        ret = sdhci_add_host(host);
 413        if (ret)
 414                goto err_out;
 415
 416        host_version = readw_relaxed((host->ioaddr + SDHCI_HOST_VERSION));
 417
 418        dev_info(&pdev->dev, "SDHCI ST Initialised: Host Version: 0x%x Vendor Version 0x%x\n",
 419                ((host_version & SDHCI_SPEC_VER_MASK) >> SDHCI_SPEC_VER_SHIFT),
 420                ((host_version & SDHCI_VENDOR_VER_MASK) >>
 421                SDHCI_VENDOR_VER_SHIFT));
 422
 423        return 0;
 424
 425err_out:
 426        clk_disable_unprepare(icnclk);
 427err_icnclk:
 428        clk_disable_unprepare(clk);
 429err_of:
 430        sdhci_pltfm_free(pdev);
 431err_pltfm_init:
 432        reset_control_assert(rstc);
 433
 434        return ret;
 435}
 436
 437static int sdhci_st_remove(struct platform_device *pdev)
 438{
 439        struct sdhci_host *host = platform_get_drvdata(pdev);
 440        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 441        struct st_mmc_platform_data *pdata = sdhci_pltfm_priv(pltfm_host);
 442        struct reset_control *rstc = pdata->rstc;
 443        int ret;
 444
 445        ret = sdhci_pltfm_unregister(pdev);
 446
 447        clk_disable_unprepare(pdata->icnclk);
 448
 449        reset_control_assert(rstc);
 450
 451        return ret;
 452}
 453
 454#ifdef CONFIG_PM_SLEEP
 455static int sdhci_st_suspend(struct device *dev)
 456{
 457        struct sdhci_host *host = dev_get_drvdata(dev);
 458        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 459        struct st_mmc_platform_data *pdata = sdhci_pltfm_priv(pltfm_host);
 460        int ret;
 461
 462        if (host->tuning_mode != SDHCI_TUNING_MODE_3)
 463                mmc_retune_needed(host->mmc);
 464
 465        ret = sdhci_suspend_host(host);
 466        if (ret)
 467                goto out;
 468
 469        reset_control_assert(pdata->rstc);
 470
 471        clk_disable_unprepare(pdata->icnclk);
 472        clk_disable_unprepare(pltfm_host->clk);
 473out:
 474        return ret;
 475}
 476
 477static int sdhci_st_resume(struct device *dev)
 478{
 479        struct sdhci_host *host = dev_get_drvdata(dev);
 480        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 481        struct st_mmc_platform_data *pdata = sdhci_pltfm_priv(pltfm_host);
 482        struct device_node *np = dev->of_node;
 483        int ret;
 484
 485        ret = clk_prepare_enable(pltfm_host->clk);
 486        if (ret)
 487                return ret;
 488
 489        ret = clk_prepare_enable(pdata->icnclk);
 490        if (ret) {
 491                clk_disable_unprepare(pltfm_host->clk);
 492                return ret;
 493        }
 494
 495        reset_control_deassert(pdata->rstc);
 496
 497        st_mmcss_cconfig(np, host);
 498
 499        return sdhci_resume_host(host);
 500}
 501#endif
 502
 503static SIMPLE_DEV_PM_OPS(sdhci_st_pmops, sdhci_st_suspend, sdhci_st_resume);
 504
 505static const struct of_device_id st_sdhci_match[] = {
 506        { .compatible = "st,sdhci" },
 507        {},
 508};
 509
 510MODULE_DEVICE_TABLE(of, st_sdhci_match);
 511
 512static struct platform_driver sdhci_st_driver = {
 513        .probe = sdhci_st_probe,
 514        .remove = sdhci_st_remove,
 515        .driver = {
 516                   .name = "sdhci-st",
 517                   .probe_type = PROBE_PREFER_ASYNCHRONOUS,
 518                   .pm = &sdhci_st_pmops,
 519                   .of_match_table = st_sdhci_match,
 520                  },
 521};
 522
 523module_platform_driver(sdhci_st_driver);
 524
 525MODULE_DESCRIPTION("SDHCI driver for STMicroelectronics SoCs");
 526MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
 527MODULE_LICENSE("GPL v2");
 528MODULE_ALIAS("platform:sdhci-st");
 529