serial: 8250_uniphier: fix error return code in uniphier_uart_probe()
[linux/fpc-iii.git] / drivers / tty / serial / 8250 / 8250_uniphier.c
blob28d88ccf5a0c2da6c399141de475f8c741960e60
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
4 */
6 #include <linux/clk.h>
7 #include <linux/console.h>
8 #include <linux/io.h>
9 #include <linux/module.h>
10 #include <linux/of.h>
11 #include <linux/platform_device.h>
13 #include "8250.h"
15 /* Most (but not all) of UniPhier UART devices have 64-depth FIFO. */
16 #define UNIPHIER_UART_DEFAULT_FIFO_SIZE 64
19 * This hardware is similar to 8250, but its register map is a bit different:
20 * - MMIO32 (regshift = 2)
21 * - FCR is not at 2, but 3
22 * - LCR and MCR are not at 3 and 4, they share 4
23 * - No SCR (Instead, CHAR can be used as a scratch register)
24 * - Divisor latch at 9, no divisor latch access bit
27 #define UNIPHIER_UART_REGSHIFT 2
29 /* bit[15:8] = CHAR, bit[7:0] = FCR */
30 #define UNIPHIER_UART_CHAR_FCR (3 << (UNIPHIER_UART_REGSHIFT))
31 /* bit[15:8] = LCR, bit[7:0] = MCR */
32 #define UNIPHIER_UART_LCR_MCR (4 << (UNIPHIER_UART_REGSHIFT))
33 /* Divisor Latch Register */
34 #define UNIPHIER_UART_DLR (9 << (UNIPHIER_UART_REGSHIFT))
36 struct uniphier8250_priv {
37 int line;
38 struct clk *clk;
39 spinlock_t atomic_write_lock;
42 #ifdef CONFIG_SERIAL_8250_CONSOLE
43 static int __init uniphier_early_console_setup(struct earlycon_device *device,
44 const char *options)
46 if (!device->port.membase)
47 return -ENODEV;
49 /* This hardware always expects MMIO32 register interface. */
50 device->port.iotype = UPIO_MEM32;
51 device->port.regshift = UNIPHIER_UART_REGSHIFT;
54 * Do not touch the divisor register in early_serial8250_setup();
55 * we assume it has been initialized by a boot loader.
57 device->baud = 0;
59 return early_serial8250_setup(device, options);
61 OF_EARLYCON_DECLARE(uniphier, "socionext,uniphier-uart",
62 uniphier_early_console_setup);
63 #endif
66 * The register map is slightly different from that of 8250.
67 * IO callbacks must be overridden for correct access to FCR, LCR, MCR and SCR.
69 static unsigned int uniphier_serial_in(struct uart_port *p, int offset)
71 unsigned int valshift = 0;
73 switch (offset) {
74 case UART_SCR:
75 /* No SCR for this hardware. Use CHAR as a scratch register */
76 valshift = 8;
77 offset = UNIPHIER_UART_CHAR_FCR;
78 break;
79 case UART_LCR:
80 valshift = 8;
81 /* fall through */
82 case UART_MCR:
83 offset = UNIPHIER_UART_LCR_MCR;
84 break;
85 default:
86 offset <<= UNIPHIER_UART_REGSHIFT;
87 break;
91 * The return value must be masked with 0xff because some registers
92 * share the same offset that must be accessed by 32-bit write/read.
93 * 8 or 16 bit access to this hardware result in unexpected behavior.
95 return (readl(p->membase + offset) >> valshift) & 0xff;
98 static void uniphier_serial_out(struct uart_port *p, int offset, int value)
100 unsigned int valshift = 0;
101 bool normal = false;
103 switch (offset) {
104 case UART_SCR:
105 /* No SCR for this hardware. Use CHAR as a scratch register */
106 valshift = 8;
107 /* fall through */
108 case UART_FCR:
109 offset = UNIPHIER_UART_CHAR_FCR;
110 break;
111 case UART_LCR:
112 valshift = 8;
113 /* Divisor latch access bit does not exist. */
114 value &= ~UART_LCR_DLAB;
115 /* fall through */
116 case UART_MCR:
117 offset = UNIPHIER_UART_LCR_MCR;
118 break;
119 default:
120 offset <<= UNIPHIER_UART_REGSHIFT;
121 normal = true;
122 break;
125 if (normal) {
126 writel(value, p->membase + offset);
127 } else {
129 * Special case: two registers share the same address that
130 * must be 32-bit accessed. As this is not longer atomic safe,
131 * take a lock just in case.
133 struct uniphier8250_priv *priv = p->private_data;
134 unsigned long flags;
135 u32 tmp;
137 spin_lock_irqsave(&priv->atomic_write_lock, flags);
138 tmp = readl(p->membase + offset);
139 tmp &= ~(0xff << valshift);
140 tmp |= value << valshift;
141 writel(tmp, p->membase + offset);
142 spin_unlock_irqrestore(&priv->atomic_write_lock, flags);
147 * This hardware does not have the divisor latch access bit.
148 * The divisor latch register exists at different address.
149 * Override dl_read/write callbacks.
151 static int uniphier_serial_dl_read(struct uart_8250_port *up)
153 return readl(up->port.membase + UNIPHIER_UART_DLR);
156 static void uniphier_serial_dl_write(struct uart_8250_port *up, int value)
158 writel(value, up->port.membase + UNIPHIER_UART_DLR);
161 static int uniphier_of_serial_setup(struct device *dev, struct uart_port *port,
162 struct uniphier8250_priv *priv)
164 int ret;
165 u32 prop;
166 struct device_node *np = dev->of_node;
168 ret = of_alias_get_id(np, "serial");
169 if (ret < 0) {
170 dev_err(dev, "failed to get alias id\n");
171 return ret;
173 port->line = ret;
175 /* Get clk rate through clk driver */
176 priv->clk = devm_clk_get(dev, NULL);
177 if (IS_ERR(priv->clk)) {
178 dev_err(dev, "failed to get clock\n");
179 return PTR_ERR(priv->clk);
182 ret = clk_prepare_enable(priv->clk);
183 if (ret < 0)
184 return ret;
186 port->uartclk = clk_get_rate(priv->clk);
188 /* Check for fifo size */
189 if (of_property_read_u32(np, "fifo-size", &prop) == 0)
190 port->fifosize = prop;
191 else
192 port->fifosize = UNIPHIER_UART_DEFAULT_FIFO_SIZE;
194 return 0;
197 static int uniphier_uart_probe(struct platform_device *pdev)
199 struct device *dev = &pdev->dev;
200 struct uart_8250_port up;
201 struct uniphier8250_priv *priv;
202 struct resource *regs;
203 void __iomem *membase;
204 int irq;
205 int ret;
207 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
208 if (!regs) {
209 dev_err(dev, "failed to get memory resource\n");
210 return -EINVAL;
213 membase = devm_ioremap(dev, regs->start, resource_size(regs));
214 if (!membase)
215 return -ENOMEM;
217 irq = platform_get_irq(pdev, 0);
218 if (irq < 0) {
219 dev_err(dev, "failed to get IRQ number\n");
220 return irq;
223 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
224 if (!priv)
225 return -ENOMEM;
227 memset(&up, 0, sizeof(up));
229 ret = uniphier_of_serial_setup(dev, &up.port, priv);
230 if (ret < 0)
231 return ret;
233 spin_lock_init(&priv->atomic_write_lock);
235 up.port.dev = dev;
236 up.port.private_data = priv;
237 up.port.mapbase = regs->start;
238 up.port.mapsize = resource_size(regs);
239 up.port.membase = membase;
240 up.port.irq = irq;
242 up.port.type = PORT_16550A;
243 up.port.iotype = UPIO_MEM32;
244 up.port.regshift = UNIPHIER_UART_REGSHIFT;
245 up.port.flags = UPF_FIXED_PORT | UPF_FIXED_TYPE;
246 up.capabilities = UART_CAP_FIFO;
248 up.port.serial_in = uniphier_serial_in;
249 up.port.serial_out = uniphier_serial_out;
250 up.dl_read = uniphier_serial_dl_read;
251 up.dl_write = uniphier_serial_dl_write;
253 ret = serial8250_register_8250_port(&up);
254 if (ret < 0) {
255 dev_err(dev, "failed to register 8250 port\n");
256 clk_disable_unprepare(priv->clk);
257 return ret;
259 priv->line = ret;
261 platform_set_drvdata(pdev, priv);
263 return 0;
266 static int uniphier_uart_remove(struct platform_device *pdev)
268 struct uniphier8250_priv *priv = platform_get_drvdata(pdev);
270 serial8250_unregister_port(priv->line);
271 clk_disable_unprepare(priv->clk);
273 return 0;
276 static int __maybe_unused uniphier_uart_suspend(struct device *dev)
278 struct uniphier8250_priv *priv = dev_get_drvdata(dev);
279 struct uart_8250_port *up = serial8250_get_port(priv->line);
281 serial8250_suspend_port(priv->line);
283 if (!uart_console(&up->port) || console_suspend_enabled)
284 clk_disable_unprepare(priv->clk);
286 return 0;
289 static int __maybe_unused uniphier_uart_resume(struct device *dev)
291 struct uniphier8250_priv *priv = dev_get_drvdata(dev);
292 struct uart_8250_port *up = serial8250_get_port(priv->line);
293 int ret;
295 if (!uart_console(&up->port) || console_suspend_enabled) {
296 ret = clk_prepare_enable(priv->clk);
297 if (ret)
298 return ret;
301 serial8250_resume_port(priv->line);
303 return 0;
306 static const struct dev_pm_ops uniphier_uart_pm_ops = {
307 SET_SYSTEM_SLEEP_PM_OPS(uniphier_uart_suspend, uniphier_uart_resume)
310 static const struct of_device_id uniphier_uart_match[] = {
311 { .compatible = "socionext,uniphier-uart" },
312 { /* sentinel */ }
314 MODULE_DEVICE_TABLE(of, uniphier_uart_match);
316 static struct platform_driver uniphier_uart_platform_driver = {
317 .probe = uniphier_uart_probe,
318 .remove = uniphier_uart_remove,
319 .driver = {
320 .name = "uniphier-uart",
321 .of_match_table = uniphier_uart_match,
322 .pm = &uniphier_uart_pm_ops,
325 module_platform_driver(uniphier_uart_platform_driver);
327 MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>");
328 MODULE_DESCRIPTION("UniPhier UART driver");
329 MODULE_LICENSE("GPL");