diff options
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/serial/ucc_uart.c | 67 |
1 files changed, 35 insertions, 32 deletions
diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index 3f4848e2174a..38a5ef0ae394 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c | |||
@@ -1270,13 +1270,12 @@ static int ucc_uart_probe(struct platform_device *ofdev, | |||
1270 | ret = of_address_to_resource(np, 0, &res); | 1270 | ret = of_address_to_resource(np, 0, &res); |
1271 | if (ret) { | 1271 | if (ret) { |
1272 | dev_err(&ofdev->dev, "missing 'reg' property in device tree\n"); | 1272 | dev_err(&ofdev->dev, "missing 'reg' property in device tree\n"); |
1273 | kfree(qe_port); | 1273 | goto out_free; |
1274 | return ret; | ||
1275 | } | 1274 | } |
1276 | if (!res.start) { | 1275 | if (!res.start) { |
1277 | dev_err(&ofdev->dev, "invalid 'reg' property in device tree\n"); | 1276 | dev_err(&ofdev->dev, "invalid 'reg' property in device tree\n"); |
1278 | kfree(qe_port); | 1277 | ret = -EINVAL; |
1279 | return -EINVAL; | 1278 | goto out_free; |
1280 | } | 1279 | } |
1281 | qe_port->port.mapbase = res.start; | 1280 | qe_port->port.mapbase = res.start; |
1282 | 1281 | ||
@@ -1286,17 +1285,17 @@ static int ucc_uart_probe(struct platform_device *ofdev, | |||
1286 | if (!iprop) { | 1285 | if (!iprop) { |
1287 | iprop = of_get_property(np, "device-id", NULL); | 1286 | iprop = of_get_property(np, "device-id", NULL); |
1288 | if (!iprop) { | 1287 | if (!iprop) { |
1289 | kfree(qe_port); | ||
1290 | dev_err(&ofdev->dev, "UCC is unspecified in " | 1288 | dev_err(&ofdev->dev, "UCC is unspecified in " |
1291 | "device tree\n"); | 1289 | "device tree\n"); |
1292 | return -EINVAL; | 1290 | ret = -EINVAL; |
1291 | goto out_free; | ||
1293 | } | 1292 | } |
1294 | } | 1293 | } |
1295 | 1294 | ||
1296 | if ((*iprop < 1) || (*iprop > UCC_MAX_NUM)) { | 1295 | if ((*iprop < 1) || (*iprop > UCC_MAX_NUM)) { |
1297 | dev_err(&ofdev->dev, "no support for UCC%u\n", *iprop); | 1296 | dev_err(&ofdev->dev, "no support for UCC%u\n", *iprop); |
1298 | kfree(qe_port); | 1297 | ret = -ENODEV; |
1299 | return -ENODEV; | 1298 | goto out_free; |
1300 | } | 1299 | } |
1301 | qe_port->ucc_num = *iprop - 1; | 1300 | qe_port->ucc_num = *iprop - 1; |
1302 | 1301 | ||
@@ -1310,16 +1309,16 @@ static int ucc_uart_probe(struct platform_device *ofdev, | |||
1310 | sprop = of_get_property(np, "rx-clock-name", NULL); | 1309 | sprop = of_get_property(np, "rx-clock-name", NULL); |
1311 | if (!sprop) { | 1310 | if (!sprop) { |
1312 | dev_err(&ofdev->dev, "missing rx-clock-name in device tree\n"); | 1311 | dev_err(&ofdev->dev, "missing rx-clock-name in device tree\n"); |
1313 | kfree(qe_port); | 1312 | ret = -ENODEV; |
1314 | return -ENODEV; | 1313 | goto out_free; |
1315 | } | 1314 | } |
1316 | 1315 | ||
1317 | qe_port->us_info.rx_clock = qe_clock_source(sprop); | 1316 | qe_port->us_info.rx_clock = qe_clock_source(sprop); |
1318 | if ((qe_port->us_info.rx_clock < QE_BRG1) || | 1317 | if ((qe_port->us_info.rx_clock < QE_BRG1) || |
1319 | (qe_port->us_info.rx_clock > QE_BRG16)) { | 1318 | (qe_port->us_info.rx_clock > QE_BRG16)) { |
1320 | dev_err(&ofdev->dev, "rx-clock-name must be a BRG for UART\n"); | 1319 | dev_err(&ofdev->dev, "rx-clock-name must be a BRG for UART\n"); |
1321 | kfree(qe_port); | 1320 | ret = -ENODEV; |
1322 | return -ENODEV; | 1321 | goto out_free; |
1323 | } | 1322 | } |
1324 | 1323 | ||
1325 | #ifdef LOOPBACK | 1324 | #ifdef LOOPBACK |
@@ -1329,39 +1328,39 @@ static int ucc_uart_probe(struct platform_device *ofdev, | |||
1329 | sprop = of_get_property(np, "tx-clock-name", NULL); | 1328 | sprop = of_get_property(np, "tx-clock-name", NULL); |
1330 | if (!sprop) { | 1329 | if (!sprop) { |
1331 | dev_err(&ofdev->dev, "missing tx-clock-name in device tree\n"); | 1330 | dev_err(&ofdev->dev, "missing tx-clock-name in device tree\n"); |
1332 | kfree(qe_port); | 1331 | ret = -ENODEV; |
1333 | return -ENODEV; | 1332 | goto out_free; |
1334 | } | 1333 | } |
1335 | qe_port->us_info.tx_clock = qe_clock_source(sprop); | 1334 | qe_port->us_info.tx_clock = qe_clock_source(sprop); |
1336 | #endif | 1335 | #endif |
1337 | if ((qe_port->us_info.tx_clock < QE_BRG1) || | 1336 | if ((qe_port->us_info.tx_clock < QE_BRG1) || |
1338 | (qe_port->us_info.tx_clock > QE_BRG16)) { | 1337 | (qe_port->us_info.tx_clock > QE_BRG16)) { |
1339 | dev_err(&ofdev->dev, "tx-clock-name must be a BRG for UART\n"); | 1338 | dev_err(&ofdev->dev, "tx-clock-name must be a BRG for UART\n"); |
1340 | kfree(qe_port); | 1339 | ret = -ENODEV; |
1341 | return -ENODEV; | 1340 | goto out_free; |
1342 | } | 1341 | } |
1343 | 1342 | ||
1344 | /* Get the port number, numbered 0-3 */ | 1343 | /* Get the port number, numbered 0-3 */ |
1345 | iprop = of_get_property(np, "port-number", NULL); | 1344 | iprop = of_get_property(np, "port-number", NULL); |
1346 | if (!iprop) { | 1345 | if (!iprop) { |
1347 | dev_err(&ofdev->dev, "missing port-number in device tree\n"); | 1346 | dev_err(&ofdev->dev, "missing port-number in device tree\n"); |
1348 | kfree(qe_port); | 1347 | ret = -EINVAL; |
1349 | return -EINVAL; | 1348 | goto out_free; |
1350 | } | 1349 | } |
1351 | qe_port->port.line = *iprop; | 1350 | qe_port->port.line = *iprop; |
1352 | if (qe_port->port.line >= UCC_MAX_UART) { | 1351 | if (qe_port->port.line >= UCC_MAX_UART) { |
1353 | dev_err(&ofdev->dev, "port-number must be 0-%u\n", | 1352 | dev_err(&ofdev->dev, "port-number must be 0-%u\n", |
1354 | UCC_MAX_UART - 1); | 1353 | UCC_MAX_UART - 1); |
1355 | kfree(qe_port); | 1354 | ret = -EINVAL; |
1356 | return -EINVAL; | 1355 | goto out_free; |
1357 | } | 1356 | } |
1358 | 1357 | ||
1359 | qe_port->port.irq = irq_of_parse_and_map(np, 0); | 1358 | qe_port->port.irq = irq_of_parse_and_map(np, 0); |
1360 | if (qe_port->port.irq == NO_IRQ) { | 1359 | if (qe_port->port.irq == NO_IRQ) { |
1361 | dev_err(&ofdev->dev, "could not map IRQ for UCC%u\n", | 1360 | dev_err(&ofdev->dev, "could not map IRQ for UCC%u\n", |
1362 | qe_port->ucc_num + 1); | 1361 | qe_port->ucc_num + 1); |
1363 | kfree(qe_port); | 1362 | ret = -EINVAL; |
1364 | return -EINVAL; | 1363 | goto out_free; |
1365 | } | 1364 | } |
1366 | 1365 | ||
1367 | /* | 1366 | /* |
@@ -1373,8 +1372,8 @@ static int ucc_uart_probe(struct platform_device *ofdev, | |||
1373 | np = of_find_node_by_type(NULL, "qe"); | 1372 | np = of_find_node_by_type(NULL, "qe"); |
1374 | if (!np) { | 1373 | if (!np) { |
1375 | dev_err(&ofdev->dev, "could not find 'qe' node\n"); | 1374 | dev_err(&ofdev->dev, "could not find 'qe' node\n"); |
1376 | kfree(qe_port); | 1375 | ret = -EINVAL; |
1377 | return -EINVAL; | 1376 | goto out_free; |
1378 | } | 1377 | } |
1379 | } | 1378 | } |
1380 | 1379 | ||
@@ -1382,8 +1381,8 @@ static int ucc_uart_probe(struct platform_device *ofdev, | |||
1382 | if (!iprop) { | 1381 | if (!iprop) { |
1383 | dev_err(&ofdev->dev, | 1382 | dev_err(&ofdev->dev, |
1384 | "missing brg-frequency in device tree\n"); | 1383 | "missing brg-frequency in device tree\n"); |
1385 | kfree(qe_port); | 1384 | ret = -EINVAL; |
1386 | return -EINVAL; | 1385 | goto out_np; |
1387 | } | 1386 | } |
1388 | 1387 | ||
1389 | if (*iprop) | 1388 | if (*iprop) |
@@ -1398,16 +1397,16 @@ static int ucc_uart_probe(struct platform_device *ofdev, | |||
1398 | if (!iprop) { | 1397 | if (!iprop) { |
1399 | dev_err(&ofdev->dev, | 1398 | dev_err(&ofdev->dev, |
1400 | "missing QE bus-frequency in device tree\n"); | 1399 | "missing QE bus-frequency in device tree\n"); |
1401 | kfree(qe_port); | 1400 | ret = -EINVAL; |
1402 | return -EINVAL; | 1401 | goto out_np; |
1403 | } | 1402 | } |
1404 | if (*iprop) | 1403 | if (*iprop) |
1405 | qe_port->port.uartclk = *iprop / 2; | 1404 | qe_port->port.uartclk = *iprop / 2; |
1406 | else { | 1405 | else { |
1407 | dev_err(&ofdev->dev, | 1406 | dev_err(&ofdev->dev, |
1408 | "invalid QE bus-frequency in device tree\n"); | 1407 | "invalid QE bus-frequency in device tree\n"); |
1409 | kfree(qe_port); | 1408 | ret = -EINVAL; |
1410 | return -EINVAL; | 1409 | goto out_np; |
1411 | } | 1410 | } |
1412 | } | 1411 | } |
1413 | 1412 | ||
@@ -1445,8 +1444,7 @@ static int ucc_uart_probe(struct platform_device *ofdev, | |||
1445 | if (ret) { | 1444 | if (ret) { |
1446 | dev_err(&ofdev->dev, "could not add /dev/ttyQE%u\n", | 1445 | dev_err(&ofdev->dev, "could not add /dev/ttyQE%u\n", |
1447 | qe_port->port.line); | 1446 | qe_port->port.line); |
1448 | kfree(qe_port); | 1447 | goto out_np; |
1449 | return ret; | ||
1450 | } | 1448 | } |
1451 | 1449 | ||
1452 | dev_set_drvdata(&ofdev->dev, qe_port); | 1450 | dev_set_drvdata(&ofdev->dev, qe_port); |
@@ -1460,6 +1458,11 @@ static int ucc_uart_probe(struct platform_device *ofdev, | |||
1460 | SERIAL_QE_MINOR + qe_port->port.line); | 1458 | SERIAL_QE_MINOR + qe_port->port.line); |
1461 | 1459 | ||
1462 | return 0; | 1460 | return 0; |
1461 | out_np: | ||
1462 | of_node_put(np); | ||
1463 | out_free: | ||
1464 | kfree(qe_port); | ||
1465 | return ret; | ||
1463 | } | 1466 | } |
1464 | 1467 | ||
1465 | static int ucc_uart_remove(struct platform_device *ofdev) | 1468 | static int ucc_uart_remove(struct platform_device *ofdev) |