Commit 5ee469cecc8e73d3d871d02acc863cbf6a9b9c8e

Authored by Rafael J. Wysocki
Committed by Greg Kroah-Hartman
1 parent 2efbdf28a6

mmc: sdio: Use empty system suspend/resume callbacks at the bus level

commit e841a7c69b708eeaf784fd517978006e8319b03a upstream.

Neil Brown reports that commit 35cd133c

   PM: Run the driver callback directly if the subsystem one is not there

breaks suspend for his libertas wifi, because SDIO has a protocol
where the suspend method can return -ENOSYS and this means "There is
no point in suspending, just turn me off".  Moreover, the suspend
methods provided by SDIO drivers are not supposed to be called by
the PM core or bus-level suspend routines (which aren't presend for
SDIO).  Instead, when the SDIO core gets to suspend the device's
ancestor, it calls the device driver's suspend function, catches the
ENOSYS, and turns the device off.

The commit above breaks the SDIO core's assumption that the device
drivers' callbacks won't be executed if it doesn't provide any
bus-level callbacks.  If fact, however, this assumption has never
been really satisfied, because device class or device type suspend
might very well use the driver's callback even without that commit.

The simplest way to address this problem is to make the SDIO core
tell the PM core to ignore driver callbacks, for example by providing
no-operation suspend/resume callbacks at the bus level for it,
which is implemented by this change.

Reported-and-tested-by: Neil Brown <neilb@suse.de>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Chris Ball <cjb@laptop.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Showing 1 changed file with 9 additions and 3 deletions Side-by-side Diff

drivers/mmc/core/sdio_bus.c
... ... @@ -192,9 +192,15 @@
192 192 return ret;
193 193 }
194 194  
195   -#ifdef CONFIG_PM_RUNTIME
  195 +#ifdef CONFIG_PM
196 196  
  197 +static int pm_no_operation(struct device *dev)
  198 +{
  199 + return 0;
  200 +}
  201 +
197 202 static const struct dev_pm_ops sdio_bus_pm_ops = {
  203 + SET_SYSTEM_SLEEP_PM_OPS(pm_no_operation, pm_no_operation)
198 204 SET_RUNTIME_PM_OPS(
199 205 pm_generic_runtime_suspend,
200 206 pm_generic_runtime_resume,
201 207  
... ... @@ -204,11 +210,11 @@
204 210  
205 211 #define SDIO_PM_OPS_PTR (&sdio_bus_pm_ops)
206 212  
207   -#else /* !CONFIG_PM_RUNTIME */
  213 +#else /* !CONFIG_PM */
208 214  
209 215 #define SDIO_PM_OPS_PTR NULL
210 216  
211   -#endif /* !CONFIG_PM_RUNTIME */
  217 +#endif /* !CONFIG_PM */
212 218  
213 219 static struct bus_type sdio_bus_type = {
214 220 .name = "sdio",