1 /* 2 * Serial Port driver for Open Firmware platform devices 3 * 4 * Copyright (C) 2006 Arnd Bergmann <arnd@arndb.de>, IBM Corp. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 * 11 */ 12 #include <linux/console.h> 13 #include <linux/module.h> 14 #include <linux/slab.h> 15 #include <linux/delay.h> 16 #include <linux/serial_core.h> 17 #include <linux/serial_reg.h> 18 #include <linux/of_address.h> 19 #include <linux/of_irq.h> 20 #include <linux/of_platform.h> 21 #include <linux/clk.h> 22 23 #include "8250.h" 24 25 struct of_serial_info { 26 struct clk *clk; 27 int type; 28 int line; 29 }; 30 31 #ifdef CONFIG_ARCH_TEGRA 32 static void tegra_serial_handle_break(struct uart_port *p) 33 { 34 unsigned int status, tmout = 10000; 35 36 do { 37 status = p->serial_in(p, UART_LSR); 38 if (status & (UART_LSR_FIFOE | UART_LSR_BRK_ERROR_BITS)) 39 status = p->serial_in(p, UART_RX); 40 else 41 break; 42 if (--tmout == 0) 43 break; 44 udelay(1); 45 } while (1); 46 } 47 #else 48 static inline void tegra_serial_handle_break(struct uart_port *port) 49 { 50 } 51 #endif 52 53 /* 54 * Fill a struct uart_port for a given device node 55 */ 56 static int of_platform_serial_setup(struct platform_device *ofdev, 57 int type, struct uart_port *port, 58 struct of_serial_info *info) 59 { 60 struct resource resource; 61 struct device_node *np = ofdev->dev.of_node; 62 u32 clk, spd, prop; 63 int ret; 64 65 memset(port, 0, sizeof *port); 66 if (of_property_read_u32(np, "clock-frequency", &clk)) { 67 68 /* Get clk rate through clk driver if present */ 69 info->clk = devm_clk_get(&ofdev->dev, NULL); 70 if (IS_ERR(info->clk)) { 71 dev_warn(&ofdev->dev, 72 "clk or clock-frequency not defined\n"); 73 return PTR_ERR(info->clk); 74 } 75 76 ret = clk_prepare_enable(info->clk); 77 if (ret < 0) 78 return ret; 79 80 clk = clk_get_rate(info->clk); 81 } 82 /* If current-speed was set, then try not to change it. */ 83 if (of_property_read_u32(np, "current-speed", &spd) == 0) 84 port->custom_divisor = clk / (16 * spd); 85 86 ret = of_address_to_resource(np, 0, &resource); 87 if (ret) { 88 dev_warn(&ofdev->dev, "invalid address\n"); 89 goto out; 90 } 91 92 spin_lock_init(&port->lock); 93 port->mapbase = resource.start; 94 port->mapsize = resource_size(&resource); 95 96 /* Check for shifted address mapping */ 97 if (of_property_read_u32(np, "reg-offset", &prop) == 0) 98 port->mapbase += prop; 99 100 /* Check for registers offset within the devices address range */ 101 if (of_property_read_u32(np, "reg-shift", &prop) == 0) 102 port->regshift = prop; 103 104 /* Check for fifo size */ 105 if (of_property_read_u32(np, "fifo-size", &prop) == 0) 106 port->fifosize = prop; 107 108 /* Check for a fixed line number */ 109 ret = of_alias_get_id(np, "serial"); 110 if (ret >= 0) 111 port->line = ret; 112 113 port->irq = irq_of_parse_and_map(np, 0); 114 port->iotype = UPIO_MEM; 115 if (of_property_read_u32(np, "reg-io-width", &prop) == 0) { 116 switch (prop) { 117 case 1: 118 port->iotype = UPIO_MEM; 119 break; 120 case 2: 121 port->iotype = UPIO_MEM16; 122 break; 123 case 4: 124 port->iotype = of_device_is_big_endian(np) ? 125 UPIO_MEM32BE : UPIO_MEM32; 126 break; 127 default: 128 dev_warn(&ofdev->dev, "unsupported reg-io-width (%d)\n", 129 prop); 130 ret = -EINVAL; 131 goto out; 132 } 133 } 134 135 port->type = type; 136 port->uartclk = clk; 137 port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP 138 | UPF_FIXED_PORT | UPF_FIXED_TYPE; 139 140 if (of_find_property(np, "no-loopback-test", NULL)) 141 port->flags |= UPF_SKIP_TEST; 142 143 port->dev = &ofdev->dev; 144 145 switch (type) { 146 case PORT_TEGRA: 147 port->handle_break = tegra_serial_handle_break; 148 break; 149 150 case PORT_RT2880: 151 port->iotype = UPIO_AU; 152 break; 153 } 154 155 if (IS_ENABLED(CONFIG_SERIAL_8250_FSL) && 156 (of_device_is_compatible(np, "fsl,ns16550") || 157 of_device_is_compatible(np, "fsl,16550-FIFO64"))) 158 port->handle_irq = fsl8250_handle_irq; 159 160 return 0; 161 out: 162 if (info->clk) 163 clk_disable_unprepare(info->clk); 164 return ret; 165 } 166 167 /* 168 * Try to register a serial port 169 */ 170 static const struct of_device_id of_platform_serial_table[]; 171 static int of_platform_serial_probe(struct platform_device *ofdev) 172 { 173 const struct of_device_id *match; 174 struct of_serial_info *info; 175 struct uart_8250_port port8250; 176 u32 tx_threshold; 177 int port_type; 178 int ret; 179 180 match = of_match_device(of_platform_serial_table, &ofdev->dev); 181 if (!match) 182 return -EINVAL; 183 184 if (of_find_property(ofdev->dev.of_node, "used-by-rtas", NULL)) 185 return -EBUSY; 186 187 info = kzalloc(sizeof(*info), GFP_KERNEL); 188 if (info == NULL) 189 return -ENOMEM; 190 191 port_type = (unsigned long)match->data; 192 memset(&port8250, 0, sizeof(port8250)); 193 ret = of_platform_serial_setup(ofdev, port_type, &port8250.port, info); 194 if (ret) 195 goto out; 196 197 if (port8250.port.fifosize) 198 port8250.capabilities = UART_CAP_FIFO; 199 200 /* Check for TX FIFO threshold & set tx_loadsz */ 201 if ((of_property_read_u32(ofdev->dev.of_node, "tx-threshold", 202 &tx_threshold) == 0) && 203 (tx_threshold < port8250.port.fifosize)) 204 port8250.tx_loadsz = port8250.port.fifosize - tx_threshold; 205 206 if (of_property_read_bool(ofdev->dev.of_node, "auto-flow-control")) 207 port8250.capabilities |= UART_CAP_AFE; 208 209 ret = serial8250_register_8250_port(&port8250); 210 if (ret < 0) 211 goto out; 212 213 info->type = port_type; 214 info->line = ret; 215 platform_set_drvdata(ofdev, info); 216 return 0; 217 out: 218 kfree(info); 219 irq_dispose_mapping(port8250.port.irq); 220 return ret; 221 } 222 223 /* 224 * Release a line 225 */ 226 static int of_platform_serial_remove(struct platform_device *ofdev) 227 { 228 struct of_serial_info *info = platform_get_drvdata(ofdev); 229 230 serial8250_unregister_port(info->line); 231 232 if (info->clk) 233 clk_disable_unprepare(info->clk); 234 kfree(info); 235 return 0; 236 } 237 238 #ifdef CONFIG_PM_SLEEP 239 static int of_serial_suspend(struct device *dev) 240 { 241 struct of_serial_info *info = dev_get_drvdata(dev); 242 struct uart_8250_port *port8250 = serial8250_get_port(info->line); 243 struct uart_port *port = &port8250->port; 244 245 serial8250_suspend_port(info->line); 246 247 if (info->clk && (!uart_console(port) || console_suspend_enabled)) 248 clk_disable_unprepare(info->clk); 249 250 return 0; 251 } 252 253 static int of_serial_resume(struct device *dev) 254 { 255 struct of_serial_info *info = dev_get_drvdata(dev); 256 struct uart_8250_port *port8250 = serial8250_get_port(info->line); 257 struct uart_port *port = &port8250->port; 258 259 if (info->clk && (!uart_console(port) || console_suspend_enabled)) 260 clk_prepare_enable(info->clk); 261 262 serial8250_resume_port(info->line); 263 264 return 0; 265 } 266 #endif 267 static SIMPLE_DEV_PM_OPS(of_serial_pm_ops, of_serial_suspend, of_serial_resume); 268 269 /* 270 * A few common types, add more as needed. 271 */ 272 static const struct of_device_id of_platform_serial_table[] = { 273 { .compatible = "ns8250", .data = (void *)PORT_8250, }, 274 { .compatible = "ns16450", .data = (void *)PORT_16450, }, 275 { .compatible = "ns16550a", .data = (void *)PORT_16550A, }, 276 { .compatible = "ns16550", .data = (void *)PORT_16550, }, 277 { .compatible = "ns16750", .data = (void *)PORT_16750, }, 278 { .compatible = "ns16850", .data = (void *)PORT_16850, }, 279 { .compatible = "nvidia,tegra20-uart", .data = (void *)PORT_TEGRA, }, 280 { .compatible = "nxp,lpc3220-uart", .data = (void *)PORT_LPC3220, }, 281 { .compatible = "ralink,rt2880-uart", .data = (void *)PORT_RT2880, }, 282 { .compatible = "altr,16550-FIFO32", 283 .data = (void *)PORT_ALTR_16550_F32, }, 284 { .compatible = "altr,16550-FIFO64", 285 .data = (void *)PORT_ALTR_16550_F64, }, 286 { .compatible = "altr,16550-FIFO128", 287 .data = (void *)PORT_ALTR_16550_F128, }, 288 { .compatible = "mrvl,mmp-uart", 289 .data = (void *)PORT_XSCALE, }, 290 { .compatible = "ti,da830-uart", .data = (void *)PORT_DA830, }, 291 { /* end of list */ }, 292 }; 293 MODULE_DEVICE_TABLE(of, of_platform_serial_table); 294 295 static struct platform_driver of_platform_serial_driver = { 296 .driver = { 297 .name = "of_serial", 298 .of_match_table = of_platform_serial_table, 299 .pm = &of_serial_pm_ops, 300 }, 301 .probe = of_platform_serial_probe, 302 .remove = of_platform_serial_remove, 303 }; 304 305 module_platform_driver(of_platform_serial_driver); 306 307 MODULE_AUTHOR("Arnd Bergmann <arnd@arndb.de>"); 308 MODULE_LICENSE("GPL"); 309 MODULE_DESCRIPTION("Serial Port driver for Open Firmware platform devices"); 310