0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/kernel.h>
0009 #include <linux/init.h>
0010 #include <linux/serial_8250.h>
0011 #include <linux/serial_reg.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/delay.h>
0014 #include <linux/clk.h>
0015 #include <linux/io.h>
0016
0017 #include "serial.h"
0018 #include "cputype.h"
0019
0020 static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
0021 int value)
0022 {
0023 offset <<= p->regshift;
0024
0025 WARN_ONCE(!p->membase, "unmapped write: uart[%d]\n", offset);
0026
0027 __raw_writel(value, p->membase + offset);
0028 }
0029
0030 static void __init davinci_serial_reset(struct plat_serial8250_port *p)
0031 {
0032 unsigned int pwremu = 0;
0033
0034 serial_write_reg(p, UART_IER, 0);
0035
0036
0037 serial_write_reg(p, UART_DAVINCI_PWREMU, pwremu);
0038 mdelay(10);
0039
0040 pwremu |= (0x3 << 13);
0041 pwremu |= 0x1;
0042 serial_write_reg(p, UART_DAVINCI_PWREMU, pwremu);
0043
0044 if (cpu_is_davinci_dm646x())
0045 serial_write_reg(p, UART_DM646X_SCR,
0046 UART_DM646X_SCR_TX_WATERMARK);
0047 }
0048
0049 int __init davinci_serial_init(struct platform_device *serial_dev)
0050 {
0051 int i, ret = 0;
0052 struct device *dev;
0053 struct plat_serial8250_port *p;
0054 struct clk *clk;
0055
0056
0057
0058
0059
0060 for (i = 0; serial_dev[i].dev.platform_data != NULL; i++) {
0061 dev = &serial_dev[i].dev;
0062 p = dev->platform_data;
0063
0064 ret = platform_device_register(&serial_dev[i]);
0065 if (ret)
0066 continue;
0067
0068 clk = clk_get(dev, NULL);
0069 if (IS_ERR(clk)) {
0070 pr_err("%s:%d: failed to get UART%d clock\n",
0071 __func__, __LINE__, i);
0072 continue;
0073 }
0074
0075 clk_prepare_enable(clk);
0076
0077 p->uartclk = clk_get_rate(clk);
0078
0079 if (!p->membase && p->mapbase) {
0080 p->membase = ioremap(p->mapbase, SZ_4K);
0081
0082 if (p->membase)
0083 p->flags &= ~UPF_IOREMAP;
0084 else
0085 pr_err("uart regs ioremap failed\n");
0086 }
0087
0088 if (p->membase && p->type != PORT_AR7)
0089 davinci_serial_reset(p);
0090 }
0091 return ret;
0092 }