Received: by 2002:a05:6a10:af89:0:0:0:0 with SMTP id iu9csp5365827pxb; Wed, 19 Jan 2022 17:10:40 -0800 (PST) X-Google-Smtp-Source: ABdhPJxnqlptPd34Drm0ecOsMs6yzacWmWXn2t3d/6erprg6C89gKhLe1UBJ02jvRziwxPwG2T9T X-Received: by 2002:a17:90b:1b45:: with SMTP id nv5mr7654573pjb.142.1642641039950; Wed, 19 Jan 2022 17:10:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1642641039; cv=none; d=google.com; s=arc-20160816; b=hOsYA3NFFT3lmEZaWWL3CM5n2oYDe9Pci5GPBdQ5GtjAkI1YLkoJ+vDTyMiMgjqdfJ YDVnTMuK9gr3Nbkz7RWd4aCHOCVJV638APw7qTl5UY9f6Emfeh/AFgtM0LOF9jI2gcua iGbicYqcP8DGAtrxyEGFcW3Xi9tmD8RBDgNvmKGdlCbrnRrxmjJNasTDOS5xj8yDfHTZ 2hzIlGiKSxSYZJMT+ko1Juqb1lEKeYRmpqSr0O7vB/2Td9+ZZ19nsRqKUPwPf+fTzfia OVKbP1rYJmMgjXQ06sK9Tqa7cG/c8uZLKySMexwTM+QXyZwXvjaQ1bYqE06TqHBUF8XR PKQg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:message-id:subject:cc:to:from:date; bh=n1HgFllEBi7OAcPpbybPWmgGjn2tqcqo53zOTD+hs+U=; b=j/+dQoOgouibEoDIo5FisKkhHyFA84zH129bzL0W1EqHJVO6Z8H6rCCSRiC/NiKRXq s4sdUqxhmS4l0zP3ORzxn6YXrZ+gt5WXWUM9f7ZFR8Y03rAxbP+oE9m+p05Jh4/IpsFk ZYi5worOxrQUjX4uFwcBUL5AcLr/G5megMipeg9Qd31hozd2k0HW1uGIkA/UfkO/zttH mp0kPgIHjPvQ7/aSMcEjdfanRyRQyVDu6sLiiKqgJSs+lU/Lb7Ux3Znt5i2LB/T+bLmj ThMohnZT7ZSWcoLfVZ+a4rgqLAL54hUgw5uapjg9EIyAT4rPulIMy9dn7S7AcEihTZkP 9Ncg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id e3si1584765pgc.62.2022.01.19.17.10.28; Wed, 19 Jan 2022 17:10:39 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231864AbiARJlI (ORCPT + 99 others); Tue, 18 Jan 2022 04:41:08 -0500 Received: from muru.com ([72.249.23.125]:51126 "EHLO muru.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229604AbiARJlH (ORCPT ); Tue, 18 Jan 2022 04:41:07 -0500 Received: from localhost (localhost [127.0.0.1]) by muru.com (Postfix) with ESMTPS id 0A9C280C0; Tue, 18 Jan 2022 09:41:54 +0000 (UTC) Date: Tue, 18 Jan 2022 11:41:03 +0200 From: Tony Lindgren To: Andy Shevchenko Cc: Johan Hovold , Greg Kroah-Hartman , Jiri Slaby , Sebastian Andrzej Siewior , Vignesh Raghavendra , linux-serial@vger.kernel.org, linux-omap@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH 1/7] serial: core: Add support of runtime PM Message-ID: References: <20211115084203.56478-1-tony@atomide.com> <20211115084203.56478-2-tony@atomide.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi, * Andy Shevchenko [211209 10:37]: > On Thu, Dec 09, 2021 at 09:29:44AM +0200, Tony Lindgren wrote: > > * Johan Hovold [211130 10:29]: > > > On Mon, Nov 15, 2021 at 10:41:57AM +0200, Tony Lindgren wrote: > > > > From: Andy Shevchenko > > > > > > > > 8250 driver has wrong implementation of runtime power management, i.e. > > > > it uses an irq_safe flag. The irq_safe flag takes a permanent usage count > > > > on the parent device preventing the parent from idling. This patch > > > > prepares for making runtime power management generic by adding runtime PM > > > > calls to serial core once for all UART drivers. > > > > > > > > As we have serial drivers that do not enable runtime PM, and drivers that > > > > enable runtime PM, we add new functions for serial_pm_resume_and_get() and > > > > serial_pm_autosuspend() functions to handle errors and allow the use also > > > > for cases when runtime PM is not enabled. The other option considered was > > > > to not check for runtime PM enable errors. But some CPUs can hang when the > > > > clocks are not enabled for the device, so ignoring the errors is not a good > > > > option. Eventually with the serial port drivers updated, we should be able > > > > to just switch to using the standard runtime PM calls with no need for the > > > > wrapper functions. > > > > > > A third option which needs to be considered is to always enable runtime > > > pm in core but to keep the ports active while they are opened unless a > > > driver opts in for more aggressive power management. This is how USB > > > devices are handled for example. > > > > > > A next step could then be to move over uart_change_pm() to be handled > > > from the pm callbacks. > > > > Yes that would be nice to do eventually :) I think we should do the "third option" above as the first preparatory patch. It can be done separately from the rest of the series, and we avoid adding serial layer specific wrappers around runtime PM calls in the later patches. Below is what I came up with for the preparatory patch, can you guys please take a look and see if you have better ideas? For system suspend and resume, it seems we don't need to do anything as runtime PM is anyways disabled already in prepare. Andy, care to give the following also a try for your serial port test cases? Regards, Tony 8< -------------------- diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -997,6 +997,7 @@ int serial8250_register_8250_port(const struct uart_8250_port *up) uart->port.regshift = up->port.regshift; uart->port.iotype = up->port.iotype; uart->port.flags = up->port.flags | UPF_BOOT_AUTOCONF; + uart->port.supports_autosuspend = up->port.supports_autosuspend; uart->bugs = up->bugs; uart->port.mapbase = up->port.mapbase; uart->port.mapsize = up->port.mapsize; diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -1352,6 +1352,7 @@ static int omap8250_probe(struct platform_device *pdev) up.rs485_start_tx = serial8250_em485_start_tx; up.rs485_stop_tx = serial8250_em485_stop_tx; up.port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_8250_CONSOLE); + up.port.supports_autosuspend = 1; ret = of_alias_get_id(np, "serial"); if (ret < 0) { diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -184,6 +185,7 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, int init_hw) { struct uart_port *uport = uart_port_check(state); + struct device *dev = uport->dev; unsigned long flags; unsigned long page; int retval = 0; @@ -191,6 +193,32 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, if (uport->type == PORT_UNKNOWN) return 1; + /* Always enable autosuspend and consider child devices for serdev */ + pm_runtime_use_autosuspend(dev); + pm_suspend_ignore_children(dev, false); + + /* + * If the port driver did not enable runtime PM in probe, do it now. + * Devices that did not enable runtime PM get set active so we can + * properly handler the returned errors for runtime PM calls. + */ + if (!pm_runtime_enabled(dev)) { + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + } else { + uport->implements_pm_runtime = 1; + } + + /* + * Keep the port enabled unless autosuspend is supported. + * Released in uart_shutdown(). + */ + if (!uport->supports_autosuspend) { + retval = pm_runtime_resume_and_get(dev); + if (retval < 0) + return retval; + } + /* * Make sure the device is in D0 state. */ @@ -279,6 +307,7 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state) { struct uart_port *uport = uart_port_check(state); struct tty_port *port = &state->port; + struct device *dev = uport->dev; unsigned long flags; char *xmit_buf = NULL; @@ -313,6 +342,19 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state) */ tty_port_set_suspended(port, 0); + /* Runtime PM paired with configuration done in uart_port_startup() */ + if (uport) { + dev = uport->dev; + pm_runtime_dont_use_autosuspend(dev); + pm_suspend_ignore_children(dev, true); + if (!uport->supports_autosuspend) + pm_runtime_put_sync(dev); + if (!uport->implements_pm_runtime) { + pm_runtime_set_suspended(dev); + pm_runtime_disable(dev); + } + } + /* * Do not free() the transmit buffer page under the port lock since * this can create various circular locking scenarios. For instance, diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -249,6 +249,8 @@ struct uart_port { unsigned char hub6; /* this should be in the 8250 driver */ unsigned char suspended; unsigned char console_reinit; + unsigned long implements_pm_runtime:1; + unsigned long supports_autosuspend:1; const char *name; /* port name */ struct attribute_group *attr_group; /* port specific attributes */ const struct attribute_group **tty_groups; /* all attributes (serial core use only) */ -- 2.34.1