aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/serial/pxa.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index 59889f6a86b2..af3a011b2b24 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -42,6 +42,7 @@
42#include <linux/tty.h> 42#include <linux/tty.h>
43#include <linux/tty_flip.h> 43#include <linux/tty_flip.h>
44#include <linux/serial_core.h> 44#include <linux/serial_core.h>
45#include <linux/clk.h>
45 46
46#include <asm/io.h> 47#include <asm/io.h>
47#include <asm/hardware.h> 48#include <asm/hardware.h>
@@ -55,7 +56,7 @@ struct uart_pxa_port {
55 unsigned char lcr; 56 unsigned char lcr;
56 unsigned char mcr; 57 unsigned char mcr;
57 unsigned int lsr_break_flag; 58 unsigned int lsr_break_flag;
58 unsigned int cken; 59 struct clk *clk;
59 char *name; 60 char *name;
60}; 61};
61 62
@@ -351,6 +352,8 @@ static int serial_pxa_startup(struct uart_port *port)
351 else 352 else
352 up->mcr = 0; 353 up->mcr = 0;
353 354
355 up->port.uartclk = clk_get_rate(up->clk);
356
354 /* 357 /*
355 * Allocate the IRQ 358 * Allocate the IRQ
356 */ 359 */
@@ -546,9 +549,11 @@ serial_pxa_pm(struct uart_port *port, unsigned int state,
546 unsigned int oldstate) 549 unsigned int oldstate)
547{ 550{
548 struct uart_pxa_port *up = (struct uart_pxa_port *)port; 551 struct uart_pxa_port *up = (struct uart_pxa_port *)port;
549 pxa_set_cken(up->cken, !state); 552
550 if (!state) 553 if (!state)
551 udelay(1); 554 clk_enable(up->clk);
555 else
556 clk_disable(up->clk);
552} 557}
553 558
554static void serial_pxa_release_port(struct uart_port *port) 559static void serial_pxa_release_port(struct uart_port *port)
@@ -635,6 +640,8 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count)
635 struct uart_pxa_port *up = serial_pxa_ports[co->index]; 640 struct uart_pxa_port *up = serial_pxa_ports[co->index];
636 unsigned int ier; 641 unsigned int ier;
637 642
643 clk_enable(up->clk);
644
638 /* 645 /*
639 * First save the IER then disable the interrupts 646 * First save the IER then disable the interrupts
640 */ 647 */
@@ -649,6 +656,8 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count)
649 */ 656 */
650 wait_for_xmitr(up); 657 wait_for_xmitr(up);
651 serial_out(up, UART_IER, ier); 658 serial_out(up, UART_IER, ier);
659
660 clk_disable(up->clk);
652} 661}
653 662
654static int __init 663static int __init
@@ -752,6 +761,12 @@ static int serial_pxa_probe(struct platform_device *dev)
752 if (!sport) 761 if (!sport)
753 return -ENOMEM; 762 return -ENOMEM;
754 763
764 sport->clk = clk_get(&dev->dev, "UARTCLK");
765 if (IS_ERR(sport->clk)) {
766 ret = PTR_ERR(sport->clk);
767 goto err_free;
768 }
769
755 sport->port.type = PORT_PXA; 770 sport->port.type = PORT_PXA;
756 sport->port.iotype = UPIO_MEM; 771 sport->port.iotype = UPIO_MEM;
757 sport->port.mapbase = mmres->start; 772 sport->port.mapbase = mmres->start;
@@ -761,7 +776,7 @@ static int serial_pxa_probe(struct platform_device *dev)
761 sport->port.line = dev->id; 776 sport->port.line = dev->id;
762 sport->port.dev = &dev->dev; 777 sport->port.dev = &dev->dev;
763 sport->port.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; 778 sport->port.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF;
764 sport->port.uartclk = 921600 * 16; 779 sport->port.uartclk = clk_get_rate(sport->clk);
765 780
766 /* 781 /*
767 * Is it worth keeping this? 782 * Is it worth keeping this?
@@ -780,7 +795,7 @@ static int serial_pxa_probe(struct platform_device *dev)
780 sport->port.membase = ioremap(mmres->start, mmres->end - mmres->start + 1); 795 sport->port.membase = ioremap(mmres->start, mmres->end - mmres->start + 1);
781 if (!sport->port.membase) { 796 if (!sport->port.membase) {
782 ret = -ENOMEM; 797 ret = -ENOMEM;
783 goto err_free; 798 goto err_clk;
784 } 799 }
785 800
786 serial_pxa_ports[dev->id] = sport; 801 serial_pxa_ports[dev->id] = sport;
@@ -790,6 +805,8 @@ static int serial_pxa_probe(struct platform_device *dev)
790 805
791 return 0; 806 return 0;
792 807
808 err_clk:
809 clk_put(sport->clk);
793 err_free: 810 err_free:
794 kfree(sport); 811 kfree(sport);
795 return ret; 812 return ret;
@@ -802,6 +819,7 @@ static int serial_pxa_remove(struct platform_device *dev)
802 platform_set_drvdata(dev, NULL); 819 platform_set_drvdata(dev, NULL);
803 820
804 uart_remove_one_port(&serial_pxa_reg, &sport->port); 821 uart_remove_one_port(&serial_pxa_reg, &sport->port);
822 clk_put(sport->clk);
805 kfree(sport); 823 kfree(sport);
806 824
807 return 0; 825 return 0;