All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andy Shevchenko <andriy.shevchenko@intel.com>
To: Tony Lindgren <tony@atomide.com>
Cc: "Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	"Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>,
	"Jiri Slaby" <jirislaby@kernel.org>,
	"Johan Hovold" <johan@kernel.org>,
	"Sebastian Andrzej Siewior" <bigeasy@linutronix.de>,
	"Vignesh Raghavendra" <vigneshr@ti.com>,
	linux-serial@vger.kernel.org, linux-omap@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] serial: core: Start managing serial controllers to enable runtime PM
Date: Mon, 11 Apr 2022 16:25:33 +0300	[thread overview]
Message-ID: <YlQsTWcM3is9TGdw@smile.fi.intel.com> (raw)
In-Reply-To: <20220411120218.17422-1-tony@atomide.com>

On Mon, Apr 11, 2022 at 03:02:18PM +0300, Tony Lindgren wrote:
> We want to enable runtime PM for serial port device drivers in a generic
> way. To do this, we want to have the serial core layer manage the
> registered serial port controllers. For runtime PM, we need a way to find
> the serial ports for each serial port controller device.
> 
> The serial core manages ports. Each serial controller can have multiple
> ports. As serial core has no struct device, and the serial port device
> drivers have their own driver data, we cannot currently start making
> use of serial core generic data easily without changing all the serial
> port device drivers.
> 
> We could consider adding a serial core specific struct device. It would
> be a child of the serial port device, and would allow us eventually to use
> device_links to add generic runtime PM calls for example. But as the serial
> core layer is not a device driver, driver specific features would need to
> be added, and are probably not justified for a virtual device.
> 
> Considering the above, let's improve the serial core layer so we can
> manage the serial port controllers better. Let's register the controllers
> with the serial core layer in addition to the serial ports.
> 
> To find the serial ports for a controller based on struct device, let's
> add a new data structure for a serial_controller. Let's add the registered
> devices into a radix_tree so we can look up the controller easily even
> with many controllers registered. This allows us to keep track of the
> runtime PM state for each serial port controller device.
> 
> As some serial port device drivers enable runtime PM in their probe before
> registering with the serial core layer, and some do not enable runtime PM
> at all currently, we need check the state in the serial core layer on
> uart_port_startup(). We need to also consider that a serial port device
> may have multiple ports.
> 
> Initially we just want to enable runtime PM for all the serial port
> controller devices. This allows us to add runtime PM calls and properly
> handle any errors without a need for serial layer specific runtime PM
> wrapper functions.
> 
> After this patch no functional changes for the serial port device drivers
> are intended. For most cases, we just enable runtime PM and keep the
> runtime PM usage count until all the serial controller ports are
> unregistered. For drivers implementing runtime PM, we just keep track of
> the configuration.
> 
> The serial core layer has the following use cases to deal with:
> 
> - If a serial port device driver does not implement runtime PM, the
>   device state is set to active state, and the runtime PM usage count
>   is kept until the last port for a device is unregistered
> 
> - If a serial port device driver implements runtime PM, the runtime PM
>   usage count is kept until the last port for the device is unregistered
> 
> - If a serial port device driver implements runtime PM autosuspend,
>   autosuspend is not prevented. This currently gets set only for the
>   8250_omap driver to keep runtime PM working for it
> 
> For system suspend, things should be mostly detached from the runtime PM.
> The serial port device drivers may call pm_runtime_force_suspend() and
> pm_runtime_force_resume() as needed.

...

> +struct serial_controller {
> +	struct uart_driver *drv;		/* For port specific uart_state */

> +	struct mutex lock;			/* For changing enabled_count */
> +	int enabled_count;			/* Enable count for runtime PM */

Wondering if we may use kref instead which will check for saturation as well.

> +	unsigned long implements_pm_runtime:1;
> +	unsigned long supports_autosuspend:1;
> +};

...

> +		WARN_ON(port->supports_autosuspend !=
> +			controller->supports_autosuspend);

One line?


...

> +	controller = kzalloc(sizeof(*controller), GFP_KERNEL);
> +	if (!controller)
> +		return -ENOMEM;
> +
> +	mutex_init(&controller->lock);
> +	controller->drv = drv;
> +	controller->supports_autosuspend = port->supports_autosuspend;
> +	port->state->controller = controller;
> +
> +	return radix_tree_insert(&serial_core_devices, idx, controller);

Hmm... Memory leak at error?


...

> +	if (!idx)
> +		return;

Do you really need this?

> +	controller = radix_tree_lookup(&serial_core_devices, idx);
> +	if (!controller)
> +		return;

...and/or this?

> +	controller = radix_tree_delete(&serial_core_devices, idx);
> +	if (!controller)
> +		return;

...

> +	struct device *dev = port->dev;

I would split assignment to be closer to first user...

...

...somewhere here.

> +	if (!dev)
> +		return 0;

...

> +	struct serial_controller *controller;
> +	struct device *dev = port->dev;
> +	struct uart_state *state;

> +	if (!dev)
> +		return;

Ditto.

...

>  	unsigned char		hub6;			/* this should be in the 8250 driver */
>  	unsigned char		suspended;
>  	unsigned char		console_reinit;
> +	unsigned long		supports_autosuspend:1;

Hmm... Maybe use unsigned char and convert all of them to something else if needed?

-- 
With Best Regards,
Andy Shevchenko



  reply	other threads:[~2022-04-11 13:29 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-11 12:02 [PATCH] serial: core: Start managing serial controllers to enable runtime PM Tony Lindgren
2022-04-11 13:25 ` Andy Shevchenko [this message]
2022-04-11 13:51   ` Tony Lindgren
2022-04-11 14:02   ` Tony Lindgren

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YlQsTWcM3is9TGdw@smile.fi.intel.com \
    --to=andriy.shevchenko@intel.com \
    --cc=bigeasy@linutronix.de \
    --cc=gregkh@linuxfoundation.org \
    --cc=ilpo.jarvinen@linux.intel.com \
    --cc=jirislaby@kernel.org \
    --cc=johan@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=linux-serial@vger.kernel.org \
    --cc=tony@atomide.com \
    --cc=vigneshr@ti.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.