aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-30 20:07:18 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-30 20:07:18 -0500
commit4bcec913d0a98d991c750034a04675443d1f10b5 (patch)
treece2e960ba26d50f09b6a7bd864b2b4d3c275e69b /drivers/tty/serial
parent03c7287dd22c18815964219c9a2e75054cd004df (diff)
parentf878f84373aefda7f041a74b24a83b8b7dec1cf0 (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
Pull more powerpc bits from Ben Herrenschmidt: "Here are a few more powerpc bits for this merge window. The bulk is made of two pull requests from Scott and Anatolij that I had missed previously (they arrived while I was away). Since both their branches are in -next independently, and the content has been around for a little while, they can still go in. The rest is mostly bug and regression fixes, a small series of cleanups to our pseries cpuidle code (including moving it to the right place), and one new cpuidle bakend for the powernv platform. I also wired up the new sched_attr syscalls" * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (37 commits) powerpc: Wire up sched_setattr and sched_getattr syscalls powerpc/hugetlb: Replace __get_cpu_var with get_cpu_var powerpc: Make sure "cache" directory is removed when offlining cpu powerpc/mm: Fix mmap errno when MAP_FIXED is set and mapping exceeds the allowed address space powerpc/powernv/cpuidle: Back-end cpuidle driver for powernv platform. powerpc/pseries/cpuidle: smt-snooze-delay cleanup. powerpc/pseries/cpuidle: Remove MAX_IDLE_STATE macro. powerpc/pseries/cpuidle: Make cpuidle-pseries backend driver a non-module. powerpc/pseries/cpuidle: Use cpuidle_register() for initialisation. powerpc/pseries/cpuidle: Move processor_idle.c to drivers/cpuidle. powerpc: Fix 32-bit frames for signals delivered when transactional powerpc/iommu: Fix initialisation of DART iommu table powerpc/numa: Fix decimal permissions powerpc/mm: Fix compile error of pgtable-ppc64.h powerpc: Fix hw breakpoints on !HAVE_HW_BREAKPOINT configurations clk: corenet: Adds the clock binding powerpc/booke64: Guard e6500 tlb handler with CONFIG_PPC_FSL_BOOK3E powerpc/512x: dts: add MPC5125 clock specs powerpc/512x: clk: support MPC5121/5123/5125 SoC variants powerpc/512x: clk: enforce even SDHC divider values ...
Diffstat (limited to 'drivers/tty/serial')
-rw-r--r--drivers/tty/serial/mpc52xx_uart.c90
1 files changed, 79 insertions, 11 deletions
diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c
index ec06505e3ae6..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;
578 } 584 }
579 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;
600 }
601 psc_fifoc_clk = clk;
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 */
@@ -619,29 +657,55 @@ static irqreturn_t mpc512x_psc_handle_irq(struct uart_port *port)
619} 657}
620 658
621static struct clk *psc_mclk_clk[MPC52xx_PSC_MAXNUM]; 659static struct clk *psc_mclk_clk[MPC52xx_PSC_MAXNUM];
660static struct clk *psc_ipg_clk[MPC52xx_PSC_MAXNUM];
622 661
623/* called from within the .request_port() callback (allocation) */ 662/* called from within the .request_port() callback (allocation) */
624static int mpc512x_psc_alloc_clock(struct uart_port *port) 663static int mpc512x_psc_alloc_clock(struct uart_port *port)
625{ 664{
626 int psc_num; 665 int psc_num;
627 char clk_name[16];
628 struct clk *clk; 666 struct clk *clk;
629 int err; 667 int err;
630 668
631 psc_num = (port->mapbase & 0xf00) >> 8; 669 psc_num = (port->mapbase & 0xf00) >> 8;
632 snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num); 670
633 clk = devm_clk_get(port->dev, clk_name); 671 clk = devm_clk_get(port->dev, "mclk");
634 if (IS_ERR(clk)) { 672 if (IS_ERR(clk)) {
635 dev_err(port->dev, "Failed to get MCLK!\n"); 673 dev_err(port->dev, "Failed to get MCLK!\n");
636 return PTR_ERR(clk); 674 err = PTR_ERR(clk);
675 goto out_err;
637 } 676 }
638 err = clk_prepare_enable(clk); 677 err = clk_prepare_enable(clk);
639 if (err) { 678 if (err) {
640 dev_err(port->dev, "Failed to enable MCLK!\n"); 679 dev_err(port->dev, "Failed to enable MCLK!\n");
641 return err; 680 goto out_err;
642 } 681 }
643 psc_mclk_clk[psc_num] = clk; 682 psc_mclk_clk[psc_num] = clk;
683
684 clk = devm_clk_get(port->dev, "ipg");
685 if (IS_ERR(clk)) {
686 dev_err(port->dev, "Failed to get IPG clock!\n");
687 err = PTR_ERR(clk);
688 goto out_err;
689 }
690 err = clk_prepare_enable(clk);
691 if (err) {
692 dev_err(port->dev, "Failed to enable IPG clock!\n");
693 goto out_err;
694 }
695 psc_ipg_clk[psc_num] = clk;
696
644 return 0; 697 return 0;
698
699out_err:
700 if (psc_mclk_clk[psc_num]) {
701 clk_disable_unprepare(psc_mclk_clk[psc_num]);
702 psc_mclk_clk[psc_num] = NULL;
703 }
704 if (psc_ipg_clk[psc_num]) {
705 clk_disable_unprepare(psc_ipg_clk[psc_num]);
706 psc_ipg_clk[psc_num] = NULL;
707 }
708 return err;
645} 709}
646 710
647/* called from within the .release_port() callback (release) */ 711/* called from within the .release_port() callback (release) */
@@ -656,6 +720,10 @@ static void mpc512x_psc_relse_clock(struct uart_port *port)
656 clk_disable_unprepare(clk); 720 clk_disable_unprepare(clk);
657 psc_mclk_clk[psc_num] = NULL; 721 psc_mclk_clk[psc_num] = NULL;
658 } 722 }
723 if (psc_ipg_clk[psc_num]) {
724 clk_disable_unprepare(psc_ipg_clk[psc_num]);
725 psc_ipg_clk[psc_num] = NULL;
726 }
659} 727}
660 728
661/* implementation of the .clock() callback (enable/disable) */ 729/* implementation of the .clock() callback (enable/disable) */