diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-18 09:31:43 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-18 09:31:43 -0400 |
commit | 0a95d92c0054e74fb79607ac2df958b7bf295706 (patch) | |
tree | e2c5f836e799dcfd72904949be47595af91432e7 /drivers/tty | |
parent | 08351fc6a75731226e1112fc7254542bd3a2912e (diff) | |
parent | 831532035b12a5f7b600515a6f4da0b207b82d6e (diff) |
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (62 commits)
powerpc/85xx: Fix signedness bug in cache-sram
powerpc/fsl: 85xx: document cache sram bindings
powerpc/fsl: define binding for fsl mpic interrupt controllers
powerpc/fsl_msi: Handle msi-available-ranges better
drivers/serial/ucc_uart.c: Add of_node_put to avoid memory leak
powerpc/85xx: Fix SPE float to integer conversion failure
powerpc/85xx: Update sata controller compatible for p1022ds board
ATA: Add FSL sata v2 controller support
powerpc/mpc8xxx_gpio: simplify searching for 'fsl, qoriq-gpio' compatiable
powerpc/8xx: remove obsolete mgsuvd board
powerpc/82xx: rename and update mgcoge board support
powerpc/83xx: rename and update kmeter1
powerpc/85xx: Workaroudn e500 CPU erratum A005
powerpc/fsl_pci: Add support for FSL PCIe controllers v2.x
powerpc/85xx: Fix writing to spin table 'cpu-release-addr' on ppc64e
powerpc/pseries: Disable MSI using new interface if possible
powerpc: Enable GENERIC_HARDIRQS_NO_DEPRECATED.
powerpc: core irq_data conversion.
powerpc: sysdev/xilinx_intc irq_data conversion.
powerpc: sysdev/uic irq_data conversion.
...
Fix up conflicts in arch/powerpc/sysdev/fsl_msi.c (due to getting rid of
of_platform_driver in arch/powerpc)
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/hvc/hvcs.c | 74 | ||||
-rw-r--r-- | drivers/tty/serial/ucc_uart.c | 67 |
2 files changed, 78 insertions, 63 deletions
diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index bedc6c1b6fa5..7e315b7f8700 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c | |||
@@ -309,6 +309,7 @@ struct hvcs_struct { | |||
309 | 309 | ||
310 | static LIST_HEAD(hvcs_structs); | 310 | static LIST_HEAD(hvcs_structs); |
311 | static DEFINE_SPINLOCK(hvcs_structs_lock); | 311 | static DEFINE_SPINLOCK(hvcs_structs_lock); |
312 | static DEFINE_MUTEX(hvcs_init_mutex); | ||
312 | 313 | ||
313 | static void hvcs_unthrottle(struct tty_struct *tty); | 314 | static void hvcs_unthrottle(struct tty_struct *tty); |
314 | static void hvcs_throttle(struct tty_struct *tty); | 315 | static void hvcs_throttle(struct tty_struct *tty); |
@@ -340,6 +341,7 @@ static int __devinit hvcs_probe(struct vio_dev *dev, | |||
340 | static int __devexit hvcs_remove(struct vio_dev *dev); | 341 | static int __devexit hvcs_remove(struct vio_dev *dev); |
341 | static int __init hvcs_module_init(void); | 342 | static int __init hvcs_module_init(void); |
342 | static void __exit hvcs_module_exit(void); | 343 | static void __exit hvcs_module_exit(void); |
344 | static int __devinit hvcs_initialize(void); | ||
343 | 345 | ||
344 | #define HVCS_SCHED_READ 0x00000001 | 346 | #define HVCS_SCHED_READ 0x00000001 |
345 | #define HVCS_QUICK_READ 0x00000002 | 347 | #define HVCS_QUICK_READ 0x00000002 |
@@ -762,7 +764,7 @@ static int __devinit hvcs_probe( | |||
762 | const struct vio_device_id *id) | 764 | const struct vio_device_id *id) |
763 | { | 765 | { |
764 | struct hvcs_struct *hvcsd; | 766 | struct hvcs_struct *hvcsd; |
765 | int index; | 767 | int index, rc; |
766 | int retval; | 768 | int retval; |
767 | 769 | ||
768 | if (!dev || !id) { | 770 | if (!dev || !id) { |
@@ -770,6 +772,13 @@ static int __devinit hvcs_probe( | |||
770 | return -EPERM; | 772 | return -EPERM; |
771 | } | 773 | } |
772 | 774 | ||
775 | /* Make sure we are properly initialized */ | ||
776 | rc = hvcs_initialize(); | ||
777 | if (rc) { | ||
778 | pr_err("HVCS: Failed to initialize core driver.\n"); | ||
779 | return rc; | ||
780 | } | ||
781 | |||
773 | /* early to avoid cleanup on failure */ | 782 | /* early to avoid cleanup on failure */ |
774 | index = hvcs_get_index(); | 783 | index = hvcs_get_index(); |
775 | if (index < 0) { | 784 | if (index < 0) { |
@@ -1464,12 +1473,15 @@ static void hvcs_free_index_list(void) | |||
1464 | hvcs_index_count = 0; | 1473 | hvcs_index_count = 0; |
1465 | } | 1474 | } |
1466 | 1475 | ||
1467 | static int __init hvcs_module_init(void) | 1476 | static int __devinit hvcs_initialize(void) |
1468 | { | 1477 | { |
1469 | int rc; | 1478 | int rc, num_ttys_to_alloc; |
1470 | int num_ttys_to_alloc; | ||
1471 | 1479 | ||
1472 | printk(KERN_INFO "Initializing %s\n", hvcs_driver_string); | 1480 | mutex_lock(&hvcs_init_mutex); |
1481 | if (hvcs_task) { | ||
1482 | mutex_unlock(&hvcs_init_mutex); | ||
1483 | return 0; | ||
1484 | } | ||
1473 | 1485 | ||
1474 | /* Has the user specified an overload with an insmod param? */ | 1486 | /* Has the user specified an overload with an insmod param? */ |
1475 | if (hvcs_parm_num_devs <= 0 || | 1487 | if (hvcs_parm_num_devs <= 0 || |
@@ -1528,35 +1540,13 @@ static int __init hvcs_module_init(void) | |||
1528 | 1540 | ||
1529 | hvcs_task = kthread_run(khvcsd, NULL, "khvcsd"); | 1541 | hvcs_task = kthread_run(khvcsd, NULL, "khvcsd"); |
1530 | if (IS_ERR(hvcs_task)) { | 1542 | if (IS_ERR(hvcs_task)) { |
1531 | printk(KERN_ERR "HVCS: khvcsd creation failed. Driver not loaded.\n"); | 1543 | printk(KERN_ERR "HVCS: khvcsd creation failed.\n"); |
1532 | rc = -EIO; | 1544 | rc = -EIO; |
1533 | goto kthread_fail; | 1545 | goto kthread_fail; |
1534 | } | 1546 | } |
1535 | 1547 | mutex_unlock(&hvcs_init_mutex); | |
1536 | rc = vio_register_driver(&hvcs_vio_driver); | ||
1537 | if (rc) { | ||
1538 | printk(KERN_ERR "HVCS: can't register vio driver\n"); | ||
1539 | goto vio_fail; | ||
1540 | } | ||
1541 | |||
1542 | /* | ||
1543 | * This needs to be done AFTER the vio_register_driver() call or else | ||
1544 | * the kobjects won't be initialized properly. | ||
1545 | */ | ||
1546 | rc = driver_create_file(&(hvcs_vio_driver.driver), &driver_attr_rescan); | ||
1547 | if (rc) { | ||
1548 | printk(KERN_ERR "HVCS: sysfs attr create failed\n"); | ||
1549 | goto attr_fail; | ||
1550 | } | ||
1551 | |||
1552 | printk(KERN_INFO "HVCS: driver module inserted.\n"); | ||
1553 | |||
1554 | return 0; | 1548 | return 0; |
1555 | 1549 | ||
1556 | attr_fail: | ||
1557 | vio_unregister_driver(&hvcs_vio_driver); | ||
1558 | vio_fail: | ||
1559 | kthread_stop(hvcs_task); | ||
1560 | kthread_fail: | 1550 | kthread_fail: |
1561 | kfree(hvcs_pi_buff); | 1551 | kfree(hvcs_pi_buff); |
1562 | buff_alloc_fail: | 1552 | buff_alloc_fail: |
@@ -1566,15 +1556,39 @@ register_fail: | |||
1566 | index_fail: | 1556 | index_fail: |
1567 | put_tty_driver(hvcs_tty_driver); | 1557 | put_tty_driver(hvcs_tty_driver); |
1568 | hvcs_tty_driver = NULL; | 1558 | hvcs_tty_driver = NULL; |
1559 | mutex_unlock(&hvcs_init_mutex); | ||
1569 | return rc; | 1560 | return rc; |
1570 | } | 1561 | } |
1571 | 1562 | ||
1563 | static int __init hvcs_module_init(void) | ||
1564 | { | ||
1565 | int rc = vio_register_driver(&hvcs_vio_driver); | ||
1566 | if (rc) { | ||
1567 | printk(KERN_ERR "HVCS: can't register vio driver\n"); | ||
1568 | return rc; | ||
1569 | } | ||
1570 | |||
1571 | pr_info("HVCS: Driver registered.\n"); | ||
1572 | |||
1573 | /* This needs to be done AFTER the vio_register_driver() call or else | ||
1574 | * the kobjects won't be initialized properly. | ||
1575 | */ | ||
1576 | rc = driver_create_file(&(hvcs_vio_driver.driver), &driver_attr_rescan); | ||
1577 | if (rc) | ||
1578 | pr_warning(KERN_ERR "HVCS: Failed to create rescan file (err %d)\n", rc); | ||
1579 | |||
1580 | return 0; | ||
1581 | } | ||
1582 | |||
1572 | static void __exit hvcs_module_exit(void) | 1583 | static void __exit hvcs_module_exit(void) |
1573 | { | 1584 | { |
1574 | /* | 1585 | /* |
1575 | * This driver receives hvcs_remove callbacks for each device upon | 1586 | * This driver receives hvcs_remove callbacks for each device upon |
1576 | * module removal. | 1587 | * module removal. |
1577 | */ | 1588 | */ |
1589 | vio_unregister_driver(&hvcs_vio_driver); | ||
1590 | if (!hvcs_task) | ||
1591 | return; | ||
1578 | 1592 | ||
1579 | /* | 1593 | /* |
1580 | * This synchronous operation will wake the khvcsd kthread if it is | 1594 | * This synchronous operation will wake the khvcsd kthread if it is |
@@ -1589,8 +1603,6 @@ static void __exit hvcs_module_exit(void) | |||
1589 | 1603 | ||
1590 | driver_remove_file(&hvcs_vio_driver.driver, &driver_attr_rescan); | 1604 | driver_remove_file(&hvcs_vio_driver.driver, &driver_attr_rescan); |
1591 | 1605 | ||
1592 | vio_unregister_driver(&hvcs_vio_driver); | ||
1593 | |||
1594 | tty_unregister_driver(hvcs_tty_driver); | 1606 | tty_unregister_driver(hvcs_tty_driver); |
1595 | 1607 | ||
1596 | hvcs_free_index_list(); | 1608 | hvcs_free_index_list(); |
diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index ff51dae1df0c..c327218cad44 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) |