71 lines
2.1 KiB
Diff
71 lines
2.1 KiB
Diff
|
From 3e1c4ac8f93cc6350d1344e669a2a5bf9caac9e7 Mon Sep 17 00:00:00 2001
|
||
|
From: Samuel Holland <samuel@sholland.org>
|
||
|
Date: Mon, 30 Dec 2019 22:50:02 -0600
|
||
|
Subject: [PATCH 155/351] bus: sunxi-rsb: Implement global suspend/resume
|
||
|
callbacks
|
||
|
|
||
|
Since system firmware is likely to use the RSB bus to communicate with a
|
||
|
PMIC while the system is suspended, we cannot make any assumptions about
|
||
|
the controller state after resuming. Thus it is important to completely
|
||
|
reinitialize the controller.
|
||
|
|
||
|
The RSB bus needs to be ready as soon as IRQs are enabled, to handle
|
||
|
wakeup event IRQs coming from the PMIC. Thus it uses NOIRQ callbacks.
|
||
|
|
||
|
Signed-off-by: Samuel Holland <samuel@sholland.org>
|
||
|
---
|
||
|
drivers/bus/sunxi-rsb.c | 22 +++++++++++++++++++++-
|
||
|
1 file changed, 21 insertions(+), 1 deletion(-)
|
||
|
|
||
|
diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c
|
||
|
index 1795ad7f0bfe..19b8ee47a47a 100644
|
||
|
--- a/drivers/bus/sunxi-rsb.c
|
||
|
+++ b/drivers/bus/sunxi-rsb.c
|
||
|
@@ -45,6 +45,7 @@
|
||
|
#include <linux/of_irq.h>
|
||
|
#include <linux/of_platform.h>
|
||
|
#include <linux/platform_device.h>
|
||
|
+#include <linux/pm.h>
|
||
|
#include <linux/regmap.h>
|
||
|
#include <linux/reset.h>
|
||
|
#include <linux/slab.h>
|
||
|
@@ -648,6 +649,24 @@ static int sunxi_rsb_exit_controller(struct sunxi_rsb *rsb)
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+static int __maybe_unused sunxi_rsb_suspend(struct device *dev)
|
||
|
+{
|
||
|
+ struct sunxi_rsb *rsb = dev_get_drvdata(dev);
|
||
|
+
|
||
|
+ return sunxi_rsb_exit_controller(rsb);
|
||
|
+}
|
||
|
+
|
||
|
+static int __maybe_unused sunxi_rsb_resume(struct device *dev)
|
||
|
+{
|
||
|
+ struct sunxi_rsb *rsb = dev_get_drvdata(dev);
|
||
|
+
|
||
|
+ return sunxi_rsb_init_controller(rsb);
|
||
|
+}
|
||
|
+
|
||
|
+static const struct dev_pm_ops sunxi_rsb_dev_pm_ops = {
|
||
|
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(sunxi_rsb_suspend, sunxi_rsb_resume)
|
||
|
+};
|
||
|
+
|
||
|
static int sunxi_rsb_probe(struct platform_device *pdev)
|
||
|
{
|
||
|
struct device *dev = &pdev->dev;
|
||
|
@@ -738,8 +757,9 @@ static struct platform_driver sunxi_rsb_driver = {
|
||
|
.probe = sunxi_rsb_probe,
|
||
|
.remove = sunxi_rsb_remove,
|
||
|
.driver = {
|
||
|
- .name = RSB_CTRL_NAME,
|
||
|
+ .name = RSB_CTRL_NAME,
|
||
|
.of_match_table = sunxi_rsb_of_match_table,
|
||
|
+ .pm = &sunxi_rsb_dev_pm_ops,
|
||
|
},
|
||
|
};
|
||
|
|
||
|
--
|
||
|
2.34.0
|
||
|
|