aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorGerhard Sittig <gsi@denx.de>2013-11-30 17:51:30 -0500
committerAnatolij Gustschin <agust@denx.de>2014-01-12 12:53:05 -0500
commitcb1ea81230f0b5593b847d2cb3d9304e1d5e4234 (patch)
tree0bfaaf1a11d3b29fe43d811f0520b797d12d8927 /drivers
parente149b42b8605f4e0e86662fe880716ccdfdb4ef9 (diff)
serial: mpc512x: setup the PSC FIFO clock as well
prepare and enable the FIFO clock upon PSC FIFO initialization, check for and propagage errors when enabling the PSC FIFO clock, disable and unprepare the FIFO clock upon PSC FIFO uninitialization devm_{get,put}_clk() doesn't apply here, as the SoC provides a single FIFO component which is shared among several PSC components, thus the FIFO isn't associated with a device (while the PSCs are) provide a fallback clock lookup approach in case the OF based clock lookup for the PSC FIFO fails, this allows for successful operation in the presence of an outdated device tree which lacks clock specs Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Jiri Slaby <jslaby@suse.cz> Cc: linux-serial@vger.kernel.org Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Gerhard Sittig <gsi@denx.de> Signed-off-by: Anatolij Gustschin <agust@denx.de>
Diffstat (limited to 'drivers')
-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 */