Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 24525
b: refs/heads/master
c: fbb18a2
h: refs/heads/master
i:
  24523: d77cff7
v: v3
  • Loading branch information
Russell King authored and Russell King committed Mar 26, 2006
1 parent dc984d1 commit bd66509
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 94 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 335bd9dff31d042b773591933d3ee5bd62d5ea27
refs/heads/master: fbb18a277a6f192404aa20ece49529acb1e1e76d
46 changes: 46 additions & 0 deletions trunk/arch/arm/mach-integrator/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include <linux/termios.h>
#include <linux/amba/bus.h>
#include <linux/amba/serial.h>

#include <asm/hardware.h>
#include <asm/irq.h>
Expand All @@ -28,6 +30,8 @@

#include "common.h"

static struct amba_pl010_data integrator_uart_data;

static struct amba_device rtc_device = {
.dev = {
.bus_id = "mb:15",
Expand All @@ -44,6 +48,7 @@ static struct amba_device rtc_device = {
static struct amba_device uart0_device = {
.dev = {
.bus_id = "mb:16",
.platform_data = &integrator_uart_data,
},
.res = {
.start = INTEGRATOR_UART0_BASE,
Expand All @@ -57,6 +62,7 @@ static struct amba_device uart0_device = {
static struct amba_device uart1_device = {
.dev = {
.bus_id = "mb:17",
.platform_data = &integrator_uart_data,
},
.res = {
.start = INTEGRATOR_UART1_BASE,
Expand Down Expand Up @@ -115,6 +121,46 @@ static int __init integrator_init(void)

arch_initcall(integrator_init);

/*
* On the Integrator platform, the port RTS and DTR are provided by
* bits in the following SC_CTRLS register bits:
* RTS DTR
* UART0 7 6
* UART1 5 4
*/
#define SC_CTRLC (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET)
#define SC_CTRLS (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET)

static void integrator_uart_set_mctrl(struct amba_device *dev, void __iomem *base, unsigned int mctrl)
{
unsigned int ctrls = 0, ctrlc = 0, rts_mask, dtr_mask;

if (dev == &uart0_device) {
rts_mask = 1 << 4;
dtr_mask = 1 << 5;
} else {
rts_mask = 1 << 6;
dtr_mask = 1 << 7;
}

if (mctrl & TIOCM_RTS)
ctrlc |= rts_mask;
else
ctrls |= rts_mask;

if (mctrl & TIOCM_DTR)
ctrlc |= dtr_mask;
else
ctrls |= dtr_mask;

__raw_writel(ctrls, SC_CTRLS);
__raw_writel(ctrlc, SC_CTRLC);
}

static struct amba_pl010_data integrator_uart_data = {
.set_mctrl = integrator_uart_set_mctrl,
};

#define CM_CTRL IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_CTRL_OFFSET

static DEFINE_SPINLOCK(cm_lock);
Expand Down
160 changes: 67 additions & 93 deletions trunk/drivers/serial/amba-pl010.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@
#include <linux/amba/serial.h>

#include <asm/io.h>
#include <asm/irq.h>
#include <asm/hardware.h>

#define UART_NR 2

Expand All @@ -65,26 +63,16 @@
#define UART_RX_DATA(s) (((s) & UART01x_FR_RXFE) == 0)
#define UART_TX_READY(s) (((s) & UART01x_FR_TXFF) == 0)

#define UART_DUMMY_RSR_RX /*256*/0
#define UART_DUMMY_RSR_RX 256
#define UART_PORT_SIZE 64

/*
* On the Integrator platform, the port RTS and DTR are provided by
* bits in the following SC_CTRLS register bits:
* RTS DTR
* UART0 7 6
* UART1 5 4
*/
#define SC_CTRLC (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET)
#define SC_CTRLS (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET)

/*
* We wrap our port structure around the generic uart_port.
*/
struct uart_amba_port {
struct uart_port port;
unsigned int dtr_mask;
unsigned int rts_mask;
struct amba_device *dev;
struct amba_pl010_data *data;
unsigned int old_status;
};

Expand Down Expand Up @@ -300,20 +288,9 @@ static unsigned int pl010_get_mctrl(struct uart_port *port)
static void pl010_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
struct uart_amba_port *uap = (struct uart_amba_port *)port;
unsigned int ctrls = 0, ctrlc = 0;

if (mctrl & TIOCM_RTS)
ctrlc |= uap->rts_mask;
else
ctrls |= uap->rts_mask;

if (mctrl & TIOCM_DTR)
ctrlc |= uap->dtr_mask;
else
ctrls |= uap->dtr_mask;

__raw_writel(ctrls, SC_CTRLS);
__raw_writel(ctrlc, SC_CTRLC);
if (uap->data)
uap->data->set_mctrl(uap->dev, uap->port.membase, mctrl);
}

static void pl010_break_ctl(struct uart_port *port, int break_state)
Expand Down Expand Up @@ -539,38 +516,7 @@ static struct uart_ops amba_pl010_pops = {
.verify_port = pl010_verify_port,
};

static struct uart_amba_port amba_ports[UART_NR] = {
{
.port = {
.membase = (void *)IO_ADDRESS(INTEGRATOR_UART0_BASE),
.mapbase = INTEGRATOR_UART0_BASE,
.iotype = UPIO_MEM,
.irq = IRQ_UARTINT0,
.uartclk = 14745600,
.fifosize = 16,
.ops = &amba_pl010_pops,
.flags = UPF_BOOT_AUTOCONF,
.line = 0,
},
.dtr_mask = 1 << 5,
.rts_mask = 1 << 4,
},
{
.port = {
.membase = (void *)IO_ADDRESS(INTEGRATOR_UART1_BASE),
.mapbase = INTEGRATOR_UART1_BASE,
.iotype = UPIO_MEM,
.irq = IRQ_UARTINT1,
.uartclk = 14745600,
.fifosize = 16,
.ops = &amba_pl010_pops,
.flags = UPF_BOOT_AUTOCONF,
.line = 1,
},
.dtr_mask = 1 << 7,
.rts_mask = 1 << 6,
}
};
static struct uart_amba_port *amba_ports[UART_NR];

#ifdef CONFIG_SERIAL_AMBA_PL010_CONSOLE

Expand All @@ -588,7 +534,7 @@ static void pl010_console_putchar(struct uart_port *port, int ch)
static void
pl010_console_write(struct console *co, const char *s, unsigned int count)
{
struct uart_port *port = &amba_ports[co->index].port;
struct uart_port *port = &amba_ports[co->index]->port;
unsigned int status, old_cr;

/*
Expand Down Expand Up @@ -651,7 +597,7 @@ static int __init pl010_console_setup(struct console *co, char *options)
*/
if (co->index >= UART_NR)
co->index = 0;
port = &amba_ports[co->index].port;
port = &amba_ports[co->index]->port;

if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
Expand All @@ -672,24 +618,6 @@ static struct console amba_console = {
.data = &amba_reg,
};

static int __init amba_console_init(void)
{
/*
* All port initializations are done statically
*/
register_console(&amba_console);
return 0;
}
console_initcall(amba_console_init);

static int __init amba_late_console_init(void)
{
if (!(amba_console.flags & CON_ENABLED))
register_console(&amba_console);
return 0;
}
late_initcall(amba_late_console_init);

#define AMBA_CONSOLE &amba_console
#else
#define AMBA_CONSOLE NULL
Expand All @@ -707,30 +635,76 @@ static struct uart_driver amba_reg = {

static int pl010_probe(struct amba_device *dev, void *id)
{
int i;
struct uart_amba_port *port;
void __iomem *base;
int i, ret;

for (i = 0; i < UART_NR; i++) {
if (amba_ports[i].port.mapbase != dev->res.start)
continue;
for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
if (amba_ports[i] == NULL)
break;

amba_ports[i].port.dev = &dev->dev;
uart_add_one_port(&amba_reg, &amba_ports[i].port);
amba_set_drvdata(dev, &amba_ports[i]);
break;
if (i == ARRAY_SIZE(amba_ports)) {
ret = -EBUSY;
goto out;
}

return 0;
port = kzalloc(sizeof(struct uart_amba_port), GFP_KERNEL);
if (!port) {
ret = -ENOMEM;
goto out;
}

base = ioremap(dev->res.start, PAGE_SIZE);
if (!base) {
ret = -ENOMEM;
goto free;
}

port->port.dev = &dev->dev;
port->port.mapbase = dev->res.start;
port->port.membase = base;
port->port.iotype = UPIO_MEM;
port->port.irq = dev->irq[0];
port->port.uartclk = 14745600;
port->port.fifosize = 16;
port->port.ops = &amba_pl010_pops;
port->port.flags = UPF_BOOT_AUTOCONF;
port->port.line = i;
port->dev = dev;
port->data = dev->dev.platform_data;

amba_ports[i] = port;

amba_set_drvdata(dev, port);
ret = uart_add_one_port(&amba_reg, &port->port);
if (ret) {
amba_set_drvdata(dev, NULL);
amba_ports[i] = NULL;
iounmap(base);
free:
kfree(port);
}

out:
return ret;
}

static int pl010_remove(struct amba_device *dev)
{
struct uart_amba_port *uap = amba_get_drvdata(dev);

if (uap)
uart_remove_one_port(&amba_reg, &uap->port);
struct uart_amba_port *port = amba_get_drvdata(dev);
int i;

amba_set_drvdata(dev, NULL);

uart_remove_one_port(&amba_reg, &port->port);

for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
if (amba_ports[i] == port)
amba_ports[i] = NULL;

iounmap(port->port.membase);
kfree(port);

return 0;
}

Expand Down
6 changes: 6 additions & 0 deletions trunk/include/linux/amba/serial.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,4 +158,10 @@
#define UART01x_RSR_ANY (UART01x_RSR_OE|UART01x_RSR_BE|UART01x_RSR_PE|UART01x_RSR_FE)
#define UART01x_FR_MODEM_ANY (UART01x_FR_DCD|UART01x_FR_DSR|UART01x_FR_CTS)

#ifndef __ASSEMBLY__
struct amba_pl010_data {
void (*set_mctrl)(struct amba_device *dev, void __iomem *base, unsigned int mctrl);
};
#endif

#endif

0 comments on commit bd66509

Please sign in to comment.