1/* linux/drivers/mmc/host/sdhci-s3c.c 2 * 3 * Copyright 2008 Openmoko Inc. 4 * Copyright 2008 Simtec Electronics 5 * Ben Dooks <ben@simtec.co.uk> 6 * http://armlinux.simtec.co.uk/ 7 * 8 * SDHCI (HSMMC) support for Samsung SoC 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 */ 14 15#include <linux/spinlock.h> 16#include <linux/delay.h> 17#include <linux/dma-mapping.h> 18#include <linux/platform_device.h> 19#include <linux/platform_data/mmc-sdhci-s3c.h> 20#include <linux/slab.h> 21#include <linux/clk.h> 22#include <linux/io.h> 23#include <linux/gpio.h> 24#include <linux/module.h> 25#include <linux/of.h> 26#include <linux/of_gpio.h> 27#include <linux/pm.h> 28#include <linux/pm_runtime.h> 29 30#include <linux/mmc/host.h> 31 32#include "sdhci-s3c-regs.h" 33#include "sdhci.h" 34 35#define MAX_BUS_CLK (4) 36 37/** 38 * struct sdhci_s3c - S3C SDHCI instance 39 * @host: The SDHCI host created 40 * @pdev: The platform device we where created from. 41 * @ioarea: The resource created when we claimed the IO area. 42 * @pdata: The platform data for this controller. 43 * @cur_clk: The index of the current bus clock. 44 * @clk_io: The clock for the internal bus interface. 45 * @clk_bus: The clocks that are available for the SD/MMC bus clock. 46 */ 47struct sdhci_s3c { 48 struct sdhci_host *host; 49 struct platform_device *pdev; 50 struct resource *ioarea; 51 struct s3c_sdhci_platdata *pdata; 52 int cur_clk; 53 int ext_cd_irq; 54 int ext_cd_gpio; 55 56 struct clk *clk_io; 57 struct clk *clk_bus[MAX_BUS_CLK]; 58 unsigned long clk_rates[MAX_BUS_CLK]; 59 60 bool no_divider; 61}; 62 63/** 64 * struct sdhci_s3c_driver_data - S3C SDHCI platform specific driver data 65 * @sdhci_quirks: sdhci host specific quirks. 66 * 67 * Specifies platform specific configuration of sdhci controller. 68 * Note: A structure for driver specific platform data is used for future 69 * expansion of its usage. 70 */ 71struct sdhci_s3c_drv_data { 72 unsigned int sdhci_quirks; 73 bool no_divider; 74}; 75 76static inline struct sdhci_s3c *to_s3c(struct sdhci_host *host) 77{ 78 return sdhci_priv(host); 79} 80 81/** 82 * sdhci_s3c_get_max_clk - callback to get maximum clock frequency. 83 * @host: The SDHCI host instance. 84 * 85 * Callback to return the maximum clock rate acheivable by the controller. 86*/ 87static unsigned int sdhci_s3c_get_max_clk(struct sdhci_host *host) 88{ 89 struct sdhci_s3c *ourhost = to_s3c(host); 90 unsigned long rate, max = 0; 91 int src; 92 93 for (src = 0; src < MAX_BUS_CLK; src++) { 94 rate = ourhost->clk_rates[src]; 95 if (rate > max) 96 max = rate; 97 } 98 99 return max; 100} 101 102/** 103 * sdhci_s3c_consider_clock - consider one the bus clocks for current setting 104 * @ourhost: Our SDHCI instance. 105 * @src: The source clock index. 106 * @wanted: The clock frequency wanted. 107 */ 108static unsigned int sdhci_s3c_consider_clock(struct sdhci_s3c *ourhost, 109 unsigned int src, 110 unsigned int wanted) 111{ 112 unsigned long rate; 113 struct clk *clksrc = ourhost->clk_bus[src]; 114 int shift; 115 116 if (IS_ERR(clksrc)) 117 return UINT_MAX; 118 119 /* 120 * If controller uses a non-standard clock division, find the best clock 121 * speed possible with selected clock source and skip the division. 122 */ 123 if (ourhost->no_divider) { 124 rate = clk_round_rate(clksrc, wanted); 125 return wanted - rate; 126 } 127 128 rate = ourhost->clk_rates[src]; 129 130 for (shift = 0; shift <= 8; ++shift) { 131 if ((rate >> shift) <= wanted) 132 break; 133 } 134 135 if (shift > 8) { 136 dev_dbg(&ourhost->pdev->dev, 137 "clk %d: rate %ld, min rate %lu > wanted %u\n", 138 src, rate, rate / 256, wanted); 139 return UINT_MAX; 140 } 141 142 dev_dbg(&ourhost->pdev->dev, "clk %d: rate %ld, want %d, got %ld\n", 143 src, rate, wanted, rate >> shift); 144 145 return wanted - (rate >> shift); 146} 147 148/** 149 * sdhci_s3c_set_clock - callback on clock change 150 * @host: The SDHCI host being changed 151 * @clock: The clock rate being requested. 152 * 153 * When the card's clock is going to be changed, look at the new frequency 154 * and find the best clock source to go with it. 155*/ 156static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock) 157{ 158 struct sdhci_s3c *ourhost = to_s3c(host); 159 unsigned int best = UINT_MAX; 160 unsigned int delta; 161 int best_src = 0; 162 int src; 163 u32 ctrl; 164 165 host->mmc->actual_clock = 0; 166 167 /* don't bother if the clock is going off. */ 168 if (clock == 0) { 169 sdhci_set_clock(host, clock); 170 return; 171 } 172 173 for (src = 0; src < MAX_BUS_CLK; src++) { 174 delta = sdhci_s3c_consider_clock(ourhost, src, clock); 175 if (delta < best) { 176 best = delta; 177 best_src = src; 178 } 179 } 180 181 dev_dbg(&ourhost->pdev->dev, 182 "selected source %d, clock %d, delta %d\n", 183 best_src, clock, best); 184 185 /* select the new clock source */ 186 if (ourhost->cur_clk != best_src) { 187 struct clk *clk = ourhost->clk_bus[best_src]; 188 189 clk_prepare_enable(clk); 190 if (ourhost->cur_clk >= 0) 191 clk_disable_unprepare( 192 ourhost->clk_bus[ourhost->cur_clk]); 193 194 ourhost->cur_clk = best_src; 195 host->max_clk = ourhost->clk_rates[best_src]; 196 } 197 198 /* turn clock off to card before changing clock source */ 199 writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL); 200 201 ctrl = readl(host->ioaddr + S3C_SDHCI_CONTROL2); 202 ctrl &= ~S3C_SDHCI_CTRL2_SELBASECLK_MASK; 203 ctrl |= best_src << S3C_SDHCI_CTRL2_SELBASECLK_SHIFT; 204 writel(ctrl, host->ioaddr + S3C_SDHCI_CONTROL2); 205 206 /* reprogram default hardware configuration */ 207 writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA, 208 host->ioaddr + S3C64XX_SDHCI_CONTROL4); 209 210 ctrl = readl(host->ioaddr + S3C_SDHCI_CONTROL2); 211 ctrl |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR | 212 S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK | 213 S3C_SDHCI_CTRL2_ENFBCLKRX | 214 S3C_SDHCI_CTRL2_DFCNT_NONE | 215 S3C_SDHCI_CTRL2_ENCLKOUTHOLD); 216 writel(ctrl, host->ioaddr + S3C_SDHCI_CONTROL2); 217 218 /* reconfigure the controller for new clock rate */ 219 ctrl = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0); 220 if (clock < 25 * 1000000) 221 ctrl |= (S3C_SDHCI_CTRL3_FCSEL3 | S3C_SDHCI_CTRL3_FCSEL2); 222 writel(ctrl, host->ioaddr + S3C_SDHCI_CONTROL3); 223 224 sdhci_set_clock(host, clock); 225} 226 227/** 228 * sdhci_s3c_get_min_clock - callback to get minimal supported clock value 229 * @host: The SDHCI host being queried 230 * 231 * To init mmc host properly a minimal clock value is needed. For high system 232 * bus clock's values the standard formula gives values out of allowed range. 233 * The clock still can be set to lower values, if clock source other then 234 * system bus is selected. 235*/ 236static unsigned int sdhci_s3c_get_min_clock(struct sdhci_host *host) 237{ 238 struct sdhci_s3c *ourhost = to_s3c(host); 239 unsigned long rate, min = ULONG_MAX; 240 int src; 241 242 for (src = 0; src < MAX_BUS_CLK; src++) { 243 rate = ourhost->clk_rates[src] / 256; 244 if (!rate) 245 continue; 246 if (rate < min) 247 min = rate; 248 } 249 250 return min; 251} 252 253/* sdhci_cmu_get_max_clk - callback to get maximum clock frequency.*/ 254static unsigned int sdhci_cmu_get_max_clock(struct sdhci_host *host) 255{ 256 struct sdhci_s3c *ourhost = to_s3c(host); 257 unsigned long rate, max = 0; 258 int src; 259 260 for (src = 0; src < MAX_BUS_CLK; src++) { 261 struct clk *clk; 262 263 clk = ourhost->clk_bus[src]; 264 if (IS_ERR(clk)) 265 continue; 266 267 rate = clk_round_rate(clk, ULONG_MAX); 268 if (rate > max) 269 max = rate; 270 } 271 272 return max; 273} 274 275/* sdhci_cmu_get_min_clock - callback to get minimal supported clock value. */ 276static unsigned int sdhci_cmu_get_min_clock(struct sdhci_host *host) 277{ 278 struct sdhci_s3c *ourhost = to_s3c(host); 279 unsigned long rate, min = ULONG_MAX; 280 int src; 281 282 for (src = 0; src < MAX_BUS_CLK; src++) { 283 struct clk *clk; 284 285 clk = ourhost->clk_bus[src]; 286 if (IS_ERR(clk)) 287 continue; 288 289 rate = clk_round_rate(clk, 0); 290 if (rate < min) 291 min = rate; 292 } 293 294 return min; 295} 296 297/* sdhci_cmu_set_clock - callback on clock change.*/ 298static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock) 299{ 300 struct sdhci_s3c *ourhost = to_s3c(host); 301 struct device *dev = &ourhost->pdev->dev; 302 unsigned long timeout; 303 u16 clk = 0; 304 int ret; 305 306 host->mmc->actual_clock = 0; 307 308 /* If the clock is going off, set to 0 at clock control register */ 309 if (clock == 0) { 310 sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); 311 return; 312 } 313 314 sdhci_s3c_set_clock(host, clock); 315 316 /* Reset SD Clock Enable */ 317 clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); 318 clk &= ~SDHCI_CLOCK_CARD_EN; 319 sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 320 321 spin_unlock_irq(&host->lock); 322 ret = clk_set_rate(ourhost->clk_bus[ourhost->cur_clk], clock); 323 spin_lock_irq(&host->lock); 324 if (ret != 0) { 325 dev_err(dev, "%s: failed to set clock rate %uHz\n", 326 mmc_hostname(host->mmc), clock); 327 return; 328 } 329 330 clk = SDHCI_CLOCK_INT_EN; 331 sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 332 333 /* Wait max 20 ms */ 334 timeout = 20; 335 while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL)) 336 & SDHCI_CLOCK_INT_STABLE)) { 337 if (timeout == 0) { 338 dev_err(dev, "%s: Internal clock never stabilised.\n", 339 mmc_hostname(host->mmc)); 340 return; 341 } 342 timeout--; 343 mdelay(1); 344 } 345 346 clk |= SDHCI_CLOCK_CARD_EN; 347 sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 348} 349 350/** 351 * sdhci_s3c_set_bus_width - support 8bit buswidth 352 * @host: The SDHCI host being queried 353 * @width: MMC_BUS_WIDTH_ macro for the bus width being requested 354 * 355 * We have 8-bit width support but is not a v3 controller. 356 * So we add platform_bus_width() and support 8bit width. 357 */ 358static void sdhci_s3c_set_bus_width(struct sdhci_host *host, int width) 359{ 360 u8 ctrl; 361 362 ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); 363 364 switch (width) { 365 case MMC_BUS_WIDTH_8: 366 ctrl |= SDHCI_CTRL_8BITBUS; 367 ctrl &= ~SDHCI_CTRL_4BITBUS; 368 break; 369 case MMC_BUS_WIDTH_4: 370 ctrl |= SDHCI_CTRL_4BITBUS; 371 ctrl &= ~SDHCI_CTRL_8BITBUS; 372 break; 373 default: 374 ctrl &= ~SDHCI_CTRL_4BITBUS; 375 ctrl &= ~SDHCI_CTRL_8BITBUS; 376 break; 377 } 378 379 sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); 380} 381 382static struct sdhci_ops sdhci_s3c_ops = { 383 .get_max_clock = sdhci_s3c_get_max_clk, 384 .set_clock = sdhci_s3c_set_clock, 385 .get_min_clock = sdhci_s3c_get_min_clock, 386 .set_bus_width = sdhci_s3c_set_bus_width, 387 .reset = sdhci_reset, 388 .set_uhs_signaling = sdhci_set_uhs_signaling, 389}; 390 391#ifdef CONFIG_OF 392static int sdhci_s3c_parse_dt(struct device *dev, 393 struct sdhci_host *host, struct s3c_sdhci_platdata *pdata) 394{ 395 struct device_node *node = dev->of_node; 396 u32 max_width; 397 398 /* if the bus-width property is not specified, assume width as 1 */ 399 if (of_property_read_u32(node, "bus-width", &max_width)) 400 max_width = 1; 401 pdata->max_width = max_width; 402 403 /* get the card detection method */ 404 if (of_get_property(node, "broken-cd", NULL)) { 405 pdata->cd_type = S3C_SDHCI_CD_NONE; 406 return 0; 407 } 408 409 if (of_get_property(node, "non-removable", NULL)) { 410 pdata->cd_type = S3C_SDHCI_CD_PERMANENT; 411 return 0; 412 } 413 414 if (of_get_named_gpio(node, "cd-gpios", 0)) 415 return 0; 416 417 /* assuming internal card detect that will be configured by pinctrl */ 418 pdata->cd_type = S3C_SDHCI_CD_INTERNAL; 419 return 0; 420} 421#else 422static int sdhci_s3c_parse_dt(struct device *dev, 423 struct sdhci_host *host, struct s3c_sdhci_platdata *pdata) 424{ 425 return -EINVAL; 426} 427#endif 428 429static const struct of_device_id sdhci_s3c_dt_match[]; 430 431static inline struct sdhci_s3c_drv_data *sdhci_s3c_get_driver_data( 432 struct platform_device *pdev) 433{ 434#ifdef CONFIG_OF 435 if (pdev->dev.of_node) { 436 const struct of_device_id *match; 437 match = of_match_node(sdhci_s3c_dt_match, pdev->dev.of_node); 438 return (struct sdhci_s3c_drv_data *)match->data; 439 } 440#endif 441 return (struct sdhci_s3c_drv_data *) 442 platform_get_device_id(pdev)->driver_data; 443} 444 445static int sdhci_s3c_probe(struct platform_device *pdev) 446{ 447 struct s3c_sdhci_platdata *pdata; 448 struct sdhci_s3c_drv_data *drv_data; 449 struct device *dev = &pdev->dev; 450 struct sdhci_host *host; 451 struct sdhci_s3c *sc; 452 struct resource *res; 453 int ret, irq, ptr, clks; 454 455 if (!pdev->dev.platform_data && !pdev->dev.of_node) { 456 dev_err(dev, "no device data specified\n"); 457 return -ENOENT; 458 } 459 460 irq = platform_get_irq(pdev, 0); 461 if (irq < 0) { 462 dev_err(dev, "no irq specified\n"); 463 return irq; 464 } 465 466 host = sdhci_alloc_host(dev, sizeof(struct sdhci_s3c)); 467 if (IS_ERR(host)) { 468 dev_err(dev, "sdhci_alloc_host() failed\n"); 469 return PTR_ERR(host); 470 } 471 sc = sdhci_priv(host); 472 473 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 474 if (!pdata) { 475 ret = -ENOMEM; 476 goto err_pdata_io_clk; 477 } 478 479 if (pdev->dev.of_node) { 480 ret = sdhci_s3c_parse_dt(&pdev->dev, host, pdata); 481 if (ret) 482 goto err_pdata_io_clk; 483 } else { 484 memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata)); 485 sc->ext_cd_gpio = -1; /* invalid gpio number */ 486 } 487 488 drv_data = sdhci_s3c_get_driver_data(pdev); 489 490 sc->host = host; 491 sc->pdev = pdev; 492 sc->pdata = pdata; 493 sc->cur_clk = -1; 494 495 platform_set_drvdata(pdev, host); 496 497 sc->clk_io = devm_clk_get(dev, "hsmmc"); 498 if (IS_ERR(sc->clk_io)) { 499 dev_err(dev, "failed to get io clock\n"); 500 ret = PTR_ERR(sc->clk_io); 501 goto err_pdata_io_clk; 502 } 503 504 /* enable the local io clock and keep it running for the moment. */ 505 clk_prepare_enable(sc->clk_io); 506 507 for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) { 508 char name[14]; 509 510 snprintf(name, 14, "mmc_busclk.%d", ptr); 511 sc->clk_bus[ptr] = devm_clk_get(dev, name); 512 if (IS_ERR(sc->clk_bus[ptr])) 513 continue; 514 515 clks++; 516 sc->clk_rates[ptr] = clk_get_rate(sc->clk_bus[ptr]); 517 518 dev_info(dev, "clock source %d: %s (%ld Hz)\n", 519 ptr, name, sc->clk_rates[ptr]); 520 } 521 522 if (clks == 0) { 523 dev_err(dev, "failed to find any bus clocks\n"); 524 ret = -ENOENT; 525 goto err_no_busclks; 526 } 527 528 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 529 host->ioaddr = devm_ioremap_resource(&pdev->dev, res); 530 if (IS_ERR(host->ioaddr)) { 531 ret = PTR_ERR(host->ioaddr); 532 goto err_req_regs; 533 } 534 535 /* Ensure we have minimal gpio selected CMD/CLK/Detect */ 536 if (pdata->cfg_gpio) 537 pdata->cfg_gpio(pdev, pdata->max_width); 538 539 host->hw_name = "samsung-hsmmc"; 540 host->ops = &sdhci_s3c_ops; 541 host->quirks = 0; 542 host->quirks2 = 0; 543 host->irq = irq; 544 545 /* Setup quirks for the controller */ 546 host->quirks |= SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC; 547 host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT; 548 if (drv_data) { 549 host->quirks |= drv_data->sdhci_quirks; 550 sc->no_divider = drv_data->no_divider; 551 } 552 553#ifndef CONFIG_MMC_SDHCI_S3C_DMA 554 555 /* we currently see overruns on errors, so disable the SDMA 556 * support as well. */ 557 host->quirks |= SDHCI_QUIRK_BROKEN_DMA; 558 559#endif /* CONFIG_MMC_SDHCI_S3C_DMA */ 560 561 /* It seems we do not get an DATA transfer complete on non-busy 562 * transfers, not sure if this is a problem with this specific 563 * SDHCI block, or a missing configuration that needs to be set. */ 564 host->quirks |= SDHCI_QUIRK_NO_BUSY_IRQ; 565 566 /* This host supports the Auto CMD12 */ 567 host->quirks |= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12; 568 569 /* Samsung SoCs need BROKEN_ADMA_ZEROLEN_DESC */ 570 host->quirks |= SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC; 571 572 if (pdata->cd_type == S3C_SDHCI_CD_NONE || 573 pdata->cd_type == S3C_SDHCI_CD_PERMANENT) 574 host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION; 575 576 if (pdata->cd_type == S3C_SDHCI_CD_PERMANENT) 577 host->mmc->caps = MMC_CAP_NONREMOVABLE; 578 579 switch (pdata->max_width) { 580 case 8: 581 host->mmc->caps |= MMC_CAP_8_BIT_DATA; 582 case 4: 583 host->mmc->caps |= MMC_CAP_4_BIT_DATA; 584 break; 585 } 586 587 if (pdata->pm_caps) 588 host->mmc->pm_caps |= pdata->pm_caps; 589 590 host->quirks |= (SDHCI_QUIRK_32BIT_DMA_ADDR | 591 SDHCI_QUIRK_32BIT_DMA_SIZE); 592 593 /* HSMMC on Samsung SoCs uses SDCLK as timeout clock */ 594 host->quirks |= SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK; 595 596 /* 597 * If controller does not have internal clock divider, 598 * we can use overriding functions instead of default. 599 */ 600 if (sc->no_divider) { 601 sdhci_s3c_ops.set_clock = sdhci_cmu_set_clock; 602 sdhci_s3c_ops.get_min_clock = sdhci_cmu_get_min_clock; 603 sdhci_s3c_ops.get_max_clock = sdhci_cmu_get_max_clock; 604 } 605 606 /* It supports additional host capabilities if needed */ 607 if (pdata->host_caps) 608 host->mmc->caps |= pdata->host_caps; 609 610 if (pdata->host_caps2) 611 host->mmc->caps2 |= pdata->host_caps2; 612 613 pm_runtime_enable(&pdev->dev); 614 pm_runtime_set_autosuspend_delay(&pdev->dev, 50); 615 pm_runtime_use_autosuspend(&pdev->dev); 616 pm_suspend_ignore_children(&pdev->dev, 1); 617 618 ret = mmc_of_parse(host->mmc); 619 if (ret) 620 goto err_req_regs; 621 622 ret = sdhci_add_host(host); 623 if (ret) { 624 dev_err(dev, "sdhci_add_host() failed\n"); 625 goto err_req_regs; 626 } 627 628#ifdef CONFIG_PM 629 if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL) 630 clk_disable_unprepare(sc->clk_io); 631#endif 632 return 0; 633 634 err_req_regs: 635 pm_runtime_disable(&pdev->dev); 636 637 err_no_busclks: 638 clk_disable_unprepare(sc->clk_io); 639 640 err_pdata_io_clk: 641 sdhci_free_host(host); 642 643 return ret; 644} 645 646static int sdhci_s3c_remove(struct platform_device *pdev) 647{ 648 struct sdhci_host *host = platform_get_drvdata(pdev); 649 struct sdhci_s3c *sc = sdhci_priv(host); 650 651 if (sc->ext_cd_irq) 652 free_irq(sc->ext_cd_irq, sc); 653 654#ifdef CONFIG_PM 655 if (sc->pdata->cd_type != S3C_SDHCI_CD_INTERNAL) 656 clk_prepare_enable(sc->clk_io); 657#endif 658 sdhci_remove_host(host, 1); 659 660 pm_runtime_dont_use_autosuspend(&pdev->dev); 661 pm_runtime_disable(&pdev->dev); 662 663 clk_disable_unprepare(sc->clk_io); 664 665 sdhci_free_host(host); 666 667 return 0; 668} 669 670#ifdef CONFIG_PM_SLEEP 671static int sdhci_s3c_suspend(struct device *dev) 672{ 673 struct sdhci_host *host = dev_get_drvdata(dev); 674 675 return sdhci_suspend_host(host); 676} 677 678static int sdhci_s3c_resume(struct device *dev) 679{ 680 struct sdhci_host *host = dev_get_drvdata(dev); 681 682 return sdhci_resume_host(host); 683} 684#endif 685 686#ifdef CONFIG_PM 687static int sdhci_s3c_runtime_suspend(struct device *dev) 688{ 689 struct sdhci_host *host = dev_get_drvdata(dev); 690 struct sdhci_s3c *ourhost = to_s3c(host); 691 struct clk *busclk = ourhost->clk_io; 692 int ret; 693 694 ret = sdhci_runtime_suspend_host(host); 695 696 if (ourhost->cur_clk >= 0) 697 clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]); 698 clk_disable_unprepare(busclk); 699 return ret; 700} 701 702static int sdhci_s3c_runtime_resume(struct device *dev) 703{ 704 struct sdhci_host *host = dev_get_drvdata(dev); 705 struct sdhci_s3c *ourhost = to_s3c(host); 706 struct clk *busclk = ourhost->clk_io; 707 int ret; 708 709 clk_prepare_enable(busclk); 710 if (ourhost->cur_clk >= 0) 711 clk_prepare_enable(ourhost->clk_bus[ourhost->cur_clk]); 712 ret = sdhci_runtime_resume_host(host); 713 return ret; 714} 715#endif 716 717#ifdef CONFIG_PM 718static const struct dev_pm_ops sdhci_s3c_pmops = { 719 SET_SYSTEM_SLEEP_PM_OPS(sdhci_s3c_suspend, sdhci_s3c_resume) 720 SET_RUNTIME_PM_OPS(sdhci_s3c_runtime_suspend, sdhci_s3c_runtime_resume, 721 NULL) 722}; 723 724#define SDHCI_S3C_PMOPS (&sdhci_s3c_pmops) 725 726#else 727#define SDHCI_S3C_PMOPS NULL 728#endif 729 730#if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS4212) 731static struct sdhci_s3c_drv_data exynos4_sdhci_drv_data = { 732 .no_divider = true, 733}; 734#define EXYNOS4_SDHCI_DRV_DATA ((kernel_ulong_t)&exynos4_sdhci_drv_data) 735#else 736#define EXYNOS4_SDHCI_DRV_DATA ((kernel_ulong_t)NULL) 737#endif 738 739static const struct platform_device_id sdhci_s3c_driver_ids[] = { 740 { 741 .name = "s3c-sdhci", 742 .driver_data = (kernel_ulong_t)NULL, 743 }, { 744 .name = "exynos4-sdhci", 745 .driver_data = EXYNOS4_SDHCI_DRV_DATA, 746 }, 747 { } 748}; 749MODULE_DEVICE_TABLE(platform, sdhci_s3c_driver_ids); 750 751#ifdef CONFIG_OF 752static const struct of_device_id sdhci_s3c_dt_match[] = { 753 { .compatible = "samsung,s3c6410-sdhci", }, 754 { .compatible = "samsung,exynos4210-sdhci", 755 .data = (void *)EXYNOS4_SDHCI_DRV_DATA }, 756 {}, 757}; 758MODULE_DEVICE_TABLE(of, sdhci_s3c_dt_match); 759#endif 760 761static struct platform_driver sdhci_s3c_driver = { 762 .probe = sdhci_s3c_probe, 763 .remove = sdhci_s3c_remove, 764 .id_table = sdhci_s3c_driver_ids, 765 .driver = { 766 .name = "s3c-sdhci", 767 .of_match_table = of_match_ptr(sdhci_s3c_dt_match), 768 .pm = SDHCI_S3C_PMOPS, 769 }, 770}; 771 772module_platform_driver(sdhci_s3c_driver); 773 774MODULE_DESCRIPTION("Samsung SDHCI (HSMMC) glue"); 775MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); 776MODULE_LICENSE("GPL v2"); 777MODULE_ALIAS("platform:s3c-sdhci"); 778