summaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorStefan Wahren <wahrenst@gmx.net>2024-07-28 15:00:28 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-07-31 12:34:51 +0200
commit0e1d8780526f4bc683699348d0c765ca78ae37bb (patch)
tree91c9a46953465772a144a653e58f04dae6b4ef9f /drivers/tty
parentarm64: dts: mediatek: mt7981: add UART controllers (diff)
downloadlinux-0e1d8780526f4bc683699348d0c765ca78ae37bb.tar.xz
linux-0e1d8780526f4bc683699348d0c765ca78ae37bb.zip
serial: 8250_bcm2835aux: add PM suspend/resume support
This adds suspend/resume support for the 8250_bcm2835aux driver to provide power management support on attached devices. Signed-off-by: Stefan Wahren <wahrenst@gmx.net> Link: https://lore.kernel.org/r/20240728130029.78279-7-wahrenst@gmx.net Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/8250/8250_bcm2835aux.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/drivers/tty/serial/8250/8250_bcm2835aux.c b/drivers/tty/serial/8250/8250_bcm2835aux.c
index 121a5ce86050..36e2bb34d82b 100644
--- a/drivers/tty/serial/8250/8250_bcm2835aux.c
+++ b/drivers/tty/serial/8250/8250_bcm2835aux.c
@@ -13,6 +13,7 @@
*/
#include <linux/clk.h>
+#include <linux/console.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
@@ -213,11 +214,47 @@ static const struct acpi_device_id bcm2835aux_serial_acpi_match[] = {
};
MODULE_DEVICE_TABLE(acpi, bcm2835aux_serial_acpi_match);
+static int bcm2835aux_suspend(struct device *dev)
+{
+ struct bcm2835aux_data *data = dev_get_drvdata(dev);
+ struct uart_8250_port *up = serial8250_get_port(data->line);
+
+ serial8250_suspend_port(data->line);
+
+ if (device_may_wakeup(dev))
+ return 0;
+
+ if (uart_console(&up->port) && !console_suspend_enabled)
+ return 0;
+
+ clk_disable_unprepare(data->clk);
+ return 0;
+}
+
+static int bcm2835aux_resume(struct device *dev)
+{
+ struct bcm2835aux_data *data = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_prepare_enable(data->clk);
+ if (ret)
+ return ret;
+
+ serial8250_resume_port(data->line);
+
+ return 0;
+}
+
+static const struct dev_pm_ops bcm2835aux_dev_pm_ops = {
+ SYSTEM_SLEEP_PM_OPS(bcm2835aux_suspend, bcm2835aux_resume)
+};
+
static struct platform_driver bcm2835aux_serial_driver = {
.driver = {
.name = "bcm2835-aux-uart",
.of_match_table = bcm2835aux_serial_match,
.acpi_match_table = bcm2835aux_serial_acpi_match,
+ .pm = pm_ptr(&bcm2835aux_dev_pm_ops),
},
.probe = bcm2835aux_serial_probe,
.remove_new = bcm2835aux_serial_remove,