Commit c4be9fc7 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/home/davem/BK/sparc-2.5

into home.transmeta.com:/home/torvalds/v2.5/linux
parents b12d2ca2 9730c0ee
...@@ -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
......
...@@ -316,6 +316,14 @@ static unsigned long __srmmu_get_nocache(int size, int align) ...@@ -316,6 +316,14 @@ static unsigned long __srmmu_get_nocache(int size, int align)
unsigned long va_tmp, phys_tmp; unsigned long va_tmp, phys_tmp;
int lowest_failed = 0; int lowest_failed = 0;
if (size < SRMMU_NOCACHE_BITMAP_SHIFT) {
printk("Size 0x%x too small for nocache request\n", size);
size = SRMMU_NOCACHE_BITMAP_SHIFT;
}
if (size & (SRMMU_NOCACHE_BITMAP_SHIFT-1)) {
printk("Size 0x%x unaligned int nocache request\n", size);
size += SRMMU_NOCACHE_BITMAP_SHIFT-1;
}
size = size >> SRMMU_NOCACHE_BITMAP_SHIFT; size = size >> SRMMU_NOCACHE_BITMAP_SHIFT;
spin_lock(&srmmu_nocache_spinlock); spin_lock(&srmmu_nocache_spinlock);
...@@ -376,8 +384,32 @@ unsigned inline long srmmu_get_nocache(int size, int align) ...@@ -376,8 +384,32 @@ unsigned inline long srmmu_get_nocache(int size, int align)
void srmmu_free_nocache(unsigned long vaddr, int size) void srmmu_free_nocache(unsigned long vaddr, int size)
{ {
int offset = (vaddr - SRMMU_NOCACHE_VADDR) >> SRMMU_NOCACHE_BITMAP_SHIFT; int offset;
if (vaddr < SRMMU_NOCACHE_VADDR) {
printk("Vaddr %x is smaller than nocache base 0x%x\n",
vaddr, SRMMU_NOCACHE_VADDR);
BUG();
}
if (vaddr >= SRMMU_NOCACHE_END) {
printk("Vaddr %x is bigger than nocache end 0x%x\n",
vaddr, SRMMU_NOCACHE_END);
BUG();
}
if (size & (size-1)) {
printk("Size 0x%x is not a power of 2\n", size);
BUG();
}
if (size < SRMMU_NOCACHE_BITMAP_SHIFT) {
printk("Size 0x%x is too small\n", size);
BUG();
}
if (vaddr & (size-1)) {
printk("Vaddr 0x%x is not aligned to size 0x%x\n", vaddr, size);
BUG();
}
offset = (vaddr - SRMMU_NOCACHE_VADDR) >> SRMMU_NOCACHE_BITMAP_SHIFT;
size = size >> SRMMU_NOCACHE_BITMAP_SHIFT; size = size >> SRMMU_NOCACHE_BITMAP_SHIFT;
spin_lock(&srmmu_nocache_spinlock); spin_lock(&srmmu_nocache_spinlock);
...@@ -501,9 +533,13 @@ static void srmmu_free_pte_fast(pte_t *pte) ...@@ -501,9 +533,13 @@ static void srmmu_free_pte_fast(pte_t *pte)
static void srmmu_pte_free(struct page *pte) static void srmmu_pte_free(struct page *pte)
{ {
unsigned long p = (unsigned long)page_address(pte); unsigned long p;
p = (unsigned long)page_address(pte); /* Cached address (for test) */
if (p == 0) if (p == 0)
BUG(); BUG();
p = ((pte - mem_map) << PAGE_SHIFT); /* Physical address */
p = (unsigned long) __nocache_va(p); /* Nocached virtual */
srmmu_free_nocache(p, SRMMU_PTE_SZ_SOFT); srmmu_free_nocache(p, SRMMU_PTE_SZ_SOFT);
} }
......
...@@ -25,6 +25,14 @@ CONFIG_SMP ...@@ -25,6 +25,14 @@ CONFIG_SMP
If you don't know what to do here, say N. If you don't know what to do here, say N.
CONFIG_HUGETLB_PAGE
This enables support for huge pages. User space applications
can make use of this support with the sys_alloc_hugepages and
sys_free_hugepages system calls. If your applications are
huge page aware, then say Y here.
Otherwise, say N.
CONFIG_PREEMPT CONFIG_PREEMPT
This option reduces the latency of the kernel when reacting to This option reduces the latency of the kernel when reacting to
real-time or interactive events by allowing a low priority process to real-time or interactive events by allowing a low priority process to
......
...@@ -15,6 +15,8 @@ define_bool CONFIG_VT y ...@@ -15,6 +15,8 @@ define_bool CONFIG_VT y
define_bool CONFIG_VT_CONSOLE y define_bool CONFIG_VT_CONSOLE y
define_bool CONFIG_HW_CONSOLE y define_bool CONFIG_HW_CONSOLE y
bool 'SPARC64 Huge TLB Page Support' CONFIG_HUGETLB_PAGE
bool 'Symmetric multi-processing support' CONFIG_SMP bool 'Symmetric multi-processing support' CONFIG_SMP
bool 'Preemptible Kernel' CONFIG_PREEMPT bool 'Preemptible Kernel' CONFIG_PREEMPT
......
...@@ -29,6 +29,7 @@ CONFIG_BBC_I2C=m ...@@ -29,6 +29,7 @@ CONFIG_BBC_I2C=m
CONFIG_VT=y CONFIG_VT=y
CONFIG_VT_CONSOLE=y CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y CONFIG_HW_CONSOLE=y
CONFIG_HUGETLB_PAGE=y
CONFIG_SMP=y CONFIG_SMP=y
# CONFIG_PREEMPT is not set # CONFIG_PREEMPT is not set
CONFIG_SPARC64=y CONFIG_SPARC64=y
...@@ -209,18 +210,8 @@ CONFIG_BLK_DEV_IDE=y ...@@ -209,18 +210,8 @@ CONFIG_BLK_DEV_IDE=y
CONFIG_BLK_DEV_IDEDISK=y CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_IDEDISK_MULTI_MODE is not set # CONFIG_IDEDISK_MULTI_MODE is not set
# CONFIG_IDEDISK_STROKE is not set # CONFIG_IDEDISK_STROKE is not set
# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
# CONFIG_BLK_DEV_IDEDISK_IBM is not set
# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
# CONFIG_BLK_DEV_IDEDISK_WD is not set
# CONFIG_BLK_DEV_COMMERIAL is not set
# CONFIG_BLK_DEV_TIVO is not set
# CONFIG_BLK_DEV_IDECS is not set # CONFIG_BLK_DEV_IDECS is not set
CONFIG_BLK_DEV_IDECD=y CONFIG_BLK_DEV_IDECD=y
# CONFIG_BLK_DEV_IDECD_BAILOUT is not set
# CONFIG_BLK_DEV_IDEFLOPPY is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_BLK_DEV_IDESCSI is not set # CONFIG_BLK_DEV_IDESCSI is not set
# CONFIG_IDE_TASK_IOCTL is not set # CONFIG_IDE_TASK_IOCTL is not set
...@@ -254,6 +245,7 @@ CONFIG_BLK_DEV_CMD64X=y ...@@ -254,6 +245,7 @@ CONFIG_BLK_DEV_CMD64X=y
# CONFIG_BLK_DEV_HPT34X is not set # CONFIG_BLK_DEV_HPT34X is not set
# CONFIG_HPT34X_AUTODMA is not set # CONFIG_HPT34X_AUTODMA is not set
# CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_PIIX is not set
# CONFIG_BLK_DEV_NFORCE is not set # CONFIG_BLK_DEV_NFORCE is not set
CONFIG_BLK_DEV_NS87415=y CONFIG_BLK_DEV_NS87415=y
# CONFIG_BLK_DEV_OPTI621 is not set # CONFIG_BLK_DEV_OPTI621 is not set
...@@ -727,6 +719,10 @@ CONFIG_UDF_FS=m ...@@ -727,6 +719,10 @@ CONFIG_UDF_FS=m
CONFIG_UDF_RW=y CONFIG_UDF_RW=y
CONFIG_UFS_FS=m CONFIG_UFS_FS=m
CONFIG_UFS_FS_WRITE=y CONFIG_UFS_FS_WRITE=y
CONFIG_XFS_FS=m
# CONFIG_XFS_RT is not set
CONFIG_XFS_QUOTA=y
CONFIG_QUOTACTL=y
# #
# Network File Systems # Network File Systems
......
...@@ -151,7 +151,7 @@ int prom_callback(long *args) ...@@ -151,7 +151,7 @@ int prom_callback(long *args)
pmd_t *pmdp; pmd_t *pmdp;
pte_t *ptep; pte_t *ptep;
for_each_task(p) { for_each_process(p) {
mm = p->mm; mm = p->mm;
if (CTX_HWBITS(mm->context) == ctx) if (CTX_HWBITS(mm->context) == ctx)
break; break;
......
...@@ -363,7 +363,6 @@ EXPORT_SYMBOL_NOVERS(VISenter); ...@@ -363,7 +363,6 @@ EXPORT_SYMBOL_NOVERS(VISenter);
EXPORT_SYMBOL(sun_do_break); EXPORT_SYMBOL(sun_do_break);
EXPORT_SYMBOL(serial_console); EXPORT_SYMBOL(serial_console);
EXPORT_SYMBOL(stop_a_enabled); EXPORT_SYMBOL(stop_a_enabled);
EXPORT_SYMBOL(kbd_pt_regs);
#ifdef CONFIG_DEBUG_BUGVERBOSE #ifdef CONFIG_DEBUG_BUGVERBOSE
EXPORT_SYMBOL(do_BUG); EXPORT_SYMBOL(do_BUG);
......
...@@ -681,3 +681,100 @@ sys_perfctr(int opcode, unsigned long arg0, unsigned long arg1, unsigned long ar ...@@ -681,3 +681,100 @@ sys_perfctr(int opcode, unsigned long arg0, unsigned long arg1, unsigned long ar
}; };
return err; return err;
} }
#ifdef CONFIG_HUGETLB_PAGE
#define HPAGE_ALIGN(x) (((unsigned long)x + (HPAGE_SIZE -1)) & HPAGE_MASK)
extern long sys_munmap(unsigned long, size_t);
/* get_addr function gets the currently unused virtual range in
* the current process's address space. It returns the LARGE_PAGE_SIZE
* aligned address (in cases of success). Other kernel generic
* routines only could gurantee that allocated address is PAGE_SIZE aligned.
*/
static long get_addr(unsigned long addr, unsigned long len)
{
struct vm_area_struct *vma;
if (addr) {
addr = HPAGE_ALIGN(addr);
vma = find_vma(current->mm, addr);
if (((TASK_SIZE - len) >= addr) &&
(!vma || addr + len <= vma->vm_start))
goto found_addr;
}
addr = HPAGE_ALIGN(TASK_UNMAPPED_BASE);
for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
if (TASK_SIZE - len < addr)
return -ENOMEM;
if (!vma || ((addr + len) < vma->vm_start))
goto found_addr;
addr = vma->vm_end;
}
found_addr:
addr = HPAGE_ALIGN(addr);
return addr;
}
extern int alloc_hugetlb_pages(int, unsigned long, unsigned long, int, int);
asmlinkage long
sys_alloc_hugepages(int key, unsigned long addr, unsigned long len, int prot, int flag)
{
struct mm_struct *mm = current->mm;
unsigned long raddr;
int retval;
if (key < 0)
return -EINVAL;
if (len & (HPAGE_SIZE - 1))
return -EINVAL;
down_write(&mm->mmap_sem);
raddr = get_addr(addr, len);
retval = 0;
if (raddr == -ENOMEM) {
retval = -ENOMEM;
goto raddr_out;
}
retval = alloc_hugetlb_pages(key, raddr, len, prot, flag);
raddr_out:
up_write(&mm->mmap_sem);
if (retval < 0)
return (long) retval;
return raddr;
}
extern int free_hugepages(struct vm_area_struct *);
asmlinkage int
sys_free_hugepages(unsigned long addr)
{
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
int retval;
vma = find_vma(current->mm, addr);
if ((!vma) || (!is_vm_hugetlb_page(vma)) || (vma->vm_start!=addr))
return -EINVAL;
down_write(&mm->mmap_sem);
spin_lock(&mm->page_table_lock);
retval = free_hugepages(vma);
spin_unlock(&mm->page_table_lock);
up_write(&mm->mmap_sem);
return retval;
}
#else
asmlinkage long
sys_alloc_hugepages(int key, unsigned long addr, size_t len, int prot, int flag)
{
return -ENOSYS;
}
asmlinkage int
sys_free_hugepages(unsigned long addr)
{
return -ENOSYS;
}
#endif
...@@ -65,8 +65,8 @@ sys_call_table32: ...@@ -65,8 +65,8 @@ sys_call_table32:
.word sys32_ipc, sys32_sigreturn, sys_clone, sys_nis_syscall, sys32_adjtimex .word sys32_ipc, sys32_sigreturn, sys_clone, sys_nis_syscall, sys32_adjtimex
/*220*/ .word sys32_sigprocmask, sys32_create_module, sys32_delete_module, sys32_get_kernel_syms, sys_getpgid /*220*/ .word sys32_sigprocmask, sys32_create_module, sys32_delete_module, sys32_get_kernel_syms, sys_getpgid
.word sys32_bdflush, sys32_sysfs, sys_nis_syscall, sys32_setfsuid16, sys32_setfsgid16 .word sys32_bdflush, sys32_sysfs, sys_nis_syscall, sys32_setfsuid16, sys32_setfsgid16
/*230*/ .word sys32_select, sys_time, sys_nis_syscall, sys_stime, sys_nis_syscall /*230*/ .word sys32_select, sys_time, sys_nis_syscall, sys_stime, sys_alloc_hugepages
.word sys_nis_syscall, sys_llseek, sys_mlock, sys_munlock, sys_mlockall .word sys_free_hugepages, sys_llseek, sys_mlock, sys_munlock, sys_mlockall
/*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler /*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler
.word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys32_sched_rr_get_interval, sys32_nanosleep .word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys32_sched_rr_get_interval, sys32_nanosleep
/*250*/ .word sys32_mremap, sys32_sysctl, sys_getsid, sys_fdatasync, sys32_nfsservctl /*250*/ .word sys32_mremap, sys32_sysctl, sys_getsid, sys_fdatasync, sys32_nfsservctl
......
...@@ -7,4 +7,6 @@ EXTRA_AFLAGS := -ansi ...@@ -7,4 +7,6 @@ EXTRA_AFLAGS := -ansi
O_TARGET := mm.o O_TARGET := mm.o
obj-y := ultra.o fault.o init.o generic.o extable.o modutil.o obj-y := ultra.o fault.o init.o generic.o extable.o modutil.o
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
This diff is collapsed.
...@@ -1690,6 +1690,13 @@ static void __init taint_real_pages(void) ...@@ -1690,6 +1690,13 @@ static void __init taint_real_pages(void)
} }
} }
#ifdef CONFIG_HUGETLB_PAGE
long htlbpagemem = 0;
long htlbpage_max;
long htlbzone_pages;
extern struct list_head htlbpage_freelist;
#endif
void __init mem_init(void) void __init mem_init(void)
{ {
unsigned long codepages, datapages, initpages; unsigned long codepages, datapages, initpages;
...@@ -1766,6 +1773,32 @@ void __init mem_init(void) ...@@ -1766,6 +1773,32 @@ void __init mem_init(void)
if (tlb_type == cheetah || tlb_type == cheetah_plus) if (tlb_type == cheetah || tlb_type == cheetah_plus)
cheetah_ecache_flush_init(); cheetah_ecache_flush_init();
#ifdef CONFIG_HUGETLB_PAGE
{
long i, j;
struct page *page, *map;
/* For now reserve quarter for hugetlb_pages. */
htlbzone_pages = (num_physpages >> ((HPAGE_SHIFT - PAGE_SHIFT) + 2)) ;
/* Will make this kernel command line. */
INIT_LIST_HEAD(&htlbpage_freelist);
for (i = 0; i < htlbzone_pages; i++) {
page = alloc_pages(GFP_ATOMIC, HUGETLB_PAGE_ORDER);
if (page == NULL)
break;
map = page;
for (j = 0; j < (HPAGE_SIZE / PAGE_SIZE); j++) {
SetPageReserved(map);
map++;
}
list_add(&page->list, &htlbpage_freelist);
}
printk("Total Huge_TLB_Page memory pages allocated %ld\n", i);
htlbzone_pages = htlbpagemem = i;
htlbpage_max = i;
}
#endif
} }
void free_initmem (void) void free_initmem (void)
......
...@@ -612,7 +612,7 @@ void bbc_envctrl_cleanup(void) ...@@ -612,7 +612,7 @@ void bbc_envctrl_cleanup(void)
int found = 0; int found = 0;
read_lock(&tasklist_lock); read_lock(&tasklist_lock);
for_each_task(p) { for_each_process(p) {
if (p == kenvctrld_task) { if (p == kenvctrld_task) {
found = 1; found = 1;
break; break;
......
...@@ -1141,7 +1141,7 @@ static void __exit envctrl_cleanup(void) ...@@ -1141,7 +1141,7 @@ static void __exit envctrl_cleanup(void)
int found = 0; int found = 0;
read_lock(&tasklist_lock); read_lock(&tasklist_lock);
for_each_task(p) { for_each_process(p) {
if (p == kenvctrld_task) { if (p == kenvctrld_task) {
found = 1; found = 1;
break; break;
......
...@@ -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)
......
...@@ -249,8 +249,8 @@ ...@@ -249,8 +249,8 @@
#define __NR_time 231 /* Linux Specific */ #define __NR_time 231 /* Linux Specific */
/* #define __NR_oldstat 232 Linux Specific */ /* #define __NR_oldstat 232 Linux Specific */
#define __NR_stime 233 /* Linux Specific */ #define __NR_stime 233 /* Linux Specific */
/* #define __NR_oldfstat 234 Linux Specific */ #define __NR_alloc_hugepages 234 /* Linux Specific */
/* #define __NR_phys 235 Linux Specific */ #define __NR_free_hugepages 235 /* Linux Specific */
#define __NR__llseek 236 /* Linux Specific */ #define __NR__llseek 236 /* Linux Specific */
#define __NR_mlock 237 #define __NR_mlock 237
#define __NR_munlock 238 #define __NR_munlock 238
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
#ifndef _SPARC64_PAGE_H #ifndef _SPARC64_PAGE_H
#define _SPARC64_PAGE_H #define _SPARC64_PAGE_H
#include <linux/config.h>
#define PAGE_SHIFT 13 #define PAGE_SHIFT 13
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
/* I have my suspicions... -DaveM */ /* I have my suspicions... -DaveM */
...@@ -99,6 +101,14 @@ typedef unsigned long iopgprot_t; ...@@ -99,6 +101,14 @@ typedef unsigned long iopgprot_t;
#endif /* (STRICT_MM_TYPECHECKS) */ #endif /* (STRICT_MM_TYPECHECKS) */
#define HPAGE_SHIFT 22
#ifdef CONFIG_HUGETLB_PAGE
#define HPAGE_SIZE ((1UL) << HPAGE_SHIFT)
#define HPAGE_MASK (~(HPAGE_SIZE - 1UL))
#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
#endif
#define TASK_UNMAPPED_BASE (test_thread_flag(TIF_32BIT) ? \ #define TASK_UNMAPPED_BASE (test_thread_flag(TIF_32BIT) ? \
(0x0000000070000000UL) : (PAGE_OFFSET)) (0x0000000070000000UL) : (PAGE_OFFSET))
......
...@@ -251,8 +251,8 @@ ...@@ -251,8 +251,8 @@
#endif #endif
/* #define __NR_oldstat 232 Linux Specific */ /* #define __NR_oldstat 232 Linux Specific */
#define __NR_stime 233 /* Linux Specific */ #define __NR_stime 233 /* Linux Specific */
/* #define __NR_oldfstat 234 Linux Specific */ #define __NR_alloc_hugepages 234 /* Linux Specific */
/* #define __NR_phys 235 Linux Specific */ #define __NR_free_hugepages 235 /* Linux Specific */
#define __NR__llseek 236 /* Linux Specific */ #define __NR__llseek 236 /* Linux Specific */
#define __NR_mlock 237 #define __NR_mlock 237
#define __NR_munlock 238 #define __NR_munlock 238
......
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