diff options
| -rw-r--r-- | drivers/tty/serial/atmel_serial.c | 139 |
1 files changed, 80 insertions, 59 deletions
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index eaf7dc7795b8..1db68713d656 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c | |||
| @@ -1370,6 +1370,80 @@ static void atmel_tasklet_func(unsigned long data) | |||
| 1370 | spin_unlock(&port->lock); | 1370 | spin_unlock(&port->lock); |
| 1371 | } | 1371 | } |
| 1372 | 1372 | ||
| 1373 | static int atmel_init_property(struct atmel_uart_port *atmel_port, | ||
| 1374 | struct platform_device *pdev) | ||
| 1375 | { | ||
| 1376 | struct device_node *np = pdev->dev.of_node; | ||
| 1377 | struct atmel_uart_data *pdata = pdev->dev.platform_data; | ||
| 1378 | |||
| 1379 | if (np) { | ||
| 1380 | /* DMA/PDC usage specification */ | ||
| 1381 | if (of_get_property(np, "atmel,use-dma-rx", NULL)) { | ||
| 1382 | if (of_get_property(np, "dmas", NULL)) { | ||
| 1383 | atmel_port->use_dma_rx = true; | ||
| 1384 | atmel_port->use_pdc_rx = false; | ||
| 1385 | } else { | ||
| 1386 | atmel_port->use_dma_rx = false; | ||
| 1387 | atmel_port->use_pdc_rx = true; | ||
| 1388 | } | ||
| 1389 | } else { | ||
| 1390 | atmel_port->use_dma_rx = false; | ||
| 1391 | atmel_port->use_pdc_rx = false; | ||
| 1392 | } | ||
| 1393 | |||
| 1394 | if (of_get_property(np, "atmel,use-dma-tx", NULL)) { | ||
| 1395 | if (of_get_property(np, "dmas", NULL)) { | ||
| 1396 | atmel_port->use_dma_tx = true; | ||
| 1397 | atmel_port->use_pdc_tx = false; | ||
| 1398 | } else { | ||
| 1399 | atmel_port->use_dma_tx = false; | ||
| 1400 | atmel_port->use_pdc_tx = true; | ||
| 1401 | } | ||
| 1402 | } else { | ||
| 1403 | atmel_port->use_dma_tx = false; | ||
| 1404 | atmel_port->use_pdc_tx = false; | ||
| 1405 | } | ||
| 1406 | |||
| 1407 | } else { | ||
| 1408 | atmel_port->use_pdc_rx = pdata->use_dma_rx; | ||
| 1409 | atmel_port->use_pdc_tx = pdata->use_dma_tx; | ||
| 1410 | atmel_port->use_dma_rx = false; | ||
| 1411 | atmel_port->use_dma_tx = false; | ||
| 1412 | } | ||
| 1413 | |||
| 1414 | return 0; | ||
| 1415 | } | ||
| 1416 | |||
| 1417 | static void atmel_init_rs485(struct atmel_uart_port *atmel_port, | ||
| 1418 | struct platform_device *pdev) | ||
| 1419 | { | ||
| 1420 | struct device_node *np = pdev->dev.of_node; | ||
| 1421 | struct atmel_uart_data *pdata = pdev->dev.platform_data; | ||
| 1422 | |||
| 1423 | if (np) { | ||
| 1424 | u32 rs485_delay[2]; | ||
| 1425 | /* rs485 properties */ | ||
| 1426 | if (of_property_read_u32_array(np, "rs485-rts-delay", | ||
| 1427 | rs485_delay, 2) == 0) { | ||
| 1428 | struct serial_rs485 *rs485conf = &atmel_port->rs485; | ||
| 1429 | |||
| 1430 | rs485conf->delay_rts_before_send = rs485_delay[0]; | ||
| 1431 | rs485conf->delay_rts_after_send = rs485_delay[1]; | ||
| 1432 | rs485conf->flags = 0; | ||
| 1433 | |||
| 1434 | if (of_get_property(np, "rs485-rx-during-tx", NULL)) | ||
| 1435 | rs485conf->flags |= SER_RS485_RX_DURING_TX; | ||
| 1436 | |||
| 1437 | if (of_get_property(np, "linux,rs485-enabled-at-boot-time", | ||
| 1438 | NULL)) | ||
| 1439 | rs485conf->flags |= SER_RS485_ENABLED; | ||
| 1440 | } | ||
| 1441 | } else { | ||
| 1442 | atmel_port->rs485 = pdata->rs485; | ||
| 1443 | } | ||
| 1444 | |||
| 1445 | } | ||
| 1446 | |||
| 1373 | static void atmel_set_ops(struct uart_port *port) | 1447 | static void atmel_set_ops(struct uart_port *port) |
| 1374 | { | 1448 | { |
| 1375 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 1449 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
| @@ -1408,6 +1482,7 @@ static void atmel_set_ops(struct uart_port *port) | |||
| 1408 | */ | 1482 | */ |
| 1409 | static int atmel_startup(struct uart_port *port) | 1483 | static int atmel_startup(struct uart_port *port) |
| 1410 | { | 1484 | { |
| 1485 | struct platform_device *pdev = to_platform_device(port->dev); | ||
| 1411 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); | 1486 | struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); |
| 1412 | struct tty_struct *tty = port->state->port.tty; | 1487 | struct tty_struct *tty = port->state->port.tty; |
| 1413 | int retval; | 1488 | int retval; |
| @@ -1432,6 +1507,8 @@ static int atmel_startup(struct uart_port *port) | |||
| 1432 | /* | 1507 | /* |
| 1433 | * Initialize DMA (if necessary) | 1508 | * Initialize DMA (if necessary) |
| 1434 | */ | 1509 | */ |
| 1510 | atmel_init_property(atmel_port, pdev); | ||
| 1511 | |||
| 1435 | if (atmel_port->prepare_rx) { | 1512 | if (atmel_port->prepare_rx) { |
| 1436 | retval = atmel_port->prepare_rx(port); | 1513 | retval = atmel_port->prepare_rx(port); |
| 1437 | if (retval < 0) | 1514 | if (retval < 0) |
| @@ -1877,55 +1954,6 @@ static struct uart_ops atmel_pops = { | |||
| 1877 | #endif | 1954 | #endif |
| 1878 | }; | 1955 | }; |
| 1879 | 1956 | ||
| 1880 | static void atmel_of_init_port(struct atmel_uart_port *atmel_port, | ||
| 1881 | struct device_node *np) | ||
| 1882 | { | ||
| 1883 | u32 rs485_delay[2]; | ||
| 1884 | |||
| 1885 | /* DMA/PDC usage specification */ | ||
| 1886 | if (of_get_property(np, "atmel,use-dma-rx", NULL)) { | ||
| 1887 | if (of_get_property(np, "dmas", NULL)) { | ||
| 1888 | atmel_port->use_dma_rx = true; | ||
| 1889 | atmel_port->use_pdc_rx = false; | ||
| 1890 | } else { | ||
| 1891 | atmel_port->use_dma_rx = false; | ||
| 1892 | atmel_port->use_pdc_rx = true; | ||
| 1893 | } | ||
| 1894 | } else { | ||
| 1895 | atmel_port->use_dma_rx = false; | ||
| 1896 | atmel_port->use_pdc_rx = false; | ||
| 1897 | } | ||
| 1898 | |||
| 1899 | if (of_get_property(np, "atmel,use-dma-tx", NULL)) { | ||
| 1900 | if (of_get_property(np, "dmas", NULL)) { | ||
| 1901 | atmel_port->use_dma_tx = true; | ||
| 1902 | atmel_port->use_pdc_tx = false; | ||
| 1903 | } else { | ||
| 1904 | atmel_port->use_dma_tx = false; | ||
| 1905 | atmel_port->use_pdc_tx = true; | ||
| 1906 | } | ||
| 1907 | } else { | ||
| 1908 | atmel_port->use_dma_tx = false; | ||
| 1909 | atmel_port->use_pdc_tx = false; | ||
| 1910 | } | ||
| 1911 | |||
| 1912 | /* rs485 properties */ | ||
| 1913 | if (of_property_read_u32_array(np, "rs485-rts-delay", | ||
| 1914 | rs485_delay, 2) == 0) { | ||
| 1915 | struct serial_rs485 *rs485conf = &atmel_port->rs485; | ||
| 1916 | |||
| 1917 | rs485conf->delay_rts_before_send = rs485_delay[0]; | ||
| 1918 | rs485conf->delay_rts_after_send = rs485_delay[1]; | ||
| 1919 | rs485conf->flags = 0; | ||
| 1920 | |||
| 1921 | if (of_get_property(np, "rs485-rx-during-tx", NULL)) | ||
| 1922 | rs485conf->flags |= SER_RS485_RX_DURING_TX; | ||
| 1923 | |||
| 1924 | if (of_get_property(np, "linux,rs485-enabled-at-boot-time", NULL)) | ||
| 1925 | rs485conf->flags |= SER_RS485_ENABLED; | ||
| 1926 | } | ||
| 1927 | } | ||
| 1928 | |||
| 1929 | /* | 1957 | /* |
| 1930 | * Configure the port from the platform device resource info. | 1958 | * Configure the port from the platform device resource info. |
| 1931 | */ | 1959 | */ |
| @@ -1936,17 +1964,10 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port, | |||
| 1936 | struct uart_port *port = &atmel_port->uart; | 1964 | struct uart_port *port = &atmel_port->uart; |
| 1937 | struct atmel_uart_data *pdata = pdev->dev.platform_data; | 1965 | struct atmel_uart_data *pdata = pdev->dev.platform_data; |
| 1938 | 1966 | ||
| 1939 | if (pdev->dev.of_node) { | 1967 | if (!atmel_init_property(atmel_port, pdev)) |
| 1940 | atmel_of_init_port(atmel_port, pdev->dev.of_node); | 1968 | atmel_set_ops(port); |
| 1941 | } else { | ||
| 1942 | atmel_port->use_pdc_rx = pdata->use_dma_rx; | ||
| 1943 | atmel_port->use_pdc_tx = pdata->use_dma_tx; | ||
| 1944 | atmel_port->use_dma_rx = false; | ||
| 1945 | atmel_port->use_dma_tx = false; | ||
| 1946 | atmel_port->rs485 = pdata->rs485; | ||
| 1947 | } | ||
| 1948 | 1969 | ||
| 1949 | atmel_set_ops(port); | 1970 | atmel_init_rs485(atmel_port, pdev); |
| 1950 | 1971 | ||
| 1951 | port->iotype = UPIO_MEM; | 1972 | port->iotype = UPIO_MEM; |
| 1952 | port->flags = UPF_BOOT_AUTOCONF; | 1973 | port->flags = UPF_BOOT_AUTOCONF; |
