14cdc2ec1Saddy ke /* 24cdc2ec1Saddy ke * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd 34cdc2ec1Saddy ke * 44cdc2ec1Saddy ke * This program is free software; you can redistribute it and/or modify 54cdc2ec1Saddy ke * it under the terms of the GNU General Public License as published by 64cdc2ec1Saddy ke * the Free Software Foundation; either version 2 of the License, or 74cdc2ec1Saddy ke * (at your option) any later version. 84cdc2ec1Saddy ke */ 94cdc2ec1Saddy ke 104cdc2ec1Saddy ke #include <linux/module.h> 114cdc2ec1Saddy ke #include <linux/platform_device.h> 124cdc2ec1Saddy ke #include <linux/clk.h> 134cdc2ec1Saddy ke #include <linux/mmc/host.h> 144cdc2ec1Saddy ke #include <linux/of_address.h> 151f5c51d7SShawn Lin #include <linux/mmc/slot-gpio.h> 16f9014268SShawn Lin #include <linux/pm_runtime.h> 17cbb79e43SAlexandru M Stan #include <linux/slab.h> 184cdc2ec1Saddy ke 194cdc2ec1Saddy ke #include "dw_mmc.h" 204cdc2ec1Saddy ke #include "dw_mmc-pltfm.h" 214cdc2ec1Saddy ke 224cdc2ec1Saddy ke #define RK3288_CLKGEN_DIV 2 234cdc2ec1Saddy ke 24cbb79e43SAlexandru M Stan struct dw_mci_rockchip_priv_data { 25cbb79e43SAlexandru M Stan struct clk *drv_clk; 26cbb79e43SAlexandru M Stan struct clk *sample_clk; 27cbb79e43SAlexandru M Stan int default_sample_phase; 281a12a70fSShawn Lin int num_phases; 29cbb79e43SAlexandru M Stan }; 30cbb79e43SAlexandru M Stan 314cdc2ec1Saddy ke static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios) 324cdc2ec1Saddy ke { 33cbb79e43SAlexandru M Stan struct dw_mci_rockchip_priv_data *priv = host->priv; 344cdc2ec1Saddy ke int ret; 354cdc2ec1Saddy ke unsigned int cclkin; 364cdc2ec1Saddy ke u32 bus_hz; 374cdc2ec1Saddy ke 38e7791079SDoug Anderson if (ios->clock == 0) 39e7791079SDoug Anderson return; 40e7791079SDoug Anderson 414cdc2ec1Saddy ke /* 424cdc2ec1Saddy ke * cclkin: source clock of mmc controller 434cdc2ec1Saddy ke * bus_hz: card interface clock generated by CLKGEN 444cdc2ec1Saddy ke * bus_hz = cclkin / RK3288_CLKGEN_DIV 454cdc2ec1Saddy ke * ios->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div)) 464cdc2ec1Saddy ke * 474cdc2ec1Saddy ke * Note: div can only be 0 or 1 484cdc2ec1Saddy ke * if DDR50 8bit mode(only emmc work in 8bit mode), 494cdc2ec1Saddy ke * div must be set 1 504cdc2ec1Saddy ke */ 514cdc2ec1Saddy ke if (ios->bus_width == MMC_BUS_WIDTH_8 && 524cdc2ec1Saddy ke ios->timing == MMC_TIMING_MMC_DDR52) 534cdc2ec1Saddy ke cclkin = 2 * ios->clock * RK3288_CLKGEN_DIV; 544cdc2ec1Saddy ke else 554cdc2ec1Saddy ke cclkin = ios->clock * RK3288_CLKGEN_DIV; 564cdc2ec1Saddy ke 574cdc2ec1Saddy ke ret = clk_set_rate(host->ciu_clk, cclkin); 584cdc2ec1Saddy ke if (ret) 594cdc2ec1Saddy ke dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock); 604cdc2ec1Saddy ke 614cdc2ec1Saddy ke bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV; 624cdc2ec1Saddy ke if (bus_hz != host->bus_hz) { 634cdc2ec1Saddy ke host->bus_hz = bus_hz; 644cdc2ec1Saddy ke /* force dw_mci_setup_bus() */ 654cdc2ec1Saddy ke host->current_speed = 0; 664cdc2ec1Saddy ke } 67cbb79e43SAlexandru M Stan 68cbb79e43SAlexandru M Stan /* Make sure we use phases which we can enumerate with */ 69cbb79e43SAlexandru M Stan if (!IS_ERR(priv->sample_clk)) 70cbb79e43SAlexandru M Stan clk_set_phase(priv->sample_clk, priv->default_sample_phase); 71d4aa908cSDouglas Anderson 72d4aa908cSDouglas Anderson /* 73d4aa908cSDouglas Anderson * Set the drive phase offset based on speed mode to achieve hold times. 74d4aa908cSDouglas Anderson * 75d4aa908cSDouglas Anderson * NOTE: this is _not_ a value that is dynamically tuned and is also 76d4aa908cSDouglas Anderson * _not_ a value that will vary from board to board. It is a value 77d4aa908cSDouglas Anderson * that could vary between different SoC models if they had massively 78d4aa908cSDouglas Anderson * different output clock delays inside their dw_mmc IP block (delay_o), 79d4aa908cSDouglas Anderson * but since it's OK to overshoot a little we don't need to do complex 80d4aa908cSDouglas Anderson * calculations and can pick values that will just work for everyone. 81d4aa908cSDouglas Anderson * 82d4aa908cSDouglas Anderson * When picking values we'll stick with picking 0/90/180/270 since 83d4aa908cSDouglas Anderson * those can be made very accurately on all known Rockchip SoCs. 84d4aa908cSDouglas Anderson * 85d4aa908cSDouglas Anderson * Note that these values match values from the DesignWare Databook 86d4aa908cSDouglas Anderson * tables for the most part except for SDR12 and "ID mode". For those 87d4aa908cSDouglas Anderson * two modes the databook calculations assume a clock in of 50MHz. As 88d4aa908cSDouglas Anderson * seen above, we always use a clock in rate that is exactly the 89d4aa908cSDouglas Anderson * card's input clock (times RK3288_CLKGEN_DIV, but that gets divided 90d4aa908cSDouglas Anderson * back out before the controller sees it). 91d4aa908cSDouglas Anderson * 92d4aa908cSDouglas Anderson * From measurement of a single device, it appears that delay_o is 93d4aa908cSDouglas Anderson * about .5 ns. Since we try to leave a bit of margin, it's expected 94d4aa908cSDouglas Anderson * that numbers here will be fine even with much larger delay_o 95d4aa908cSDouglas Anderson * (the 1.4 ns assumed by the DesignWare Databook would result in the 96d4aa908cSDouglas Anderson * same results, for instance). 97d4aa908cSDouglas Anderson */ 98d4aa908cSDouglas Anderson if (!IS_ERR(priv->drv_clk)) { 99d4aa908cSDouglas Anderson int phase; 100d4aa908cSDouglas Anderson 101d4aa908cSDouglas Anderson /* 102d4aa908cSDouglas Anderson * In almost all cases a 90 degree phase offset will provide 103d4aa908cSDouglas Anderson * sufficient hold times across all valid input clock rates 104d4aa908cSDouglas Anderson * assuming delay_o is not absurd for a given SoC. We'll use 105d4aa908cSDouglas Anderson * that as a default. 106d4aa908cSDouglas Anderson */ 107d4aa908cSDouglas Anderson phase = 90; 108d4aa908cSDouglas Anderson 109d4aa908cSDouglas Anderson switch (ios->timing) { 110d4aa908cSDouglas Anderson case MMC_TIMING_MMC_DDR52: 111d4aa908cSDouglas Anderson /* 112d4aa908cSDouglas Anderson * Since clock in rate with MMC_DDR52 is doubled when 113d4aa908cSDouglas Anderson * bus width is 8 we need to double the phase offset 114d4aa908cSDouglas Anderson * to get the same timings. 115d4aa908cSDouglas Anderson */ 116d4aa908cSDouglas Anderson if (ios->bus_width == MMC_BUS_WIDTH_8) 117d4aa908cSDouglas Anderson phase = 180; 118d4aa908cSDouglas Anderson break; 119d4aa908cSDouglas Anderson case MMC_TIMING_UHS_SDR104: 120d4aa908cSDouglas Anderson case MMC_TIMING_MMC_HS200: 121d4aa908cSDouglas Anderson /* 122d4aa908cSDouglas Anderson * In the case of 150 MHz clock (typical max for 123d4aa908cSDouglas Anderson * Rockchip SoCs), 90 degree offset will add a delay 124d4aa908cSDouglas Anderson * of 1.67 ns. That will meet min hold time of .8 ns 125d4aa908cSDouglas Anderson * as long as clock output delay is < .87 ns. On 126d4aa908cSDouglas Anderson * SoCs measured this seems to be OK, but it doesn't 127d4aa908cSDouglas Anderson * hurt to give margin here, so we use 180. 128d4aa908cSDouglas Anderson */ 129d4aa908cSDouglas Anderson phase = 180; 130d4aa908cSDouglas Anderson break; 131d4aa908cSDouglas Anderson } 132d4aa908cSDouglas Anderson 133d4aa908cSDouglas Anderson clk_set_phase(priv->drv_clk, phase); 134d4aa908cSDouglas Anderson } 135cbb79e43SAlexandru M Stan } 136cbb79e43SAlexandru M Stan 1371a12a70fSShawn Lin #define TUNING_ITERATION_TO_PHASE(i, num_phases) \ 1381a12a70fSShawn Lin (DIV_ROUND_UP((i) * 360, num_phases)) 139cbb79e43SAlexandru M Stan 1409979dbe5SChaotian Jing static int dw_mci_rk3288_execute_tuning(struct dw_mci_slot *slot, u32 opcode) 141cbb79e43SAlexandru M Stan { 142cbb79e43SAlexandru M Stan struct dw_mci *host = slot->host; 143cbb79e43SAlexandru M Stan struct dw_mci_rockchip_priv_data *priv = host->priv; 144cbb79e43SAlexandru M Stan struct mmc_host *mmc = slot->mmc; 145cbb79e43SAlexandru M Stan int ret = 0; 146cbb79e43SAlexandru M Stan int i; 147cbb79e43SAlexandru M Stan bool v, prev_v = 0, first_v; 148cbb79e43SAlexandru M Stan struct range_t { 149cbb79e43SAlexandru M Stan int start; 150cbb79e43SAlexandru M Stan int end; /* inclusive */ 151cbb79e43SAlexandru M Stan }; 152cbb79e43SAlexandru M Stan struct range_t *ranges; 153cbb79e43SAlexandru M Stan unsigned int range_count = 0; 154cbb79e43SAlexandru M Stan int longest_range_len = -1; 155cbb79e43SAlexandru M Stan int longest_range = -1; 156cbb79e43SAlexandru M Stan int middle_phase; 157cbb79e43SAlexandru M Stan 158cbb79e43SAlexandru M Stan if (IS_ERR(priv->sample_clk)) { 159cbb79e43SAlexandru M Stan dev_err(host->dev, "Tuning clock (sample_clk) not defined.\n"); 160cbb79e43SAlexandru M Stan return -EIO; 161cbb79e43SAlexandru M Stan } 162cbb79e43SAlexandru M Stan 1631a12a70fSShawn Lin ranges = kmalloc_array(priv->num_phases / 2 + 1, 1641a12a70fSShawn Lin sizeof(*ranges), GFP_KERNEL); 165cbb79e43SAlexandru M Stan if (!ranges) 166cbb79e43SAlexandru M Stan return -ENOMEM; 167cbb79e43SAlexandru M Stan 168cbb79e43SAlexandru M Stan /* Try each phase and extract good ranges */ 1691a12a70fSShawn Lin for (i = 0; i < priv->num_phases; ) { 1701a12a70fSShawn Lin clk_set_phase(priv->sample_clk, 1711a12a70fSShawn Lin TUNING_ITERATION_TO_PHASE(i, priv->num_phases)); 172cbb79e43SAlexandru M Stan 1739979dbe5SChaotian Jing v = !mmc_send_tuning(mmc, opcode, NULL); 174cbb79e43SAlexandru M Stan 175cbb79e43SAlexandru M Stan if (i == 0) 176cbb79e43SAlexandru M Stan first_v = v; 177cbb79e43SAlexandru M Stan 178cbb79e43SAlexandru M Stan if ((!prev_v) && v) { 179cbb79e43SAlexandru M Stan range_count++; 180cbb79e43SAlexandru M Stan ranges[range_count-1].start = i; 181cbb79e43SAlexandru M Stan } 182cbb79e43SAlexandru M Stan if (v) { 183cbb79e43SAlexandru M Stan ranges[range_count-1].end = i; 184cbb79e43SAlexandru M Stan i++; 1851a12a70fSShawn Lin } else if (i == priv->num_phases - 1) { 186cbb79e43SAlexandru M Stan /* No extra skipping rules if we're at the end */ 187cbb79e43SAlexandru M Stan i++; 188cbb79e43SAlexandru M Stan } else { 189cbb79e43SAlexandru M Stan /* 190cbb79e43SAlexandru M Stan * No need to check too close to an invalid 191cbb79e43SAlexandru M Stan * one since testing bad phases is slow. Skip 192cbb79e43SAlexandru M Stan * 20 degrees. 193cbb79e43SAlexandru M Stan */ 1941a12a70fSShawn Lin i += DIV_ROUND_UP(20 * priv->num_phases, 360); 195cbb79e43SAlexandru M Stan 196cbb79e43SAlexandru M Stan /* Always test the last one */ 1971a12a70fSShawn Lin if (i >= priv->num_phases) 1981a12a70fSShawn Lin i = priv->num_phases - 1; 199cbb79e43SAlexandru M Stan } 200cbb79e43SAlexandru M Stan 201cbb79e43SAlexandru M Stan prev_v = v; 202cbb79e43SAlexandru M Stan } 203cbb79e43SAlexandru M Stan 204cbb79e43SAlexandru M Stan if (range_count == 0) { 205cbb79e43SAlexandru M Stan dev_warn(host->dev, "All phases bad!"); 206cbb79e43SAlexandru M Stan ret = -EIO; 207cbb79e43SAlexandru M Stan goto free; 208cbb79e43SAlexandru M Stan } 209cbb79e43SAlexandru M Stan 210cbb79e43SAlexandru M Stan /* wrap around case, merge the end points */ 211cbb79e43SAlexandru M Stan if ((range_count > 1) && first_v && v) { 212cbb79e43SAlexandru M Stan ranges[0].start = ranges[range_count-1].start; 213cbb79e43SAlexandru M Stan range_count--; 214cbb79e43SAlexandru M Stan } 215cbb79e43SAlexandru M Stan 2161a12a70fSShawn Lin if (ranges[0].start == 0 && ranges[0].end == priv->num_phases - 1) { 217cbb79e43SAlexandru M Stan clk_set_phase(priv->sample_clk, priv->default_sample_phase); 218cbb79e43SAlexandru M Stan dev_info(host->dev, "All phases work, using default phase %d.", 219cbb79e43SAlexandru M Stan priv->default_sample_phase); 220cbb79e43SAlexandru M Stan goto free; 221cbb79e43SAlexandru M Stan } 222cbb79e43SAlexandru M Stan 223cbb79e43SAlexandru M Stan /* Find the longest range */ 224cbb79e43SAlexandru M Stan for (i = 0; i < range_count; i++) { 225cbb79e43SAlexandru M Stan int len = (ranges[i].end - ranges[i].start + 1); 226cbb79e43SAlexandru M Stan 227cbb79e43SAlexandru M Stan if (len < 0) 2281a12a70fSShawn Lin len += priv->num_phases; 229cbb79e43SAlexandru M Stan 230cbb79e43SAlexandru M Stan if (longest_range_len < len) { 231cbb79e43SAlexandru M Stan longest_range_len = len; 232cbb79e43SAlexandru M Stan longest_range = i; 233cbb79e43SAlexandru M Stan } 234cbb79e43SAlexandru M Stan 235cbb79e43SAlexandru M Stan dev_dbg(host->dev, "Good phase range %d-%d (%d len)\n", 2361a12a70fSShawn Lin TUNING_ITERATION_TO_PHASE(ranges[i].start, 2371a12a70fSShawn Lin priv->num_phases), 2381a12a70fSShawn Lin TUNING_ITERATION_TO_PHASE(ranges[i].end, 2391a12a70fSShawn Lin priv->num_phases), 240cbb79e43SAlexandru M Stan len 241cbb79e43SAlexandru M Stan ); 242cbb79e43SAlexandru M Stan } 243cbb79e43SAlexandru M Stan 244cbb79e43SAlexandru M Stan dev_dbg(host->dev, "Best phase range %d-%d (%d len)\n", 2451a12a70fSShawn Lin TUNING_ITERATION_TO_PHASE(ranges[longest_range].start, 2461a12a70fSShawn Lin priv->num_phases), 2471a12a70fSShawn Lin TUNING_ITERATION_TO_PHASE(ranges[longest_range].end, 2481a12a70fSShawn Lin priv->num_phases), 249cbb79e43SAlexandru M Stan longest_range_len 250cbb79e43SAlexandru M Stan ); 251cbb79e43SAlexandru M Stan 252cbb79e43SAlexandru M Stan middle_phase = ranges[longest_range].start + longest_range_len / 2; 2531a12a70fSShawn Lin middle_phase %= priv->num_phases; 254cbb79e43SAlexandru M Stan dev_info(host->dev, "Successfully tuned phase to %d\n", 2551a12a70fSShawn Lin TUNING_ITERATION_TO_PHASE(middle_phase, priv->num_phases)); 256cbb79e43SAlexandru M Stan 257cbb79e43SAlexandru M Stan clk_set_phase(priv->sample_clk, 2581a12a70fSShawn Lin TUNING_ITERATION_TO_PHASE(middle_phase, 2591a12a70fSShawn Lin priv->num_phases)); 260cbb79e43SAlexandru M Stan 261cbb79e43SAlexandru M Stan free: 262cbb79e43SAlexandru M Stan kfree(ranges); 263cbb79e43SAlexandru M Stan return ret; 264cbb79e43SAlexandru M Stan } 265cbb79e43SAlexandru M Stan 266cbb79e43SAlexandru M Stan static int dw_mci_rk3288_parse_dt(struct dw_mci *host) 267cbb79e43SAlexandru M Stan { 268cbb79e43SAlexandru M Stan struct device_node *np = host->dev->of_node; 269cbb79e43SAlexandru M Stan struct dw_mci_rockchip_priv_data *priv; 270cbb79e43SAlexandru M Stan 271cbb79e43SAlexandru M Stan priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL); 272cbb79e43SAlexandru M Stan if (!priv) 273cbb79e43SAlexandru M Stan return -ENOMEM; 274cbb79e43SAlexandru M Stan 2751a12a70fSShawn Lin if (of_property_read_u32(np, "rockchip,desired-num-phases", 2761a12a70fSShawn Lin &priv->num_phases)) 2771a12a70fSShawn Lin priv->num_phases = 360; 2781a12a70fSShawn Lin 279cbb79e43SAlexandru M Stan if (of_property_read_u32(np, "rockchip,default-sample-phase", 280cbb79e43SAlexandru M Stan &priv->default_sample_phase)) 281cbb79e43SAlexandru M Stan priv->default_sample_phase = 0; 282cbb79e43SAlexandru M Stan 283cbb79e43SAlexandru M Stan priv->drv_clk = devm_clk_get(host->dev, "ciu-drive"); 284cbb79e43SAlexandru M Stan if (IS_ERR(priv->drv_clk)) 285cbb79e43SAlexandru M Stan dev_dbg(host->dev, "ciu_drv not available\n"); 286cbb79e43SAlexandru M Stan 287cbb79e43SAlexandru M Stan priv->sample_clk = devm_clk_get(host->dev, "ciu-sample"); 288cbb79e43SAlexandru M Stan if (IS_ERR(priv->sample_clk)) 289cbb79e43SAlexandru M Stan dev_dbg(host->dev, "ciu_sample not available\n"); 290cbb79e43SAlexandru M Stan 291cbb79e43SAlexandru M Stan host->priv = priv; 292cbb79e43SAlexandru M Stan 293cbb79e43SAlexandru M Stan return 0; 2944cdc2ec1Saddy ke } 2954cdc2ec1Saddy ke 29676756234SAddy Ke static int dw_mci_rockchip_init(struct dw_mci *host) 29776756234SAddy Ke { 29876756234SAddy Ke /* It is slot 8 on Rockchip SoCs */ 29976756234SAddy Ke host->sdio_id0 = 8; 30076756234SAddy Ke 30119756760SShawn Lin if (of_device_is_compatible(host->dev->of_node, 30219756760SShawn Lin "rockchip,rk3288-dw-mshc")) 30319756760SShawn Lin host->bus_hz /= RK3288_CLKGEN_DIV; 30419756760SShawn Lin 30576756234SAddy Ke return 0; 30676756234SAddy Ke } 30776756234SAddy Ke 308c6a9bf99SShawn Lin /* Common capabilities of RK3288 SoC */ 309c6a9bf99SShawn Lin static unsigned long dw_mci_rk3288_dwmmc_caps[4] = { 3102c4c7146SJaehoon Chung MMC_CAP_CMD23, 3112c4c7146SJaehoon Chung MMC_CAP_CMD23, 3122c4c7146SJaehoon Chung MMC_CAP_CMD23, 3132c4c7146SJaehoon Chung MMC_CAP_CMD23, 314c6a9bf99SShawn Lin }; 315c6a9bf99SShawn Lin 3164cdc2ec1Saddy ke static const struct dw_mci_drv_data rk2928_drv_data = { 31776756234SAddy Ke .init = dw_mci_rockchip_init, 3184cdc2ec1Saddy ke }; 3194cdc2ec1Saddy ke 3204cdc2ec1Saddy ke static const struct dw_mci_drv_data rk3288_drv_data = { 321c6a9bf99SShawn Lin .caps = dw_mci_rk3288_dwmmc_caps, 3224cdc2ec1Saddy ke .set_ios = dw_mci_rk3288_set_ios, 323cbb79e43SAlexandru M Stan .execute_tuning = dw_mci_rk3288_execute_tuning, 324cbb79e43SAlexandru M Stan .parse_dt = dw_mci_rk3288_parse_dt, 32576756234SAddy Ke .init = dw_mci_rockchip_init, 3264cdc2ec1Saddy ke }; 3274cdc2ec1Saddy ke 3284cdc2ec1Saddy ke static const struct of_device_id dw_mci_rockchip_match[] = { 3294cdc2ec1Saddy ke { .compatible = "rockchip,rk2928-dw-mshc", 3304cdc2ec1Saddy ke .data = &rk2928_drv_data }, 3314cdc2ec1Saddy ke { .compatible = "rockchip,rk3288-dw-mshc", 3324cdc2ec1Saddy ke .data = &rk3288_drv_data }, 3334cdc2ec1Saddy ke {}, 3344cdc2ec1Saddy ke }; 3354cdc2ec1Saddy ke MODULE_DEVICE_TABLE(of, dw_mci_rockchip_match); 3364cdc2ec1Saddy ke 3374cdc2ec1Saddy ke static int dw_mci_rockchip_probe(struct platform_device *pdev) 3384cdc2ec1Saddy ke { 3394cdc2ec1Saddy ke const struct dw_mci_drv_data *drv_data; 3404cdc2ec1Saddy ke const struct of_device_id *match; 341f9014268SShawn Lin int ret; 3424cdc2ec1Saddy ke 3434cdc2ec1Saddy ke if (!pdev->dev.of_node) 3444cdc2ec1Saddy ke return -ENODEV; 3454cdc2ec1Saddy ke 3464cdc2ec1Saddy ke match = of_match_node(dw_mci_rockchip_match, pdev->dev.of_node); 3474cdc2ec1Saddy ke drv_data = match->data; 3484cdc2ec1Saddy ke 349f9014268SShawn Lin pm_runtime_get_noresume(&pdev->dev); 350f9014268SShawn Lin pm_runtime_set_active(&pdev->dev); 351f9014268SShawn Lin pm_runtime_enable(&pdev->dev); 352f9014268SShawn Lin pm_runtime_set_autosuspend_delay(&pdev->dev, 50); 353f9014268SShawn Lin pm_runtime_use_autosuspend(&pdev->dev); 354f9014268SShawn Lin 355f9014268SShawn Lin ret = dw_mci_pltfm_register(pdev, drv_data); 356f9014268SShawn Lin if (ret) { 357f9014268SShawn Lin pm_runtime_disable(&pdev->dev); 358f9014268SShawn Lin pm_runtime_set_suspended(&pdev->dev); 359f9014268SShawn Lin pm_runtime_put_noidle(&pdev->dev); 360f9014268SShawn Lin return ret; 3614cdc2ec1Saddy ke } 3624cdc2ec1Saddy ke 363f9014268SShawn Lin pm_runtime_put_autosuspend(&pdev->dev); 364f9014268SShawn Lin 365f9014268SShawn Lin return 0; 366f9014268SShawn Lin } 367f9014268SShawn Lin 368f9014268SShawn Lin static int dw_mci_rockchip_remove(struct platform_device *pdev) 369f9014268SShawn Lin { 370f9014268SShawn Lin pm_runtime_get_sync(&pdev->dev); 371f9014268SShawn Lin pm_runtime_disable(&pdev->dev); 372f9014268SShawn Lin pm_runtime_put_noidle(&pdev->dev); 373f9014268SShawn Lin 374f9014268SShawn Lin return dw_mci_pltfm_remove(pdev); 375f9014268SShawn Lin } 376f9014268SShawn Lin 377f9014268SShawn Lin static const struct dev_pm_ops dw_mci_rockchip_dev_pm_ops = { 378f9014268SShawn Lin SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 379f9014268SShawn Lin pm_runtime_force_resume) 380f9014268SShawn Lin SET_RUNTIME_PM_OPS(dw_mci_runtime_suspend, 381f9014268SShawn Lin dw_mci_runtime_resume, 382f9014268SShawn Lin NULL) 383f9014268SShawn Lin }; 384f9014268SShawn Lin 3854cdc2ec1Saddy ke static struct platform_driver dw_mci_rockchip_pltfm_driver = { 3864cdc2ec1Saddy ke .probe = dw_mci_rockchip_probe, 387f9014268SShawn Lin .remove = dw_mci_rockchip_remove, 3884cdc2ec1Saddy ke .driver = { 3894cdc2ec1Saddy ke .name = "dwmmc_rockchip", 3904cdc2ec1Saddy ke .of_match_table = dw_mci_rockchip_match, 391f9014268SShawn Lin .pm = &dw_mci_rockchip_dev_pm_ops, 3924cdc2ec1Saddy ke }, 3934cdc2ec1Saddy ke }; 3944cdc2ec1Saddy ke 3954cdc2ec1Saddy ke module_platform_driver(dw_mci_rockchip_pltfm_driver); 3964cdc2ec1Saddy ke 3974cdc2ec1Saddy ke MODULE_AUTHOR("Addy Ke <addy.ke@rock-chips.com>"); 3984cdc2ec1Saddy ke MODULE_DESCRIPTION("Rockchip Specific DW-MSHC Driver Extension"); 399a7ca2b16SZhangfei Gao MODULE_ALIAS("platform:dwmmc_rockchip"); 4004cdc2ec1Saddy ke MODULE_LICENSE("GPL v2"); 401