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