aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-18 09:31:43 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-18 09:31:43 -0400
commit0a95d92c0054e74fb79607ac2df958b7bf295706 (patch)
treee2c5f836e799dcfd72904949be47595af91432e7 /drivers/tty
parent08351fc6a75731226e1112fc7254542bd3a2912e (diff)
parent831532035b12a5f7b600515a6f4da0b207b82d6e (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.c74
-rw-r--r--drivers/tty/serial/ucc_uart.c67
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
310static LIST_HEAD(hvcs_structs); 310static LIST_HEAD(hvcs_structs);
311static DEFINE_SPINLOCK(hvcs_structs_lock); 311static DEFINE_SPINLOCK(hvcs_structs_lock);
312static DEFINE_MUTEX(hvcs_init_mutex);
312 313
313static void hvcs_unthrottle(struct tty_struct *tty); 314static void hvcs_unthrottle(struct tty_struct *tty);
314static void hvcs_throttle(struct tty_struct *tty); 315static void hvcs_throttle(struct tty_struct *tty);
@@ -340,6 +341,7 @@ static int __devinit hvcs_probe(struct vio_dev *dev,
340static int __devexit hvcs_remove(struct vio_dev *dev); 341static int __devexit hvcs_remove(struct vio_dev *dev);
341static int __init hvcs_module_init(void); 342static int __init hvcs_module_init(void);
342static void __exit hvcs_module_exit(void); 343static void __exit hvcs_module_exit(void);
344static 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
1467static int __init hvcs_module_init(void) 1476static 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
1556attr_fail:
1557 vio_unregister_driver(&hvcs_vio_driver);
1558vio_fail:
1559 kthread_stop(hvcs_task);
1560kthread_fail: 1550kthread_fail:
1561 kfree(hvcs_pi_buff); 1551 kfree(hvcs_pi_buff);
1562buff_alloc_fail: 1552buff_alloc_fail:
@@ -1566,15 +1556,39 @@ register_fail:
1566index_fail: 1556index_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
1563static 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
1572static void __exit hvcs_module_exit(void) 1583static 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;
1460out_np:
1461 of_node_put(np);
1462out_free:
1463 kfree(qe_port);
1464 return ret;
1462} 1465}
1463 1466
1464static int ucc_uart_remove(struct platform_device *ofdev) 1467static int ucc_uart_remove(struct platform_device *ofdev)