aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/mmci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/mmci.c')
-rw-r--r--drivers/mmc/host/mmci.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 604e41db00db..d135c76c4855 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -62,6 +62,7 @@ static unsigned int fmax = 515633;
62 * @signal_direction: input/out direction of bus signals can be indicated 62 * @signal_direction: input/out direction of bus signals can be indicated
63 * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock 63 * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock
64 * @busy_detect: true if busy detection on dat0 is supported 64 * @busy_detect: true if busy detection on dat0 is supported
65 * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply
65 */ 66 */
66struct variant_data { 67struct variant_data {
67 unsigned int clkreg; 68 unsigned int clkreg;
@@ -76,6 +77,7 @@ struct variant_data {
76 bool signal_direction; 77 bool signal_direction;
77 bool pwrreg_clkgate; 78 bool pwrreg_clkgate;
78 bool busy_detect; 79 bool busy_detect;
80 bool pwrreg_nopower;
79}; 81};
80 82
81static struct variant_data variant_arm = { 83static struct variant_data variant_arm = {
@@ -109,6 +111,7 @@ static struct variant_data variant_u300 = {
109 .pwrreg_powerup = MCI_PWR_ON, 111 .pwrreg_powerup = MCI_PWR_ON,
110 .signal_direction = true, 112 .signal_direction = true,
111 .pwrreg_clkgate = true, 113 .pwrreg_clkgate = true,
114 .pwrreg_nopower = true,
112}; 115};
113 116
114static struct variant_data variant_nomadik = { 117static struct variant_data variant_nomadik = {
@@ -121,6 +124,7 @@ static struct variant_data variant_nomadik = {
121 .pwrreg_powerup = MCI_PWR_ON, 124 .pwrreg_powerup = MCI_PWR_ON,
122 .signal_direction = true, 125 .signal_direction = true,
123 .pwrreg_clkgate = true, 126 .pwrreg_clkgate = true,
127 .pwrreg_nopower = true,
124}; 128};
125 129
126static struct variant_data variant_ux500 = { 130static struct variant_data variant_ux500 = {
@@ -135,6 +139,7 @@ static struct variant_data variant_ux500 = {
135 .signal_direction = true, 139 .signal_direction = true,
136 .pwrreg_clkgate = true, 140 .pwrreg_clkgate = true,
137 .busy_detect = true, 141 .busy_detect = true,
142 .pwrreg_nopower = true,
138}; 143};
139 144
140static struct variant_data variant_ux500v2 = { 145static struct variant_data variant_ux500v2 = {
@@ -150,6 +155,7 @@ static struct variant_data variant_ux500v2 = {
150 .signal_direction = true, 155 .signal_direction = true,
151 .pwrreg_clkgate = true, 156 .pwrreg_clkgate = true,
152 .busy_detect = true, 157 .busy_detect = true,
158 .pwrreg_nopower = true,
153}; 159};
154 160
155static int mmci_card_busy(struct mmc_host *mmc) 161static int mmci_card_busy(struct mmc_host *mmc)
@@ -1759,6 +1765,41 @@ static int mmci_resume(struct device *dev)
1759#endif 1765#endif
1760 1766
1761#ifdef CONFIG_PM_RUNTIME 1767#ifdef CONFIG_PM_RUNTIME
1768static void mmci_save(struct mmci_host *host)
1769{
1770 unsigned long flags;
1771
1772 if (host->variant->pwrreg_nopower) {
1773 spin_lock_irqsave(&host->lock, flags);
1774
1775 writel(0, host->base + MMCIMASK0);
1776 writel(0, host->base + MMCIDATACTRL);
1777 writel(0, host->base + MMCIPOWER);
1778 writel(0, host->base + MMCICLOCK);
1779 mmci_reg_delay(host);
1780
1781 spin_unlock_irqrestore(&host->lock, flags);
1782 }
1783
1784}
1785
1786static void mmci_restore(struct mmci_host *host)
1787{
1788 unsigned long flags;
1789
1790 if (host->variant->pwrreg_nopower) {
1791 spin_lock_irqsave(&host->lock, flags);
1792
1793 writel(host->clk_reg, host->base + MMCICLOCK);
1794 writel(host->datactrl_reg, host->base + MMCIDATACTRL);
1795 writel(host->pwr_reg, host->base + MMCIPOWER);
1796 writel(MCI_IRQENABLE, host->base + MMCIMASK0);
1797 mmci_reg_delay(host);
1798
1799 spin_unlock_irqrestore(&host->lock, flags);
1800 }
1801}
1802
1762static int mmci_runtime_suspend(struct device *dev) 1803static int mmci_runtime_suspend(struct device *dev)
1763{ 1804{
1764 struct amba_device *adev = to_amba_device(dev); 1805 struct amba_device *adev = to_amba_device(dev);
@@ -1767,6 +1808,7 @@ static int mmci_runtime_suspend(struct device *dev)
1767 if (mmc) { 1808 if (mmc) {
1768 struct mmci_host *host = mmc_priv(mmc); 1809 struct mmci_host *host = mmc_priv(mmc);
1769 pinctrl_pm_select_sleep_state(dev); 1810 pinctrl_pm_select_sleep_state(dev);
1811 mmci_save(host);
1770 clk_disable_unprepare(host->clk); 1812 clk_disable_unprepare(host->clk);
1771 } 1813 }
1772 1814
@@ -1781,6 +1823,7 @@ static int mmci_runtime_resume(struct device *dev)
1781 if (mmc) { 1823 if (mmc) {
1782 struct mmci_host *host = mmc_priv(mmc); 1824 struct mmci_host *host = mmc_priv(mmc);
1783 clk_prepare_enable(host->clk); 1825 clk_prepare_enable(host->clk);
1826 mmci_restore(host);
1784 pinctrl_pm_select_default_state(dev); 1827 pinctrl_pm_select_default_state(dev);
1785 } 1828 }
1786 1829