Commit db86bb6e authored by Tony Lindgren's avatar Tony Lindgren Committed by Greg Kroah-Hartman

serial: 8250: omap: Shut down on remove for console uart

When unbinding the console uart, we want to power down the uart hardware
on remove. For the console uart, the normal shutdown path will never get
called as the cons_filp stays open. Let's rearrange the dma related
functions a bit so we can call driver shutdown also on console uart rebind.

Currently we set up->dma on probe, but that causes issues calling
omap_8250_shutdown() on remove. The dma startup will not get called on
the next rebind as we still have up->dma set from probe.

Note that serial8250_release_dma() already checks for dma so we can
remove the check for it in 8205_omap driver.

With these changes we also avoid hogging dma virtual channels for the
unused uarts that may be limited on some devices.
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
Link: https://lore.kernel.org/r/20230508082014.23083-5-tony@atomide.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent fef4f600
...@@ -679,6 +679,7 @@ static int omap_8250_startup(struct uart_port *port) ...@@ -679,6 +679,7 @@ static int omap_8250_startup(struct uart_port *port)
{ {
struct uart_8250_port *up = up_to_u8250p(port); struct uart_8250_port *up = up_to_u8250p(port);
struct omap8250_priv *priv = port->private_data; struct omap8250_priv *priv = port->private_data;
struct uart_8250_dma *dma = &priv->omap8250_dma;
int ret; int ret;
if (priv->wakeirq) { if (priv->wakeirq) {
...@@ -697,16 +698,16 @@ static int omap_8250_startup(struct uart_port *port) ...@@ -697,16 +698,16 @@ static int omap_8250_startup(struct uart_port *port)
up->msr_saved_flags = 0; up->msr_saved_flags = 0;
/* Disable DMA for console UART */ /* Disable DMA for console UART */
if (uart_console(port)) if (dma->fn && !uart_console(port)) {
up->dma = NULL; up->dma = &priv->omap8250_dma;
if (up->dma) {
ret = serial8250_request_dma(up); ret = serial8250_request_dma(up);
if (ret) { if (ret) {
dev_warn_ratelimited(port->dev, dev_warn_ratelimited(port->dev,
"failed to request DMA\n"); "failed to request DMA\n");
up->dma = NULL; up->dma = NULL;
} }
} else {
up->dma = NULL;
} }
up->ier = UART_IER_RLSI | UART_IER_RDI; up->ier = UART_IER_RLSI | UART_IER_RDI;
...@@ -752,8 +753,8 @@ static void omap_8250_shutdown(struct uart_port *port) ...@@ -752,8 +753,8 @@ static void omap_8250_shutdown(struct uart_port *port)
disable_irq_nosync(up->port.irq); disable_irq_nosync(up->port.irq);
dev_pm_clear_wake_irq(port->dev); dev_pm_clear_wake_irq(port->dev);
if (up->dma) serial8250_release_dma(up);
serial8250_release_dma(up); up->dma = NULL;
/* /*
* Disable break condition and FIFOs * Disable break condition and FIFOs
...@@ -1499,24 +1500,24 @@ static int omap8250_probe(struct platform_device *pdev) ...@@ -1499,24 +1500,24 @@ static int omap8250_probe(struct platform_device *pdev)
ret = of_property_count_strings(np, "dma-names"); ret = of_property_count_strings(np, "dma-names");
if (ret == 2) { if (ret == 2) {
struct omap8250_dma_params *dma_params = NULL; struct omap8250_dma_params *dma_params = NULL;
struct uart_8250_dma *dma = &priv->omap8250_dma;
up.dma = &priv->omap8250_dma; dma->fn = the_no_dma_filter_fn;
up.dma->fn = the_no_dma_filter_fn; dma->tx_dma = omap_8250_tx_dma;
up.dma->tx_dma = omap_8250_tx_dma; dma->rx_dma = omap_8250_rx_dma;
up.dma->rx_dma = omap_8250_rx_dma;
if (pdata) if (pdata)
dma_params = pdata->dma_params; dma_params = pdata->dma_params;
if (dma_params) { if (dma_params) {
up.dma->rx_size = dma_params->rx_size; dma->rx_size = dma_params->rx_size;
up.dma->rxconf.src_maxburst = dma_params->rx_trigger; dma->rxconf.src_maxburst = dma_params->rx_trigger;
up.dma->txconf.dst_maxburst = dma_params->tx_trigger; dma->txconf.dst_maxburst = dma_params->tx_trigger;
priv->rx_trigger = dma_params->rx_trigger; priv->rx_trigger = dma_params->rx_trigger;
priv->tx_trigger = dma_params->tx_trigger; priv->tx_trigger = dma_params->tx_trigger;
} else { } else {
up.dma->rx_size = RX_TRIGGER; dma->rx_size = RX_TRIGGER;
up.dma->rxconf.src_maxburst = RX_TRIGGER; dma->rxconf.src_maxburst = RX_TRIGGER;
up.dma->txconf.dst_maxburst = TX_TRIGGER; dma->txconf.dst_maxburst = TX_TRIGGER;
} }
} }
#endif #endif
...@@ -1550,12 +1551,15 @@ static int omap8250_probe(struct platform_device *pdev) ...@@ -1550,12 +1551,15 @@ static int omap8250_probe(struct platform_device *pdev)
static int omap8250_remove(struct platform_device *pdev) static int omap8250_remove(struct platform_device *pdev)
{ {
struct omap8250_priv *priv = platform_get_drvdata(pdev); struct omap8250_priv *priv = platform_get_drvdata(pdev);
struct uart_8250_port *up;
int err; int err;
err = pm_runtime_resume_and_get(&pdev->dev); err = pm_runtime_resume_and_get(&pdev->dev);
if (err) if (err)
return err; return err;
up = serial8250_get_port(priv->line);
omap_8250_shutdown(&up->port);
serial8250_unregister_port(priv->line); serial8250_unregister_port(priv->line);
priv->line = -ENODEV; priv->line = -ENODEV;
pm_runtime_dont_use_autosuspend(&pdev->dev); pm_runtime_dont_use_autosuspend(&pdev->dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment