100 lines
2.3 KiB
C
100 lines
2.3 KiB
C
|
/*
|
||
|
* Copyright 2011, Netlogic Microsystems.
|
||
|
* Copyright 2004, Matt Porter <mporter@kernel.crashing.org>
|
||
|
*
|
||
|
* This file is licensed under the terms of the GNU General Public
|
||
|
* License version 2. This program is licensed "as is" without any
|
||
|
* warranty of any kind, whether express or implied.
|
||
|
*/
|
||
|
|
||
|
#include <linux/device.h>
|
||
|
#include <linux/platform_device.h>
|
||
|
#include <linux/kernel.h>
|
||
|
#include <linux/init.h>
|
||
|
#include <linux/resource.h>
|
||
|
#include <linux/serial_8250.h>
|
||
|
#include <linux/serial_reg.h>
|
||
|
|
||
|
#include <asm/netlogic/haldefs.h>
|
||
|
#include <asm/netlogic/xlr/iomap.h>
|
||
|
#include <asm/netlogic/xlr/pic.h>
|
||
|
#include <asm/netlogic/xlr/xlr.h>
|
||
|
|
||
|
unsigned int nlm_xlr_uart_in(struct uart_port *p, int offset)
|
||
|
{
|
||
|
uint64_t uartbase;
|
||
|
unsigned int value;
|
||
|
|
||
|
/* sign extend to 64 bits, if needed */
|
||
|
uartbase = (uint64_t)(long)p->membase;
|
||
|
value = nlm_read_reg(uartbase, offset);
|
||
|
|
||
|
/* See XLR/XLS errata */
|
||
|
if (offset == UART_MSR)
|
||
|
value ^= 0xF0;
|
||
|
else if (offset == UART_MCR)
|
||
|
value ^= 0x3;
|
||
|
|
||
|
return value;
|
||
|
}
|
||
|
|
||
|
void nlm_xlr_uart_out(struct uart_port *p, int offset, int value)
|
||
|
{
|
||
|
uint64_t uartbase;
|
||
|
|
||
|
/* sign extend to 64 bits, if needed */
|
||
|
uartbase = (uint64_t)(long)p->membase;
|
||
|
|
||
|
/* See XLR/XLS errata */
|
||
|
if (offset == UART_MSR)
|
||
|
value ^= 0xF0;
|
||
|
else if (offset == UART_MCR)
|
||
|
value ^= 0x3;
|
||
|
|
||
|
nlm_write_reg(uartbase, offset, value);
|
||
|
}
|
||
|
|
||
|
#define PORT(_irq) \
|
||
|
{ \
|
||
|
.irq = _irq, \
|
||
|
.regshift = 2, \
|
||
|
.iotype = UPIO_MEM32, \
|
||
|
.flags = (UPF_SKIP_TEST | \
|
||
|
UPF_FIXED_TYPE | UPF_BOOT_AUTOCONF),\
|
||
|
.uartclk = PIC_CLKS_PER_SEC, \
|
||
|
.type = PORT_16550A, \
|
||
|
.serial_in = nlm_xlr_uart_in, \
|
||
|
.serial_out = nlm_xlr_uart_out, \
|
||
|
}
|
||
|
|
||
|
static struct plat_serial8250_port xlr_uart_data[] = {
|
||
|
PORT(PIC_UART_0_IRQ),
|
||
|
PORT(PIC_UART_1_IRQ),
|
||
|
{},
|
||
|
};
|
||
|
|
||
|
static struct platform_device uart_device = {
|
||
|
.name = "serial8250",
|
||
|
.id = PLAT8250_DEV_PLATFORM,
|
||
|
.dev = {
|
||
|
.platform_data = xlr_uart_data,
|
||
|
},
|
||
|
};
|
||
|
|
||
|
static int __init nlm_uart_init(void)
|
||
|
{
|
||
|
unsigned long uartbase;
|
||
|
|
||
|
uartbase = (unsigned long)nlm_mmio_base(NETLOGIC_IO_UART_0_OFFSET);
|
||
|
xlr_uart_data[0].membase = (void __iomem *)uartbase;
|
||
|
xlr_uart_data[0].mapbase = CPHYSADDR(uartbase);
|
||
|
|
||
|
uartbase = (unsigned long)nlm_mmio_base(NETLOGIC_IO_UART_1_OFFSET);
|
||
|
xlr_uart_data[1].membase = (void __iomem *)uartbase;
|
||
|
xlr_uart_data[1].mapbase = CPHYSADDR(uartbase);
|
||
|
|
||
|
return platform_device_register(&uart_device);
|
||
|
}
|
||
|
|
||
|
arch_initcall(nlm_uart_init);
|