aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/serial')
-rw-r--r--drivers/tty/serial/mpc52xx_uart.c50
1 files changed, 44 insertions, 6 deletions
diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c
index 6345f377a246..97888f4900ec 100644
--- a/drivers/tty/serial/mpc52xx_uart.c
+++ b/drivers/tty/serial/mpc52xx_uart.c
@@ -421,6 +421,7 @@ struct psc_fifoc {
421 421
422static struct psc_fifoc __iomem *psc_fifoc; 422static struct psc_fifoc __iomem *psc_fifoc;
423static unsigned int psc_fifoc_irq; 423static unsigned int psc_fifoc_irq;
424static struct clk *psc_fifoc_clk;
424 425
425static void mpc512x_psc_fifo_init(struct uart_port *port) 426static void mpc512x_psc_fifo_init(struct uart_port *port)
426{ 427{
@@ -568,36 +569,73 @@ static unsigned int mpc512x_psc_set_baudrate(struct uart_port *port,
568/* Init PSC FIFO Controller */ 569/* Init PSC FIFO Controller */
569static int __init mpc512x_psc_fifoc_init(void) 570static int __init mpc512x_psc_fifoc_init(void)
570{ 571{
572 int err;
571 struct device_node *np; 573 struct device_node *np;
574 struct clk *clk;
575
576 /* default error code, potentially overwritten by clock calls */
577 err = -ENODEV;
572 578
573 np = of_find_compatible_node(NULL, NULL, 579 np = of_find_compatible_node(NULL, NULL,
574 "fsl,mpc5121-psc-fifo"); 580 "fsl,mpc5121-psc-fifo");
575 if (!np) { 581 if (!np) {
576 pr_err("%s: Can't find FIFOC node\n", __func__); 582 pr_err("%s: Can't find FIFOC node\n", __func__);
577 return -ENODEV; 583 goto out_err;
584 }
585
586 clk = of_clk_get(np, 0);
587 if (IS_ERR(clk)) {
588 /* backwards compat with device trees that lack clock specs */
589 clk = clk_get_sys(np->name, "ipg");
590 }
591 if (IS_ERR(clk)) {
592 pr_err("%s: Can't lookup FIFO clock\n", __func__);
593 err = PTR_ERR(clk);
594 goto out_ofnode_put;
595 }
596 if (clk_prepare_enable(clk)) {
597 pr_err("%s: Can't enable FIFO clock\n", __func__);
598 clk_put(clk);
599 goto out_ofnode_put;
578 } 600 }
601 psc_fifoc_clk = clk;
579 602
580 psc_fifoc = of_iomap(np, 0); 603 psc_fifoc = of_iomap(np, 0);
581 if (!psc_fifoc) { 604 if (!psc_fifoc) {
582 pr_err("%s: Can't map FIFOC\n", __func__); 605 pr_err("%s: Can't map FIFOC\n", __func__);
583 of_node_put(np); 606 goto out_clk_disable;
584 return -ENODEV;
585 } 607 }
586 608
587 psc_fifoc_irq = irq_of_parse_and_map(np, 0); 609 psc_fifoc_irq = irq_of_parse_and_map(np, 0);
588 of_node_put(np);
589 if (psc_fifoc_irq == 0) { 610 if (psc_fifoc_irq == 0) {
590 pr_err("%s: Can't get FIFOC irq\n", __func__); 611 pr_err("%s: Can't get FIFOC irq\n", __func__);
591 iounmap(psc_fifoc); 612 goto out_unmap;
592 return -ENODEV;
593 } 613 }
594 614
615 of_node_put(np);
595 return 0; 616 return 0;
617
618out_unmap:
619 iounmap(psc_fifoc);
620out_clk_disable:
621 clk_disable_unprepare(psc_fifoc_clk);
622 clk_put(psc_fifoc_clk);
623out_ofnode_put:
624 of_node_put(np);
625out_err:
626 return err;
596} 627}
597 628
598static void __exit mpc512x_psc_fifoc_uninit(void) 629static void __exit mpc512x_psc_fifoc_uninit(void)
599{ 630{
600 iounmap(psc_fifoc); 631 iounmap(psc_fifoc);
632
633 /* disable the clock, errors are not fatal */
634 if (psc_fifoc_clk) {
635 clk_disable_unprepare(psc_fifoc_clk);
636 clk_put(psc_fifoc_clk);
637 psc_fifoc_clk = NULL;
638 }
601} 639}
602 640
603/* 512x specific interrupt handler. The caller holds the port lock */ 641/* 512x specific interrupt handler. The caller holds the port lock */