Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bc75159f authored by Russell King's avatar Russell King Committed by Russell King
Browse files

Merge branch 'v2630-rc3-fixes' of git://aeryn.fluff.org.uk/bjdooks/linux

parents b4348f32 dc8fc7ed
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <linux/io.h>

#include <mach/hardware.h>
#include <asm/cacheflush.h>
#include <asm/irq.h>

#include <mach/regs-power.h>
@@ -39,6 +40,8 @@ static void s3c2412_cpu_suspend(void)
{
	unsigned long tmp;

	flush_cache_all();

	/* set our standby method to sleep */

	tmp = __raw_readl(S3C2412_PWRCFG);
+2 −0
Original line number Diff line number Diff line
@@ -40,6 +40,8 @@

#define S3C64XX_PA_FB		(0x77100000)
#define S3C64XX_PA_SYSCON	(0x7E00F000)
#define S3C64XX_PA_IIS0		(0x7F002000)
#define S3C64XX_PA_IIS1		(0x7F003000)
#define S3C64XX_PA_TIMER	(0x7F006000)
#define S3C64XX_PA_IIC0		(0x7F004000)
#define S3C64XX_PA_IIC1		(0x7F00F000)
+1 −0
Original line number Diff line number Diff line
@@ -102,6 +102,7 @@ static struct s3c24xx_uart_info s3c6400_uart_inf = {
	.name		= "Samsung S3C6400 UART",
	.type		= PORT_S3C6400,
	.fifosize	= 64,
	.has_divslot	= 1,
	.rx_fifomask	= S3C2440_UFSTAT_RXMASK,
	.rx_fifoshift	= S3C2440_UFSTAT_RXSHIFT,
	.rx_fifofull	= S3C2440_UFSTAT_RXFULL,
+58 −3
Original line number Diff line number Diff line
@@ -508,6 +508,7 @@ s3c24xx_serial_setsource(struct uart_port *port, struct s3c24xx_uart_clksrc *c)
struct baud_calc {
	struct s3c24xx_uart_clksrc	*clksrc;
	unsigned int			 calc;
	unsigned int			 divslot;
	unsigned int			 quot;
	struct clk			*src;
};
@@ -517,6 +518,7 @@ static int s3c24xx_serial_calcbaud(struct baud_calc *calc,
				   struct s3c24xx_uart_clksrc *clksrc,
				   unsigned int baud)
{
	struct s3c24xx_uart_port *ourport = to_ourport(port);
	unsigned long rate;

	calc->src = clk_get(port->dev, clksrc->name);
@@ -527,8 +529,24 @@ static int s3c24xx_serial_calcbaud(struct baud_calc *calc,
	rate /= clksrc->divisor;

	calc->clksrc = clksrc;

	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--;
	return 1;
@@ -611,6 +629,30 @@ static unsigned int s3c24xx_serial_getclk(struct uart_port *port,
	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,
				       struct ktermios *termios,
				       struct ktermios *old)
@@ -623,6 +665,7 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
	unsigned int baud, quot;
	unsigned int ulcon;
	unsigned int umcon;
	unsigned int udivslot = 0;

	/*
	 * 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 */

	if (ourport->clksrc != clksrc || ourport->baudclk != clk) {
		dbg("selecting clock %p\n", clk);
		s3c24xx_serial_setsource(port, clksrc);

		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;
	}

	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) {
	case CS5:
		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);

	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_UBRDIV, quot);
	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",
	    rd_regl(port, S3C2410_ULCON),
	    rd_regl(port, S3C2410_UCON),
+4 −0
Original line number Diff line number Diff line
@@ -21,6 +21,10 @@ struct s3c24xx_uart_info {
	unsigned long		tx_fifoshift;
	unsigned long		tx_fifofull;

	/* uart port features */

	unsigned int		has_divslot:1;

	/* clock source control */

	int (*get_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk);