static int dw8250_probe(struct platform_device *pdev) { struct uart_8250_port uart = {}; struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); struct dw8250_data *data; int err; if (!regs || !irq) { dev_err(&pdev->dev, "no registers/irq defined\n"); return -EINVAL; } spin_lock_init(&uart.port.lock); uart.port.mapbase = regs->start; uart.port.irq = irq->start; uart.port.handle_irq = dw8250_handle_irq; uart.port.pm = dw8250_do_pm; uart.port.type = PORT_8250; uart.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT; uart.port.dev = &pdev->dev; uart.port.membase = devm_ioremap(&pdev->dev, regs->start, resource_size(regs)); if (!uart.port.membase) return -ENOMEM; data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; data->clk = devm_clk_get(&pdev->dev, NULL); if (!IS_ERR(data->clk)) { clk_prepare_enable(data->clk); uart.port.uartclk = clk_get_rate(data->clk); } uart.port.iotype = UPIO_MEM; uart.port.serial_in = dw8250_serial_in; uart.port.serial_out = dw8250_serial_out; uart.port.private_data = data; dw8250_setup_port(&uart); if (pdev->dev.of_node) { err = dw8250_probe_of(&uart.port); if (err) return err; } else if (ACPI_HANDLE(&pdev->dev)) { err = dw8250_probe_acpi(&uart); if (err) return err; } else { return -ENODEV; } data->line = serial8250_register_8250_port(&uart); if (data->line < 0) return data->line; platform_set_drvdata(pdev, data); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); return 0; }
static int dw8250_probe(struct platform_device *pdev) { struct uart_8250_port uart = {}; struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); int irq = platform_get_irq(pdev, 0); struct dw8250_data *data; int err; if (!regs) { dev_err(&pdev->dev, "no registers defined\n"); return -EINVAL; } if (irq < 0) { if (irq != -EPROBE_DEFER) dev_err(&pdev->dev, "cannot get irq\n"); return irq; } spin_lock_init(&uart.port.lock); uart.port.mapbase = regs->start; uart.port.irq = irq; uart.port.handle_irq = dw8250_handle_irq; uart.port.pm = dw8250_do_pm; uart.port.type = PORT_8250; uart.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT; uart.port.dev = &pdev->dev; uart.port.membase = devm_ioremap(&pdev->dev, regs->start, resource_size(regs)); if (!uart.port.membase) return -ENOMEM; data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; data->usr_reg = DW_UART_USR; /* Always ask for fixed clock rate from a property. */ device_property_read_u32(&pdev->dev, "clock-frequency", &uart.port.uartclk); /* If there is separate baudclk, get the rate from it. */ data->clk = devm_clk_get(&pdev->dev, "baudclk"); if (IS_ERR(data->clk) && PTR_ERR(data->clk) != -EPROBE_DEFER) data->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(data->clk) && PTR_ERR(data->clk) == -EPROBE_DEFER) return -EPROBE_DEFER; if (!IS_ERR_OR_NULL(data->clk)) { err = clk_prepare_enable(data->clk); if (err) dev_warn(&pdev->dev, "could not enable optional baudclk: %d\n", err); else uart.port.uartclk = clk_get_rate(data->clk); } /* If no clock rate is defined, fail. */ if (!uart.port.uartclk) { dev_err(&pdev->dev, "clock rate not defined\n"); return -EINVAL; } data->pclk = devm_clk_get(&pdev->dev, "apb_pclk"); if (IS_ERR(data->clk) && PTR_ERR(data->clk) == -EPROBE_DEFER) { err = -EPROBE_DEFER; goto err_clk; } if (!IS_ERR(data->pclk)) { err = clk_prepare_enable(data->pclk); if (err) { dev_err(&pdev->dev, "could not enable apb_pclk\n"); goto err_clk; } } data->rst = devm_reset_control_get_optional(&pdev->dev, NULL); if (IS_ERR(data->rst) && PTR_ERR(data->rst) == -EPROBE_DEFER) { err = -EPROBE_DEFER; goto err_pclk; } if (!IS_ERR(data->rst)) reset_control_deassert(data->rst); data->dma.rx_param = data; data->dma.tx_param = data; data->dma.fn = dw8250_dma_filter; uart.port.iotype = UPIO_MEM; uart.port.serial_in = dw8250_serial_in; uart.port.serial_out = dw8250_serial_out; uart.port.private_data = data; if (pdev->dev.of_node) { err = dw8250_probe_of(&uart.port, data); if (err) goto err_reset; } else if (ACPI_HANDLE(&pdev->dev)) { err = dw8250_probe_acpi(&uart, data); if (err) goto err_reset; } else { err = -ENODEV; goto err_reset; } data->line = serial8250_register_8250_port(&uart); if (data->line < 0) { err = data->line; goto err_reset; } platform_set_drvdata(pdev, data); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); return 0; err_reset: if (!IS_ERR(data->rst)) reset_control_assert(data->rst); err_pclk: if (!IS_ERR(data->pclk)) clk_disable_unprepare(data->pclk); err_clk: if (!IS_ERR(data->clk)) clk_disable_unprepare(data->clk); return err; }