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_exclusive(&pdev->dev, NULL);
 366        if (IS_ERR(rstc))
 367                rstc = NULL;
 368        else
 369                reset_control_deassert(rstc);
 370
 371        host = sdhci_pltfm_init(pdev, &sdhci_st_pdata, sizeof(*pdata));
 372        if (IS_ERR(host)) {
 373                dev_err(&pdev->dev, "Failed sdhci_pltfm_init\n");
 374                ret = PTR_ERR(host);
 375                goto err_pltfm_init;
 376        }
 377
 378        pltfm_host = sdhci_priv(host);
 379        pdata = sdhci_pltfm_priv(pltfm_host);
 380        pdata->rstc = rstc;
 381
 382        ret = mmc_of_parse(host->mmc);
 383        if (ret) {
 384                dev_err(&pdev->dev, "Failed mmc_of_parse\n");
 385                goto err_of;
 386        }
 387
 388        ret = clk_prepare_enable(clk);
 389        if (ret) {
 390                dev_err(&pdev->dev, "Failed to prepare clock\n");
 391                goto err_of;
 392        }
 393
 394        ret = clk_prepare_enable(icnclk);
 395        if (ret) {
 396                dev_err(&pdev->dev, "Failed to prepare icn clock\n");
 397                goto err_icnclk;
 398        }
 399
 400        /* Configure the FlashSS Top registers for setting eMMC TX/RX delay */
 401        res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 402                                           "top-mmc-delay");
 403        pdata->top_ioaddr = devm_ioremap_resource(&pdev->dev, res);
 404        if (IS_ERR(pdata->top_ioaddr)) {
 405                dev_warn(&pdev->dev, "FlashSS Top Dly registers not available");
 406                pdata->top_ioaddr = NULL;
 407        }
 408
 409        pltfm_host->clk = clk;
 410        pdata->icnclk = icnclk;
 411
 412        /* Configure the Arasan HC inside the flashSS */
 413        st_mmcss_cconfig(np, host);
 414
 415        ret = sdhci_add_host(host);
 416        if (ret)
 417                goto err_out;
 418
 419        host_version = readw_relaxed((host->ioaddr + SDHCI_HOST_VERSION));
 420
 421        dev_info(&pdev->dev, "SDHCI ST Initialised: Host Version: 0x%x Vendor Version 0x%x\n",
 422                ((host_version & SDHCI_SPEC_VER_MASK) >> SDHCI_SPEC_VER_SHIFT),
 423                ((host_version & SDHCI_VENDOR_VER_MASK) >>
 424                SDHCI_VENDOR_VER_SHIFT));
 425
 426        return 0;
 427
 428err_out:
 429        clk_disable_unprepare(icnclk);
 430err_icnclk:
 431        clk_disable_unprepare(clk);
 432err_of:
 433        sdhci_pltfm_free(pdev);
 434err_pltfm_init:
 435        if (rstc)
 436                reset_control_assert(rstc);
 437
 438        return ret;
 439}
 440
 441static int sdhci_st_remove(struct platform_device *pdev)
 442{
 443        struct sdhci_host *host = platform_get_drvdata(pdev);
 444        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 445        struct st_mmc_platform_data *pdata = sdhci_pltfm_priv(pltfm_host);
 446        struct reset_control *rstc = pdata->rstc;
 447        int ret;
 448
 449        ret = sdhci_pltfm_unregister(pdev);
 450
 451        clk_disable_unprepare(pdata->icnclk);
 452
 453        if (rstc)
 454                reset_control_assert(rstc);
 455
 456        return ret;
 457}
 458
 459#ifdef CONFIG_PM_SLEEP
 460static int sdhci_st_suspend(struct device *dev)
 461{
 462        struct sdhci_host *host = dev_get_drvdata(dev);
 463        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 464        struct st_mmc_platform_data *pdata = sdhci_pltfm_priv(pltfm_host);
 465        int ret;
 466
 467        if (host->tuning_mode != SDHCI_TUNING_MODE_3)
 468                mmc_retune_needed(host->mmc);
 469
 470        ret = sdhci_suspend_host(host);
 471        if (ret)
 472                goto out;
 473
 474        if (pdata->rstc)
 475                reset_control_assert(pdata->rstc);
 476
 477        clk_disable_unprepare(pdata->icnclk);
 478        clk_disable_unprepare(pltfm_host->clk);
 479out:
 480        return ret;
 481}
 482
 483static int sdhci_st_resume(struct device *dev)
 484{
 485        struct sdhci_host *host = dev_get_drvdata(dev);
 486        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 487        struct st_mmc_platform_data *pdata = sdhci_pltfm_priv(pltfm_host);
 488        struct device_node *np = dev->of_node;
 489        int ret;
 490
 491        ret = clk_prepare_enable(pltfm_host->clk);
 492        if (ret)
 493                return ret;
 494
 495        ret = clk_prepare_enable(pdata->icnclk);
 496        if (ret) {
 497                clk_disable_unprepare(pltfm_host->clk);
 498                return ret;
 499        }
 500
 501        if (pdata->rstc)
 502                reset_control_deassert(pdata->rstc);
 503
 504        st_mmcss_cconfig(np, host);
 505
 506        return sdhci_resume_host(host);
 507}
 508#endif
 509
 510static SIMPLE_DEV_PM_OPS(sdhci_st_pmops, sdhci_st_suspend, sdhci_st_resume);
 511
 512static const struct of_device_id st_sdhci_match[] = {
 513        { .compatible = "st,sdhci" },
 514        {},
 515};
 516
 517MODULE_DEVICE_TABLE(of, st_sdhci_match);
 518
 519static struct platform_driver sdhci_st_driver = {
 520        .probe = sdhci_st_probe,
 521        .remove = sdhci_st_remove,
 522        .driver = {
 523                   .name = "sdhci-st",
 524                   .pm = &sdhci_st_pmops,
 525                   .of_match_table = of_match_ptr(st_sdhci_match),
 526                  },
 527};
 528
 529module_platform_driver(sdhci_st_driver);
 530
 531MODULE_DESCRIPTION("SDHCI driver for STMicroelectronics SoCs");
 532MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
 533MODULE_LICENSE("GPL v2");
 534MODULE_ALIAS("platform:sdhci-st");
 535