Skip to content

Commit

Permalink
[ARM] Convert AMBA PL010 driver to use the clk infrastructure
Browse files Browse the repository at this point in the history
Convert the AMBA PL010 serial driver to use the clock infrastructure
to allow EP93xx platforms to properly gate the clock to the UARTs.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
Russell King authored and Russell King committed Apr 22, 2007
1 parent 1b0646a commit ed519de
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
5 changes: 5 additions & 0 deletions arch/arm/mach-ep93xx/clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ struct clk {
u32 enable_mask;
};

static struct clk clk_uart = {
.name = "UARTCLK",
.rate = 14745600,
};
static struct clk clk_pll1 = {
.name = "pll1",
};
Expand All @@ -50,6 +54,7 @@ static struct clk clk_usb_host = {


static struct clk *clocks[] = {
&clk_uart,
&clk_pll1,
&clk_f,
&clk_h,
Expand Down
39 changes: 37 additions & 2 deletions drivers/serial/amba-pl010.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include <linux/serial.h>
#include <linux/amba/bus.h>
#include <linux/amba/serial.h>
#include <linux/clk.h>

#include <asm/io.h>

Expand All @@ -70,6 +71,7 @@
*/
struct uart_amba_port {
struct uart_port port;
struct clk *clk;
struct amba_device *dev;
struct amba_pl010_data *data;
unsigned int old_status;
Expand Down Expand Up @@ -312,12 +314,21 @@ static int pl010_startup(struct uart_port *port)
struct uart_amba_port *uap = (struct uart_amba_port *)port;
int retval;

/*
* Try to enable the clock producer.
*/
retval = clk_enable(uap->clk);
if (retval)
goto out;

uap->port.uartclk = clk_get_rate(uap->clk);

/*
* Allocate the IRQ
*/
retval = request_irq(uap->port.irq, pl010_int, 0, "uart-pl010", uap);
if (retval)
return retval;
goto clk_dis;

/*
* initialise the old status of the modem signals
Expand All @@ -331,6 +342,11 @@ static int pl010_startup(struct uart_port *port)
uap->port.membase + UART010_CR);

return 0;

clk_dis:
clk_disable(uap->clk);
out:
return retval;
}

static void pl010_shutdown(struct uart_port *port)
Expand All @@ -351,6 +367,11 @@ static void pl010_shutdown(struct uart_port *port)
writel(readb(uap->port.membase + UART010_LCRH) &
~(UART01x_LCRH_BRK | UART01x_LCRH_FEN),
uap->port.membase + UART010_LCRH);

/*
* Shut down the clock producer
*/
clk_disable(uap->clk);
}

static void
Expand Down Expand Up @@ -540,6 +561,8 @@ pl010_console_write(struct console *co, const char *s, unsigned int count)
struct uart_amba_port *uap = amba_ports[co->index];
unsigned int status, old_cr;

clk_enable(uap->clk);

/*
* First save the CR then disable the interrupts
*/
Expand All @@ -557,6 +580,8 @@ pl010_console_write(struct console *co, const char *s, unsigned int count)
barrier();
} while (status & UART01x_FR_BUSY);
writel(old_cr, uap->port.membase + UART010_CR);

clk_disable(uap->clk);
}

static void __init
Expand Down Expand Up @@ -605,6 +630,8 @@ static int __init pl010_console_setup(struct console *co, char *options)
if (!uap)
return -ENODEV;

uap->port.uartclk = clk_get_rate(uap->clk);

if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
else
Expand Down Expand Up @@ -666,12 +693,17 @@ static int pl010_probe(struct amba_device *dev, void *id)
goto free;
}

uap->clk = clk_get(&dev->dev, "UARTCLK");
if (IS_ERR(uap->clk)) {
ret = PTR_ERR(uap->clk);
goto unmap;
}

uap->port.dev = &dev->dev;
uap->port.mapbase = dev->res.start;
uap->port.membase = base;
uap->port.iotype = UPIO_MEM;
uap->port.irq = dev->irq[0];
uap->port.uartclk = 14745600;
uap->port.fifosize = 16;
uap->port.ops = &amba_pl010_pops;
uap->port.flags = UPF_BOOT_AUTOCONF;
Expand All @@ -686,6 +718,8 @@ static int pl010_probe(struct amba_device *dev, void *id)
if (ret) {
amba_set_drvdata(dev, NULL);
amba_ports[i] = NULL;
clk_put(uap->clk);
unmap:
iounmap(base);
free:
kfree(uap);
Expand All @@ -708,6 +742,7 @@ static int pl010_remove(struct amba_device *dev)
amba_ports[i] = NULL;

iounmap(uap->port.membase);
clk_put(uap->clk);
kfree(uap);
return 0;
}
Expand Down

0 comments on commit ed519de

Please sign in to comment.