diff options
author | Geert Uytterhoeven <geert+renesas@glider.be> | 2018-09-05 04:49:38 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2018-09-05 07:40:06 -0400 |
commit | c1ca59c22c56930b377a665fdd1b43351887830b (patch) | |
tree | 8a20b9aa37193e855d08b24bd009c7b7f1d5962a | |
parent | 31a5fae4c5a009898da6d177901d5328051641ff (diff) |
spi: rspi: Fix invalid SPI use during system suspend
If the SPI queue is running during system suspend, the system may lock
up.
Fix this by stopping/restarting the queue during system suspend/resume,
by calling spi_master_suspend()/spi_master_resume() from the PM
callbacks. In-kernel users will receive an -ESHUTDOWN error while
system suspend/resume is in progress.
Based on a patch for sh-msiof by Gaku Inami.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Mark Brown <broonie@kernel.org>
Cc: stable@vger.kernel.org
-rw-r--r-- | drivers/spi/spi-rspi.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 95dc4d78618d..f93a4587e3fb 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c | |||
@@ -1350,12 +1350,36 @@ static const struct platform_device_id spi_driver_ids[] = { | |||
1350 | 1350 | ||
1351 | MODULE_DEVICE_TABLE(platform, spi_driver_ids); | 1351 | MODULE_DEVICE_TABLE(platform, spi_driver_ids); |
1352 | 1352 | ||
1353 | #ifdef CONFIG_PM_SLEEP | ||
1354 | static int rspi_suspend(struct device *dev) | ||
1355 | { | ||
1356 | struct platform_device *pdev = to_platform_device(dev); | ||
1357 | struct rspi_data *rspi = platform_get_drvdata(pdev); | ||
1358 | |||
1359 | return spi_master_suspend(rspi->master); | ||
1360 | } | ||
1361 | |||
1362 | static int rspi_resume(struct device *dev) | ||
1363 | { | ||
1364 | struct platform_device *pdev = to_platform_device(dev); | ||
1365 | struct rspi_data *rspi = platform_get_drvdata(pdev); | ||
1366 | |||
1367 | return spi_master_resume(rspi->master); | ||
1368 | } | ||
1369 | |||
1370 | static SIMPLE_DEV_PM_OPS(rspi_pm_ops, rspi_suspend, rspi_resume); | ||
1371 | #define DEV_PM_OPS &rspi_pm_ops | ||
1372 | #else | ||
1373 | #define DEV_PM_OPS NULL | ||
1374 | #endif /* CONFIG_PM_SLEEP */ | ||
1375 | |||
1353 | static struct platform_driver rspi_driver = { | 1376 | static struct platform_driver rspi_driver = { |
1354 | .probe = rspi_probe, | 1377 | .probe = rspi_probe, |
1355 | .remove = rspi_remove, | 1378 | .remove = rspi_remove, |
1356 | .id_table = spi_driver_ids, | 1379 | .id_table = spi_driver_ids, |
1357 | .driver = { | 1380 | .driver = { |
1358 | .name = "renesas_spi", | 1381 | .name = "renesas_spi", |
1382 | .pm = DEV_PM_OPS, | ||
1359 | .of_match_table = of_match_ptr(rspi_of_match), | 1383 | .of_match_table = of_match_ptr(rspi_of_match), |
1360 | }, | 1384 | }, |
1361 | }; | 1385 | }; |