in serial/8250/8250_omap.c [1283:1469]
static int omap8250_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct omap8250_priv *priv;
const struct omap8250_platdata *pdata;
struct uart_8250_port up;
struct resource *regs;
void __iomem *membase;
int irq, ret;
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!regs) {
dev_err(&pdev->dev, "missing registers\n");
return -EINVAL;
}
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
membase = devm_ioremap(&pdev->dev, regs->start,
resource_size(regs));
if (!membase)
return -ENODEV;
memset(&up, 0, sizeof(up));
up.port.dev = &pdev->dev;
up.port.mapbase = regs->start;
up.port.membase = membase;
up.port.irq = irq;
/*
* It claims to be 16C750 compatible however it is a little different.
* It has EFR and has no FCR7_64byte bit. The AFE (which it claims to
* have) is enabled via EFR instead of MCR. The type is set here 8250
* just to get things going. UNKNOWN does not work for a few reasons and
* we don't need our own type since we don't use 8250's set_termios()
* or pm callback.
*/
up.port.type = PORT_8250;
up.port.iotype = UPIO_MEM;
up.port.flags = UPF_FIXED_PORT | UPF_FIXED_TYPE | UPF_SOFT_FLOW |
UPF_HARD_FLOW;
up.port.private_data = priv;
up.port.regshift = 2;
up.port.fifosize = 64;
up.tx_loadsz = 64;
up.capabilities = UART_CAP_FIFO;
#ifdef CONFIG_PM
/*
* Runtime PM is mostly transparent. However to do it right we need to a
* TX empty interrupt before we can put the device to auto idle. So if
* PM is not enabled we don't add that flag and can spare that one extra
* interrupt in the TX path.
*/
up.capabilities |= UART_CAP_RPM;
#endif
up.port.set_termios = omap_8250_set_termios;
up.port.set_mctrl = omap8250_set_mctrl;
up.port.pm = omap_8250_pm;
up.port.startup = omap_8250_startup;
up.port.shutdown = omap_8250_shutdown;
up.port.throttle = omap_8250_throttle;
up.port.unthrottle = omap_8250_unthrottle;
up.port.rs485_config = serial8250_em485_config;
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);
ret = of_alias_get_id(np, "serial");
if (ret < 0) {
dev_err(&pdev->dev, "failed to get alias\n");
return ret;
}
up.port.line = ret;
if (of_property_read_u32(np, "clock-frequency", &up.port.uartclk)) {
struct clk *clk;
clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(clk)) {
if (PTR_ERR(clk) == -EPROBE_DEFER)
return -EPROBE_DEFER;
} else {
up.port.uartclk = clk_get_rate(clk);
}
}
if (of_property_read_u32(np, "overrun-throttle-ms",
&up.overrun_backoff_time_ms) != 0)
up.overrun_backoff_time_ms = 0;
priv->wakeirq = irq_of_parse_and_map(np, 1);
pdata = of_device_get_match_data(&pdev->dev);
if (pdata)
priv->habit |= pdata->habit;
if (!up.port.uartclk) {
up.port.uartclk = DEFAULT_CLK_SPEED;
dev_warn(&pdev->dev,
"No clock speed specified: using default: %d\n",
DEFAULT_CLK_SPEED);
}
priv->latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE;
priv->calc_latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE;
cpu_latency_qos_add_request(&priv->pm_qos_request, priv->latency);
INIT_WORK(&priv->qos_work, omap8250_uart_qos_work);
spin_lock_init(&priv->rx_dma_lock);
device_init_wakeup(&pdev->dev, true);
pm_runtime_enable(&pdev->dev);
pm_runtime_use_autosuspend(&pdev->dev);
/*
* Disable runtime PM until autosuspend delay unless specifically
* enabled by the user via sysfs. This is the historic way to
* prevent an unsafe default policy with lossy characters on wake-up.
* For serdev devices this is not needed, the policy can be managed by
* the serdev driver.
*/
if (!of_get_available_child_count(pdev->dev.of_node))
pm_runtime_set_autosuspend_delay(&pdev->dev, -1);
pm_runtime_irq_safe(&pdev->dev);
pm_runtime_get_sync(&pdev->dev);
omap_serial_fill_features_erratas(&up, priv);
up.port.handle_irq = omap8250_no_handle_irq;
priv->rx_trigger = RX_TRIGGER;
priv->tx_trigger = TX_TRIGGER;
#ifdef CONFIG_SERIAL_8250_DMA
/*
* Oh DMA support. If there are no DMA properties in the DT then
* we will fall back to a generic DMA channel which does not
* really work here. To ensure that we do not get a generic DMA
* channel assigned, we have the the_no_dma_filter_fn() here.
* To avoid "failed to request DMA" messages we check for DMA
* properties in DT.
*/
ret = of_property_count_strings(np, "dma-names");
if (ret == 2) {
struct omap8250_dma_params *dma_params = NULL;
up.dma = &priv->omap8250_dma;
up.dma->fn = the_no_dma_filter_fn;
up.dma->tx_dma = omap_8250_tx_dma;
up.dma->rx_dma = omap_8250_rx_dma;
if (pdata)
dma_params = pdata->dma_params;
if (dma_params) {
up.dma->rx_size = dma_params->rx_size;
up.dma->rxconf.src_maxburst = dma_params->rx_trigger;
up.dma->txconf.dst_maxburst = dma_params->tx_trigger;
priv->rx_trigger = dma_params->rx_trigger;
priv->tx_trigger = dma_params->tx_trigger;
} else {
up.dma->rx_size = RX_TRIGGER;
up.dma->rxconf.src_maxburst = RX_TRIGGER;
up.dma->txconf.dst_maxburst = TX_TRIGGER;
}
}
#endif
ret = serial8250_register_8250_port(&up);
if (ret < 0) {
dev_err(&pdev->dev, "unable to register 8250 port\n");
goto err;
}
priv->line = ret;
platform_set_drvdata(pdev, priv);
pm_runtime_mark_last_busy(&pdev->dev);
pm_runtime_put_autosuspend(&pdev->dev);
return 0;
err:
pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
return ret;
}