diff options
Diffstat (limited to 'drivers/mmc/host/omap_hsmmc.c')
-rw-r--r-- | drivers/mmc/host/omap_hsmmc.c | 177 |
1 files changed, 116 insertions, 61 deletions
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index fedd258cc4ea..d0a912fbad3b 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/io.h> | 37 | #include <linux/io.h> |
38 | #include <linux/gpio.h> | 38 | #include <linux/gpio.h> |
39 | #include <linux/regulator/consumer.h> | 39 | #include <linux/regulator/consumer.h> |
40 | #include <linux/pinctrl/consumer.h> | ||
40 | #include <linux/pm_runtime.h> | 41 | #include <linux/pm_runtime.h> |
41 | #include <mach/hardware.h> | 42 | #include <mach/hardware.h> |
42 | #include <plat/mmc.h> | 43 | #include <plat/mmc.h> |
@@ -62,6 +63,7 @@ | |||
62 | 63 | ||
63 | #define VS18 (1 << 26) | 64 | #define VS18 (1 << 26) |
64 | #define VS30 (1 << 25) | 65 | #define VS30 (1 << 25) |
66 | #define HSS (1 << 21) | ||
65 | #define SDVS18 (0x5 << 9) | 67 | #define SDVS18 (0x5 << 9) |
66 | #define SDVS30 (0x6 << 9) | 68 | #define SDVS30 (0x6 << 9) |
67 | #define SDVS33 (0x7 << 9) | 69 | #define SDVS33 (0x7 << 9) |
@@ -78,28 +80,17 @@ | |||
78 | #define CLKD_SHIFT 6 | 80 | #define CLKD_SHIFT 6 |
79 | #define DTO_MASK 0x000F0000 | 81 | #define DTO_MASK 0x000F0000 |
80 | #define DTO_SHIFT 16 | 82 | #define DTO_SHIFT 16 |
81 | #define INT_EN_MASK 0x307F0033 | ||
82 | #define BWR_ENABLE (1 << 4) | ||
83 | #define BRR_ENABLE (1 << 5) | ||
84 | #define DTO_ENABLE (1 << 20) | ||
85 | #define INIT_STREAM (1 << 1) | 83 | #define INIT_STREAM (1 << 1) |
86 | #define DP_SELECT (1 << 21) | 84 | #define DP_SELECT (1 << 21) |
87 | #define DDIR (1 << 4) | 85 | #define DDIR (1 << 4) |
88 | #define DMA_EN 0x1 | 86 | #define DMAE 0x1 |
89 | #define MSBS (1 << 5) | 87 | #define MSBS (1 << 5) |
90 | #define BCE (1 << 1) | 88 | #define BCE (1 << 1) |
91 | #define FOUR_BIT (1 << 1) | 89 | #define FOUR_BIT (1 << 1) |
90 | #define HSPE (1 << 2) | ||
92 | #define DDR (1 << 19) | 91 | #define DDR (1 << 19) |
93 | #define DW8 (1 << 5) | 92 | #define DW8 (1 << 5) |
94 | #define CC 0x1 | ||
95 | #define TC 0x02 | ||
96 | #define OD 0x1 | 93 | #define OD 0x1 |
97 | #define ERR (1 << 15) | ||
98 | #define CMD_TIMEOUT (1 << 16) | ||
99 | #define DATA_TIMEOUT (1 << 20) | ||
100 | #define CMD_CRC (1 << 17) | ||
101 | #define DATA_CRC (1 << 21) | ||
102 | #define CARD_ERR (1 << 28) | ||
103 | #define STAT_CLEAR 0xFFFFFFFF | 94 | #define STAT_CLEAR 0xFFFFFFFF |
104 | #define INIT_STREAM_CMD 0x00000000 | 95 | #define INIT_STREAM_CMD 0x00000000 |
105 | #define DUAL_VOLT_OCR_BIT 7 | 96 | #define DUAL_VOLT_OCR_BIT 7 |
@@ -108,6 +99,26 @@ | |||
108 | #define SOFTRESET (1 << 1) | 99 | #define SOFTRESET (1 << 1) |
109 | #define RESETDONE (1 << 0) | 100 | #define RESETDONE (1 << 0) |
110 | 101 | ||
102 | /* Interrupt masks for IE and ISE register */ | ||
103 | #define CC_EN (1 << 0) | ||
104 | #define TC_EN (1 << 1) | ||
105 | #define BWR_EN (1 << 4) | ||
106 | #define BRR_EN (1 << 5) | ||
107 | #define ERR_EN (1 << 15) | ||
108 | #define CTO_EN (1 << 16) | ||
109 | #define CCRC_EN (1 << 17) | ||
110 | #define CEB_EN (1 << 18) | ||
111 | #define CIE_EN (1 << 19) | ||
112 | #define DTO_EN (1 << 20) | ||
113 | #define DCRC_EN (1 << 21) | ||
114 | #define DEB_EN (1 << 22) | ||
115 | #define CERR_EN (1 << 28) | ||
116 | #define BADA_EN (1 << 29) | ||
117 | |||
118 | #define INT_EN_MASK (BADA_EN | CERR_EN | DEB_EN | DCRC_EN |\ | ||
119 | DTO_EN | CIE_EN | CEB_EN | CCRC_EN | CTO_EN | \ | ||
120 | BRR_EN | BWR_EN | TC_EN | CC_EN) | ||
121 | |||
111 | #define MMC_AUTOSUSPEND_DELAY 100 | 122 | #define MMC_AUTOSUSPEND_DELAY 100 |
112 | #define MMC_TIMEOUT_MS 20 | 123 | #define MMC_TIMEOUT_MS 20 |
113 | #define OMAP_MMC_MIN_CLOCK 400000 | 124 | #define OMAP_MMC_MIN_CLOCK 400000 |
@@ -302,7 +313,7 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) | |||
302 | 313 | ||
303 | reg = regulator_get(host->dev, "vmmc"); | 314 | reg = regulator_get(host->dev, "vmmc"); |
304 | if (IS_ERR(reg)) { | 315 | if (IS_ERR(reg)) { |
305 | dev_dbg(host->dev, "vmmc regulator missing\n"); | 316 | dev_err(host->dev, "vmmc regulator missing\n"); |
306 | return PTR_ERR(reg); | 317 | return PTR_ERR(reg); |
307 | } else { | 318 | } else { |
308 | mmc_slot(host).set_power = omap_hsmmc_set_power; | 319 | mmc_slot(host).set_power = omap_hsmmc_set_power; |
@@ -455,13 +466,13 @@ static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host, | |||
455 | unsigned int irq_mask; | 466 | unsigned int irq_mask; |
456 | 467 | ||
457 | if (host->use_dma) | 468 | if (host->use_dma) |
458 | irq_mask = INT_EN_MASK & ~(BRR_ENABLE | BWR_ENABLE); | 469 | irq_mask = INT_EN_MASK & ~(BRR_EN | BWR_EN); |
459 | else | 470 | else |
460 | irq_mask = INT_EN_MASK; | 471 | irq_mask = INT_EN_MASK; |
461 | 472 | ||
462 | /* Disable timeout for erases */ | 473 | /* Disable timeout for erases */ |
463 | if (cmd->opcode == MMC_ERASE) | 474 | if (cmd->opcode == MMC_ERASE) |
464 | irq_mask &= ~DTO_ENABLE; | 475 | irq_mask &= ~DTO_EN; |
465 | 476 | ||
466 | OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR); | 477 | OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR); |
467 | OMAP_HSMMC_WRITE(host->base, ISE, irq_mask); | 478 | OMAP_HSMMC_WRITE(host->base, ISE, irq_mask); |
@@ -494,6 +505,7 @@ static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host) | |||
494 | struct mmc_ios *ios = &host->mmc->ios; | 505 | struct mmc_ios *ios = &host->mmc->ios; |
495 | unsigned long regval; | 506 | unsigned long regval; |
496 | unsigned long timeout; | 507 | unsigned long timeout; |
508 | unsigned long clkdiv; | ||
497 | 509 | ||
498 | dev_vdbg(mmc_dev(host->mmc), "Set clock to %uHz\n", ios->clock); | 510 | dev_vdbg(mmc_dev(host->mmc), "Set clock to %uHz\n", ios->clock); |
499 | 511 | ||
@@ -501,7 +513,8 @@ static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host) | |||
501 | 513 | ||
502 | regval = OMAP_HSMMC_READ(host->base, SYSCTL); | 514 | regval = OMAP_HSMMC_READ(host->base, SYSCTL); |
503 | regval = regval & ~(CLKD_MASK | DTO_MASK); | 515 | regval = regval & ~(CLKD_MASK | DTO_MASK); |
504 | regval = regval | (calc_divisor(host, ios) << 6) | (DTO << 16); | 516 | clkdiv = calc_divisor(host, ios); |
517 | regval = regval | (clkdiv << 6) | (DTO << 16); | ||
505 | OMAP_HSMMC_WRITE(host->base, SYSCTL, regval); | 518 | OMAP_HSMMC_WRITE(host->base, SYSCTL, regval); |
506 | OMAP_HSMMC_WRITE(host->base, SYSCTL, | 519 | OMAP_HSMMC_WRITE(host->base, SYSCTL, |
507 | OMAP_HSMMC_READ(host->base, SYSCTL) | ICE); | 520 | OMAP_HSMMC_READ(host->base, SYSCTL) | ICE); |
@@ -512,6 +525,27 @@ static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host) | |||
512 | && time_before(jiffies, timeout)) | 525 | && time_before(jiffies, timeout)) |
513 | cpu_relax(); | 526 | cpu_relax(); |
514 | 527 | ||
528 | /* | ||
529 | * Enable High-Speed Support | ||
530 | * Pre-Requisites | ||
531 | * - Controller should support High-Speed-Enable Bit | ||
532 | * - Controller should not be using DDR Mode | ||
533 | * - Controller should advertise that it supports High Speed | ||
534 | * in capabilities register | ||
535 | * - MMC/SD clock coming out of controller > 25MHz | ||
536 | */ | ||
537 | if ((mmc_slot(host).features & HSMMC_HAS_HSPE_SUPPORT) && | ||
538 | (ios->timing != MMC_TIMING_UHS_DDR50) && | ||
539 | ((OMAP_HSMMC_READ(host->base, CAPA) & HSS) == HSS)) { | ||
540 | regval = OMAP_HSMMC_READ(host->base, HCTL); | ||
541 | if (clkdiv && (clk_get_rate(host->fclk)/clkdiv) > 25000000) | ||
542 | regval |= HSPE; | ||
543 | else | ||
544 | regval &= ~HSPE; | ||
545 | |||
546 | OMAP_HSMMC_WRITE(host->base, HCTL, regval); | ||
547 | } | ||
548 | |||
515 | omap_hsmmc_start_clock(host); | 549 | omap_hsmmc_start_clock(host); |
516 | } | 550 | } |
517 | 551 | ||
@@ -676,8 +710,8 @@ static void send_init_stream(struct omap_hsmmc_host *host) | |||
676 | OMAP_HSMMC_WRITE(host->base, CMD, INIT_STREAM_CMD); | 710 | OMAP_HSMMC_WRITE(host->base, CMD, INIT_STREAM_CMD); |
677 | 711 | ||
678 | timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS); | 712 | timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS); |
679 | while ((reg != CC) && time_before(jiffies, timeout)) | 713 | while ((reg != CC_EN) && time_before(jiffies, timeout)) |
680 | reg = OMAP_HSMMC_READ(host->base, STAT) & CC; | 714 | reg = OMAP_HSMMC_READ(host->base, STAT) & CC_EN; |
681 | 715 | ||
682 | OMAP_HSMMC_WRITE(host->base, CON, | 716 | OMAP_HSMMC_WRITE(host->base, CON, |
683 | OMAP_HSMMC_READ(host->base, CON) & ~INIT_STREAM); | 717 | OMAP_HSMMC_READ(host->base, CON) & ~INIT_STREAM); |
@@ -768,7 +802,7 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, | |||
768 | } | 802 | } |
769 | 803 | ||
770 | if (host->use_dma) | 804 | if (host->use_dma) |
771 | cmdreg |= DMA_EN; | 805 | cmdreg |= DMAE; |
772 | 806 | ||
773 | host->req_in_progress = 1; | 807 | host->req_in_progress = 1; |
774 | 808 | ||
@@ -968,16 +1002,20 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host, | |||
968 | __func__); | 1002 | __func__); |
969 | } | 1003 | } |
970 | 1004 | ||
971 | static void hsmmc_command_incomplete(struct omap_hsmmc_host *host, int err) | 1005 | static void hsmmc_command_incomplete(struct omap_hsmmc_host *host, |
1006 | int err, int end_cmd) | ||
972 | { | 1007 | { |
973 | omap_hsmmc_reset_controller_fsm(host, SRC); | 1008 | if (end_cmd) { |
974 | host->cmd->error = err; | 1009 | omap_hsmmc_reset_controller_fsm(host, SRC); |
1010 | if (host->cmd) | ||
1011 | host->cmd->error = err; | ||
1012 | } | ||
975 | 1013 | ||
976 | if (host->data) { | 1014 | if (host->data) { |
977 | omap_hsmmc_reset_controller_fsm(host, SRD); | 1015 | omap_hsmmc_reset_controller_fsm(host, SRD); |
978 | omap_hsmmc_dma_cleanup(host, err); | 1016 | omap_hsmmc_dma_cleanup(host, err); |
979 | } | 1017 | } else if (host->mrq && host->mrq->cmd) |
980 | 1018 | host->mrq->cmd->error = err; | |
981 | } | 1019 | } |
982 | 1020 | ||
983 | static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status) | 1021 | static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status) |
@@ -988,23 +1026,25 @@ static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status) | |||
988 | data = host->data; | 1026 | data = host->data; |
989 | dev_vdbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status); | 1027 | dev_vdbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status); |
990 | 1028 | ||
991 | if (status & ERR) { | 1029 | if (status & ERR_EN) { |
992 | omap_hsmmc_dbg_report_irq(host, status); | 1030 | omap_hsmmc_dbg_report_irq(host, status); |
993 | if (status & (CMD_TIMEOUT | DATA_TIMEOUT)) | ||
994 | hsmmc_command_incomplete(host, -ETIMEDOUT); | ||
995 | else if (status & (CMD_CRC | DATA_CRC)) | ||
996 | hsmmc_command_incomplete(host, -EILSEQ); | ||
997 | 1031 | ||
998 | end_cmd = 1; | 1032 | if (status & (CTO_EN | CCRC_EN)) |
1033 | end_cmd = 1; | ||
1034 | if (status & (CTO_EN | DTO_EN)) | ||
1035 | hsmmc_command_incomplete(host, -ETIMEDOUT, end_cmd); | ||
1036 | else if (status & (CCRC_EN | DCRC_EN)) | ||
1037 | hsmmc_command_incomplete(host, -EILSEQ, end_cmd); | ||
1038 | |||
999 | if (host->data || host->response_busy) { | 1039 | if (host->data || host->response_busy) { |
1000 | end_trans = 1; | 1040 | end_trans = !end_cmd; |
1001 | host->response_busy = 0; | 1041 | host->response_busy = 0; |
1002 | } | 1042 | } |
1003 | } | 1043 | } |
1004 | 1044 | ||
1005 | if (end_cmd || ((status & CC) && host->cmd)) | 1045 | if (end_cmd || ((status & CC_EN) && host->cmd)) |
1006 | omap_hsmmc_cmd_done(host, host->cmd); | 1046 | omap_hsmmc_cmd_done(host, host->cmd); |
1007 | if ((end_trans || (status & TC)) && host->mrq) | 1047 | if ((end_trans || (status & TC_EN)) && host->mrq) |
1008 | omap_hsmmc_xfer_done(host, data); | 1048 | omap_hsmmc_xfer_done(host, data); |
1009 | } | 1049 | } |
1010 | 1050 | ||
@@ -1101,7 +1141,7 @@ static int omap_hsmmc_switch_opcond(struct omap_hsmmc_host *host, int vdd) | |||
1101 | 1141 | ||
1102 | return 0; | 1142 | return 0; |
1103 | err: | 1143 | err: |
1104 | dev_dbg(mmc_dev(host->mmc), "Unable to switch operating voltage\n"); | 1144 | dev_err(mmc_dev(host->mmc), "Unable to switch operating voltage\n"); |
1105 | return ret; | 1145 | return ret; |
1106 | } | 1146 | } |
1107 | 1147 | ||
@@ -1360,7 +1400,7 @@ omap_hsmmc_prepare_data(struct omap_hsmmc_host *host, struct mmc_request *req) | |||
1360 | if (host->use_dma) { | 1400 | if (host->use_dma) { |
1361 | ret = omap_hsmmc_start_dma_transfer(host, req); | 1401 | ret = omap_hsmmc_start_dma_transfer(host, req); |
1362 | if (ret != 0) { | 1402 | if (ret != 0) { |
1363 | dev_dbg(mmc_dev(host->mmc), "MMC start dma failure\n"); | 1403 | dev_err(mmc_dev(host->mmc), "MMC start dma failure\n"); |
1364 | return ret; | 1404 | return ret; |
1365 | } | 1405 | } |
1366 | } | 1406 | } |
@@ -1678,7 +1718,7 @@ static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev) | |||
1678 | { | 1718 | { |
1679 | struct omap_mmc_platform_data *pdata; | 1719 | struct omap_mmc_platform_data *pdata; |
1680 | struct device_node *np = dev->of_node; | 1720 | struct device_node *np = dev->of_node; |
1681 | u32 bus_width; | 1721 | u32 bus_width, max_freq; |
1682 | 1722 | ||
1683 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | 1723 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); |
1684 | if (!pdata) | 1724 | if (!pdata) |
@@ -1705,6 +1745,12 @@ static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev) | |||
1705 | if (of_find_property(np, "ti,needs-special-reset", NULL)) | 1745 | if (of_find_property(np, "ti,needs-special-reset", NULL)) |
1706 | pdata->slots[0].features |= HSMMC_HAS_UPDATED_RESET; | 1746 | pdata->slots[0].features |= HSMMC_HAS_UPDATED_RESET; |
1707 | 1747 | ||
1748 | if (!of_property_read_u32(np, "max-frequency", &max_freq)) | ||
1749 | pdata->max_freq = max_freq; | ||
1750 | |||
1751 | if (of_find_property(np, "ti,needs-special-hs-handling", NULL)) | ||
1752 | pdata->slots[0].features |= HSMMC_HAS_HSPE_SUPPORT; | ||
1753 | |||
1708 | return pdata; | 1754 | return pdata; |
1709 | } | 1755 | } |
1710 | #else | 1756 | #else |
@@ -1725,6 +1771,7 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev) | |||
1725 | const struct of_device_id *match; | 1771 | const struct of_device_id *match; |
1726 | dma_cap_mask_t mask; | 1772 | dma_cap_mask_t mask; |
1727 | unsigned tx_req, rx_req; | 1773 | unsigned tx_req, rx_req; |
1774 | struct pinctrl *pinctrl; | ||
1728 | 1775 | ||
1729 | match = of_match_device(of_match_ptr(omap_mmc_of_match), &pdev->dev); | 1776 | match = of_match_device(of_match_ptr(omap_mmc_of_match), &pdev->dev); |
1730 | if (match) { | 1777 | if (match) { |
@@ -1821,7 +1868,6 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev) | |||
1821 | * MMC can still work without debounce clock. | 1868 | * MMC can still work without debounce clock. |
1822 | */ | 1869 | */ |
1823 | if (IS_ERR(host->dbclk)) { | 1870 | if (IS_ERR(host->dbclk)) { |
1824 | dev_warn(mmc_dev(host->mmc), "Failed to get debounce clk\n"); | ||
1825 | host->dbclk = NULL; | 1871 | host->dbclk = NULL; |
1826 | } else if (clk_prepare_enable(host->dbclk) != 0) { | 1872 | } else if (clk_prepare_enable(host->dbclk) != 0) { |
1827 | dev_warn(mmc_dev(host->mmc), "Failed to enable debounce clk\n"); | 1873 | dev_warn(mmc_dev(host->mmc), "Failed to enable debounce clk\n"); |
@@ -1889,13 +1935,13 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev) | |||
1889 | ret = request_irq(host->irq, omap_hsmmc_irq, 0, | 1935 | ret = request_irq(host->irq, omap_hsmmc_irq, 0, |
1890 | mmc_hostname(mmc), host); | 1936 | mmc_hostname(mmc), host); |
1891 | if (ret) { | 1937 | if (ret) { |
1892 | dev_dbg(mmc_dev(host->mmc), "Unable to grab HSMMC IRQ\n"); | 1938 | dev_err(mmc_dev(host->mmc), "Unable to grab HSMMC IRQ\n"); |
1893 | goto err_irq; | 1939 | goto err_irq; |
1894 | } | 1940 | } |
1895 | 1941 | ||
1896 | if (pdata->init != NULL) { | 1942 | if (pdata->init != NULL) { |
1897 | if (pdata->init(&pdev->dev) != 0) { | 1943 | if (pdata->init(&pdev->dev) != 0) { |
1898 | dev_dbg(mmc_dev(host->mmc), | 1944 | dev_err(mmc_dev(host->mmc), |
1899 | "Unable to configure MMC IRQs\n"); | 1945 | "Unable to configure MMC IRQs\n"); |
1900 | goto err_irq_cd_init; | 1946 | goto err_irq_cd_init; |
1901 | } | 1947 | } |
@@ -1918,7 +1964,7 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev) | |||
1918 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | 1964 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, |
1919 | mmc_hostname(mmc), host); | 1965 | mmc_hostname(mmc), host); |
1920 | if (ret) { | 1966 | if (ret) { |
1921 | dev_dbg(mmc_dev(host->mmc), | 1967 | dev_err(mmc_dev(host->mmc), |
1922 | "Unable to grab MMC CD IRQ\n"); | 1968 | "Unable to grab MMC CD IRQ\n"); |
1923 | goto err_irq_cd; | 1969 | goto err_irq_cd; |
1924 | } | 1970 | } |
@@ -1928,6 +1974,11 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev) | |||
1928 | 1974 | ||
1929 | omap_hsmmc_disable_irq(host); | 1975 | omap_hsmmc_disable_irq(host); |
1930 | 1976 | ||
1977 | pinctrl = devm_pinctrl_get_select_default(&pdev->dev); | ||
1978 | if (IS_ERR(pinctrl)) | ||
1979 | dev_warn(&pdev->dev, | ||
1980 | "pins are not configured from the driver\n"); | ||
1981 | |||
1931 | omap_hsmmc_protect_card(host); | 1982 | omap_hsmmc_protect_card(host); |
1932 | 1983 | ||
1933 | mmc_add_host(mmc); | 1984 | mmc_add_host(mmc); |
@@ -2027,6 +2078,25 @@ static int __devexit omap_hsmmc_remove(struct platform_device *pdev) | |||
2027 | } | 2078 | } |
2028 | 2079 | ||
2029 | #ifdef CONFIG_PM | 2080 | #ifdef CONFIG_PM |
2081 | static int omap_hsmmc_prepare(struct device *dev) | ||
2082 | { | ||
2083 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); | ||
2084 | |||
2085 | if (host->pdata->suspend) | ||
2086 | return host->pdata->suspend(dev, host->slot_id); | ||
2087 | |||
2088 | return 0; | ||
2089 | } | ||
2090 | |||
2091 | static void omap_hsmmc_complete(struct device *dev) | ||
2092 | { | ||
2093 | struct omap_hsmmc_host *host = dev_get_drvdata(dev); | ||
2094 | |||
2095 | if (host->pdata->resume) | ||
2096 | host->pdata->resume(dev, host->slot_id); | ||
2097 | |||
2098 | } | ||
2099 | |||
2030 | static int omap_hsmmc_suspend(struct device *dev) | 2100 | static int omap_hsmmc_suspend(struct device *dev) |
2031 | { | 2101 | { |
2032 | int ret = 0; | 2102 | int ret = 0; |
@@ -2040,23 +2110,10 @@ static int omap_hsmmc_suspend(struct device *dev) | |||
2040 | 2110 | ||
2041 | pm_runtime_get_sync(host->dev); | 2111 | pm_runtime_get_sync(host->dev); |
2042 | host->suspended = 1; | 2112 | host->suspended = 1; |
2043 | if (host->pdata->suspend) { | ||
2044 | ret = host->pdata->suspend(dev, host->slot_id); | ||
2045 | if (ret) { | ||
2046 | dev_dbg(dev, "Unable to handle MMC board" | ||
2047 | " level suspend\n"); | ||
2048 | host->suspended = 0; | ||
2049 | return ret; | ||
2050 | } | ||
2051 | } | ||
2052 | ret = mmc_suspend_host(host->mmc); | 2113 | ret = mmc_suspend_host(host->mmc); |
2053 | 2114 | ||
2054 | if (ret) { | 2115 | if (ret) { |
2055 | host->suspended = 0; | 2116 | host->suspended = 0; |
2056 | if (host->pdata->resume) { | ||
2057 | if (host->pdata->resume(dev, host->slot_id)) | ||
2058 | dev_dbg(dev, "Unmask interrupt failed\n"); | ||
2059 | } | ||
2060 | goto err; | 2117 | goto err; |
2061 | } | 2118 | } |
2062 | 2119 | ||
@@ -2093,12 +2150,6 @@ static int omap_hsmmc_resume(struct device *dev) | |||
2093 | if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER)) | 2150 | if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER)) |
2094 | omap_hsmmc_conf_bus_power(host); | 2151 | omap_hsmmc_conf_bus_power(host); |
2095 | 2152 | ||
2096 | if (host->pdata->resume) { | ||
2097 | ret = host->pdata->resume(dev, host->slot_id); | ||
2098 | if (ret) | ||
2099 | dev_dbg(dev, "Unmask interrupt failed\n"); | ||
2100 | } | ||
2101 | |||
2102 | omap_hsmmc_protect_card(host); | 2153 | omap_hsmmc_protect_card(host); |
2103 | 2154 | ||
2104 | /* Notify the core to resume the host */ | 2155 | /* Notify the core to resume the host */ |
@@ -2114,8 +2165,10 @@ static int omap_hsmmc_resume(struct device *dev) | |||
2114 | } | 2165 | } |
2115 | 2166 | ||
2116 | #else | 2167 | #else |
2168 | #define omap_hsmmc_prepare NULL | ||
2169 | #define omap_hsmmc_complete NULL | ||
2117 | #define omap_hsmmc_suspend NULL | 2170 | #define omap_hsmmc_suspend NULL |
2118 | #define omap_hsmmc_resume NULL | 2171 | #define omap_hsmmc_resume NULL |
2119 | #endif | 2172 | #endif |
2120 | 2173 | ||
2121 | static int omap_hsmmc_runtime_suspend(struct device *dev) | 2174 | static int omap_hsmmc_runtime_suspend(struct device *dev) |
@@ -2143,6 +2196,8 @@ static int omap_hsmmc_runtime_resume(struct device *dev) | |||
2143 | static struct dev_pm_ops omap_hsmmc_dev_pm_ops = { | 2196 | static struct dev_pm_ops omap_hsmmc_dev_pm_ops = { |
2144 | .suspend = omap_hsmmc_suspend, | 2197 | .suspend = omap_hsmmc_suspend, |
2145 | .resume = omap_hsmmc_resume, | 2198 | .resume = omap_hsmmc_resume, |
2199 | .prepare = omap_hsmmc_prepare, | ||
2200 | .complete = omap_hsmmc_complete, | ||
2146 | .runtime_suspend = omap_hsmmc_runtime_suspend, | 2201 | .runtime_suspend = omap_hsmmc_runtime_suspend, |
2147 | .runtime_resume = omap_hsmmc_runtime_resume, | 2202 | .runtime_resume = omap_hsmmc_runtime_resume, |
2148 | }; | 2203 | }; |