diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/tty/serial/mpc52xx_uart.c | 50 |
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 | ||
422 | static struct psc_fifoc __iomem *psc_fifoc; | 422 | static struct psc_fifoc __iomem *psc_fifoc; |
423 | static unsigned int psc_fifoc_irq; | 423 | static unsigned int psc_fifoc_irq; |
424 | static struct clk *psc_fifoc_clk; | ||
424 | 425 | ||
425 | static void mpc512x_psc_fifo_init(struct uart_port *port) | 426 | static 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 */ |
569 | static int __init mpc512x_psc_fifoc_init(void) | 570 | static 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 | |||
618 | out_unmap: | ||
619 | iounmap(psc_fifoc); | ||
620 | out_clk_disable: | ||
621 | clk_disable_unprepare(psc_fifoc_clk); | ||
622 | clk_put(psc_fifoc_clk); | ||
623 | out_ofnode_put: | ||
624 | of_node_put(np); | ||
625 | out_err: | ||
626 | return err; | ||
596 | } | 627 | } |
597 | 628 | ||
598 | static void __exit mpc512x_psc_fifoc_uninit(void) | 629 | static 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 */ |