Commit 9730c0ee authored by Pete Zaitcev's avatar Pete Zaitcev Committed by David S. Miller

[SPARC32]: Fix console, sunsu, and IO macros.

parent 48d85404
...@@ -171,31 +171,23 @@ static void __init boot_flags_init(char *commands) ...@@ -171,31 +171,23 @@ static void __init boot_flags_init(char *commands)
/* Process any command switches, otherwise skip it. */ /* Process any command switches, otherwise skip it. */
if (*commands == '\0') if (*commands == '\0')
break; break;
else if (*commands == '-') { if (*commands == '-') {
commands++; commands++;
while (*commands && *commands != ' ') while (*commands && *commands != ' ')
process_switch(*commands++); process_switch(*commands++);
} else { } else {
if (!strncmp(commands, "console=", 8)) { if (!strncmp(commands, "console=", 8)) {
commands += 8; commands += 8;
if (!strncmp (commands, "ttya", 4)) {
console_fb = 2;
prom_printf ("Using /dev/ttya as console.\n");
} else if (!strncmp (commands, "ttyb", 4)) {
console_fb = 3;
prom_printf ("Using /dev/ttyb as console.\n");
#if defined(CONFIG_PROM_CONSOLE) #if defined(CONFIG_PROM_CONSOLE)
} else if (!strncmp (commands, "prom", 4)) { if (!strncmp (commands, "prom", 4)) {
char *p; char *p;
for (p = commands - 8; *p && *p != ' '; p++) for (p = commands - 8; *p && *p != ' '; p++)
*p = ' '; *p = ' ';
conswitchp = &prom_con; conswitchp = &prom_con;
console_fb = 1; console_fb = 1;
#endif
} else {
console_fb = 1;
} }
#endif
} else if (!strncmp(commands, "mem=", 4)) { } else if (!strncmp(commands, "mem=", 4)) {
/* /*
* "mem=XXX[kKmM] overrides the PROM-reported * "mem=XXX[kKmM] overrides the PROM-reported
...@@ -342,33 +334,28 @@ void __init setup_arch(char **cmdline_p) ...@@ -342,33 +334,28 @@ void __init setup_arch(char **cmdline_p)
#ifndef CONFIG_SERIAL_CONSOLE /* Not CONFIG_SERIAL_SUNCORE: to be gone. */ #ifndef CONFIG_SERIAL_CONSOLE /* Not CONFIG_SERIAL_SUNCORE: to be gone. */
serial_console = 0; serial_console = 0;
#else #else
switch (console_fb) { if (console_fb != 0) {
case 0: /* Let get our io devices from prom */ serial_console = 0;
{ } else {
int idev = prom_query_input_device(); int idev = prom_query_input_device();
int odev = prom_query_output_device(); int odev = prom_query_output_device();
if (idev == PROMDEV_IKBD && odev == PROMDEV_OSCREEN) { if (idev == PROMDEV_IKBD && odev == PROMDEV_OSCREEN) {
serial_console = 0; serial_console = 0;
} else if (idev == PROMDEV_ITTYA && odev == PROMDEV_OTTYA) { } else if (idev == PROMDEV_ITTYA && odev == PROMDEV_OTTYA) {
serial_console = 1; serial_console = 1;
} else if (idev == PROMDEV_ITTYB && odev == PROMDEV_OTTYB) { } else if (idev == PROMDEV_ITTYB && odev == PROMDEV_OTTYB) {
serial_console = 2; serial_console = 2;
} else if (idev == PROMDEV_I_UNK && odev == PROMDEV_OTTYA) { } else if (idev == PROMDEV_I_UNK && odev == PROMDEV_OTTYA) {
prom_printf("MrCoffee ttya\n"); prom_printf("MrCoffee ttya\n");
serial_console = 1; serial_console = 1;
} else if (idev == PROMDEV_I_UNK && odev == PROMDEV_OSCREEN) { } else if (idev == PROMDEV_I_UNK && odev == PROMDEV_OSCREEN) {
serial_console = 0; serial_console = 0;
prom_printf("MrCoffee keyboard\n"); prom_printf("MrCoffee keyboard\n");
} else { } else {
prom_printf("Inconsistent or unknown console\n"); prom_printf("Confusing console (idev %d, odev %d)\n",
prom_printf("You cannot mix serial and non serial input/output devices\n"); idev, odev);
prom_halt(); serial_console = 1;
}
} }
break;
case 1: serial_console = 0; break; /* Force one of the framebuffers as console */
case 2: serial_console = 1; break; /* Force ttya as console */
case 3: serial_console = 2; break; /* Force ttyb as console */
} }
#endif #endif
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/tty_flip.h> #include <linux/tty_flip.h>
...@@ -28,11 +29,12 @@ ...@@ -28,11 +29,12 @@
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/circ_buf.h> #include <linux/circ_buf.h>
#include <linux/serial.h> #include <linux/serial.h>
#include <linux/sysrq.h>
#include <linux/console.h> #include <linux/console.h>
#include <linux/spinlock.h>
#ifdef CONFIG_SERIO #ifdef CONFIG_SERIO
#include <linux/serio.h> #include <linux/serio.h>
#endif #endif
#include <linux/serial_reg.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/delay.h> #include <linux/delay.h>
...@@ -44,8 +46,12 @@ ...@@ -44,8 +46,12 @@
#include <asm/isa.h> #include <asm/isa.h>
#endif #endif
/* #if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) */
#if defined(CONFIG_MAGIC_SYSRQ)
#define SUPPORT_SYSRQ
#endif
#include <linux/serial_core.h> #include <linux/serial_core.h>
#include <linux/serial_reg.h>
#include "suncore.h" #include "suncore.h"
...@@ -88,6 +94,7 @@ struct uart_sunsu_port { ...@@ -88,6 +94,7 @@ struct uart_sunsu_port {
/* Probing information. */ /* Probing information. */
enum su_type su_type; enum su_type su_type;
unsigned int type_probed; /* XXX Stupid */
int port_node; int port_node;
unsigned int irq; unsigned int irq;
...@@ -333,7 +340,8 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs ...@@ -333,7 +340,8 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs
if (*status & UART_LSR_BI) { if (*status & UART_LSR_BI) {
*status &= ~(UART_LSR_FE | UART_LSR_PE); *status &= ~(UART_LSR_FE | UART_LSR_PE);
up->port.icount.brk++; up->port.icount.brk++;
if (up->port.line == up->port.cons->index) if (up->port.cons != NULL &&
up->port.line == up->port.cons->index)
saw_console_brk = 1; saw_console_brk = 1;
/* /*
* We do the SysRQ and SAK checking * We do the SysRQ and SAK checking
...@@ -355,7 +363,8 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs ...@@ -355,7 +363,8 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs
*/ */
*status &= up->port.read_status_mask; *status &= up->port.read_status_mask;
if (up->port.line == up->port.cons->index) { if (up->port.cons != NULL &&
up->port.line == up->port.cons->index) {
/* Recover the break flag from console xmit */ /* Recover the break flag from console xmit */
*status |= up->lsr_break_flag; *status |= up->lsr_break_flag;
up->lsr_break_flag = 0; up->lsr_break_flag = 0;
...@@ -910,6 +919,16 @@ static int sunsu_request_port(struct uart_port *port) ...@@ -910,6 +919,16 @@ static int sunsu_request_port(struct uart_port *port)
static void sunsu_config_port(struct uart_port *port, int flags) static void sunsu_config_port(struct uart_port *port, int flags)
{ {
struct uart_sunsu_port *up = (struct uart_sunsu_port *) port;
if (flags & UART_CONFIG_TYPE) {
/*
* We are supposed to call autoconfig here, but this requires
* splitting all the OBP probing crap from the UART probing.
* We'll do it when we kill sunsu.c altogether.
*/
port->type = up->type_probed; /* XXX */
}
} }
static int static int
...@@ -1020,6 +1039,7 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up) ...@@ -1020,6 +1039,7 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up)
if (!up->port_node || !up->su_type) if (!up->port_node || !up->su_type)
return; return;
up->type_probed = PORT_UNKNOWN;
up->port.iotype = SERIAL_IO_MEM; up->port.iotype = SERIAL_IO_MEM;
/* /*
...@@ -1028,7 +1048,16 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up) ...@@ -1028,7 +1048,16 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up)
for_each_ebus(ebus) { for_each_ebus(ebus) {
for_each_ebusdev(dev, ebus) { for_each_ebusdev(dev, ebus) {
if (dev->prom_node == up->port_node) { if (dev->prom_node == up->port_node) {
/*
* The EBus is broken on sparc; it delivers
* virtual addresses in resources. Oh well...
* This is correct on sparc64, though.
*/
up->port.membase = (char *) dev->resource[0].start; up->port.membase = (char *) dev->resource[0].start;
/*
* This is correct on both architectures.
*/
up->port.mapbase = dev->resource[0].start;
up->irq = dev->irqs[0]; up->irq = dev->irqs[0];
goto ebus_done; goto ebus_done;
} }
...@@ -1039,7 +1068,9 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up) ...@@ -1039,7 +1068,9 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up)
for_each_isa(isa_br) { for_each_isa(isa_br) {
for_each_isadev(isa_dev, isa_br) { for_each_isadev(isa_dev, isa_br) {
if (isa_dev->prom_node == up->port_node) { if (isa_dev->prom_node == up->port_node) {
/* Same on sparc64. Cool architecure... */
up->port.membase = (char *) isa_dev->resource.start; up->port.membase = (char *) isa_dev->resource.start;
up->port.mapbase = isa_dev->resource.start;
up->irq = isa_dev->irq; up->irq = isa_dev->irq;
goto ebus_done; goto ebus_done;
} }
...@@ -1067,6 +1098,7 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up) ...@@ -1067,6 +1098,7 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up)
reg0.which_io, reg0.phys_addr); reg0.which_io, reg0.phys_addr);
return; return;
} }
up->port.mapbase = reg0.phys_addr;
if ((up->port.membase = ioremap(reg0.phys_addr, reg0.reg_size)) == 0) { if ((up->port.membase = ioremap(reg0.phys_addr, reg0.reg_size)) == 0) {
prom_printf("sunsu: Cannot map registers.\n"); prom_printf("sunsu: Cannot map registers.\n");
return; return;
...@@ -1203,6 +1235,7 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up) ...@@ -1203,6 +1235,7 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up)
if (up->port.type == PORT_UNKNOWN) if (up->port.type == PORT_UNKNOWN)
goto out; goto out;
up->type_probed = up->port.type; /* XXX */
/* /*
* Reset the UART. * Reset the UART.
...@@ -1454,6 +1487,7 @@ static int __init sunsu_serial_init(void) ...@@ -1454,6 +1487,7 @@ static int __init sunsu_serial_init(void)
up->su_type == SU_PORT_KBD) up->su_type == SU_PORT_KBD)
continue; continue;
up->port.flags |= ASYNC_BOOT_AUTOCONF;
up->port.type = PORT_UNKNOWN; up->port.type = PORT_UNKNOWN;
up->port.uartclk = (SU_BASE_BAUD * 16); up->port.uartclk = (SU_BASE_BAUD * 16);
...@@ -1475,7 +1509,6 @@ static int __init sunsu_serial_init(void) ...@@ -1475,7 +1509,6 @@ static int __init sunsu_serial_init(void)
if (ret < 0) if (ret < 0)
return ret; return ret;
instance = 0;
for (i = 0; i < UART_NR; i++) { for (i = 0; i < UART_NR; i++) {
struct uart_sunsu_port *up = &sunsu_ports[i]; struct uart_sunsu_port *up = &sunsu_ports[i];
...@@ -1645,9 +1678,6 @@ static int __init sunsu_probe(void) ...@@ -1645,9 +1678,6 @@ static int __init sunsu_probe(void)
/* /*
* Console must be initiated after the generic initialization. * Console must be initiated after the generic initialization.
*/ */
sunsu_reg.cons = &sunsu_cons;
sunsu_reg.nr = scan.devices;
sunsu_serial_init(); sunsu_serial_init();
sunsu_serial_console_init(); sunsu_serial_console_init();
......
...@@ -25,38 +25,17 @@ static __inline__ u16 flip_word (u16 d) ...@@ -25,38 +25,17 @@ static __inline__ u16 flip_word (u16 d)
/* /*
* Memory mapped I/O to PCI * Memory mapped I/O to PCI
*
* Observe that ioremap returns void* cookie, but accessors, such
* as readb, take unsigned long as address, by API. This mismatch
* happened historically. The ioremap is much older than accessors,
* so at one time ioremap's cookie was used as address (*a = val).
* When accessors came about, they were designed to be compatible across
* buses, so that drivers can select proper ones like sunhme.c did.
* To make that easier, they use same aruments (ulong) for sbus, pci, isa.
* The offshot is, we must cast readb et. al. arguments with a #define.
*/ */
static __inline__ u8 readb(unsigned long addr)
{
return *(volatile u8 *)addr;
}
static __inline__ u16 readw(unsigned long addr)
{
return flip_word(*(volatile u16 *)addr);
}
static __inline__ u32 readl(unsigned long addr)
{
return flip_dword(*(volatile u32 *)addr);
}
static __inline__ void writeb(u8 b, unsigned long addr)
{
*(volatile u8 *)addr = b;
}
static __inline__ void writew(u16 b, unsigned long addr)
{
*(volatile u16 *)addr = flip_word(b);
}
static __inline__ void writel(u32 b, unsigned long addr)
{
*(volatile u32 *)addr = flip_dword(b);
}
/* Now the 'raw' versions. */
static __inline__ u8 __raw_readb(unsigned long addr) static __inline__ u8 __raw_readb(unsigned long addr)
{ {
return *(volatile u8 *)addr; return *(volatile u8 *)addr;
...@@ -87,6 +66,14 @@ static __inline__ void __raw_writel(u32 b, unsigned long addr) ...@@ -87,6 +66,14 @@ static __inline__ void __raw_writel(u32 b, unsigned long addr)
*(volatile u32 *)addr = b; *(volatile u32 *)addr = b;
} }
#define readb(addr) (*(volatile u8 *)(addr))
#define readw(addr) flip_word(*(volatile u16 *)(addr))
#define readl(addr) flip_dword(*(volatile u32 *)(addr))
#define writeb(b, a) (*(volatile u8 *)(a) = b)
#define writew(b, a) (*(volatile u16 *)(a) = flip_word(b))
#define writel(b, a) (*(volatile u32 *)(a) = flip_dword(b))
/* /*
* I/O space operations * I/O space operations
* *
...@@ -163,7 +150,6 @@ static __inline__ void _sbus_writel(u32 b, unsigned long addr) ...@@ -163,7 +150,6 @@ static __inline__ void _sbus_writel(u32 b, unsigned long addr)
/* /*
* The only reason for #define's is to hide casts to unsigned long. * The only reason for #define's is to hide casts to unsigned long.
* XXX Rewrite drivers without structures for registers.
*/ */
#define sbus_readb(a) _sbus_readb((unsigned long)(a)) #define sbus_readb(a) _sbus_readb((unsigned long)(a))
#define sbus_readw(a) _sbus_readw((unsigned long)(a)) #define sbus_readw(a) _sbus_readw((unsigned long)(a))
...@@ -193,13 +179,11 @@ extern void *ioremap(unsigned long offset, unsigned long size); ...@@ -193,13 +179,11 @@ extern void *ioremap(unsigned long offset, unsigned long size);
#define ioremap_nocache(X,Y) ioremap((X),(Y)) #define ioremap_nocache(X,Y) ioremap((X),(Y))
extern void iounmap(void *addr); extern void iounmap(void *addr);
/* P3: talk davem into dropping "name" argument in favor of res->name */
/* /*
* Bus number may be in res->flags... somewhere. * Bus number may be in res->flags... somewhere.
*/ */
extern unsigned long sbus_ioremap(struct resource *res, unsigned long offset, extern unsigned long sbus_ioremap(struct resource *res, unsigned long offset,
unsigned long size, char *name); unsigned long size, char *name);
/* XXX Partial deallocations? I think not! */
extern void sbus_iounmap(unsigned long vaddr, unsigned long size); extern void sbus_iounmap(unsigned long vaddr, unsigned long size);
...@@ -215,7 +199,7 @@ extern void sbus_iounmap(unsigned long vaddr, unsigned long size); ...@@ -215,7 +199,7 @@ extern void sbus_iounmap(unsigned long vaddr, unsigned long size);
#define RTC_ALWAYS_BCD 0 #define RTC_ALWAYS_BCD 0
/* Nothing to do */ /* Nothing to do */
/* P3: Only IDE DMA may need these. */ /* P3: Only IDE DMA may need these. XXX Verify that it still does... */
#define dma_cache_inv(_start,_size) do { } while (0) #define dma_cache_inv(_start,_size) do { } while (0)
#define dma_cache_wback(_start,_size) do { } while (0) #define dma_cache_wback(_start,_size) do { } while (0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment