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 /drivers/tty | |
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>
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/serial/imx.c | 83 |
1 files changed, 72 insertions, 11 deletions
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 | ||