aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/core/sdio_bus.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/core/sdio_bus.c')
-rw-r--r--drivers/mmc/core/sdio_bus.c33
1 files changed, 22 insertions, 11 deletions
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
index 2716c7ab6bbf..203da443e339 100644
--- a/drivers/mmc/core/sdio_bus.c
+++ b/drivers/mmc/core/sdio_bus.c
@@ -17,6 +17,7 @@
17#include <linux/pm_runtime.h> 17#include <linux/pm_runtime.h>
18 18
19#include <linux/mmc/card.h> 19#include <linux/mmc/card.h>
20#include <linux/mmc/host.h>
20#include <linux/mmc/sdio_func.h> 21#include <linux/mmc/sdio_func.h>
21 22
22#include "sdio_cis.h" 23#include "sdio_cis.h"
@@ -132,9 +133,11 @@ static int sdio_bus_probe(struct device *dev)
132 * it should call pm_runtime_put_noidle() in its probe routine and 133 * it should call pm_runtime_put_noidle() in its probe routine and
133 * pm_runtime_get_noresume() in its remove routine. 134 * pm_runtime_get_noresume() in its remove routine.
134 */ 135 */
135 ret = pm_runtime_get_sync(dev); 136 if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) {
136 if (ret < 0) 137 ret = pm_runtime_get_sync(dev);
137 goto out; 138 if (ret < 0)
139 goto out;
140 }
138 141
139 /* Set the default block size so the driver is sure it's something 142 /* Set the default block size so the driver is sure it's something
140 * sensible. */ 143 * sensible. */
@@ -151,7 +154,8 @@ static int sdio_bus_probe(struct device *dev)
151 return 0; 154 return 0;
152 155
153disable_runtimepm: 156disable_runtimepm:
154 pm_runtime_put_noidle(dev); 157 if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
158 pm_runtime_put_noidle(dev);
155out: 159out:
156 return ret; 160 return ret;
157} 161}
@@ -160,12 +164,14 @@ static int sdio_bus_remove(struct device *dev)
160{ 164{
161 struct sdio_driver *drv = to_sdio_driver(dev->driver); 165 struct sdio_driver *drv = to_sdio_driver(dev->driver);
162 struct sdio_func *func = dev_to_sdio_func(dev); 166 struct sdio_func *func = dev_to_sdio_func(dev);
163 int ret; 167 int ret = 0;
164 168
165 /* Make sure card is powered before invoking ->remove() */ 169 /* Make sure card is powered before invoking ->remove() */
166 ret = pm_runtime_get_sync(dev); 170 if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) {
167 if (ret < 0) 171 ret = pm_runtime_get_sync(dev);
168 goto out; 172 if (ret < 0)
173 goto out;
174 }
169 175
170 drv->remove(func); 176 drv->remove(func);
171 177
@@ -178,10 +184,12 @@ static int sdio_bus_remove(struct device *dev)
178 } 184 }
179 185
180 /* First, undo the increment made directly above */ 186 /* First, undo the increment made directly above */
181 pm_runtime_put_noidle(dev); 187 if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
188 pm_runtime_put_noidle(dev);
182 189
183 /* Then undo the runtime PM settings in sdio_bus_probe() */ 190 /* Then undo the runtime PM settings in sdio_bus_probe() */
184 pm_runtime_put_noidle(dev); 191 if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
192 pm_runtime_put_noidle(dev);
185 193
186out: 194out:
187 return ret; 195 return ret;
@@ -191,6 +199,8 @@ out:
191 199
192static int sdio_bus_pm_prepare(struct device *dev) 200static int sdio_bus_pm_prepare(struct device *dev)
193{ 201{
202 struct sdio_func *func = dev_to_sdio_func(dev);
203
194 /* 204 /*
195 * Resume an SDIO device which was suspended at run time at this 205 * Resume an SDIO device which was suspended at run time at this
196 * point, in order to allow standard SDIO suspend/resume paths 206 * point, in order to allow standard SDIO suspend/resume paths
@@ -212,7 +222,8 @@ static int sdio_bus_pm_prepare(struct device *dev)
212 * since there is little point in failing system suspend if a 222 * since there is little point in failing system suspend if a
213 * device can't be resumed. 223 * device can't be resumed.
214 */ 224 */
215 pm_runtime_resume(dev); 225 if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
226 pm_runtime_resume(dev);
216 227
217 return 0; 228 return 0;
218} 229}