1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* |
3 | * Serial Port driver for Tegra devices |
4 | * |
5 | * Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. |
6 | */ |
7 | |
8 | #include <linux/acpi.h> |
9 | #include <linux/clk.h> |
10 | #include <linux/console.h> |
11 | #include <linux/delay.h> |
12 | #include <linux/io.h> |
13 | #include <linux/module.h> |
14 | #include <linux/of.h> |
15 | #include <linux/reset.h> |
16 | #include <linux/slab.h> |
17 | |
18 | #include "8250.h" |
19 | |
20 | struct tegra_uart { |
21 | struct clk *clk; |
22 | struct reset_control *rst; |
23 | int line; |
24 | }; |
25 | |
26 | static void tegra_uart_handle_break(struct uart_port *p) |
27 | { |
28 | unsigned int status, tmout = 10000; |
29 | |
30 | while (1) { |
31 | status = p->serial_in(p, UART_LSR); |
32 | if (!(status & (UART_LSR_FIFOE | UART_LSR_BRK_ERROR_BITS))) |
33 | break; |
34 | |
35 | p->serial_in(p, UART_RX); |
36 | |
37 | if (--tmout == 0) |
38 | break; |
39 | udelay(1); |
40 | } |
41 | } |
42 | |
43 | static int tegra_uart_probe(struct platform_device *pdev) |
44 | { |
45 | struct uart_8250_port port8250; |
46 | struct tegra_uart *uart; |
47 | struct uart_port *port; |
48 | struct resource *res; |
49 | int ret; |
50 | |
51 | uart = devm_kzalloc(dev: &pdev->dev, size: sizeof(*uart), GFP_KERNEL); |
52 | if (!uart) |
53 | return -ENOMEM; |
54 | |
55 | memset(&port8250, 0, sizeof(port8250)); |
56 | |
57 | port = &port8250.port; |
58 | spin_lock_init(&port->lock); |
59 | |
60 | port->flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT | UPF_FIXED_TYPE; |
61 | port->type = PORT_TEGRA; |
62 | port->dev = &pdev->dev; |
63 | port->handle_break = tegra_uart_handle_break; |
64 | |
65 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
66 | if (!res) |
67 | return -ENODEV; |
68 | |
69 | port->membase = devm_ioremap(dev: &pdev->dev, offset: res->start, |
70 | size: resource_size(res)); |
71 | if (!port->membase) |
72 | return -ENOMEM; |
73 | |
74 | port->mapbase = res->start; |
75 | port->mapsize = resource_size(res); |
76 | |
77 | ret = uart_read_port_properties(port); |
78 | if (ret) |
79 | return ret; |
80 | |
81 | port->iotype = UPIO_MEM32; |
82 | port->regshift = 2; |
83 | |
84 | uart->rst = devm_reset_control_get_optional_shared(dev: &pdev->dev, NULL); |
85 | if (IS_ERR(ptr: uart->rst)) |
86 | return PTR_ERR(ptr: uart->rst); |
87 | |
88 | if (!port->uartclk) { |
89 | uart->clk = devm_clk_get(dev: &pdev->dev, NULL); |
90 | if (IS_ERR(ptr: uart->clk)) { |
91 | dev_err(&pdev->dev, "failed to get clock!\n" ); |
92 | return -ENODEV; |
93 | } |
94 | |
95 | ret = clk_prepare_enable(clk: uart->clk); |
96 | if (ret < 0) |
97 | return ret; |
98 | |
99 | port->uartclk = clk_get_rate(clk: uart->clk); |
100 | } |
101 | |
102 | ret = reset_control_deassert(rstc: uart->rst); |
103 | if (ret) |
104 | goto err_clkdisable; |
105 | |
106 | ret = serial8250_register_8250_port(&port8250); |
107 | if (ret < 0) |
108 | goto err_ctrl_assert; |
109 | |
110 | platform_set_drvdata(pdev, data: uart); |
111 | uart->line = ret; |
112 | |
113 | return 0; |
114 | |
115 | err_ctrl_assert: |
116 | reset_control_assert(rstc: uart->rst); |
117 | err_clkdisable: |
118 | clk_disable_unprepare(clk: uart->clk); |
119 | |
120 | return ret; |
121 | } |
122 | |
123 | static void tegra_uart_remove(struct platform_device *pdev) |
124 | { |
125 | struct tegra_uart *uart = platform_get_drvdata(pdev); |
126 | |
127 | serial8250_unregister_port(line: uart->line); |
128 | reset_control_assert(rstc: uart->rst); |
129 | clk_disable_unprepare(clk: uart->clk); |
130 | } |
131 | |
132 | #ifdef CONFIG_PM_SLEEP |
133 | static int tegra_uart_suspend(struct device *dev) |
134 | { |
135 | struct tegra_uart *uart = dev_get_drvdata(dev); |
136 | struct uart_8250_port *port8250 = serial8250_get_port(line: uart->line); |
137 | struct uart_port *port = &port8250->port; |
138 | |
139 | serial8250_suspend_port(line: uart->line); |
140 | |
141 | if (!uart_console(port) || console_suspend_enabled) |
142 | clk_disable_unprepare(clk: uart->clk); |
143 | |
144 | return 0; |
145 | } |
146 | |
147 | static int tegra_uart_resume(struct device *dev) |
148 | { |
149 | struct tegra_uart *uart = dev_get_drvdata(dev); |
150 | struct uart_8250_port *port8250 = serial8250_get_port(line: uart->line); |
151 | struct uart_port *port = &port8250->port; |
152 | |
153 | if (!uart_console(port) || console_suspend_enabled) |
154 | clk_prepare_enable(clk: uart->clk); |
155 | |
156 | serial8250_resume_port(line: uart->line); |
157 | |
158 | return 0; |
159 | } |
160 | #endif |
161 | |
162 | static SIMPLE_DEV_PM_OPS(tegra_uart_pm_ops, tegra_uart_suspend, |
163 | tegra_uart_resume); |
164 | |
165 | static const struct of_device_id tegra_uart_of_match[] = { |
166 | { .compatible = "nvidia,tegra20-uart" , }, |
167 | { }, |
168 | }; |
169 | MODULE_DEVICE_TABLE(of, tegra_uart_of_match); |
170 | |
171 | static const struct acpi_device_id tegra_uart_acpi_match[] __maybe_unused = { |
172 | { "NVDA0100" , 0 }, |
173 | { }, |
174 | }; |
175 | MODULE_DEVICE_TABLE(acpi, tegra_uart_acpi_match); |
176 | |
177 | static struct platform_driver tegra_uart_driver = { |
178 | .driver = { |
179 | .name = "tegra-uart" , |
180 | .pm = &tegra_uart_pm_ops, |
181 | .of_match_table = tegra_uart_of_match, |
182 | .acpi_match_table = ACPI_PTR(tegra_uart_acpi_match), |
183 | }, |
184 | .probe = tegra_uart_probe, |
185 | .remove_new = tegra_uart_remove, |
186 | }; |
187 | |
188 | module_platform_driver(tegra_uart_driver); |
189 | |
190 | MODULE_AUTHOR("Jeff Brasen <jbrasen@nvidia.com>" ); |
191 | MODULE_DESCRIPTION("NVIDIA Tegra 8250 Driver" ); |
192 | MODULE_LICENSE("GPL v2" ); |
193 | |