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 | |
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')
-rw-r--r-- | drivers/ata/sata_fsl.c | 25 | ||||
-rw-r--r-- | drivers/macintosh/rack-meter.c | 2 | ||||
-rw-r--r-- | drivers/tty/hvc/hvcs.c | 74 | ||||
-rw-r--r-- | drivers/tty/serial/ucc_uart.c | 67 |
4 files changed, 97 insertions, 71 deletions
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index ef3ce26bb1f0..0f91e583892e 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * Author: Ashish Kalra <ashish.kalra@freescale.com> | 6 | * Author: Ashish Kalra <ashish.kalra@freescale.com> |
7 | * Li Yang <leoli@freescale.com> | 7 | * Li Yang <leoli@freescale.com> |
8 | * | 8 | * |
9 | * Copyright (c) 2006-2007 Freescale Semiconductor, Inc. | 9 | * Copyright (c) 2006-2007, 2011 Freescale Semiconductor, Inc. |
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or modify it | 11 | * This program is free software; you can redistribute it and/or modify it |
12 | * under the terms of the GNU General Public License as published by the | 12 | * under the terms of the GNU General Public License as published by the |
@@ -157,7 +157,8 @@ enum { | |||
157 | IE_ON_SINGL_DEVICE_ERR | IE_ON_CMD_COMPLETE, | 157 | IE_ON_SINGL_DEVICE_ERR | IE_ON_CMD_COMPLETE, |
158 | 158 | ||
159 | EXT_INDIRECT_SEG_PRD_FLAG = (1 << 31), | 159 | EXT_INDIRECT_SEG_PRD_FLAG = (1 << 31), |
160 | DATA_SNOOP_ENABLE = (1 << 22), | 160 | DATA_SNOOP_ENABLE_V1 = (1 << 22), |
161 | DATA_SNOOP_ENABLE_V2 = (1 << 28), | ||
161 | }; | 162 | }; |
162 | 163 | ||
163 | /* | 164 | /* |
@@ -260,6 +261,7 @@ struct sata_fsl_host_priv { | |||
260 | void __iomem *ssr_base; | 261 | void __iomem *ssr_base; |
261 | void __iomem *csr_base; | 262 | void __iomem *csr_base; |
262 | int irq; | 263 | int irq; |
264 | int data_snoop; | ||
263 | }; | 265 | }; |
264 | 266 | ||
265 | static inline unsigned int sata_fsl_tag(unsigned int tag, | 267 | static inline unsigned int sata_fsl_tag(unsigned int tag, |
@@ -312,7 +314,8 @@ static void sata_fsl_setup_cmd_hdr_entry(struct sata_fsl_port_priv *pp, | |||
312 | } | 314 | } |
313 | 315 | ||
314 | static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc, | 316 | static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc, |
315 | u32 *ttl, dma_addr_t cmd_desc_paddr) | 317 | u32 *ttl, dma_addr_t cmd_desc_paddr, |
318 | int data_snoop) | ||
316 | { | 319 | { |
317 | struct scatterlist *sg; | 320 | struct scatterlist *sg; |
318 | unsigned int num_prde = 0; | 321 | unsigned int num_prde = 0; |
@@ -362,8 +365,7 @@ static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc, | |||
362 | 365 | ||
363 | ttl_dwords += sg_len; | 366 | ttl_dwords += sg_len; |
364 | prd->dba = cpu_to_le32(sg_addr); | 367 | prd->dba = cpu_to_le32(sg_addr); |
365 | prd->ddc_and_ext = | 368 | prd->ddc_and_ext = cpu_to_le32(data_snoop | (sg_len & ~0x03)); |
366 | cpu_to_le32(DATA_SNOOP_ENABLE | (sg_len & ~0x03)); | ||
367 | 369 | ||
368 | VPRINTK("sg_fill, ttl=%d, dba=0x%x, ddc=0x%x\n", | 370 | VPRINTK("sg_fill, ttl=%d, dba=0x%x, ddc=0x%x\n", |
369 | ttl_dwords, prd->dba, prd->ddc_and_ext); | 371 | ttl_dwords, prd->dba, prd->ddc_and_ext); |
@@ -378,7 +380,7 @@ static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc, | |||
378 | /* set indirect extension flag along with indirect ext. size */ | 380 | /* set indirect extension flag along with indirect ext. size */ |
379 | prd_ptr_to_indirect_ext->ddc_and_ext = | 381 | prd_ptr_to_indirect_ext->ddc_and_ext = |
380 | cpu_to_le32((EXT_INDIRECT_SEG_PRD_FLAG | | 382 | cpu_to_le32((EXT_INDIRECT_SEG_PRD_FLAG | |
381 | DATA_SNOOP_ENABLE | | 383 | data_snoop | |
382 | (indirect_ext_segment_sz & ~0x03))); | 384 | (indirect_ext_segment_sz & ~0x03))); |
383 | } | 385 | } |
384 | 386 | ||
@@ -421,7 +423,8 @@ static void sata_fsl_qc_prep(struct ata_queued_cmd *qc) | |||
421 | 423 | ||
422 | if (qc->flags & ATA_QCFLAG_DMAMAP) | 424 | if (qc->flags & ATA_QCFLAG_DMAMAP) |
423 | num_prde = sata_fsl_fill_sg(qc, (void *)cd, | 425 | num_prde = sata_fsl_fill_sg(qc, (void *)cd, |
424 | &ttl_dwords, cd_paddr); | 426 | &ttl_dwords, cd_paddr, |
427 | host_priv->data_snoop); | ||
425 | 428 | ||
426 | if (qc->tf.protocol == ATA_PROT_NCQ) | 429 | if (qc->tf.protocol == ATA_PROT_NCQ) |
427 | desc_info |= FPDMA_QUEUED_CMD; | 430 | desc_info |= FPDMA_QUEUED_CMD; |
@@ -1349,6 +1352,11 @@ static int sata_fsl_probe(struct platform_device *ofdev) | |||
1349 | } | 1352 | } |
1350 | host_priv->irq = irq; | 1353 | host_priv->irq = irq; |
1351 | 1354 | ||
1355 | if (of_device_is_compatible(ofdev->dev.of_node, "fsl,pq-sata-v2")) | ||
1356 | host_priv->data_snoop = DATA_SNOOP_ENABLE_V2; | ||
1357 | else | ||
1358 | host_priv->data_snoop = DATA_SNOOP_ENABLE_V1; | ||
1359 | |||
1352 | /* allocate host structure */ | 1360 | /* allocate host structure */ |
1353 | host = ata_host_alloc_pinfo(&ofdev->dev, ppi, SATA_FSL_MAX_PORTS); | 1361 | host = ata_host_alloc_pinfo(&ofdev->dev, ppi, SATA_FSL_MAX_PORTS); |
1354 | 1362 | ||
@@ -1431,6 +1439,9 @@ static struct of_device_id fsl_sata_match[] = { | |||
1431 | { | 1439 | { |
1432 | .compatible = "fsl,pq-sata", | 1440 | .compatible = "fsl,pq-sata", |
1433 | }, | 1441 | }, |
1442 | { | ||
1443 | .compatible = "fsl,pq-sata-v2", | ||
1444 | }, | ||
1434 | {}, | 1445 | {}, |
1435 | }; | 1446 | }; |
1436 | 1447 | ||
diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c index 39f660b2a60d..2637c139777b 100644 --- a/drivers/macintosh/rack-meter.c +++ b/drivers/macintosh/rack-meter.c | |||
@@ -283,7 +283,7 @@ static void __devinit rackmeter_init_cpu_sniffer(struct rackmeter *rm) | |||
283 | } | 283 | } |
284 | } | 284 | } |
285 | 285 | ||
286 | static void __devexit rackmeter_stop_cpu_sniffer(struct rackmeter *rm) | 286 | static void rackmeter_stop_cpu_sniffer(struct rackmeter *rm) |
287 | { | 287 | { |
288 | cancel_delayed_work_sync(&rm->cpu[0].sniffer); | 288 | cancel_delayed_work_sync(&rm->cpu[0].sniffer); |
289 | cancel_delayed_work_sync(&rm->cpu[1].sniffer); | 289 | cancel_delayed_work_sync(&rm->cpu[1].sniffer); |
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) |