Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

serial/imx: add device tree probe support

It adds device tree probe support for imx tty/serial driver.

Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
Signed-off-by: Jason Liu <jason.hui@linaro.org>
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Alan Cox <alan@linux.intel.com>
Cc: Cc: Greg Kroah-Hartman <gregkh@suse.de>
Cc: Grant Likely <grant.likely@secretlab.ca>
Acked-by: Grant Likely <grant.likely@secretlab.ca>

Shawn Guo 22698aa2 fe6b540a

+91 -11
+19
Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt
··· 1 + * Freescale i.MX Universal Asynchronous Receiver/Transmitter (UART) 2 + 3 + Required properties: 4 + - compatible : Should be "fsl,<soc>-uart" 5 + - reg : Address and length of the register set for the device 6 + - interrupts : Should contain uart interrupt 7 + 8 + Optional properties: 9 + - fsl,uart-has-rtscts : Indicate the uart has rts and cts 10 + - fsl,irda-mode : Indicate the uart supports irda mode 11 + 12 + Example: 13 + 14 + uart@73fbc000 { 15 + compatible = "fsl,imx51-uart", "fsl,imx21-uart"; 16 + reg = <0x73fbc000 0x4000>; 17 + interrupts = <31>; 18 + fsl,uart-has-rtscts; 19 + };
+72 -11
drivers/tty/serial/imx.c
··· 45 45 #include <linux/delay.h> 46 46 #include <linux/rational.h> 47 47 #include <linux/slab.h> 48 + #include <linux/of.h> 49 + #include <linux/of_device.h> 48 50 49 51 #include <asm/io.h> 50 52 #include <asm/irq.h> ··· 236 234 } 237 235 }; 238 236 MODULE_DEVICE_TABLE(platform, imx_uart_devtype); 237 + 238 + static struct of_device_id imx_uart_dt_ids[] = { 239 + { .compatible = "fsl,imx1-uart", .data = &imx_uart_devdata[IMX1_UART], }, 240 + { .compatible = "fsl,imx21-uart", .data = &imx_uart_devdata[IMX21_UART], }, 241 + { /* sentinel */ } 242 + }; 243 + MODULE_DEVICE_TABLE(of, imx_uart_dt_ids); 239 244 240 245 static inline unsigned uts_reg(struct imx_port *sport) 241 246 { ··· 1282 1273 return 0; 1283 1274 } 1284 1275 1276 + #ifdef CONFIG_OF 1277 + static int serial_imx_probe_dt(struct imx_port *sport, 1278 + struct platform_device *pdev) 1279 + { 1280 + struct device_node *np = pdev->dev.of_node; 1281 + const struct of_device_id *of_id = 1282 + of_match_device(imx_uart_dt_ids, &pdev->dev); 1283 + int ret; 1284 + 1285 + if (!np) 1286 + return -ENODEV; 1287 + 1288 + ret = of_alias_get_id(np, "serial"); 1289 + if (ret < 0) { 1290 + pr_err("%s: failed to get alias id, errno %d\n", 1291 + __func__, ret); 1292 + return -ENODEV; 1293 + } else { 1294 + sport->port.line = ret; 1295 + } 1296 + 1297 + if (of_get_property(np, "fsl,uart-has-rtscts", NULL)) 1298 + sport->have_rtscts = 1; 1299 + 1300 + if (of_get_property(np, "fsl,irda-mode", NULL)) 1301 + sport->use_irda = 1; 1302 + 1303 + sport->devdata = of_id->data; 1304 + 1305 + return 0; 1306 + } 1307 + #else 1308 + static inline int serial_imx_probe_dt(struct imx_port *sport, 1309 + struct platform_device *pdev) 1310 + { 1311 + return -ENODEV; 1312 + } 1313 + #endif 1314 + 1315 + static void serial_imx_probe_pdata(struct imx_port *sport, 1316 + struct platform_device *pdev) 1317 + { 1318 + struct imxuart_platform_data *pdata = pdev->dev.platform_data; 1319 + 1320 + sport->port.line = pdev->id; 1321 + sport->devdata = (struct imx_uart_data *) pdev->id_entry->driver_data; 1322 + 1323 + if (!pdata) 1324 + return; 1325 + 1326 + if (pdata->flags & IMXUART_HAVE_RTSCTS) 1327 + sport->have_rtscts = 1; 1328 + 1329 + if (pdata->flags & IMXUART_IRDA) 1330 + sport->use_irda = 1; 1331 + } 1332 + 1285 1333 static int serial_imx_probe(struct platform_device *pdev) 1286 1334 { 1287 1335 struct imx_port *sport; ··· 1350 1284 sport = kzalloc(sizeof(*sport), GFP_KERNEL); 1351 1285 if (!sport) 1352 1286 return -ENOMEM; 1287 + 1288 + ret = serial_imx_probe_dt(sport, pdev); 1289 + if (ret == -ENODEV) 1290 + serial_imx_probe_pdata(sport, pdev); 1353 1291 1354 1292 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1355 1293 if (!res) { ··· 1379 1309 sport->port.fifosize = 32; 1380 1310 sport->port.ops = &imx_pops; 1381 1311 sport->port.flags = UPF_BOOT_AUTOCONF; 1382 - sport->port.line = pdev->id; 1383 1312 init_timer(&sport->timer); 1384 1313 sport->timer.function = imx_timeout; 1385 1314 sport->timer.data = (unsigned long)sport; 1386 - sport->devdata = (struct imx_uart_data *) pdev->id_entry->driver_data; 1387 1315 1388 1316 sport->clk = clk_get(&pdev->dev, "uart"); 1389 1317 if (IS_ERR(sport->clk)) { ··· 1392 1324 1393 1325 sport->port.uartclk = clk_get_rate(sport->clk); 1394 1326 1395 - imx_ports[pdev->id] = sport; 1327 + imx_ports[sport->port.line] = sport; 1396 1328 1397 1329 pdata = pdev->dev.platform_data; 1398 - if (pdata && (pdata->flags & IMXUART_HAVE_RTSCTS)) 1399 - sport->have_rtscts = 1; 1400 - 1401 - #ifdef CONFIG_IRDA 1402 - if (pdata && (pdata->flags & IMXUART_IRDA)) 1403 - sport->use_irda = 1; 1404 - #endif 1405 - 1406 1330 if (pdata && pdata->init) { 1407 1331 ret = pdata->init(pdev); 1408 1332 if (ret) ··· 1456 1396 .driver = { 1457 1397 .name = "imx-uart", 1458 1398 .owner = THIS_MODULE, 1399 + .of_match_table = imx_uart_dt_ids, 1459 1400 }, 1460 1401 }; 1461 1402