mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 19:56:18 +00:00
Merge branch 'v2630-rc3-fixes' of git://aeryn.fluff.org.uk/bjdooks/linux
This commit is contained in:
commit
bc75159f2e
5 changed files with 68 additions and 3 deletions
|
@ -21,6 +21,7 @@
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
|
|
||||||
#include <mach/hardware.h>
|
#include <mach/hardware.h>
|
||||||
|
#include <asm/cacheflush.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
|
|
||||||
#include <mach/regs-power.h>
|
#include <mach/regs-power.h>
|
||||||
|
@ -39,6 +40,8 @@ static void s3c2412_cpu_suspend(void)
|
||||||
{
|
{
|
||||||
unsigned long tmp;
|
unsigned long tmp;
|
||||||
|
|
||||||
|
flush_cache_all();
|
||||||
|
|
||||||
/* set our standby method to sleep */
|
/* set our standby method to sleep */
|
||||||
|
|
||||||
tmp = __raw_readl(S3C2412_PWRCFG);
|
tmp = __raw_readl(S3C2412_PWRCFG);
|
||||||
|
|
|
@ -40,6 +40,8 @@
|
||||||
|
|
||||||
#define S3C64XX_PA_FB (0x77100000)
|
#define S3C64XX_PA_FB (0x77100000)
|
||||||
#define S3C64XX_PA_SYSCON (0x7E00F000)
|
#define S3C64XX_PA_SYSCON (0x7E00F000)
|
||||||
|
#define S3C64XX_PA_IIS0 (0x7F002000)
|
||||||
|
#define S3C64XX_PA_IIS1 (0x7F003000)
|
||||||
#define S3C64XX_PA_TIMER (0x7F006000)
|
#define S3C64XX_PA_TIMER (0x7F006000)
|
||||||
#define S3C64XX_PA_IIC0 (0x7F004000)
|
#define S3C64XX_PA_IIC0 (0x7F004000)
|
||||||
#define S3C64XX_PA_IIC1 (0x7F00F000)
|
#define S3C64XX_PA_IIC1 (0x7F00F000)
|
||||||
|
|
|
@ -102,6 +102,7 @@ static struct s3c24xx_uart_info s3c6400_uart_inf = {
|
||||||
.name = "Samsung S3C6400 UART",
|
.name = "Samsung S3C6400 UART",
|
||||||
.type = PORT_S3C6400,
|
.type = PORT_S3C6400,
|
||||||
.fifosize = 64,
|
.fifosize = 64,
|
||||||
|
.has_divslot = 1,
|
||||||
.rx_fifomask = S3C2440_UFSTAT_RXMASK,
|
.rx_fifomask = S3C2440_UFSTAT_RXMASK,
|
||||||
.rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
|
.rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
|
||||||
.rx_fifofull = S3C2440_UFSTAT_RXFULL,
|
.rx_fifofull = S3C2440_UFSTAT_RXFULL,
|
||||||
|
|
|
@ -508,6 +508,7 @@ s3c24xx_serial_setsource(struct uart_port *port, struct s3c24xx_uart_clksrc *c)
|
||||||
struct baud_calc {
|
struct baud_calc {
|
||||||
struct s3c24xx_uart_clksrc *clksrc;
|
struct s3c24xx_uart_clksrc *clksrc;
|
||||||
unsigned int calc;
|
unsigned int calc;
|
||||||
|
unsigned int divslot;
|
||||||
unsigned int quot;
|
unsigned int quot;
|
||||||
struct clk *src;
|
struct clk *src;
|
||||||
};
|
};
|
||||||
|
@ -517,6 +518,7 @@ static int s3c24xx_serial_calcbaud(struct baud_calc *calc,
|
||||||
struct s3c24xx_uart_clksrc *clksrc,
|
struct s3c24xx_uart_clksrc *clksrc,
|
||||||
unsigned int baud)
|
unsigned int baud)
|
||||||
{
|
{
|
||||||
|
struct s3c24xx_uart_port *ourport = to_ourport(port);
|
||||||
unsigned long rate;
|
unsigned long rate;
|
||||||
|
|
||||||
calc->src = clk_get(port->dev, clksrc->name);
|
calc->src = clk_get(port->dev, clksrc->name);
|
||||||
|
@ -527,8 +529,24 @@ static int s3c24xx_serial_calcbaud(struct baud_calc *calc,
|
||||||
rate /= clksrc->divisor;
|
rate /= clksrc->divisor;
|
||||||
|
|
||||||
calc->clksrc = clksrc;
|
calc->clksrc = clksrc;
|
||||||
calc->quot = (rate + (8 * baud)) / (16 * baud);
|
|
||||||
calc->calc = (rate / (calc->quot * 16));
|
if (ourport->info->has_divslot) {
|
||||||
|
unsigned long div = rate / baud;
|
||||||
|
|
||||||
|
/* The UDIVSLOT register on the newer UARTs allows us to
|
||||||
|
* get a divisor adjustment of 1/16th on the baud clock.
|
||||||
|
*
|
||||||
|
* We don't keep the UDIVSLOT value (the 16ths we calculated
|
||||||
|
* by not multiplying the baud by 16) as it is easy enough
|
||||||
|
* to recalculate.
|
||||||
|
*/
|
||||||
|
|
||||||
|
calc->quot = div / 16;
|
||||||
|
calc->calc = rate / div;
|
||||||
|
} else {
|
||||||
|
calc->quot = (rate + (8 * baud)) / (16 * baud);
|
||||||
|
calc->calc = (rate / (calc->quot * 16));
|
||||||
|
}
|
||||||
|
|
||||||
calc->quot--;
|
calc->quot--;
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -611,6 +629,30 @@ static unsigned int s3c24xx_serial_getclk(struct uart_port *port,
|
||||||
return best->quot;
|
return best->quot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* udivslot_table[]
|
||||||
|
*
|
||||||
|
* This table takes the fractional value of the baud divisor and gives
|
||||||
|
* the recommended setting for the UDIVSLOT register.
|
||||||
|
*/
|
||||||
|
static u16 udivslot_table[16] = {
|
||||||
|
[0] = 0x0000,
|
||||||
|
[1] = 0x0080,
|
||||||
|
[2] = 0x0808,
|
||||||
|
[3] = 0x0888,
|
||||||
|
[4] = 0x2222,
|
||||||
|
[5] = 0x4924,
|
||||||
|
[6] = 0x4A52,
|
||||||
|
[7] = 0x54AA,
|
||||||
|
[8] = 0x5555,
|
||||||
|
[9] = 0xD555,
|
||||||
|
[10] = 0xD5D5,
|
||||||
|
[11] = 0xDDD5,
|
||||||
|
[12] = 0xDDDD,
|
||||||
|
[13] = 0xDFDD,
|
||||||
|
[14] = 0xDFDF,
|
||||||
|
[15] = 0xFFDF,
|
||||||
|
};
|
||||||
|
|
||||||
static void s3c24xx_serial_set_termios(struct uart_port *port,
|
static void s3c24xx_serial_set_termios(struct uart_port *port,
|
||||||
struct ktermios *termios,
|
struct ktermios *termios,
|
||||||
struct ktermios *old)
|
struct ktermios *old)
|
||||||
|
@ -623,6 +665,7 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
|
||||||
unsigned int baud, quot;
|
unsigned int baud, quot;
|
||||||
unsigned int ulcon;
|
unsigned int ulcon;
|
||||||
unsigned int umcon;
|
unsigned int umcon;
|
||||||
|
unsigned int udivslot = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We don't support modem control lines.
|
* We don't support modem control lines.
|
||||||
|
@ -644,6 +687,7 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
|
||||||
/* check to see if we need to change clock source */
|
/* check to see if we need to change clock source */
|
||||||
|
|
||||||
if (ourport->clksrc != clksrc || ourport->baudclk != clk) {
|
if (ourport->clksrc != clksrc || ourport->baudclk != clk) {
|
||||||
|
dbg("selecting clock %p\n", clk);
|
||||||
s3c24xx_serial_setsource(port, clksrc);
|
s3c24xx_serial_setsource(port, clksrc);
|
||||||
|
|
||||||
if (ourport->baudclk != NULL && !IS_ERR(ourport->baudclk)) {
|
if (ourport->baudclk != NULL && !IS_ERR(ourport->baudclk)) {
|
||||||
|
@ -658,6 +702,13 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
|
||||||
ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0;
|
ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ourport->info->has_divslot) {
|
||||||
|
unsigned int div = ourport->baudclk_rate / baud;
|
||||||
|
|
||||||
|
udivslot = udivslot_table[div & 15];
|
||||||
|
dbg("udivslot = %04x (div %d)\n", udivslot, div & 15);
|
||||||
|
}
|
||||||
|
|
||||||
switch (termios->c_cflag & CSIZE) {
|
switch (termios->c_cflag & CSIZE) {
|
||||||
case CS5:
|
case CS5:
|
||||||
dbg("config: 5bits/char\n");
|
dbg("config: 5bits/char\n");
|
||||||
|
@ -697,12 +748,16 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
|
||||||
|
|
||||||
spin_lock_irqsave(&port->lock, flags);
|
spin_lock_irqsave(&port->lock, flags);
|
||||||
|
|
||||||
dbg("setting ulcon to %08x, brddiv to %d\n", ulcon, quot);
|
dbg("setting ulcon to %08x, brddiv to %d, udivslot %08x\n",
|
||||||
|
ulcon, quot, udivslot);
|
||||||
|
|
||||||
wr_regl(port, S3C2410_ULCON, ulcon);
|
wr_regl(port, S3C2410_ULCON, ulcon);
|
||||||
wr_regl(port, S3C2410_UBRDIV, quot);
|
wr_regl(port, S3C2410_UBRDIV, quot);
|
||||||
wr_regl(port, S3C2410_UMCON, umcon);
|
wr_regl(port, S3C2410_UMCON, umcon);
|
||||||
|
|
||||||
|
if (ourport->info->has_divslot)
|
||||||
|
wr_regl(port, S3C2443_DIVSLOT, udivslot);
|
||||||
|
|
||||||
dbg("uart: ulcon = 0x%08x, ucon = 0x%08x, ufcon = 0x%08x\n",
|
dbg("uart: ulcon = 0x%08x, ucon = 0x%08x, ufcon = 0x%08x\n",
|
||||||
rd_regl(port, S3C2410_ULCON),
|
rd_regl(port, S3C2410_ULCON),
|
||||||
rd_regl(port, S3C2410_UCON),
|
rd_regl(port, S3C2410_UCON),
|
||||||
|
|
|
@ -21,6 +21,10 @@ struct s3c24xx_uart_info {
|
||||||
unsigned long tx_fifoshift;
|
unsigned long tx_fifoshift;
|
||||||
unsigned long tx_fifofull;
|
unsigned long tx_fifofull;
|
||||||
|
|
||||||
|
/* uart port features */
|
||||||
|
|
||||||
|
unsigned int has_divslot:1;
|
||||||
|
|
||||||
/* clock source control */
|
/* clock source control */
|
||||||
|
|
||||||
int (*get_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk);
|
int (*get_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk);
|
||||||
|
|
Loading…
Reference in a new issue