* serial.c driver, and is currently the preferred form.
*/
#include <linux/config.h>
+
+#if defined(CONFIG_SERIAL_M32R_SIO_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/ioport.h>
#include <asm/io.h>
#include <asm/irq.h>
-#if defined(CONFIG_SERIAL_M32R_SIO_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-#define SUPPORT_SYSRQ
-#endif
-
-#define PORT_SIO 1
-#define PORT_MAX_SIO 1
+#define PORT_M32R_BASE PORT_M32R_SIO
+#define PORT_INDEX(x) (x - PORT_M32R_BASE + 1)
#define BAUD_RATE 115200
#include <linux/serial_core.h>
#include "m32r_sio.h"
#include "m32r_sio_reg.h"
-/*
- * Configuration:
- * share_irqs - whether we pass SA_SHIRQ to request_irq(). This option
- * is unsafe when used on edge-triggered interrupts.
- */
-unsigned int share_irqs_sio = M32R_SIO_SHARE_IRQS;
-
/*
* Debugging.
*/
*/
#define is_real_interrupt(irq) ((irq) != 0)
-/*
- * This converts from our new CONFIG_ symbols to the symbols
- * that asm/serial.h expects. You _NEED_ to comment out the
- * linux/config.h include contained inside asm/serial.h for
- * this to work.
- */
-#undef CONFIG_SERIAL_MANY_PORTS
-#undef CONFIG_SERIAL_DETECT_IRQ
-#undef CONFIG_SERIAL_MULTIPORT
-#undef CONFIG_HUB6
+#include <asm/serial.h>
-#ifdef CONFIG_SERIAL_M32R_SIO_DETECT_IRQ
-#define CONFIG_SERIAL_DETECT_IRQ 1
-#endif
-#ifdef CONFIG_SERIAL_M32R_SIO_MULTIPORT
-#define CONFIG_SERIAL_MULTIPORT 1
-#endif
-#ifdef CONFIG_SERIAL_M32R_SIO_MANY_PORTS
-#define CONFIG_SERIAL_MANY_PORTS 1
-#endif
+/* Standard COM flags */
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
/*
- * HUB6 is always on. This will be removed once the header
- * files have been cleaned.
+ * SERIAL_PORT_DFNS tells us about built-in ports that have no
+ * standard enumeration mechanism. Platforms that can find all
+ * serial ports via mechanisms like ACPI or PCI need not supply it.
*/
-#define CONFIG_HUB6 1
+#undef SERIAL_PORT_DFNS
+#if defined(CONFIG_PLAT_USRV)
-#include <asm/serial.h>
+#define SERIAL_PORT_DFNS \
+ /* UART CLK PORT IRQ FLAGS */ \
+ { 0, BASE_BAUD, 0x3F8, PLD_IRQ_UART0, STD_COM_FLAGS }, /* ttyS0 */ \
+ { 0, BASE_BAUD, 0x2F8, PLD_IRQ_UART1, STD_COM_FLAGS }, /* ttyS1 */
-#ifdef CONFIG_SERIAL_M32R_PLDSIO
-static struct old_serial_port old_serial_port[] = {
- { 0, BASE_BAUD, ((unsigned long)PLD_ESIO0CR), PLD_IRQ_SIO0_RCV, STD_COM_FLAGS },
-};
+#else /* !CONFIG_PLAT_USRV */
+
+#if defined(CONFIG_SERIAL_M32R_PLDSIO)
+#define SERIAL_PORT_DFNS \
+ { 0, BASE_BAUD, ((unsigned long)PLD_ESIO0CR), PLD_IRQ_SIO0_RCV, \
+ STD_COM_FLAGS }, /* ttyS0 */
#else
+#define SERIAL_PORT_DFNS \
+ { 0, BASE_BAUD, M32R_SIO_OFFSET, M32R_IRQ_SIO0_R, \
+ STD_COM_FLAGS }, /* ttyS0 */
+#endif
+
+#endif /* !CONFIG_PLAT_USRV */
+
static struct old_serial_port old_serial_port[] = {
- { 0, BASE_BAUD, M32R_SIO_OFFSET, M32R_IRQ_SIO0_R, STD_COM_FLAGS },
+ SERIAL_PORT_DFNS /* defined in asm/serial.h */
};
-#endif
#define UART_NR ARRAY_SIZE(old_serial_port)
/*
* Here we define the default xmit fifo size used for each type of UART.
*/
-static const struct serial_uart_config uart_config[PORT_MAX_SIO+1] = {
- { "unknown", 1, 0 },
- { "M32RSIO", 1, 0 }
+static const struct serial_uart_config uart_config[] = {
+ [PORT_UNKNOWN] = {
+ .name = "unknown",
+ .dfl_xmit_fifo_size = 1,
+ .flags = 0,
+ },
+ [PORT_INDEX(PORT_M32R_SIO)] = {
+ .name = "M32RSIO",
+ .dfl_xmit_fifo_size = 1,
+ .flags = 0,
+ },
};
#ifdef CONFIG_SERIAL_M32R_PLDSIO
if (status & 0x04)
receive_chars(up, &status, regs);
- // check_modem_status(up);
if (status & 0x01)
transmit_chars(up);
}
}
/*
- * This function is used to handle ports that do not have an
- * interrupt. This doesn't work very well for 16450's, but gives
- * barely passable results for a 16550A. (Although at the expense
- * of much CPU overhead).
+ * This function is used to handle ports that do not have an interrupt.
*/
static void m32r_sio_timeout(unsigned long data)
{
int ret = 0;
switch (up->port.iotype) {
- case SERIAL_IO_MEM:
+ case UPIO_MEM:
if (up->port.mapbase) {
#ifdef CONFIG_SERIAL_M32R_PLDSIO
*res = request_mem_region(up->port.mapbase, size, "serial");
#else
start = up->port.mapbase;
- start += UART_RSA_BASE << up->port.regshift;
*res = request_mem_region(start, size, "serial");
#endif
if (!*res)
}
break;
- case SERIAL_IO_HUB6:
- case SERIAL_IO_PORT:
+ case UPIO_PORT:
*res = request_region(up->port.iobase, size, "serial");
if (!*res)
ret = -EBUSY;
return ret;
}
-static int
-m32r_sio_request_rsa_resource(struct uart_sio_port *up, struct resource **res)
-{
- unsigned int size = 8 << up->port.regshift;
- unsigned long start;
- int ret = 0;
-
- switch (up->port.iotype) {
- case SERIAL_IO_MEM:
- if (up->port.mapbase) {
- start = up->port.mapbase;
- start += UART_RSA_BASE << up->port.regshift;
-#ifdef CONFIG_SERIAL_M32R_PLDSIO
- *res = request_mem_region(start, size, "serial-rsa");
-#else
- *res = request_mem_region(up->port.mapbase, size, "serial-rsa");
-#endif
- if (!*res)
- ret = -EBUSY;
- }
- break;
-
- case SERIAL_IO_HUB6:
- case SERIAL_IO_PORT:
- start = up->port.iobase;
- start += UART_RSA_BASE << up->port.regshift;
- *res = request_region(up->port.iobase, size, "serial-rsa");
- if (!*res)
- ret = -EBUSY;
- break;
- }
-
- return ret;
-}
-
static void m32r_sio_release_port(struct uart_port *port)
{
struct uart_sio_port *up = (struct uart_sio_port *)port;
unsigned long start, offset = 0, size = 0;
- if (up->port.type == PORT_RSA) {
- offset = UART_RSA_BASE << up->port.regshift;
- size = 8;
- }
-
size <<= up->port.regshift;
switch (up->port.iotype) {
- case SERIAL_IO_MEM:
+ case UPIO_MEM:
if (up->port.mapbase) {
/*
* Unmap the area.
}
break;
- case SERIAL_IO_HUB6:
- case SERIAL_IO_PORT:
+ case UPIO_PORT:
start = up->port.iobase;
if (size)
static int m32r_sio_request_port(struct uart_port *port)
{
struct uart_sio_port *up = (struct uart_sio_port *)port;
- struct resource *res = NULL, *res_rsa = NULL;
+ struct resource *res = NULL;
int ret = 0;
- if (up->port.type == PORT_RSA){
- ret = m32r_sio_request_rsa_resource(up, &res_rsa);
- if (ret < 0)
- return ret;
- }
ret = m32r_sio_request_std_resource(up, &res);
/*
}
if (ret < 0) {
- if (res_rsa)
- release_resource(res_rsa);
if (res)
release_resource(res);
}
+
return ret;
}
spin_lock_irqsave(&up->port.lock, flags);
- up->port.type = PORT_SIO;
+ up->port.type = (PORT_M32R_SIO - PORT_M32R_BASE + 1);
up->port.fifosize = uart_config[up->port.type].dfl_xmit_fifo_size;
spin_unlock_irqrestore(&up->port.lock, flags);
{
if (ser->irq >= NR_IRQS || ser->irq < 0 ||
ser->baud_base < 9600 || ser->type < PORT_UNKNOWN ||
- ser->type > PORT_MAX_SIO || ser->type == PORT_CIRRUS ||
- ser->type == PORT_STARTECH)
+ ser->type >= ARRAY_SIZE(uart_config))
return -EINVAL;
return 0;
}
static struct uart_sio_port m32r_sio_ports[UART_NR];
-static void __init m32r_sio_isa_init_ports(void)
+static void __init m32r_sio_init_ports(void)
{
struct uart_sio_port *up;
static int first = 1;
up->port.irq = irq_canonicalize(old_serial_port[i].irq);
up->port.uartclk = old_serial_port[i].baud_base * 16;
up->port.flags = old_serial_port[i].flags;
- up->port.hub6 = old_serial_port[i].hub6;
up->port.membase = old_serial_port[i].iomem_base;
up->port.iotype = old_serial_port[i].io_type;
up->port.regshift = old_serial_port[i].iomem_reg_shift;
up->port.ops = &m32r_sio_pops;
- if (share_irqs_sio)
- up->port.flags |= UPF_SHARE_IRQ;
}
}
{
int i;
- m32r_sio_isa_init_ports();
+ m32r_sio_init_ports();
for (i = 0; i < UART_NR; i++) {
struct uart_sio_port *up = &m32r_sio_ports[i];
{
sio_reset();
sio_init();
- m32r_sio_isa_init_ports();
+ m32r_sio_init_ports();
register_console(&m32r_sio_console);
return 0;
}
.cons = M32R_SIO_CONSOLE,
};
-/*
- * register_serial and unregister_serial allows for 16x50 serial ports to be
- * configured at run-time, to support PCMCIA modems.
- */
-
-static int __register_m32r_sio(struct serial_struct *req, int line)
-{
- struct uart_port port;
-
- port.iobase = req->port;
- port.membase = req->iomem_base;
- port.irq = req->irq;
- port.uartclk = req->baud_base * 16;
- port.fifosize = req->xmit_fifo_size;
- port.regshift = req->iomem_reg_shift;
- port.iotype = req->io_type;
- port.flags = req->flags | UPF_BOOT_AUTOCONF;
- port.mapbase = req->iomap_base;
- port.line = line;
-
- if (share_irqs_sio)
- port.flags |= UPF_SHARE_IRQ;
-
- if (HIGH_BITS_OFFSET)
- port.iobase |= (long) req->port_high << HIGH_BITS_OFFSET;
-
- /*
- * If a clock rate wasn't specified by the low level
- * driver, then default to the standard clock rate.
- */
- if (port.uartclk == 0)
- port.uartclk = BASE_BAUD * 16;
-
- return uart_register_port(&m32r_sio_reg, &port);
-}
-
-/**
- * register_serial - configure a 16x50 serial port at runtime
- * @req: request structure
- *
- * Configure the serial port specified by the request. If the
- * port exists and is in use an error is returned. If the port
- * is not currently in the table it is added.
- *
- * The port is then probed and if necessary the IRQ is autodetected
- * If this fails an error is returned.
- *
- * On success the port is ready to use and the line number is returned.
- */
-int register_m32r_sio(struct serial_struct *req)
-{
- return __register_m32r_sio(req, -1);
-}
-
-int __init early_m32r_sio_setup(struct uart_port *port)
-{
- m32r_sio_isa_init_ports();
- m32r_sio_ports[port->line].port = *port;
- m32r_sio_ports[port->line].port.ops = &m32r_sio_pops;
-
- return 0;
-}
-
-/**
- * unregister_serial - remove a 16x50 serial port at runtime
- * @line: serial line number
- *
- * Remove one serial port. This may be called from interrupt
- * context.
- */
-void unregister_m32r_sio(int line)
-{
- uart_unregister_port(&m32r_sio_reg, line);
-}
-
-/*
- * This is for ISAPNP only.
- */
-void m32r_sio_get_irq_map(unsigned int *map)
-{
- int i;
-
- for (i = 0; i < UART_NR; i++) {
- if (m32r_sio_ports[i].port.type != PORT_UNKNOWN &&
- m32r_sio_ports[i].port.irq < 16)
- *map |= 1 << m32r_sio_ports[i].port.irq;
- }
-}
-
/**
* m32r_sio_suspend_port - suspend one serial port
* @line: serial line number
{
int ret, i;
- printk(KERN_INFO "Serial: M32R SIO driver $Revision: 1.9 $ "
- "IRQ sharing %sabled\n", share_irqs_sio ? "en" : "dis");
+ printk(KERN_INFO "Serial: M32R SIO driver $Revision: 1.11 $ ");
for (i = 0; i < NR_IRQS; i++)
spin_lock_init(&irq_lists[i].lock);
module_init(m32r_sio_init);
module_exit(m32r_sio_exit);
-EXPORT_SYMBOL(register_m32r_sio);
-EXPORT_SYMBOL(unregister_m32r_sio);
-EXPORT_SYMBOL(m32r_sio_get_irq_map);
EXPORT_SYMBOL(m32r_sio_suspend_port);
EXPORT_SYMBOL(m32r_sio_resume_port);
MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Generic M32R SIO serial driver $Revision: 1.9 $");
-
-module_param(share_irqs_sio, bool, 0400);
-MODULE_PARM_DESC(share_irqs_sio, "Share IRQs with other non-M32R SIO devices"
- " (unsafe)");
+MODULE_DESCRIPTION("Generic M32R SIO serial driver $Revision: 1.11 $");