Merge tag 'trace-v5.2-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt...
[sfrench/cifs-2.6.git] / arch / arm / mach-davinci / serial.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * TI DaVinci serial driver
4  *
5  * Copyright (C) 2006 Texas Instruments.
6  */
7
8 #include <linux/kernel.h>
9 #include <linux/init.h>
10 #include <linux/serial_8250.h>
11 #include <linux/serial_reg.h>
12 #include <linux/platform_device.h>
13 #include <linux/delay.h>
14 #include <linux/clk.h>
15 #include <linux/io.h>
16
17 #include <mach/serial.h>
18 #include <mach/cputype.h>
19
20 static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
21                                     int value)
22 {
23         offset <<= p->regshift;
24
25         WARN_ONCE(!p->membase, "unmapped write: uart[%d]\n", offset);
26
27         __raw_writel(value, p->membase + offset);
28 }
29
30 static void __init davinci_serial_reset(struct plat_serial8250_port *p)
31 {
32         unsigned int pwremu = 0;
33
34         serial_write_reg(p, UART_IER, 0);  /* disable all interrupts */
35
36         /* reset both transmitter and receiver: bits 14,13 = UTRST, URRST */
37         serial_write_reg(p, UART_DAVINCI_PWREMU, pwremu);
38         mdelay(10);
39
40         pwremu |= (0x3 << 13);
41         pwremu |= 0x1;
42         serial_write_reg(p, UART_DAVINCI_PWREMU, pwremu);
43
44         if (cpu_is_davinci_dm646x())
45                 serial_write_reg(p, UART_DM646X_SCR,
46                                  UART_DM646X_SCR_TX_WATERMARK);
47 }
48
49 int __init davinci_serial_init(struct platform_device *serial_dev)
50 {
51         int i, ret = 0;
52         struct device *dev;
53         struct plat_serial8250_port *p;
54         struct clk *clk;
55
56         /*
57          * Make sure the serial ports are muxed on at this point.
58          * You have to mux them off in device drivers later on if not needed.
59          */
60         for (i = 0; serial_dev[i].dev.platform_data != NULL; i++) {
61                 dev = &serial_dev[i].dev;
62                 p = dev->platform_data;
63
64                 ret = platform_device_register(&serial_dev[i]);
65                 if (ret)
66                         continue;
67
68                 clk = clk_get(dev, NULL);
69                 if (IS_ERR(clk)) {
70                         pr_err("%s:%d: failed to get UART%d clock\n",
71                                __func__, __LINE__, i);
72                         continue;
73                 }
74
75                 clk_prepare_enable(clk);
76
77                 p->uartclk = clk_get_rate(clk);
78
79                 if (!p->membase && p->mapbase) {
80                         p->membase = ioremap(p->mapbase, SZ_4K);
81
82                         if (p->membase)
83                                 p->flags &= ~UPF_IOREMAP;
84                         else
85                                 pr_err("uart regs ioremap failed\n");
86                 }
87
88                 if (p->membase && p->type != PORT_AR7)
89                         davinci_serial_reset(p);
90         }
91         return ret;
92 }