Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm: (241 commits) [ARM] 5171/1: ep93xx: fix compilation of modules using clocks [ARM] 5133/2: at91sam9g20 defconfig file [ARM] 5130/4: Support for the at91sam9g20 [ARM] 5160/1: IOP3XX: gpio/gpiolib support [ARM] at91: Fix NAND FLASH timings for at91sam9x evaluation kits. [ARM] 5084/1: zylonite: Register AC97 device [ARM] 5085/2: PXA: Move AC97 over to the new central device declaration model [ARM] 5120/1: pxa: correct platform driver names for PXA25x and PXA27x UDC drivers [ARM] 5147/1: pxaficp_ir: drop pxa_gpio_mode calls, as pin setting [ARM] 5145/1: PXA2xx: provide api to control IrDA pins state [ARM] 5144/1: pxaficp_ir: cleanup includes [ARM] pxa: remove pxa_set_cken() [ARM] pxa: allow clk aliases [ARM] Feroceon: don't disable BPU on boot [ARM] Orion: LED support for HP mv2120 [ARM] Orion: add RD88F5181L-FXO support [ARM] Orion: add RD88F5181L-GE support [ARM] Orion: add Netgear WNR854T support [ARM] s3c2410_defconfig: update for current build [ARM] Acer n30: Minor style and indentation fixes. ...
This commit is contained in:
@@ -448,22 +448,27 @@ config SERIAL_CLPS711X_CONSOLE
|
||||
your boot loader (lilo or loadlin) about how to pass options to the
|
||||
kernel at boot time.)
|
||||
|
||||
config SERIAL_S3C2410
|
||||
tristate "Samsung S3C2410/S3C2440/S3C2442/S3C2412 Serial port support"
|
||||
depends on ARM && ARCH_S3C2410
|
||||
select SERIAL_CORE
|
||||
config SERIAL_SAMSUNG
|
||||
tristate "Samsung SoC serial support"
|
||||
depends on ARM && PLAT_S3C24XX
|
||||
help
|
||||
Support for the on-chip UARTs on the Samsung S3C24XX series CPUs,
|
||||
providing /dev/ttySAC0, 1 and 2 (note, some machines may not
|
||||
provide all of these ports, depending on how the serial port
|
||||
pins are configured.
|
||||
|
||||
Currently this driver supports the UARTS on the S3C2410, S3C2440,
|
||||
S3C2442, S3C2412 and S3C2413 CPUs.
|
||||
config SERIAL_SAMSUNG_DEBUG
|
||||
bool "Samsung SoC serial debug"
|
||||
depends on SERIAL_SAMSUNG
|
||||
help
|
||||
Add support for debugging the serial driver. Since this is
|
||||
generally being used as a console, we use our own output
|
||||
routines that go via the low-level debug printascii()
|
||||
function.
|
||||
|
||||
config SERIAL_S3C2410_CONSOLE
|
||||
bool "Support for console on S3C2410 serial port"
|
||||
depends on SERIAL_S3C2410=y
|
||||
config SERIAL_SAMSUNG_CONSOLE
|
||||
bool "Support for console on Samsung SoC serial port"
|
||||
depends on SERIAL_SAMSUNG=y
|
||||
select SERIAL_CORE_CONSOLE
|
||||
help
|
||||
Allow selection of the S3C24XX on-board serial ports for use as
|
||||
@@ -476,6 +481,37 @@ config SERIAL_S3C2410_CONSOLE
|
||||
your boot loader about how to pass options to the kernel at
|
||||
boot time.)
|
||||
|
||||
config SERIAL_S3C2400
|
||||
tristate "Samsung S3C2410 Serial port support"
|
||||
depends on ARM && SERIAL_SAMSUNG && CPU_S3C2400
|
||||
default y if CPU_S3C2400
|
||||
help
|
||||
Serial port support for the Samsung S3C2400 SoC
|
||||
|
||||
config SERIAL_S3C2410
|
||||
tristate "Samsung S3C2410 Serial port support"
|
||||
depends on SERIAL_SAMSUNG && CPU_S3C2410
|
||||
default y if CPU_S3C2410
|
||||
help
|
||||
Serial port support for the Samsung S3C2410 SoC
|
||||
|
||||
config SERIAL_S3C2412
|
||||
tristate "Samsung S3C2412/S3C2413 Serial port support"
|
||||
depends on SERIAL_SAMSUNG && CPU_S3C2412
|
||||
default y if CPU_S3C2412
|
||||
help
|
||||
Serial port support for the Samsung S3C2412 and S3C2413 SoC
|
||||
|
||||
config SERIAL_S3C2440
|
||||
tristate "Samsung S3C2440/S3C2442 Serial port support"
|
||||
depends on SERIAL_SAMSUNG && (CPU_S3C2440 || CPU_S3C2442)
|
||||
default y if CPU_S3C2440
|
||||
default y if CPU_S3C2442
|
||||
help
|
||||
Serial port support for the Samsung S3C2440 and S3C2442 SoC
|
||||
|
||||
|
||||
|
||||
config SERIAL_DZ
|
||||
bool "DECstation DZ serial driver"
|
||||
depends on MACH_DECSTATION && 32BIT
|
||||
@@ -753,7 +789,7 @@ config BFIN_UART3_CTSRTS
|
||||
|
||||
config SERIAL_IMX
|
||||
bool "IMX serial port support"
|
||||
depends on ARM && ARCH_IMX
|
||||
depends on ARM && (ARCH_IMX || ARCH_MXC)
|
||||
select SERIAL_CORE
|
||||
help
|
||||
If you have a machine based on a Motorola IMX CPU you
|
||||
|
||||
@@ -28,7 +28,11 @@ obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o
|
||||
obj-$(CONFIG_SERIAL_SA1100) += sa1100.o
|
||||
obj-$(CONFIG_SERIAL_BFIN) += bfin_5xx.o
|
||||
obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o
|
||||
obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o
|
||||
obj-$(CONFIG_SERIAL_S3C2400) += s3c2400.o
|
||||
obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o
|
||||
obj-$(CONFIG_SERIAL_S3C2412) += s3c2412.o
|
||||
obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o
|
||||
obj-$(CONFIG_SERIAL_SUNCORE) += suncore.o
|
||||
obj-$(CONFIG_SERIAL_SUNHV) += sunhv.o
|
||||
obj-$(CONFIG_SERIAL_SUNZILOG) += sunzilog.o
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
@@ -61,6 +62,11 @@
|
||||
#define UBIR 0xa4 /* BRM Incremental Register */
|
||||
#define UBMR 0xa8 /* BRM Modulator Register */
|
||||
#define UBRC 0xac /* Baud Rate Count Register */
|
||||
#if defined CONFIG_ARCH_MX3 || defined CONFIG_ARCH_MX2
|
||||
#define ONEMS 0xb0 /* One Millisecond register */
|
||||
#define UTS 0xb4 /* UART Test Register */
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_IMX
|
||||
#define BIPR1 0xb0 /* Incremental Preset Register 1 */
|
||||
#define BIPR2 0xb4 /* Incremental Preset Register 2 */
|
||||
#define BIPR3 0xb8 /* Incremental Preset Register 3 */
|
||||
@@ -70,6 +76,7 @@
|
||||
#define BMPR3 0xc8 /* BRM Modulator Register 3 */
|
||||
#define BMPR4 0xcc /* BRM Modulator Register 4 */
|
||||
#define UTS 0xd0 /* UART Test Register */
|
||||
#endif
|
||||
|
||||
/* UART Control Register Bit Fields.*/
|
||||
#define URXD_CHARRDY (1<<15)
|
||||
@@ -89,7 +96,12 @@
|
||||
#define UCR1_RTSDEN (1<<5) /* RTS delta interrupt enable */
|
||||
#define UCR1_SNDBRK (1<<4) /* Send break */
|
||||
#define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */
|
||||
#ifdef CONFIG_ARCH_IMX
|
||||
#define UCR1_UARTCLKEN (1<<2) /* UART clock enabled */
|
||||
#endif
|
||||
#if defined CONFIG_ARCH_MX3 || defined CONFIG_ARCH_MX2
|
||||
#define UCR1_UARTCLKEN (0) /* not present on mx2/mx3 */
|
||||
#endif
|
||||
#define UCR1_DOZE (1<<1) /* Doze */
|
||||
#define UCR1_UARTEN (1<<0) /* UART enabled */
|
||||
#define UCR2_ESCI (1<<15) /* Escape seq interrupt enable */
|
||||
@@ -163,8 +175,19 @@
|
||||
#define UTS_SOFTRST (1<<0) /* Software reset */
|
||||
|
||||
/* We've been assigned a range on the "Low-density serial ports" major */
|
||||
#ifdef CONFIG_ARCH_IMX
|
||||
#define SERIAL_IMX_MAJOR 204
|
||||
#define MINOR_START 41
|
||||
#define DEV_NAME "ttySMX"
|
||||
#define MAX_INTERNAL_IRQ IMX_IRQS
|
||||
#endif
|
||||
|
||||
#if defined CONFIG_ARCH_MX3 || defined CONFIG_ARCH_MX2
|
||||
#define SERIAL_IMX_MAJOR 207
|
||||
#define MINOR_START 16
|
||||
#define DEV_NAME "ttymxc"
|
||||
#define MAX_INTERNAL_IRQ MXC_MAX_INT_LINES
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This determines how often we check the modem status signals
|
||||
@@ -176,12 +199,15 @@
|
||||
|
||||
#define DRIVER_NAME "IMX-uart"
|
||||
|
||||
#define UART_NR 8
|
||||
|
||||
struct imx_port {
|
||||
struct uart_port port;
|
||||
struct timer_list timer;
|
||||
unsigned int old_status;
|
||||
int txirq,rxirq,rtsirq;
|
||||
int have_rtscts:1;
|
||||
struct clk *clk;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -405,6 +431,26 @@ out:
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t imx_int(int irq, void *dev_id)
|
||||
{
|
||||
struct imx_port *sport = dev_id;
|
||||
unsigned int sts;
|
||||
|
||||
sts = readl(sport->port.membase + USR1);
|
||||
|
||||
if (sts & USR1_RRDY)
|
||||
imx_rxint(irq, dev_id);
|
||||
|
||||
if (sts & USR1_TRDY &&
|
||||
readl(sport->port.membase + UCR1) & UCR1_TXMPTYEN)
|
||||
imx_txint(irq, dev_id);
|
||||
|
||||
if (sts & USR1_RTSS)
|
||||
imx_rtsint(irq, dev_id);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TIOCSER_TEMT when transmitter is not busy.
|
||||
*/
|
||||
@@ -477,7 +523,8 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode)
|
||||
* RFDIV is set such way to satisfy requested uartclk value
|
||||
*/
|
||||
val = TXTL << 10 | RXTL;
|
||||
ufcr_rfdiv = (imx_get_perclk1() + sport->port.uartclk / 2) / sport->port.uartclk;
|
||||
ufcr_rfdiv = (clk_get_rate(sport->clk) + sport->port.uartclk / 2)
|
||||
/ sport->port.uartclk;
|
||||
|
||||
if(!ufcr_rfdiv)
|
||||
ufcr_rfdiv = 1;
|
||||
@@ -509,21 +556,34 @@ static int imx_startup(struct uart_port *port)
|
||||
writel(temp & ~UCR4_DREN, sport->port.membase + UCR4);
|
||||
|
||||
/*
|
||||
* Allocate the IRQ
|
||||
* Allocate the IRQ(s) i.MX1 has three interrupts whereas later
|
||||
* chips only have one interrupt.
|
||||
*/
|
||||
retval = request_irq(sport->rxirq, imx_rxint, 0,
|
||||
DRIVER_NAME, sport);
|
||||
if (retval) goto error_out1;
|
||||
if (sport->txirq > 0) {
|
||||
retval = request_irq(sport->rxirq, imx_rxint, 0,
|
||||
DRIVER_NAME, sport);
|
||||
if (retval)
|
||||
goto error_out1;
|
||||
|
||||
retval = request_irq(sport->txirq, imx_txint, 0,
|
||||
DRIVER_NAME, sport);
|
||||
if (retval) goto error_out2;
|
||||
retval = request_irq(sport->txirq, imx_txint, 0,
|
||||
DRIVER_NAME, sport);
|
||||
if (retval)
|
||||
goto error_out2;
|
||||
|
||||
retval = request_irq(sport->rtsirq, imx_rtsint,
|
||||
(sport->rtsirq < IMX_IRQS) ? 0 :
|
||||
retval = request_irq(sport->rtsirq, imx_rtsint,
|
||||
(sport->rtsirq < MAX_INTERNAL_IRQ) ? 0 :
|
||||
IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
|
||||
DRIVER_NAME, sport);
|
||||
if (retval) goto error_out3;
|
||||
DRIVER_NAME, sport);
|
||||
if (retval)
|
||||
goto error_out3;
|
||||
} else {
|
||||
retval = request_irq(sport->port.irq, imx_int, 0,
|
||||
DRIVER_NAME, sport);
|
||||
if (retval) {
|
||||
free_irq(sport->port.irq, sport);
|
||||
goto error_out1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Finally, clear and enable interrupts
|
||||
@@ -548,9 +608,11 @@ static int imx_startup(struct uart_port *port)
|
||||
return 0;
|
||||
|
||||
error_out3:
|
||||
free_irq(sport->txirq, sport);
|
||||
if (sport->txirq)
|
||||
free_irq(sport->txirq, sport);
|
||||
error_out2:
|
||||
free_irq(sport->rxirq, sport);
|
||||
if (sport->rxirq)
|
||||
free_irq(sport->rxirq, sport);
|
||||
error_out1:
|
||||
return retval;
|
||||
}
|
||||
@@ -568,9 +630,12 @@ static void imx_shutdown(struct uart_port *port)
|
||||
/*
|
||||
* Free the interrupts
|
||||
*/
|
||||
free_irq(sport->rtsirq, sport);
|
||||
free_irq(sport->txirq, sport);
|
||||
free_irq(sport->rxirq, sport);
|
||||
if (sport->txirq > 0) {
|
||||
free_irq(sport->rtsirq, sport);
|
||||
free_irq(sport->txirq, sport);
|
||||
free_irq(sport->rxirq, sport);
|
||||
} else
|
||||
free_irq(sport->port.irq, sport);
|
||||
|
||||
/*
|
||||
* Disable all interrupts, port and break condition.
|
||||
@@ -589,6 +654,7 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
|
||||
unsigned long flags;
|
||||
unsigned int ucr2, old_ucr1, old_txrxen, baud, quot;
|
||||
unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
|
||||
unsigned int div, num, denom, ufcr;
|
||||
|
||||
/*
|
||||
* If we don't support modem control lines, don't allow
|
||||
@@ -634,7 +700,7 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
|
||||
/*
|
||||
* Ask the core to calculate the divisor for us.
|
||||
*/
|
||||
baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
|
||||
baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 16);
|
||||
quot = uart_get_divisor(port, baud);
|
||||
|
||||
spin_lock_irqsave(&sport->port.lock, flags);
|
||||
@@ -684,14 +750,41 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
|
||||
sport->port.membase + UCR2);
|
||||
old_txrxen &= (UCR2_TXEN | UCR2_RXEN);
|
||||
|
||||
/* set the baud rate. We assume uartclk = 16 MHz
|
||||
*
|
||||
* baud * 16 UBIR - 1
|
||||
* --------- = --------
|
||||
* uartclk UBMR - 1
|
||||
*/
|
||||
writel((baud / 100) - 1, sport->port.membase + UBIR);
|
||||
writel(10000 - 1, sport->port.membase + UBMR);
|
||||
div = sport->port.uartclk / (baud * 16);
|
||||
if (div > 7)
|
||||
div = 7;
|
||||
if (!div)
|
||||
div = 1;
|
||||
|
||||
num = baud;
|
||||
denom = port->uartclk / div / 16;
|
||||
|
||||
/* shift num and denom right until they fit into 16 bits */
|
||||
while (num > 0x10000 || denom > 0x10000) {
|
||||
num >>= 1;
|
||||
denom >>= 1;
|
||||
}
|
||||
if (num > 0)
|
||||
num -= 1;
|
||||
if (denom > 0)
|
||||
denom -= 1;
|
||||
|
||||
writel(num, sport->port.membase + UBIR);
|
||||
writel(denom, sport->port.membase + UBMR);
|
||||
|
||||
if (div == 7)
|
||||
div = 6; /* 6 in RFDIV means divide by 7 */
|
||||
else
|
||||
div = 6 - div;
|
||||
|
||||
ufcr = readl(sport->port.membase + UFCR);
|
||||
ufcr = (ufcr & (~UFCR_RFDIV)) |
|
||||
(div << 7);
|
||||
writel(ufcr, sport->port.membase + UFCR);
|
||||
|
||||
#ifdef ONEMS
|
||||
writel(sport->port.uartclk / div / 1000, sport->port.membase + ONEMS);
|
||||
#endif
|
||||
|
||||
writel(old_ucr1, sport->port.membase + UCR1);
|
||||
|
||||
@@ -801,65 +894,7 @@ static struct uart_ops imx_pops = {
|
||||
.verify_port = imx_verify_port,
|
||||
};
|
||||
|
||||
static struct imx_port imx_ports[] = {
|
||||
{
|
||||
.txirq = UART1_MINT_TX,
|
||||
.rxirq = UART1_MINT_RX,
|
||||
.rtsirq = UART1_MINT_RTS,
|
||||
.port = {
|
||||
.type = PORT_IMX,
|
||||
.iotype = UPIO_MEM,
|
||||
.membase = (void *)IMX_UART1_BASE,
|
||||
.mapbase = 0x00206000,
|
||||
.irq = UART1_MINT_RX,
|
||||
.uartclk = 16000000,
|
||||
.fifosize = 32,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.ops = &imx_pops,
|
||||
.line = 0,
|
||||
},
|
||||
}, {
|
||||
.txirq = UART2_MINT_TX,
|
||||
.rxirq = UART2_MINT_RX,
|
||||
.rtsirq = UART2_MINT_RTS,
|
||||
.port = {
|
||||
.type = PORT_IMX,
|
||||
.iotype = UPIO_MEM,
|
||||
.membase = (void *)IMX_UART2_BASE,
|
||||
.mapbase = 0x00207000,
|
||||
.irq = UART2_MINT_RX,
|
||||
.uartclk = 16000000,
|
||||
.fifosize = 32,
|
||||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.ops = &imx_pops,
|
||||
.line = 1,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Setup the IMX serial ports.
|
||||
* Note also that we support "console=ttySMXx" where "x" is either 0 or 1.
|
||||
* Which serial port this ends up being depends on the machine you're
|
||||
* running this kernel on. I'm not convinced that this is a good idea,
|
||||
* but that's the way it traditionally works.
|
||||
*
|
||||
*/
|
||||
static void __init imx_init_ports(void)
|
||||
{
|
||||
static int first = 1;
|
||||
int i;
|
||||
|
||||
if (!first)
|
||||
return;
|
||||
first = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(imx_ports); i++) {
|
||||
init_timer(&imx_ports[i].timer);
|
||||
imx_ports[i].timer.function = imx_timeout;
|
||||
imx_ports[i].timer.data = (unsigned long)&imx_ports[i];
|
||||
}
|
||||
}
|
||||
static struct imx_port *imx_ports[UART_NR];
|
||||
|
||||
#ifdef CONFIG_SERIAL_IMX_CONSOLE
|
||||
static void imx_console_putchar(struct uart_port *port, int ch)
|
||||
@@ -878,7 +913,7 @@ static void imx_console_putchar(struct uart_port *port, int ch)
|
||||
static void
|
||||
imx_console_write(struct console *co, const char *s, unsigned int count)
|
||||
{
|
||||
struct imx_port *sport = &imx_ports[co->index];
|
||||
struct imx_port *sport = imx_ports[co->index];
|
||||
unsigned int old_ucr1, old_ucr2;
|
||||
|
||||
/*
|
||||
@@ -944,7 +979,7 @@ imx_console_get_options(struct imx_port *sport, int *baud,
|
||||
else
|
||||
ucfr_rfdiv = 6 - ucfr_rfdiv;
|
||||
|
||||
uartclk = imx_get_perclk1();
|
||||
uartclk = clk_get_rate(sport->clk);
|
||||
uartclk /= ucfr_rfdiv;
|
||||
|
||||
{ /*
|
||||
@@ -984,7 +1019,7 @@ imx_console_setup(struct console *co, char *options)
|
||||
*/
|
||||
if (co->index == -1 || co->index >= ARRAY_SIZE(imx_ports))
|
||||
co->index = 0;
|
||||
sport = &imx_ports[co->index];
|
||||
sport = imx_ports[co->index];
|
||||
|
||||
if (options)
|
||||
uart_parse_options(options, &baud, &parity, &bits, &flow);
|
||||
@@ -998,7 +1033,7 @@ imx_console_setup(struct console *co, char *options)
|
||||
|
||||
static struct uart_driver imx_reg;
|
||||
static struct console imx_console = {
|
||||
.name = "ttySMX",
|
||||
.name = DEV_NAME,
|
||||
.write = imx_console_write,
|
||||
.device = uart_console_device,
|
||||
.setup = imx_console_setup,
|
||||
@@ -1007,14 +1042,6 @@ static struct console imx_console = {
|
||||
.data = &imx_reg,
|
||||
};
|
||||
|
||||
static int __init imx_rs_console_init(void)
|
||||
{
|
||||
imx_init_ports();
|
||||
register_console(&imx_console);
|
||||
return 0;
|
||||
}
|
||||
console_initcall(imx_rs_console_init);
|
||||
|
||||
#define IMX_CONSOLE &imx_console
|
||||
#else
|
||||
#define IMX_CONSOLE NULL
|
||||
@@ -1023,7 +1050,7 @@ console_initcall(imx_rs_console_init);
|
||||
static struct uart_driver imx_reg = {
|
||||
.owner = THIS_MODULE,
|
||||
.driver_name = DRIVER_NAME,
|
||||
.dev_name = "ttySMX",
|
||||
.dev_name = DEV_NAME,
|
||||
.major = SERIAL_IMX_MAJOR,
|
||||
.minor = MINOR_START,
|
||||
.nr = ARRAY_SIZE(imx_ports),
|
||||
@@ -1050,29 +1077,98 @@ static int serial_imx_resume(struct platform_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int serial_imx_probe(struct platform_device *dev)
|
||||
static int serial_imx_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct imx_port *sport;
|
||||
struct imxuart_platform_data *pdata;
|
||||
void __iomem *base;
|
||||
int ret = 0;
|
||||
struct resource *res;
|
||||
|
||||
imx_ports[dev->id].port.dev = &dev->dev;
|
||||
sport = kzalloc(sizeof(*sport), GFP_KERNEL);
|
||||
if (!sport)
|
||||
return -ENOMEM;
|
||||
|
||||
pdata = (struct imxuart_platform_data *)dev->dev.platform_data;
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
ret = -ENODEV;
|
||||
goto free;
|
||||
}
|
||||
|
||||
base = ioremap(res->start, PAGE_SIZE);
|
||||
if (!base) {
|
||||
ret = -ENOMEM;
|
||||
goto free;
|
||||
}
|
||||
|
||||
sport->port.dev = &pdev->dev;
|
||||
sport->port.mapbase = res->start;
|
||||
sport->port.membase = base;
|
||||
sport->port.type = PORT_IMX,
|
||||
sport->port.iotype = UPIO_MEM;
|
||||
sport->port.irq = platform_get_irq(pdev, 0);
|
||||
sport->rxirq = platform_get_irq(pdev, 0);
|
||||
sport->txirq = platform_get_irq(pdev, 1);
|
||||
sport->rtsirq = platform_get_irq(pdev, 2);
|
||||
sport->port.fifosize = 32;
|
||||
sport->port.ops = &imx_pops;
|
||||
sport->port.flags = UPF_BOOT_AUTOCONF;
|
||||
sport->port.line = pdev->id;
|
||||
init_timer(&sport->timer);
|
||||
sport->timer.function = imx_timeout;
|
||||
sport->timer.data = (unsigned long)sport;
|
||||
|
||||
sport->clk = clk_get(&pdev->dev, "uart_clk");
|
||||
if (IS_ERR(sport->clk)) {
|
||||
ret = PTR_ERR(sport->clk);
|
||||
goto unmap;
|
||||
}
|
||||
clk_enable(sport->clk);
|
||||
|
||||
sport->port.uartclk = clk_get_rate(sport->clk);
|
||||
|
||||
imx_ports[pdev->id] = sport;
|
||||
|
||||
pdata = pdev->dev.platform_data;
|
||||
if(pdata && (pdata->flags & IMXUART_HAVE_RTSCTS))
|
||||
imx_ports[dev->id].have_rtscts = 1;
|
||||
sport->have_rtscts = 1;
|
||||
|
||||
if (pdata->init)
|
||||
pdata->init(pdev);
|
||||
|
||||
uart_add_one_port(&imx_reg, &sport->port);
|
||||
platform_set_drvdata(pdev, &sport->port);
|
||||
|
||||
uart_add_one_port(&imx_reg, &imx_ports[dev->id].port);
|
||||
platform_set_drvdata(dev, &imx_ports[dev->id]);
|
||||
return 0;
|
||||
unmap:
|
||||
iounmap(sport->port.membase);
|
||||
free:
|
||||
kfree(sport);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int serial_imx_remove(struct platform_device *dev)
|
||||
static int serial_imx_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct imx_port *sport = platform_get_drvdata(dev);
|
||||
struct imxuart_platform_data *pdata;
|
||||
struct imx_port *sport = platform_get_drvdata(pdev);
|
||||
|
||||
platform_set_drvdata(dev, NULL);
|
||||
pdata = pdev->dev.platform_data;
|
||||
|
||||
if (sport)
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
||||
if (sport) {
|
||||
uart_remove_one_port(&imx_reg, &sport->port);
|
||||
clk_put(sport->clk);
|
||||
}
|
||||
|
||||
clk_disable(sport->clk);
|
||||
|
||||
if (pdata->exit)
|
||||
pdata->exit(pdev);
|
||||
|
||||
iounmap(sport->port.membase);
|
||||
kfree(sport);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1095,8 +1191,6 @@ static int __init imx_serial_init(void)
|
||||
|
||||
printk(KERN_INFO "Serial: IMX driver\n");
|
||||
|
||||
imx_init_ports();
|
||||
|
||||
ret = uart_register_driver(&imx_reg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
106
drivers/serial/s3c2400.c
Normal file
106
drivers/serial/s3c2400.c
Normal file
@@ -0,0 +1,106 @@
|
||||
/* linux/drivers/serial/s3c240.c
|
||||
*
|
||||
* Driver for Samsung SoC onboard UARTs.
|
||||
*
|
||||
* Ben Dooks, Copyright (c) 2003-2005 Simtec Electronics
|
||||
* http://armlinux.simtec.co.uk/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
|
||||
#include <asm/hardware.h>
|
||||
|
||||
#include <asm/plat-s3c/regs-serial.h>
|
||||
#include <asm/arch/regs-gpio.h>
|
||||
|
||||
#include "samsung.h"
|
||||
|
||||
static int s3c2400_serial_getsource(struct uart_port *port,
|
||||
struct s3c24xx_uart_clksrc *clk)
|
||||
{
|
||||
clk->divisor = 1;
|
||||
clk->name = "pclk";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s3c2400_serial_setsource(struct uart_port *port,
|
||||
struct s3c24xx_uart_clksrc *clk)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s3c2400_serial_resetport(struct uart_port *port,
|
||||
struct s3c2410_uartcfg *cfg)
|
||||
{
|
||||
dbg("s3c2400_serial_resetport: port=%p (%08lx), cfg=%p\n",
|
||||
port, port->mapbase, cfg);
|
||||
|
||||
wr_regl(port, S3C2410_UCON, cfg->ucon);
|
||||
wr_regl(port, S3C2410_ULCON, cfg->ulcon);
|
||||
|
||||
/* reset both fifos */
|
||||
|
||||
wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
|
||||
wr_regl(port, S3C2410_UFCON, cfg->ufcon);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct s3c24xx_uart_info s3c2400_uart_inf = {
|
||||
.name = "Samsung S3C2400 UART",
|
||||
.type = PORT_S3C2400,
|
||||
.fifosize = 16,
|
||||
.rx_fifomask = S3C2410_UFSTAT_RXMASK,
|
||||
.rx_fifoshift = S3C2410_UFSTAT_RXSHIFT,
|
||||
.rx_fifofull = S3C2410_UFSTAT_RXFULL,
|
||||
.tx_fifofull = S3C2410_UFSTAT_TXFULL,
|
||||
.tx_fifomask = S3C2410_UFSTAT_TXMASK,
|
||||
.tx_fifoshift = S3C2410_UFSTAT_TXSHIFT,
|
||||
.get_clksrc = s3c2400_serial_getsource,
|
||||
.set_clksrc = s3c2400_serial_setsource,
|
||||
.reset_port = s3c2400_serial_resetport,
|
||||
};
|
||||
|
||||
static int s3c2400_serial_probe(struct platform_device *dev)
|
||||
{
|
||||
return s3c24xx_serial_probe(dev, &s3c2400_uart_inf);
|
||||
}
|
||||
|
||||
static struct platform_driver s3c2400_serial_drv = {
|
||||
.probe = s3c2400_serial_probe,
|
||||
.remove = s3c24xx_serial_remove,
|
||||
.driver = {
|
||||
.name = "s3c2400-uart",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
s3c24xx_console_init(&s3c2400_serial_drv, &s3c2400_uart_inf);
|
||||
|
||||
static inline int s3c2400_serial_init(void)
|
||||
{
|
||||
return s3c24xx_serial_init(&s3c2400_serial_drv, &s3c2400_uart_inf);
|
||||
}
|
||||
|
||||
static inline void s3c2400_serial_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&s3c2400_serial_drv);
|
||||
}
|
||||
|
||||
module_init(s3c2400_serial_init);
|
||||
module_exit(s3c2400_serial_exit);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
|
||||
MODULE_DESCRIPTION("Samsung S3C2400 SoC Serial port driver");
|
||||
MODULE_ALIAS("platform:s3c2400-uart");
|
||||
File diff suppressed because it is too large
Load Diff
151
drivers/serial/s3c2412.c
Normal file
151
drivers/serial/s3c2412.c
Normal file
@@ -0,0 +1,151 @@
|
||||
/* linux/drivers/serial/s3c2412.c
|
||||
*
|
||||
* Driver for Samsung S3C2412 and S3C2413 SoC onboard UARTs.
|
||||
*
|
||||
* Ben Dooks, Copyright (c) 2003-2005,2008 Simtec Electronics
|
||||
* http://armlinux.simtec.co.uk/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/serial.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <asm/hardware.h>
|
||||
|
||||
#include <asm/plat-s3c/regs-serial.h>
|
||||
#include <asm/arch/regs-gpio.h>
|
||||
|
||||
#include "samsung.h"
|
||||
|
||||
static int s3c2412_serial_setsource(struct uart_port *port,
|
||||
struct s3c24xx_uart_clksrc *clk)
|
||||
{
|
||||
unsigned long ucon = rd_regl(port, S3C2410_UCON);
|
||||
|
||||
ucon &= ~S3C2412_UCON_CLKMASK;
|
||||
|
||||
if (strcmp(clk->name, "uclk") == 0)
|
||||
ucon |= S3C2440_UCON_UCLK;
|
||||
else if (strcmp(clk->name, "pclk") == 0)
|
||||
ucon |= S3C2440_UCON_PCLK;
|
||||
else if (strcmp(clk->name, "usysclk") == 0)
|
||||
ucon |= S3C2412_UCON_USYSCLK;
|
||||
else {
|
||||
printk(KERN_ERR "unknown clock source %s\n", clk->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
wr_regl(port, S3C2410_UCON, ucon);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int s3c2412_serial_getsource(struct uart_port *port,
|
||||
struct s3c24xx_uart_clksrc *clk)
|
||||
{
|
||||
unsigned long ucon = rd_regl(port, S3C2410_UCON);
|
||||
|
||||
switch (ucon & S3C2412_UCON_CLKMASK) {
|
||||
case S3C2412_UCON_UCLK:
|
||||
clk->divisor = 1;
|
||||
clk->name = "uclk";
|
||||
break;
|
||||
|
||||
case S3C2412_UCON_PCLK:
|
||||
case S3C2412_UCON_PCLK2:
|
||||
clk->divisor = 1;
|
||||
clk->name = "pclk";
|
||||
break;
|
||||
|
||||
case S3C2412_UCON_USYSCLK:
|
||||
clk->divisor = 1;
|
||||
clk->name = "usysclk";
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s3c2412_serial_resetport(struct uart_port *port,
|
||||
struct s3c2410_uartcfg *cfg)
|
||||
{
|
||||
unsigned long ucon = rd_regl(port, S3C2410_UCON);
|
||||
|
||||
dbg("%s: port=%p (%08lx), cfg=%p\n",
|
||||
__func__, port, port->mapbase, cfg);
|
||||
|
||||
/* ensure we don't change the clock settings... */
|
||||
|
||||
ucon &= S3C2412_UCON_CLKMASK;
|
||||
|
||||
wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
|
||||
wr_regl(port, S3C2410_ULCON, cfg->ulcon);
|
||||
|
||||
/* reset both fifos */
|
||||
|
||||
wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
|
||||
wr_regl(port, S3C2410_UFCON, cfg->ufcon);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct s3c24xx_uart_info s3c2412_uart_inf = {
|
||||
.name = "Samsung S3C2412 UART",
|
||||
.type = PORT_S3C2412,
|
||||
.fifosize = 64,
|
||||
.rx_fifomask = S3C2440_UFSTAT_RXMASK,
|
||||
.rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
|
||||
.rx_fifofull = S3C2440_UFSTAT_RXFULL,
|
||||
.tx_fifofull = S3C2440_UFSTAT_TXFULL,
|
||||
.tx_fifomask = S3C2440_UFSTAT_TXMASK,
|
||||
.tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
|
||||
.get_clksrc = s3c2412_serial_getsource,
|
||||
.set_clksrc = s3c2412_serial_setsource,
|
||||
.reset_port = s3c2412_serial_resetport,
|
||||
};
|
||||
|
||||
/* device management */
|
||||
|
||||
static int s3c2412_serial_probe(struct platform_device *dev)
|
||||
{
|
||||
dbg("s3c2440_serial_probe: dev=%p\n", dev);
|
||||
return s3c24xx_serial_probe(dev, &s3c2412_uart_inf);
|
||||
}
|
||||
|
||||
static struct platform_driver s3c2412_serial_drv = {
|
||||
.probe = s3c2412_serial_probe,
|
||||
.remove = s3c24xx_serial_remove,
|
||||
.driver = {
|
||||
.name = "s3c2412-uart",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
s3c24xx_console_init(&s3c2412_serial_drv, &s3c2412_uart_inf);
|
||||
|
||||
static inline int s3c2412_serial_init(void)
|
||||
{
|
||||
return s3c24xx_serial_init(&s3c2412_serial_drv, &s3c2412_uart_inf);
|
||||
}
|
||||
|
||||
static inline void s3c2412_serial_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&s3c2412_serial_drv);
|
||||
}
|
||||
|
||||
module_init(s3c2412_serial_init);
|
||||
module_exit(s3c2412_serial_exit);
|
||||
|
||||
MODULE_DESCRIPTION("Samsung S3C2412,S3C2413 SoC Serial port driver");
|
||||
MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("platform:s3c2412-uart");
|
||||
181
drivers/serial/s3c2440.c
Normal file
181
drivers/serial/s3c2440.c
Normal file
@@ -0,0 +1,181 @@
|
||||
/* linux/drivers/serial/s3c2440.c
|
||||
*
|
||||
* Driver for Samsung S3C2440 and S3C2442 SoC onboard UARTs.
|
||||
*
|
||||
* Ben Dooks, Copyright (c) 2003-2005,2008 Simtec Electronics
|
||||
* http://armlinux.simtec.co.uk/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/serial.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <asm/hardware.h>
|
||||
|
||||
#include <asm/plat-s3c/regs-serial.h>
|
||||
#include <asm/arch/regs-gpio.h>
|
||||
|
||||
#include "samsung.h"
|
||||
|
||||
|
||||
static int s3c2440_serial_setsource(struct uart_port *port,
|
||||
struct s3c24xx_uart_clksrc *clk)
|
||||
{
|
||||
unsigned long ucon = rd_regl(port, S3C2410_UCON);
|
||||
|
||||
/* todo - proper fclk<>nonfclk switch. */
|
||||
|
||||
ucon &= ~S3C2440_UCON_CLKMASK;
|
||||
|
||||
if (strcmp(clk->name, "uclk") == 0)
|
||||
ucon |= S3C2440_UCON_UCLK;
|
||||
else if (strcmp(clk->name, "pclk") == 0)
|
||||
ucon |= S3C2440_UCON_PCLK;
|
||||
else if (strcmp(clk->name, "fclk") == 0)
|
||||
ucon |= S3C2440_UCON_FCLK;
|
||||
else {
|
||||
printk(KERN_ERR "unknown clock source %s\n", clk->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
wr_regl(port, S3C2410_UCON, ucon);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int s3c2440_serial_getsource(struct uart_port *port,
|
||||
struct s3c24xx_uart_clksrc *clk)
|
||||
{
|
||||
unsigned long ucon = rd_regl(port, S3C2410_UCON);
|
||||
unsigned long ucon0, ucon1, ucon2;
|
||||
|
||||
switch (ucon & S3C2440_UCON_CLKMASK) {
|
||||
case S3C2440_UCON_UCLK:
|
||||
clk->divisor = 1;
|
||||
clk->name = "uclk";
|
||||
break;
|
||||
|
||||
case S3C2440_UCON_PCLK:
|
||||
case S3C2440_UCON_PCLK2:
|
||||
clk->divisor = 1;
|
||||
clk->name = "pclk";
|
||||
break;
|
||||
|
||||
case S3C2440_UCON_FCLK:
|
||||
/* the fun of calculating the uart divisors on
|
||||
* the s3c2440 */
|
||||
|
||||
ucon0 = __raw_readl(S3C24XX_VA_UART0 + S3C2410_UCON);
|
||||
ucon1 = __raw_readl(S3C24XX_VA_UART1 + S3C2410_UCON);
|
||||
ucon2 = __raw_readl(S3C24XX_VA_UART2 + S3C2410_UCON);
|
||||
|
||||
printk("ucons: %08lx, %08lx, %08lx\n", ucon0, ucon1, ucon2);
|
||||
|
||||
ucon0 &= S3C2440_UCON0_DIVMASK;
|
||||
ucon1 &= S3C2440_UCON1_DIVMASK;
|
||||
ucon2 &= S3C2440_UCON2_DIVMASK;
|
||||
|
||||
if (ucon0 != 0) {
|
||||
clk->divisor = ucon0 >> S3C2440_UCON_DIVSHIFT;
|
||||
clk->divisor += 6;
|
||||
} else if (ucon1 != 0) {
|
||||
clk->divisor = ucon1 >> S3C2440_UCON_DIVSHIFT;
|
||||
clk->divisor += 21;
|
||||
} else if (ucon2 != 0) {
|
||||
clk->divisor = ucon2 >> S3C2440_UCON_DIVSHIFT;
|
||||
clk->divisor += 36;
|
||||
} else {
|
||||
/* manual calims 44, seems to be 9 */
|
||||
clk->divisor = 9;
|
||||
}
|
||||
|
||||
clk->name = "fclk";
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s3c2440_serial_resetport(struct uart_port *port,
|
||||
struct s3c2410_uartcfg *cfg)
|
||||
{
|
||||
unsigned long ucon = rd_regl(port, S3C2410_UCON);
|
||||
|
||||
dbg("s3c2440_serial_resetport: port=%p (%08lx), cfg=%p\n",
|
||||
port, port->mapbase, cfg);
|
||||
|
||||
/* ensure we don't change the clock settings... */
|
||||
|
||||
ucon &= (S3C2440_UCON0_DIVMASK | (3<<10));
|
||||
|
||||
wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
|
||||
wr_regl(port, S3C2410_ULCON, cfg->ulcon);
|
||||
|
||||
/* reset both fifos */
|
||||
|
||||
wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
|
||||
wr_regl(port, S3C2410_UFCON, cfg->ufcon);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct s3c24xx_uart_info s3c2440_uart_inf = {
|
||||
.name = "Samsung S3C2440 UART",
|
||||
.type = PORT_S3C2440,
|
||||
.fifosize = 64,
|
||||
.rx_fifomask = S3C2440_UFSTAT_RXMASK,
|
||||
.rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
|
||||
.rx_fifofull = S3C2440_UFSTAT_RXFULL,
|
||||
.tx_fifofull = S3C2440_UFSTAT_TXFULL,
|
||||
.tx_fifomask = S3C2440_UFSTAT_TXMASK,
|
||||
.tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
|
||||
.get_clksrc = s3c2440_serial_getsource,
|
||||
.set_clksrc = s3c2440_serial_setsource,
|
||||
.reset_port = s3c2440_serial_resetport,
|
||||
};
|
||||
|
||||
/* device management */
|
||||
|
||||
static int s3c2440_serial_probe(struct platform_device *dev)
|
||||
{
|
||||
dbg("s3c2440_serial_probe: dev=%p\n", dev);
|
||||
return s3c24xx_serial_probe(dev, &s3c2440_uart_inf);
|
||||
}
|
||||
|
||||
static struct platform_driver s3c2440_serial_drv = {
|
||||
.probe = s3c2440_serial_probe,
|
||||
.remove = s3c24xx_serial_remove,
|
||||
.driver = {
|
||||
.name = "s3c2440-uart",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
s3c24xx_console_init(&s3c2440_serial_drv, &s3c2440_uart_inf);
|
||||
|
||||
static int __init s3c2440_serial_init(void)
|
||||
{
|
||||
return s3c24xx_serial_init(&s3c2440_serial_drv, &s3c2440_uart_inf);
|
||||
}
|
||||
|
||||
static void __exit s3c2440_serial_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&s3c2440_serial_drv);
|
||||
}
|
||||
|
||||
module_init(s3c2440_serial_init);
|
||||
module_exit(s3c2440_serial_exit);
|
||||
|
||||
MODULE_DESCRIPTION("Samsung S3C2440,S3C2442 SoC Serial port driver");
|
||||
MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
|
||||
MODULE_LICENSE("GPLi v2");
|
||||
MODULE_ALIAS("platform:s3c2440-uart");
|
||||
1317
drivers/serial/samsung.c
Normal file
1317
drivers/serial/samsung.c
Normal file
File diff suppressed because it is too large
Load Diff
102
drivers/serial/samsung.h
Normal file
102
drivers/serial/samsung.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/* linux/drivers/serial/samsung.h
|
||||
*
|
||||
* Driver for Samsung SoC onboard UARTs.
|
||||
*
|
||||
* Ben Dooks, Copyright (c) 2003-2005,2008 Simtec Electronics
|
||||
* http://armlinux.simtec.co.uk/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
struct s3c24xx_uart_info {
|
||||
char *name;
|
||||
unsigned int type;
|
||||
unsigned int fifosize;
|
||||
unsigned long rx_fifomask;
|
||||
unsigned long rx_fifoshift;
|
||||
unsigned long rx_fifofull;
|
||||
unsigned long tx_fifomask;
|
||||
unsigned long tx_fifoshift;
|
||||
unsigned long tx_fifofull;
|
||||
|
||||
/* clock source control */
|
||||
|
||||
int (*get_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk);
|
||||
int (*set_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk);
|
||||
|
||||
/* uart controls */
|
||||
int (*reset_port)(struct uart_port *, struct s3c2410_uartcfg *);
|
||||
};
|
||||
|
||||
struct s3c24xx_uart_port {
|
||||
unsigned char rx_claimed;
|
||||
unsigned char tx_claimed;
|
||||
|
||||
struct s3c24xx_uart_info *info;
|
||||
struct s3c24xx_uart_clksrc *clksrc;
|
||||
struct clk *clk;
|
||||
struct clk *baudclk;
|
||||
struct uart_port port;
|
||||
};
|
||||
|
||||
/* conversion functions */
|
||||
|
||||
#define s3c24xx_dev_to_port(__dev) (struct uart_port *)dev_get_drvdata(__dev)
|
||||
#define s3c24xx_dev_to_cfg(__dev) (struct s3c2410_uartcfg *)((__dev)->platform_data)
|
||||
|
||||
/* register access controls */
|
||||
|
||||
#define portaddr(port, reg) ((port)->membase + (reg))
|
||||
|
||||
#define rd_regb(port, reg) (__raw_readb(portaddr(port, reg)))
|
||||
#define rd_regl(port, reg) (__raw_readl(portaddr(port, reg)))
|
||||
|
||||
#define wr_regb(port, reg, val) __raw_writeb(val, portaddr(port, reg))
|
||||
#define wr_regl(port, reg, val) __raw_writel(val, portaddr(port, reg))
|
||||
|
||||
extern int s3c24xx_serial_probe(struct platform_device *dev,
|
||||
struct s3c24xx_uart_info *uart);
|
||||
|
||||
extern int s3c24xx_serial_remove(struct platform_device *dev);
|
||||
|
||||
extern int s3c24xx_serial_initconsole(struct platform_driver *drv,
|
||||
struct s3c24xx_uart_info *uart);
|
||||
|
||||
extern int s3c24xx_serial_init(struct platform_driver *drv,
|
||||
struct s3c24xx_uart_info *info);
|
||||
|
||||
#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
|
||||
|
||||
#define s3c24xx_console_init(__drv, __inf) \
|
||||
static int __init s3c_serial_console_init(void) \
|
||||
{ \
|
||||
return s3c24xx_serial_initconsole(__drv, __inf); \
|
||||
} \
|
||||
\
|
||||
console_initcall(s3c_serial_console_init)
|
||||
|
||||
#else
|
||||
#define s3c24xx_console_init(drv, inf) extern void no_console(void)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SERIAL_SAMSUNG_DEBUG
|
||||
|
||||
extern void printascii(const char *);
|
||||
|
||||
static void dbg(const char *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
char buff[256];
|
||||
|
||||
va_start(va, fmt);
|
||||
vsprintf(buff, fmt, va);
|
||||
va_end(va);
|
||||
|
||||
printascii(buff);
|
||||
}
|
||||
|
||||
#else
|
||||
#define dbg(x...) do { } while (0)
|
||||
#endif
|
||||
Reference in New Issue
Block a user