Message ID | 20240728130029.78279-7-wahrenst@gmx.net |
---|---|
State | New |
Headers | show |
Series | ARM: bcm2835: Implement initial S2Idle for Raspberry Pi | expand |
On Sun, 28 Jul 2024 at 15:07, Stefan Wahren <wahrenst@gmx.net> wrote: > > 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> > --- > drivers/tty/serial/8250/8250_bcm2835aux.c | 37 +++++++++++++++++++++++ > 1 file changed, 37 insertions(+) > > 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); Doesn't this create clk prepare/enable - unprepare/disable imbalance problem when the uart is configured for system wakeup? > + 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, > -- > 2.34.1 > Kind regards Uffe
Am 14.08.24 um 14:18 schrieb Ulf Hansson: > On Sun, 28 Jul 2024 at 15:07, Stefan Wahren <wahrenst@gmx.net> wrote: >> 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> >> --- >> drivers/tty/serial/8250/8250_bcm2835aux.c | 37 +++++++++++++++++++++++ >> 1 file changed, 37 insertions(+) >> >> 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); > Doesn't this create clk prepare/enable - unprepare/disable imbalance > problem when the uart is configured for system wakeup? Thanks, i will send a follow-up Regards > >> + 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, >> -- >> 2.34.1 >> > Kind regards > Uffe >
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,
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> --- drivers/tty/serial/8250/8250_bcm2835aux.c | 37 +++++++++++++++++++++++ 1 file changed, 37 insertions(+) -- 2.34.1