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)
/* Process any command switches, otherwise skip it. */
if (*commands == '\0')
break;
else if (*commands == '-') {
if (*commands == '-') {
commands++;
while (*commands && *commands != ' ')
process_switch(*commands++);
} else {
if (!strncmp(commands, "console=", 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)
} else if (!strncmp (commands, "prom", 4)) {
if (!strncmp (commands, "prom", 4)) {
char *p;
for (p = commands - 8; *p && *p != ' '; p++)
*p = ' ';
conswitchp = &prom_con;
console_fb = 1;
#endif
} else {
console_fb = 1;
}
#endif
} else if (!strncmp(commands, "mem=", 4)) {
/*
* "mem=XXX[kKmM] overrides the PROM-reported
......@@ -342,9 +334,9 @@ void __init setup_arch(char **cmdline_p)
#ifndef CONFIG_SERIAL_CONSOLE /* Not CONFIG_SERIAL_SUNCORE: to be gone. */
serial_console = 0;
#else
switch (console_fb) {
case 0: /* Let get our io devices from prom */
{
if (console_fb != 0) {
serial_console = 0;
} else {
int idev = prom_query_input_device();
int odev = prom_query_output_device();
if (idev == PROMDEV_IKBD && odev == PROMDEV_OSCREEN) {
......@@ -360,15 +352,10 @@ void __init setup_arch(char **cmdline_p)
serial_console = 0;
prom_printf("MrCoffee keyboard\n");
} else {
prom_printf("Inconsistent or unknown console\n");
prom_printf("You cannot mix serial and non serial input/output devices\n");
prom_halt();
}
prom_printf("Confusing console (idev %d, odev %d)\n",
idev, odev);
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
......
......@@ -19,6 +19,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
......@@ -28,11 +29,12 @@
#include <linux/ioport.h>
#include <linux/circ_buf.h>
#include <linux/serial.h>
#include <linux/sysrq.h>
#include <linux/console.h>
#include <linux/spinlock.h>
#ifdef CONFIG_SERIO
#include <linux/serio.h>
#endif
#include <linux/serial_reg.h>
#include <linux/init.h>
#include <linux/delay.h>
......@@ -44,8 +46,12 @@
#include <asm/isa.h>
#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_reg.h>
#include "suncore.h"
......@@ -88,6 +94,7 @@ struct uart_sunsu_port {
/* Probing information. */
enum su_type su_type;
unsigned int type_probed; /* XXX Stupid */
int port_node;
unsigned int irq;
......@@ -333,7 +340,8 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs
if (*status & UART_LSR_BI) {
*status &= ~(UART_LSR_FE | UART_LSR_PE);
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;
/*
* We do the SysRQ and SAK checking
......@@ -355,7 +363,8 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs
*/
*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 */
*status |= up->lsr_break_flag;
up->lsr_break_flag = 0;
......@@ -910,6 +919,16 @@ static int sunsu_request_port(struct uart_port *port)
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
......@@ -1020,6 +1039,7 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up)
if (!up->port_node || !up->su_type)
return;
up->type_probed = PORT_UNKNOWN;
up->port.iotype = SERIAL_IO_MEM;
/*
......@@ -1028,7 +1048,16 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up)
for_each_ebus(ebus) {
for_each_ebusdev(dev, ebus) {
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;
/*
* This is correct on both architectures.
*/
up->port.mapbase = dev->resource[0].start;
up->irq = dev->irqs[0];
goto ebus_done;
}
......@@ -1039,7 +1068,9 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up)
for_each_isa(isa_br) {
for_each_isadev(isa_dev, isa_br) {
if (isa_dev->prom_node == up->port_node) {
/* Same on sparc64. Cool architecure... */
up->port.membase = (char *) isa_dev->resource.start;
up->port.mapbase = isa_dev->resource.start;
up->irq = isa_dev->irq;
goto ebus_done;
}
......@@ -1067,6 +1098,7 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up)
reg0.which_io, reg0.phys_addr);
return;
}
up->port.mapbase = reg0.phys_addr;
if ((up->port.membase = ioremap(reg0.phys_addr, reg0.reg_size)) == 0) {
prom_printf("sunsu: Cannot map registers.\n");
return;
......@@ -1203,6 +1235,7 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up)
if (up->port.type == PORT_UNKNOWN)
goto out;
up->type_probed = up->port.type; /* XXX */
/*
* Reset the UART.
......@@ -1454,6 +1487,7 @@ static int __init sunsu_serial_init(void)
up->su_type == SU_PORT_KBD)
continue;
up->port.flags |= ASYNC_BOOT_AUTOCONF;
up->port.type = PORT_UNKNOWN;
up->port.uartclk = (SU_BASE_BAUD * 16);
......@@ -1475,7 +1509,6 @@ static int __init sunsu_serial_init(void)
if (ret < 0)
return ret;
instance = 0;
for (i = 0; i < UART_NR; i++) {
struct uart_sunsu_port *up = &sunsu_ports[i];
......@@ -1645,9 +1678,6 @@ static int __init sunsu_probe(void)
/*
* Console must be initiated after the generic initialization.
*/
sunsu_reg.cons = &sunsu_cons;
sunsu_reg.nr = scan.devices;
sunsu_serial_init();
sunsu_serial_console_init();
......
......@@ -25,38 +25,17 @@ static __inline__ u16 flip_word (u16 d)
/*
* 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)
{
return *(volatile u8 *)addr;
......@@ -87,6 +66,14 @@ static __inline__ void __raw_writel(u32 b, unsigned long addr)
*(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
*
......@@ -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.
* XXX Rewrite drivers without structures for registers.
*/
#define sbus_readb(a) _sbus_readb((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);
#define ioremap_nocache(X,Y) ioremap((X),(Y))
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.
*/
extern unsigned long sbus_ioremap(struct resource *res, unsigned long offset,
unsigned long size, char *name);
/* XXX Partial deallocations? I think not! */
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
/* 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_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