root/drivers/mmc/host/sdhci-st.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. st_mmcss_set_static_delay
  2. st_mmcss_cconfig
  3. st_mmcss_set_dll
  4. st_mmcss_lock_dll
  5. sdhci_st_set_dll_for_clock
  6. sdhci_st_set_uhs_signaling
  7. sdhci_st_readl
  8. sdhci_st_probe
  9. sdhci_st_remove
  10. sdhci_st_suspend
  11. sdhci_st_resume

   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 
  20 struct 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 
 123 static 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  */
 142 static 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 
 214 static 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 
 224 static 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 
 242 static 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 
 256 static 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 
 307 static 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 
 323 static 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 
 332 static 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 
 342 static 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 
 428 err_out:
 429         clk_disable_unprepare(icnclk);
 430 err_icnclk:
 431         clk_disable_unprepare(clk);
 432 err_of:
 433         sdhci_pltfm_free(pdev);
 434 err_pltfm_init:
 435         if (rstc)
 436                 reset_control_assert(rstc);
 437 
 438         return ret;
 439 }
 440 
 441 static 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
 460 static 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);
 479 out:
 480         return ret;
 481 }
 482 
 483 static 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 
 510 static SIMPLE_DEV_PM_OPS(sdhci_st_pmops, sdhci_st_suspend, sdhci_st_resume);
 511 
 512 static const struct of_device_id st_sdhci_match[] = {
 513         { .compatible = "st,sdhci" },
 514         {},
 515 };
 516 
 517 MODULE_DEVICE_TABLE(of, st_sdhci_match);
 518 
 519 static 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 
 529 module_platform_driver(sdhci_st_driver);
 530 
 531 MODULE_DESCRIPTION("SDHCI driver for STMicroelectronics SoCs");
 532 MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
 533 MODULE_LICENSE("GPL v2");
 534 MODULE_ALIAS("platform:sdhci-st");

/* [<][>][^][v][top][bottom][index][help] */