diff options
| author | Shawn Guo <shawn.guo@linaro.org> | 2011-06-24 14:04:34 -0400 |
|---|---|---|
| committer | Shawn Guo <shawn.guo@linaro.org> | 2011-07-26 21:30:43 -0400 |
| commit | 22698aa252e5e10f5b6d171bf82669deeab3bee1 (patch) | |
| tree | b731eaeb9fac137612a4a4705bafeb5be1e9c6a1 | |
| parent | fe6b540ac033be6e9fa00dab1c8902dea0ad4016 (diff) | |
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>
| -rw-r--r-- | Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt | 19 | ||||
| -rw-r--r-- | drivers/tty/serial/imx.c | 83 |
2 files changed, 91 insertions, 11 deletions
diff --git a/Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt b/Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt new file mode 100644 index 000000000000..a9c0406280e8 --- /dev/null +++ b/Documentation/devicetree/bindings/tty/serial/fsl-imx-uart.txt | |||
| @@ -0,0 +1,19 @@ | |||
| 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 | }; | ||
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 2d5eac20c5cd..827db7654594 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c | |||
| @@ -45,6 +45,8 @@ | |||
| 45 | #include <linux/delay.h> | 45 | #include <linux/delay.h> |
| 46 | #include <linux/rational.h> | 46 | #include <linux/rational.h> |
| 47 | #include <linux/slab.h> | 47 | #include <linux/slab.h> |
| 48 | #include <linux/of.h> | ||
| 49 | #include <linux/of_device.h> | ||
| 48 | 50 | ||
| 49 | #include <asm/io.h> | 51 | #include <asm/io.h> |
| 50 | #include <asm/irq.h> | 52 | #include <asm/irq.h> |
| @@ -235,6 +237,13 @@ static struct platform_device_id imx_uart_devtype[] = { | |||
| 235 | }; | 237 | }; |
| 236 | MODULE_DEVICE_TABLE(platform, imx_uart_devtype); | 238 | MODULE_DEVICE_TABLE(platform, imx_uart_devtype); |
| 237 | 239 | ||
| 240 | static struct of_device_id imx_uart_dt_ids[] = { | ||
| 241 | { .compatible = "fsl,imx1-uart", .data = &imx_uart_devdata[IMX1_UART], }, | ||
| 242 | { .compatible = "fsl,imx21-uart", .data = &imx_uart_devdata[IMX21_UART], }, | ||
| 243 | { /* sentinel */ } | ||
| 244 | }; | ||
| 245 | MODULE_DEVICE_TABLE(of, imx_uart_dt_ids); | ||
| 246 | |||
| 238 | static inline unsigned uts_reg(struct imx_port *sport) | 247 | static inline unsigned uts_reg(struct imx_port *sport) |
| 239 | { | 248 | { |
| 240 | return sport->devdata->uts_reg; | 249 | return sport->devdata->uts_reg; |
| @@ -1273,6 +1282,63 @@ static int serial_imx_resume(struct platform_device *dev) | |||
| 1273 | return 0; | 1282 | return 0; |
| 1274 | } | 1283 | } |
| 1275 | 1284 | ||
| 1285 | #ifdef CONFIG_OF | ||
| 1286 | static int serial_imx_probe_dt(struct imx_port *sport, | ||
| 1287 | struct platform_device *pdev) | ||
| 1288 | { | ||
| 1289 | struct device_node *np = pdev->dev.of_node; | ||
| 1290 | const struct of_device_id *of_id = | ||
| 1291 | of_match_device(imx_uart_dt_ids, &pdev->dev); | ||
| 1292 | int ret; | ||
| 1293 | |||
| 1294 | if (!np) | ||
| 1295 | return -ENODEV; | ||
| 1296 | |||
| 1297 | ret = of_alias_get_id(np, "serial"); | ||
| 1298 | if (ret < 0) { | ||
| 1299 | pr_err("%s: failed to get alias id, errno %d\n", | ||
| 1300 | __func__, ret); | ||
| 1301 | return -ENODEV; | ||
| 1302 | } else { | ||
| 1303 | sport->port.line = ret; | ||
| 1304 | } | ||
| 1305 | |||
| 1306 | if (of_get_property(np, "fsl,uart-has-rtscts", NULL)) | ||
| 1307 | sport->have_rtscts = 1; | ||
| 1308 | |||
| 1309 | if (of_get_property(np, "fsl,irda-mode", NULL)) | ||
| 1310 | sport->use_irda = 1; | ||
| 1311 | |||
| 1312 | sport->devdata = of_id->data; | ||
| 1313 | |||
| 1314 | return 0; | ||
| 1315 | } | ||
| 1316 | #else | ||
| 1317 | static inline int serial_imx_probe_dt(struct imx_port *sport, | ||
| 1318 | struct platform_device *pdev) | ||
| 1319 | { | ||
| 1320 | return -ENODEV; | ||
| 1321 | } | ||
| 1322 | #endif | ||
| 1323 | |||
| 1324 | static void serial_imx_probe_pdata(struct imx_port *sport, | ||
| 1325 | struct platform_device *pdev) | ||
| 1326 | { | ||
| 1327 | struct imxuart_platform_data *pdata = pdev->dev.platform_data; | ||
| 1328 | |||
| 1329 | sport->port.line = pdev->id; | ||
| 1330 | sport->devdata = (struct imx_uart_data *) pdev->id_entry->driver_data; | ||
| 1331 | |||
| 1332 | if (!pdata) | ||
| 1333 | return; | ||
| 1334 | |||
| 1335 | if (pdata->flags & IMXUART_HAVE_RTSCTS) | ||
| 1336 | sport->have_rtscts = 1; | ||
| 1337 | |||
| 1338 | if (pdata->flags & IMXUART_IRDA) | ||
| 1339 | sport->use_irda = 1; | ||
| 1340 | } | ||
| 1341 | |||
| 1276 | static int serial_imx_probe(struct platform_device *pdev) | 1342 | static int serial_imx_probe(struct platform_device *pdev) |
| 1277 | { | 1343 | { |
| 1278 | struct imx_port *sport; | 1344 | struct imx_port *sport; |
| @@ -1285,6 +1351,10 @@ static int serial_imx_probe(struct platform_device *pdev) | |||
| 1285 | if (!sport) | 1351 | if (!sport) |
| 1286 | return -ENOMEM; | 1352 | return -ENOMEM; |
| 1287 | 1353 | ||
| 1354 | ret = serial_imx_probe_dt(sport, pdev); | ||
| 1355 | if (ret == -ENODEV) | ||
| 1356 | serial_imx_probe_pdata(sport, pdev); | ||
| 1357 | |||
| 1288 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1358 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 1289 | if (!res) { | 1359 | if (!res) { |
| 1290 | ret = -ENODEV; | 1360 | ret = -ENODEV; |
| @@ -1309,11 +1379,9 @@ static int serial_imx_probe(struct platform_device *pdev) | |||
| 1309 | sport->port.fifosize = 32; | 1379 | sport->port.fifosize = 32; |
| 1310 | sport->port.ops = &imx_pops; | 1380 | sport->port.ops = &imx_pops; |
| 1311 | sport->port.flags = UPF_BOOT_AUTOCONF; | 1381 | sport->port.flags = UPF_BOOT_AUTOCONF; |
| 1312 | sport->port.line = pdev->id; | ||
| 1313 | init_timer(&sport->timer); | 1382 | init_timer(&sport->timer); |
| 1314 | sport->timer.function = imx_timeout; | 1383 | sport->timer.function = imx_timeout; |
| 1315 | sport->timer.data = (unsigned long)sport; | 1384 | sport->timer.data = (unsigned long)sport; |
| 1316 | sport->devdata = (struct imx_uart_data *) pdev->id_entry->driver_data; | ||
| 1317 | 1385 | ||
| 1318 | sport->clk = clk_get(&pdev->dev, "uart"); | 1386 | sport->clk = clk_get(&pdev->dev, "uart"); |
| 1319 | if (IS_ERR(sport->clk)) { | 1387 | if (IS_ERR(sport->clk)) { |
| @@ -1324,17 +1392,9 @@ static int serial_imx_probe(struct platform_device *pdev) | |||
| 1324 | 1392 | ||
| 1325 | sport->port.uartclk = clk_get_rate(sport->clk); | 1393 | sport->port.uartclk = clk_get_rate(sport->clk); |
| 1326 | 1394 | ||
| 1327 | imx_ports[pdev->id] = sport; | 1395 | imx_ports[sport->port.line] = sport; |
| 1328 | 1396 | ||
| 1329 | pdata = pdev->dev.platform_data; | 1397 | pdata = pdev->dev.platform_data; |
| 1330 | if (pdata && (pdata->flags & IMXUART_HAVE_RTSCTS)) | ||
| 1331 | sport->have_rtscts = 1; | ||
| 1332 | |||
| 1333 | #ifdef CONFIG_IRDA | ||
| 1334 | if (pdata && (pdata->flags & IMXUART_IRDA)) | ||
| 1335 | sport->use_irda = 1; | ||
| 1336 | #endif | ||
| 1337 | |||
| 1338 | if (pdata && pdata->init) { | 1398 | if (pdata && pdata->init) { |
| 1339 | ret = pdata->init(pdev); | 1399 | ret = pdata->init(pdev); |
| 1340 | if (ret) | 1400 | if (ret) |
| @@ -1396,6 +1456,7 @@ static struct platform_driver serial_imx_driver = { | |||
| 1396 | .driver = { | 1456 | .driver = { |
| 1397 | .name = "imx-uart", | 1457 | .name = "imx-uart", |
| 1398 | .owner = THIS_MODULE, | 1458 | .owner = THIS_MODULE, |
| 1459 | .of_match_table = imx_uart_dt_ids, | ||
| 1399 | }, | 1460 | }, |
| 1400 | }; | 1461 | }; |
| 1401 | 1462 | ||
