Commit f32c9e05 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'parisc-4.14-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux

Pull parisc updates from Helge Deller:
 "Major changes include:

   - Full support of the firmware Page Deallocation Table with
     MADV_HWPOISON and MADV_SOFT_OFFLINE. A kernel thread scans
     regularily for new bad memory pages.

   - Full support for self-extracting kernel.

   - Added UBSAN support.

   - Lots of section mismatch fixes across all parisc drivers.

   - Added examples for %pF and %pS usage in printk-formats.txt"

* 'parisc-4.14-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux: (28 commits)
  printk-formats.txt: Add examples for %pF and %pS usage
  parisc: Fix up devices below a PCI-PCI MegaRAID controller bridge
  parisc/core: Fix section mismatches
  parisc/ipmi_si_intf: Fix section mismatches on parisc platform
  parisc/input/hilkbd: Fix section mismatches
  parisc/net/lasi_82596: Fix section mismatches
  parisc/serio: Fix section mismatches in gscps2 and hp_sdc drivers
  parisc: Fix section mismatches in parisc core drivers
  parisc/parport_gsc: Fix section mismatches
  parisc/scsi/lasi700: Fix section mismatches
  parisc/scsi/zalon: Fix section mismatches
  parisc/8250_gsc: Fix section mismatches
  parisc/mux: Fix section mismatches
  parisc/sticore: Fix section mismatches
  parisc/harmony: Fix section mismatches
  parisc: Wire up support for self-extracting kernel
  parisc: Make existing core files reuseable for bootloader
  parisc: Add core code for self-extracting kernel
  parisc: Enable UBSAN support
  parisc/random: Add machine specific randomness
  ...
parents d1ce4956 fd46cd55
...@@ -75,6 +75,16 @@ used when printing stack backtraces. The specifier takes into ...@@ -75,6 +75,16 @@ used when printing stack backtraces. The specifier takes into
consideration the effect of compiler optimisations which may occur consideration the effect of compiler optimisations which may occur
when tail-call``s are used and marked with the noreturn GCC attribute. when tail-call``s are used and marked with the noreturn GCC attribute.
Examples::
printk("Going to call: %pF\n", gettimeofday);
printk("Going to call: %pF\n", p->func);
printk("%s: called from %pS\n", __func__, (void *)_RET_IP_);
printk("%s: called from %pS\n", __func__,
(void *)__builtin_return_address(0));
printk("Faulted at %pS\n", (void *)regs->ip);
printk(" %s%pB\n", (reliable ? "" : "? "), (void *)*stack);
Kernel Pointers Kernel Pointers
=============== ===============
......
...@@ -9,6 +9,9 @@ config PARISC ...@@ -9,6 +9,9 @@ config PARISC
select ARCH_WANT_FRAME_POINTERS select ARCH_WANT_FRAME_POINTERS
select ARCH_HAS_ELF_RANDOMIZE select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_STRICT_KERNEL_RWX select ARCH_HAS_STRICT_KERNEL_RWX
select ARCH_HAS_UBSAN_SANITIZE_ALL
select ARCH_WANTS_UBSAN_NO_NULL
select ARCH_SUPPORTS_MEMORY_FAILURE
select RTC_CLASS select RTC_CLASS
select RTC_DRV_GENERIC select RTC_DRV_GENERIC
select INIT_ALL_POSSIBLE select INIT_ALL_POSSIBLE
...@@ -17,6 +20,12 @@ config PARISC ...@@ -17,6 +20,12 @@ config PARISC
select BUG select BUG
select BUILDTIME_EXTABLE_SORT select BUILDTIME_EXTABLE_SORT
select HAVE_PERF_EVENTS select HAVE_PERF_EVENTS
select HAVE_KERNEL_BZIP2
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_LZ4
select HAVE_KERNEL_LZMA
select HAVE_KERNEL_LZO
select HAVE_KERNEL_XZ
select GENERIC_ATOMIC64 if !64BIT select GENERIC_ATOMIC64 if !64BIT
select GENERIC_IRQ_PROBE select GENERIC_IRQ_PROBE
select GENERIC_PCI_IOMAP select GENERIC_PCI_IOMAP
......
...@@ -24,15 +24,20 @@ KBUILD_DEFCONFIG := default_defconfig ...@@ -24,15 +24,20 @@ KBUILD_DEFCONFIG := default_defconfig
NM = sh $(srctree)/arch/parisc/nm NM = sh $(srctree)/arch/parisc/nm
CHECKFLAGS += -D__hppa__=1 CHECKFLAGS += -D__hppa__=1
LIBGCC = $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) LIBGCC = $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
export LIBGCC
ifdef CONFIG_64BIT ifdef CONFIG_64BIT
UTS_MACHINE := parisc64 UTS_MACHINE := parisc64
CHECKFLAGS += -D__LP64__=1 -m64 CHECKFLAGS += -D__LP64__=1 -m64
CC_ARCHES = hppa64 CC_ARCHES = hppa64
LD_BFD := elf64-hppa-linux
else # 32-bit else # 32-bit
CC_ARCHES = hppa hppa2.0 hppa1.1 CC_ARCHES = hppa hppa2.0 hppa1.1
LD_BFD := elf32-hppa-linux
endif endif
export LD_BFD
ifneq ($(SUBARCH),$(UTS_MACHINE)) ifneq ($(SUBARCH),$(UTS_MACHINE))
ifeq ($(CROSS_COMPILE),) ifeq ($(CROSS_COMPILE),)
CC_SUFFIXES = linux linux-gnu unknown-linux-gnu CC_SUFFIXES = linux linux-gnu unknown-linux-gnu
...@@ -88,6 +93,8 @@ libs-y += arch/parisc/lib/ $(LIBGCC) ...@@ -88,6 +93,8 @@ libs-y += arch/parisc/lib/ $(LIBGCC)
drivers-$(CONFIG_OPROFILE) += arch/parisc/oprofile/ drivers-$(CONFIG_OPROFILE) += arch/parisc/oprofile/
boot := arch/parisc/boot
PALO := $(shell if (which palo 2>&1); then : ; \ PALO := $(shell if (which palo 2>&1); then : ; \
elif [ -x /sbin/palo ]; then echo /sbin/palo; \ elif [ -x /sbin/palo ]; then echo /sbin/palo; \
fi) fi)
...@@ -116,11 +123,14 @@ INSTALL_TARGETS = zinstall install ...@@ -116,11 +123,14 @@ INSTALL_TARGETS = zinstall install
PHONY += bzImage $(BOOT_TARGETS) $(INSTALL_TARGETS) PHONY += bzImage $(BOOT_TARGETS) $(INSTALL_TARGETS)
bzImage zImage: vmlinuz zImage: vmlinuz
Image: vmlinux Image: vmlinux
vmlinuz: vmlinux bzImage: vmlinux
@gzip -cf -9 $< > $@ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
vmlinuz: bzImage
$(OBJCOPY) $(boot)/bzImage $@
install: install:
$(CONFIG_SHELL) $(src)/arch/parisc/install.sh \ $(CONFIG_SHELL) $(src)/arch/parisc/install.sh \
......
#
# Makefile for the linux parisc-specific parts of the boot image creator.
#
COMPILE_VERSION := __linux_compile_version_id__`hostname | \
tr -c '[0-9A-Za-z]' '_'`__`date | \
tr -c '[0-9A-Za-z]' '_'`_t
ccflags-y := -DCOMPILE_VERSION=$(COMPILE_VERSION) -gstabs -I.
targets := image
targets += bzImage
subdir- := compressed
$(obj)/image: vmlinux FORCE
$(call if_changed,objcopy)
$(obj)/bzImage: $(obj)/compressed/vmlinux FORCE
$(call if_changed,objcopy)
$(obj)/compressed/vmlinux: FORCE
$(Q)$(MAKE) $(build)=$(obj)/compressed $@
install: $(CONFIGURE) $(obj)/bzImage
sh -x $(srctree)/$(obj)/install.sh $(KERNELRELEASE) $(obj)/bzImage \
System.map "$(INSTALL_PATH)"
sizes.h
vmlinux
vmlinux.lds
#
# linux/arch/parisc/boot/compressed/Makefile
#
# create a compressed self-extracting vmlinux image from the original vmlinux
#
KCOV_INSTRUMENT := n
GCOV_PROFILE := n
UBSAN_SANITIZE := n
targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2
targets += vmlinux.bin.xz vmlinux.bin.lzma vmlinux.bin.lzo vmlinux.bin.lz4
targets += misc.o piggy.o sizes.h head.o real2.o firmware.o
KBUILD_CFLAGS := -D__KERNEL__ -O2 -DBOOTLOADER
KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
KBUILD_CFLAGS += $(cflags-y) -fno-delete-null-pointer-checks
KBUILD_CFLAGS += -fno-PIE -mno-space-regs -mdisable-fpregs
ifndef CONFIG_64BIT
KBUILD_CFLAGS += -mfast-indirect-calls
endif
OBJECTS += $(obj)/head.o $(obj)/real2.o $(obj)/firmware.o $(obj)/misc.o $(obj)/piggy.o
# LDFLAGS_vmlinux := -X --whole-archive -e startup -T
LDFLAGS_vmlinux := -X -e startup --as-needed -T
$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS) $(LIBGCC)
$(call if_changed,ld)
sed-sizes := -e 's/^\([0-9a-fA-F]*\) . \(__bss_start\|_end\|parisc_kernel_start\)$$/\#define SZ\2 0x\1/p'
quiet_cmd_sizes = GEN $@
cmd_sizes = $(NM) $< | sed -n $(sed-sizes) > $@
$(obj)/sizes.h: vmlinux
$(call if_changed,sizes)
AFLAGS_head.o += -I$(objtree)/$(obj) -DBOOTLOADER
$(obj)/head.o: $(obj)/sizes.h
CFLAGS_misc.o += -I$(objtree)/$(obj)
$(obj)/misc.o: $(obj)/sizes.h
$(obj)/firmware.o: $(obj)/firmware.c
$(obj)/firmware.c: $(srctree)/arch/$(SRCARCH)/kernel/firmware.c
$(call cmd,shipped)
AFLAGS_real2.o += -DBOOTLOADER
$(obj)/real2.o: $(obj)/real2.S
$(obj)/real2.S: $(srctree)/arch/$(SRCARCH)/kernel/real2.S
$(call cmd,shipped)
$(obj)/misc.o: $(obj)/sizes.h
CPPFLAGS_vmlinux.lds += -I$(objtree)/$(obj) -DBOOTLOADER
$(obj)/vmlinux.lds: $(obj)/sizes.h
OBJCOPYFLAGS_vmlinux.bin := -O binary -R .comment -S
$(obj)/vmlinux.bin: vmlinux
$(call if_changed,objcopy)
vmlinux.bin.all-y := $(obj)/vmlinux.bin
suffix-$(CONFIG_KERNEL_GZIP) := gz
suffix-$(CONFIG_KERNEL_BZIP2) := bz2
suffix-$(CONFIG_KERNEL_LZ4) := lz4
suffix-$(CONFIG_KERNEL_LZMA) := lzma
suffix-$(CONFIG_KERNEL_LZO) := lzo
suffix-$(CONFIG_KERNEL_XZ) := xz
$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y)
$(call if_changed,gzip)
$(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y)
$(call if_changed,bzip2)
$(obj)/vmlinux.bin.lz4: $(vmlinux.bin.all-y)
$(call if_changed,lz4)
$(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y)
$(call if_changed,lzma)
$(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y)
$(call if_changed,lzo)
$(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y)
$(call if_changed,xzkern)
LDFLAGS_piggy.o := -r --format binary --oformat $(LD_BFD) -T
$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y)
$(call if_changed,ld)
/*
* Startup glue code to uncompress the kernel
*
* (C) 2017 Helge Deller <deller@gmx.de>
*/
#include <linux/init.h>
#include <linux/linkage.h>
#include <asm/asm-offsets.h>
#include <asm/page.h>
#include <asm/psw.h>
#include <asm/pdc.h>
#include <asm/assembly.h>
#include "sizes.h"
#define BOOTADDR(x) (x)
#ifndef CONFIG_64BIT
.import $global$ /* forward declaration */
#endif /*!CONFIG_64BIT*/
__HEAD
ENTRY(startup)
.level LEVEL
#define PSW_W_SM 0x200
#define PSW_W_BIT 36
;! nuke the W bit, saving original value
.level 2.0
rsm PSW_W_SM, %r1
.level 1.1
extrw,u %r1, PSW_W_BIT-32, 1, %r1
copy %r1, %arg0
/* Make sure sr4-sr7 are set to zero for the kernel address space */
mtsp %r0,%sr4
mtsp %r0,%sr5
mtsp %r0,%sr6
mtsp %r0,%sr7
/* Clear BSS */
.import _bss,data
.import _ebss,data
load32 BOOTADDR(_bss),%r3
load32 BOOTADDR(_ebss),%r4
ldo FRAME_SIZE(%r4),%sp /* stack at end of bss */
$bss_loop:
cmpb,<<,n %r3,%r4,$bss_loop
stw,ma %r0,4(%r3)
/* Initialize the global data pointer */
loadgp
/* arg0..arg4 were set by palo. */
copy %arg1, %r6 /* command line */
copy %arg2, %r7 /* rd-start */
copy %arg3, %r8 /* rd-end */
load32 BOOTADDR(decompress_kernel),%r3
#ifdef CONFIG_64BIT
.level LEVEL
ssm PSW_W_SM, %r0 /* set W-bit */
depdi 0, 31, 32, %r3
#endif
load32 BOOTADDR(startup_continue), %r2
bv,n 0(%r3)
startup_continue:
#ifdef CONFIG_64BIT
.level LEVEL
rsm PSW_W_SM, %r0 /* clear W-bit */
#endif
load32 KERNEL_BINARY_TEXT_START, %arg0 /* free mem */
copy %r6, %arg1 /* command line */
copy %r7, %arg2 /* rd-start */
copy %r8, %arg3 /* rd-end */
bv,n 0(%ret0)
END(startup)
/*
* Definitions and wrapper functions for kernel decompressor
*
* (C) 2017 Helge Deller <deller@gmx.de>
*/
#include <linux/uaccess.h>
#include <asm/unaligned.h>
#include <asm/page.h>
#include "sizes.h"
/*
* gzip declarations
*/
#define STATIC static
#undef memmove
#define memmove memmove
#define memzero(s, n) memset((s), 0, (n))
#define malloc malloc_gzip
#define free free_gzip
/* Symbols defined by linker scripts */
extern char input_data[];
extern int input_len;
extern __le32 output_len; /* at unaligned address, little-endian */
extern char _text, _end;
extern char _bss, _ebss;
extern char _startcode_end;
extern void startup_continue(void *entry, unsigned long cmdline,
unsigned long rd_start, unsigned long rd_end) __noreturn;
void error(char *m) __noreturn;
static unsigned long free_mem_ptr;
static unsigned long free_mem_end_ptr;
#ifdef CONFIG_KERNEL_GZIP
#include "../../../../lib/decompress_inflate.c"
#endif
#ifdef CONFIG_KERNEL_BZIP2
#include "../../../../lib/decompress_bunzip2.c"
#endif
#ifdef CONFIG_KERNEL_LZ4
#include "../../../../lib/decompress_unlz4.c"
#endif
#ifdef CONFIG_KERNEL_LZMA
#include "../../../../lib/decompress_unlzma.c"
#endif
#ifdef CONFIG_KERNEL_LZO
#include "../../../../lib/decompress_unlzo.c"
#endif
#ifdef CONFIG_KERNEL_XZ
#include "../../../../lib/decompress_unxz.c"
#endif
void *memmove(void *dest, const void *src, size_t n)
{
const char *s = src;
char *d = dest;
if (d <= s) {
while (n--)
*d++ = *s++;
} else {
d += n;
s += n;
while (n--)
*--d = *--s;
}
return dest;
}
void *memset(void *s, int c, size_t count)
{
char *xs = (char *)s;
while (count--)
*xs++ = c;
return s;
}
void *memcpy(void *d, const void *s, size_t len)
{
char *dest = (char *)d;
const char *source = (const char *)s;
while (len--)
*dest++ = *source++;
return d;
}
size_t strlen(const char *s)
{
const char *sc;
for (sc = s; *sc != '\0'; ++sc)
;
return sc - s;
}
char *strchr(const char *s, int c)
{
while (*s) {
if (*s == (char)c)
return (char *)s;
++s;
}
return NULL;
}
int puts(const char *s)
{
const char *nuline = s;
while ((nuline = strchr(s, '\n')) != NULL) {
if (nuline != s)
pdc_iodc_print(s, nuline - s);
pdc_iodc_print("\r\n", 2);
s = nuline + 1;
}
if (*s != '\0')
pdc_iodc_print(s, strlen(s));
return 0;
}
static int putchar(int c)
{
char buf[2];
buf[0] = c;
buf[1] = '\0';
puts(buf);
return c;
}
void __noreturn error(char *x)
{
puts("\n\n");
puts(x);
puts("\n\n -- System halted");
while (1) /* wait forever */
;
}
static int print_hex(unsigned long num)
{
const char hex[] = "0123456789abcdef";
char str[40];
int i = sizeof(str)-1;
str[i--] = '\0';
do {
str[i--] = hex[num & 0x0f];
num >>= 4;
} while (num);
str[i--] = 'x';
str[i] = '0';
puts(&str[i]);
return 0;
}
int printf(const char *fmt, ...)
{
va_list args;
int i = 0;
va_start(args, fmt);
while (fmt[i]) {
if (fmt[i] != '%') {
put:
putchar(fmt[i++]);
continue;
}
if (fmt[++i] == '%')
goto put;
++i;
print_hex(va_arg(args, unsigned long));
}
va_end(args);
return 0;
}
/* helper functions for libgcc */
void abort(void)
{
error("aborted.");
}
#undef malloc
void *malloc(size_t size)
{
return malloc_gzip(size);
}
#undef free
void free(void *ptr)
{
return free_gzip(ptr);
}
static void flush_data_cache(char *start, unsigned long length)
{
char *end = start + length;
do {
asm volatile("fdc 0(%0)" : : "r" (start));
asm volatile("fic 0(%%sr0,%0)" : : "r" (start));
start += 16;
} while (start < end);
asm volatile("fdc 0(%0)" : : "r" (end));
asm ("sync");
}
unsigned long decompress_kernel(unsigned int started_wide,
unsigned int command_line,
const unsigned int rd_start,
const unsigned int rd_end)
{
char *output;
unsigned long len, len_all;
#ifdef CONFIG_64BIT
parisc_narrow_firmware = 0;
#endif
set_firmware_width_unlocked();
putchar('U'); /* if you get this p and no more, string storage */
/* in $GLOBAL$ is wrong or %dp is wrong */
puts("ncompressing ...\n");
output = (char *) KERNEL_BINARY_TEXT_START;
len_all = __pa(SZ_end) - __pa(SZparisc_kernel_start);
if ((unsigned long) &_startcode_end > (unsigned long) output)
error("Bootcode overlaps kernel code");
len = get_unaligned_le32(&output_len);
if (len > len_all)
error("Output len too big.");
else
memset(&output[len], 0, len_all - len);
/*
* Initialize free_mem_ptr and free_mem_end_ptr.
*/
free_mem_ptr = (unsigned long) &_ebss;
free_mem_ptr += 2*1024*1024; /* leave 2 MB for stack */
/* Limit memory for bootoader to 1GB */
#define ARTIFICIAL_LIMIT (1*1024*1024*1024)
free_mem_end_ptr = PAGE0->imm_max_mem;
if (free_mem_end_ptr > ARTIFICIAL_LIMIT)
free_mem_end_ptr = ARTIFICIAL_LIMIT;
#ifdef CONFIG_BLK_DEV_INITRD
/* if we have ramdisk this is at end of memory */
if (rd_start && rd_start < free_mem_end_ptr)
free_mem_end_ptr = rd_start;
#endif
#ifdef DEBUG
printf("startcode_end = %x\n", &_startcode_end);
printf("commandline = %x\n", command_line);
printf("rd_start = %x\n", rd_start);
printf("rd_end = %x\n", rd_end);
printf("free_ptr = %x\n", free_mem_ptr);
printf("free_ptr_end = %x\n", free_mem_end_ptr);
printf("input_data = %x\n", input_data);
printf("input_len = %x\n", input_len);
printf("output = %x\n", output);
printf("output_len = %x\n", len);
printf("output_max = %x\n", len_all);
#endif
__decompress(input_data, input_len, NULL, NULL,
output, 0, NULL, error);
flush_data_cache(output, len);
printf("Booting kernel ...\n\n");
return (unsigned long) output;
}
#include <asm-generic/vmlinux.lds.h>
#include <asm/page.h>
#include "sizes.h"
#ifndef CONFIG_64BIT
OUTPUT_FORMAT("elf32-hppa-linux")
OUTPUT_ARCH(hppa)
#else
OUTPUT_FORMAT("elf64-hppa-linux")
OUTPUT_ARCH(hppa:hppa2.0w)
#endif
ENTRY(startup)
SECTIONS
{
/* palo loads at 0x60000 */
/* loaded kernel will move to 0x10000 */
. = 0xe0000; /* should not overwrite palo code */
.head.text : {
_head = . ;
HEAD_TEXT
_ehead = . ;
}
/* keep __gp below 0x1000000 */
#ifdef CONFIG_64BIT
. = ALIGN(16);
/* Linkage tables */
.opd : {
*(.opd)
} PROVIDE (__gp = .);
.plt : {
*(.plt)
}
.dlt : {
*(.dlt)
}
#endif
_startcode_end = .;
/* bootloader code and data starts behind area of extracted kernel */
. = (SZ_end - SZparisc_kernel_start + KERNEL_BINARY_TEXT_START);
/* align on next page boundary */
. = ALIGN(4096);
.text : {
_text = .; /* Text */
*(.text)
*(.text.*)
_etext = . ;
}
. = ALIGN(8);
.data : {
_data = . ;
*(.data)
*(.data.*)
_edata = . ;
}
. = ALIGN(8);
.rodata : {
_rodata = . ;
*(.rodata) /* read-only data */
*(.rodata.*)
_erodata = . ;
}
. = ALIGN(8);
.rodata.compressed : {
*(.rodata.compressed)
}
. = ALIGN(8);
.bss : {
_bss = . ;
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(4096);
_ebss = .;
}
STABS_DEBUG
.note 0 : { *(.note) }
/* Sections to be discarded */
DISCARDS
/DISCARD/ : {
#ifdef CONFIG_64BIT
/* temporary hack until binutils is fixed to not emit these
* for static binaries
*/
*(.PARISC.unwind) /* no unwind data */
*(.interp)
*(.dynsym)
*(.dynstr)
*(.dynamic)
*(.hash)
*(.gnu.hash)
#endif
}
}
SECTIONS
{
.rodata.compressed : {
input_len = .;
LONG(input_data_end - input_data) input_data = .;
*(.data)
output_len = . - 4; /* can be at unaligned address */
input_data_end = .;
}
}
#!/bin/sh
#
# arch/parisc/install.sh, derived from arch/i386/boot/install.sh
#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
# for more details.
#
# Copyright (C) 1995 by Linus Torvalds
#
# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
#
# "make install" script for i386 architecture
#
# Arguments:
# $1 - kernel version
# $2 - kernel image file
# $3 - kernel map file
# $4 - default install path (blank if root directory)
#
verify () {
if [ ! -f "$1" ]; then
echo "" 1>&2
echo " *** Missing file: $1" 1>&2
echo ' *** You need to run "make" before "make install".' 1>&2
echo "" 1>&2
exit 1
fi
}
# Make sure the files actually exist
verify "$2"
verify "$3"
# User may have a custom install script
if [ -n "${INSTALLKERNEL}" ]; then
if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi
fi
# Default install
if [ "$(basename $2)" = "zImage" ]; then
# Compressed install
echo "Installing compressed kernel"
base=vmlinuz
else
# Normal install
echo "Installing normal kernel"
base=vmlinux
fi
if [ -f $4/$base-$1 ]; then
mv $4/$base-$1 $4/$base-$1.old
fi
cat $2 > $4/$base-$1
# Install system map file
if [ -f $4/System.map-$1 ]; then
mv $4/System.map-$1 $4/System.map-$1.old
fi
cp $3 $4/System.map-$1
...@@ -63,6 +63,9 @@ static inline void switch_mm(struct mm_struct *prev, ...@@ -63,6 +63,9 @@ static inline void switch_mm(struct mm_struct *prev,
{ {
unsigned long flags; unsigned long flags;
if (prev == next)
return;
local_irq_save(flags); local_irq_save(flags);
switch_mm_irqs_off(prev, next, tsk); switch_mm_irqs_off(prev, next, tsk);
local_irq_restore(flags); local_irq_restore(flags);
......
...@@ -116,11 +116,15 @@ extern int npmem_ranges; ...@@ -116,11 +116,15 @@ extern int npmem_ranges;
/* This governs the relationship between virtual and physical addresses. /* This governs the relationship between virtual and physical addresses.
* If you alter it, make sure to take care of our various fixed mapping * If you alter it, make sure to take care of our various fixed mapping
* segments in fixmap.h */ * segments in fixmap.h */
#if defined(BOOTLOADER)
#define __PAGE_OFFSET (0) /* bootloader uses physical addresses */
#else
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
#define __PAGE_OFFSET (0x40000000) /* 1GB */ #define __PAGE_OFFSET (0x40000000) /* 1GB */
#else #else
#define __PAGE_OFFSET (0x10000000) /* 256MB */ #define __PAGE_OFFSET (0x10000000) /* 256MB */
#endif #endif
#endif /* BOOTLOADER */
#define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET) #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#if !defined(__ASSEMBLY__) #if !defined(__ASSEMBLY__)
extern int parisc_narrow_firmware;
extern int pdc_type; extern int pdc_type;
extern unsigned long parisc_cell_num; /* cell number the CPU runs on (PAT) */ extern unsigned long parisc_cell_num; /* cell number the CPU runs on (PAT) */
extern unsigned long parisc_cell_loc; /* cell location of CPU (PAT) */ extern unsigned long parisc_cell_loc; /* cell location of CPU (PAT) */
......
...@@ -223,6 +223,18 @@ struct pdc_pat_mem_retinfo { /* PDC_PAT_MEM/PDC_PAT_MEM_PD_INFO (return info) */ ...@@ -223,6 +223,18 @@ struct pdc_pat_mem_retinfo { /* PDC_PAT_MEM/PDC_PAT_MEM_PD_INFO (return info) */
unsigned long clear_time; /* last PDT clear time (since Jan 1970) */ unsigned long clear_time; /* last PDT clear time (since Jan 1970) */
}; };
struct pdc_pat_mem_cell_pdt_retinfo { /* PDC_PAT_MEM/PDC_PAT_MEM_CELL_INFO */
u64 reserved:32;
u64 cs:1; /* clear status: cleared since the last call? */
u64 current_pdt_entries:15;
u64 ic:1; /* interleaving had to be changed ? */
u64 max_pdt_entries:15;
unsigned long good_mem;
unsigned long first_dbe_loc; /* first location of double bit error */
unsigned long clear_time; /* last PDT clear time (since Jan 1970) */
};
struct pdc_pat_mem_read_pd_retinfo { /* PDC_PAT_MEM/PDC_PAT_MEM_PD_READ */ struct pdc_pat_mem_read_pd_retinfo { /* PDC_PAT_MEM/PDC_PAT_MEM_PD_READ */
unsigned long actual_count_bytes; unsigned long actual_count_bytes;
unsigned long pdt_entries; unsigned long pdt_entries;
...@@ -325,6 +337,8 @@ extern int pdc_pat_io_pci_cfg_read(unsigned long pci_addr, int pci_size, u32 *va ...@@ -325,6 +337,8 @@ extern int pdc_pat_io_pci_cfg_read(unsigned long pci_addr, int pci_size, u32 *va
extern int pdc_pat_io_pci_cfg_write(unsigned long pci_addr, int pci_size, u32 val); extern int pdc_pat_io_pci_cfg_write(unsigned long pci_addr, int pci_size, u32 val);
extern int pdc_pat_mem_pdt_info(struct pdc_pat_mem_retinfo *rinfo); extern int pdc_pat_mem_pdt_info(struct pdc_pat_mem_retinfo *rinfo);
extern int pdc_pat_mem_pdt_cell_info(struct pdc_pat_mem_cell_pdt_retinfo *rinfo,
unsigned long cell);
extern int pdc_pat_mem_read_cell_pdt(struct pdc_pat_mem_read_pd_retinfo *pret, extern int pdc_pat_mem_read_cell_pdt(struct pdc_pat_mem_read_pd_retinfo *pret,
unsigned long *pdt_entries_ptr, unsigned long max_entries); unsigned long *pdt_entries_ptr, unsigned long max_entries);
extern int pdc_pat_mem_read_pd_pdt(struct pdc_pat_mem_read_pd_retinfo *pret, extern int pdc_pat_mem_read_pd_pdt(struct pdc_pat_mem_read_pd_retinfo *pret,
......
...@@ -40,9 +40,6 @@ ...@@ -40,9 +40,6 @@
#define MADV_SEQUENTIAL 2 /* expect sequential page references */ #define MADV_SEQUENTIAL 2 /* expect sequential page references */
#define MADV_WILLNEED 3 /* will need these pages */ #define MADV_WILLNEED 3 /* will need these pages */
#define MADV_DONTNEED 4 /* don't need these pages */ #define MADV_DONTNEED 4 /* don't need these pages */
#define MADV_SPACEAVAIL 5 /* insure that resources are reserved */
#define MADV_VPS_PURGE 6 /* Purge pages from VM page cache */
#define MADV_VPS_INHERIT 7 /* Inherit parents page size */
/* common/generic parameters */ /* common/generic parameters */
#define MADV_FREE 8 /* free pages only if memory pressure */ #define MADV_FREE 8 /* free pages only if memory pressure */
...@@ -60,6 +57,9 @@ ...@@ -60,6 +57,9 @@
overrides the coredump filter bits */ overrides the coredump filter bits */
#define MADV_DODUMP 70 /* Clear the MADV_NODUMP flag */ #define MADV_DODUMP 70 /* Clear the MADV_NODUMP flag */
#define MADV_HWPOISON 100 /* poison a page for testing */
#define MADV_SOFT_OFFLINE 101 /* soft offline page for testing */
/* compatibility flags */ /* compatibility flags */
#define MAP_FILE 0 #define MAP_FILE 0
#define MAP_VARIABLE 0 #define MAP_VARIABLE 0
......
...@@ -69,7 +69,15 @@ ...@@ -69,7 +69,15 @@
#include <asm/pdcpat.h> #include <asm/pdcpat.h>
#include <asm/processor.h> /* for boot_cpu_data */ #include <asm/processor.h> /* for boot_cpu_data */
#if defined(BOOTLOADER)
# undef spin_lock_irqsave
# define spin_lock_irqsave(a, b) { b = 1; }
# undef spin_unlock_irqrestore
# define spin_unlock_irqrestore(a, b)
#else
static DEFINE_SPINLOCK(pdc_lock); static DEFINE_SPINLOCK(pdc_lock);
#endif
extern unsigned long pdc_result[NUM_PDC_RESULT]; extern unsigned long pdc_result[NUM_PDC_RESULT];
extern unsigned long pdc_result2[NUM_PDC_RESULT]; extern unsigned long pdc_result2[NUM_PDC_RESULT];
...@@ -142,8 +150,8 @@ static void convert_to_wide(unsigned long *addr) ...@@ -142,8 +150,8 @@ static void convert_to_wide(unsigned long *addr)
int i; int i;
unsigned int *p = (unsigned int *)addr; unsigned int *p = (unsigned int *)addr;
if(unlikely(parisc_narrow_firmware)) { if (unlikely(parisc_narrow_firmware)) {
for(i = 31; i >= 0; --i) for (i = (NUM_PDC_RESULT-1); i >= 0; --i)
addr[i] = p[i]; addr[i] = p[i];
} }
#endif #endif
...@@ -186,6 +194,8 @@ void set_firmware_width(void) ...@@ -186,6 +194,8 @@ void set_firmware_width(void)
} }
#endif /*CONFIG_64BIT*/ #endif /*CONFIG_64BIT*/
#if !defined(BOOTLOADER)
/** /**
* pdc_emergency_unlock - Unlock the linux pdc lock * pdc_emergency_unlock - Unlock the linux pdc lock
* *
...@@ -979,16 +989,22 @@ int pdc_mem_pdt_read_entries(struct pdc_mem_read_pdt *pret, ...@@ -979,16 +989,22 @@ int pdc_mem_pdt_read_entries(struct pdc_mem_read_pdt *pret,
spin_lock_irqsave(&pdc_lock, flags); spin_lock_irqsave(&pdc_lock, flags);
retval = mem_pdc_call(PDC_MEM, PDC_MEM_READ_PDT, __pa(pdc_result), retval = mem_pdc_call(PDC_MEM, PDC_MEM_READ_PDT, __pa(pdc_result),
__pa(pdc_result2)); __pa(pdt_entries_ptr));
if (retval == PDC_OK) { if (retval == PDC_OK) {
convert_to_wide(pdc_result); convert_to_wide(pdc_result);
memcpy(pret, pdc_result, sizeof(*pret)); memcpy(pret, pdc_result, sizeof(*pret));
convert_to_wide(pdc_result2);
memcpy(pdt_entries_ptr, pdc_result2,
pret->pdt_entries * sizeof(*pdt_entries_ptr));
} }
spin_unlock_irqrestore(&pdc_lock, flags); spin_unlock_irqrestore(&pdc_lock, flags);
#ifdef CONFIG_64BIT
/*
* 64-bit kernels should not call this PDT function in narrow mode.
* The pdt_entries_ptr array above will now contain 32-bit values
*/
if (WARN_ON_ONCE((retval == PDC_OK) && parisc_narrow_firmware))
return PDC_ERROR;
#endif
return retval; return retval;
} }
...@@ -1143,6 +1159,8 @@ void pdc_io_reset_devices(void) ...@@ -1143,6 +1159,8 @@ void pdc_io_reset_devices(void)
spin_unlock_irqrestore(&pdc_lock, flags); spin_unlock_irqrestore(&pdc_lock, flags);
} }
#endif /* defined(BOOTLOADER) */
/* locked by pdc_console_lock */ /* locked by pdc_console_lock */
static int __attribute__((aligned(8))) iodc_retbuf[32]; static int __attribute__((aligned(8))) iodc_retbuf[32];
static char __attribute__((aligned(64))) iodc_dbuf[4096]; static char __attribute__((aligned(64))) iodc_dbuf[4096];
...@@ -1187,6 +1205,7 @@ int pdc_iodc_print(const unsigned char *str, unsigned count) ...@@ -1187,6 +1205,7 @@ int pdc_iodc_print(const unsigned char *str, unsigned count)
return i; return i;
} }
#if !defined(BOOTLOADER)
/** /**
* pdc_iodc_getc - Read a character (non-blocking) from the PDC console. * pdc_iodc_getc - Read a character (non-blocking) from the PDC console.
* *
...@@ -1439,6 +1458,29 @@ int pdc_pat_mem_pdt_info(struct pdc_pat_mem_retinfo *rinfo) ...@@ -1439,6 +1458,29 @@ int pdc_pat_mem_pdt_info(struct pdc_pat_mem_retinfo *rinfo)
return retval; return retval;
} }
/**
* pdc_pat_mem_pdt_cell_info - Retrieve information about page deallocation
* table of a cell
* @rinfo: memory pdt information
* @cell: cell number
*
*/
int pdc_pat_mem_pdt_cell_info(struct pdc_pat_mem_cell_pdt_retinfo *rinfo,
unsigned long cell)
{
int retval;
unsigned long flags;
spin_lock_irqsave(&pdc_lock, flags);
retval = mem_pdc_call(PDC_PAT_MEM, PDC_PAT_MEM_CELL_INFO,
__pa(&pdc_result), cell);
if (retval == PDC_OK)
memcpy(rinfo, &pdc_result, sizeof(*rinfo));
spin_unlock_irqrestore(&pdc_lock, flags);
return retval;
}
/** /**
* pdc_pat_mem_read_cell_pdt - Read PDT entries from (old) PAT firmware * pdc_pat_mem_read_cell_pdt - Read PDT entries from (old) PAT firmware
* @pret: array of PDT entries * @pret: array of PDT entries
...@@ -1455,14 +1497,14 @@ int pdc_pat_mem_read_cell_pdt(struct pdc_pat_mem_read_pd_retinfo *pret, ...@@ -1455,14 +1497,14 @@ int pdc_pat_mem_read_cell_pdt(struct pdc_pat_mem_read_pd_retinfo *pret,
spin_lock_irqsave(&pdc_lock, flags); spin_lock_irqsave(&pdc_lock, flags);
/* PDC_PAT_MEM_CELL_READ is available on early PAT machines only */ /* PDC_PAT_MEM_CELL_READ is available on early PAT machines only */
retval = mem_pdc_call(PDC_PAT_MEM, PDC_PAT_MEM_CELL_READ, retval = mem_pdc_call(PDC_PAT_MEM, PDC_PAT_MEM_CELL_READ,
__pa(&pdc_result), parisc_cell_num, __pa(&pdc_result2)); __pa(&pdc_result), parisc_cell_num,
__pa(pdt_entries_ptr));
if (retval == PDC_OK) { if (retval == PDC_OK) {
/* build up return value as for PDC_PAT_MEM_PD_READ */ /* build up return value as for PDC_PAT_MEM_PD_READ */
entries = min(pdc_result[0], max_entries); entries = min(pdc_result[0], max_entries);
pret->pdt_entries = entries; pret->pdt_entries = entries;
pret->actual_count_bytes = entries * sizeof(unsigned long); pret->actual_count_bytes = entries * sizeof(unsigned long);
memcpy(pdt_entries_ptr, &pdc_result2, pret->actual_count_bytes);
} }
spin_unlock_irqrestore(&pdc_lock, flags); spin_unlock_irqrestore(&pdc_lock, flags);
...@@ -1474,6 +1516,8 @@ int pdc_pat_mem_read_cell_pdt(struct pdc_pat_mem_read_pd_retinfo *pret, ...@@ -1474,6 +1516,8 @@ int pdc_pat_mem_read_cell_pdt(struct pdc_pat_mem_read_pd_retinfo *pret,
* pdc_pat_mem_read_pd_pdt - Read PDT entries from (newer) PAT firmware * pdc_pat_mem_read_pd_pdt - Read PDT entries from (newer) PAT firmware
* @pret: array of PDT entries * @pret: array of PDT entries
* @pdt_entries_ptr: ptr to hold number of PDT entries * @pdt_entries_ptr: ptr to hold number of PDT entries
* @count: number of bytes to read
* @offset: offset to start (in bytes)
* *
*/ */
int pdc_pat_mem_read_pd_pdt(struct pdc_pat_mem_read_pd_retinfo *pret, int pdc_pat_mem_read_pd_pdt(struct pdc_pat_mem_read_pd_retinfo *pret,
...@@ -1524,6 +1568,7 @@ int pdc_pat_mem_get_dimm_phys_location( ...@@ -1524,6 +1568,7 @@ int pdc_pat_mem_get_dimm_phys_location(
return retval; return retval;
} }
#endif /* CONFIG_64BIT */ #endif /* CONFIG_64BIT */
#endif /* defined(BOOTLOADER) */
/***************** 32-bit real-mode calls ***********/ /***************** 32-bit real-mode calls ***********/
...@@ -1633,4 +1678,3 @@ long real64_call(unsigned long fn, ...) ...@@ -1633,4 +1678,3 @@ long real64_call(unsigned long fn, ...)
} }
#endif /* CONFIG_64BIT */ #endif /* CONFIG_64BIT */
...@@ -41,7 +41,7 @@ static unsigned long pcxl_used_bytes __read_mostly = 0; ...@@ -41,7 +41,7 @@ static unsigned long pcxl_used_bytes __read_mostly = 0;
static unsigned long pcxl_used_pages __read_mostly = 0; static unsigned long pcxl_used_pages __read_mostly = 0;
extern unsigned long pcxl_dma_start; /* Start of pcxl dma mapping area */ extern unsigned long pcxl_dma_start; /* Start of pcxl dma mapping area */
static spinlock_t pcxl_res_lock; static DEFINE_SPINLOCK(pcxl_res_lock);
static char *pcxl_res_map; static char *pcxl_res_map;
static int pcxl_res_hint; static int pcxl_res_hint;
static int pcxl_res_size; static int pcxl_res_size;
...@@ -390,7 +390,6 @@ pcxl_dma_init(void) ...@@ -390,7 +390,6 @@ pcxl_dma_init(void)
if (pcxl_dma_start == 0) if (pcxl_dma_start == 0)
return 0; return 0;
spin_lock_init(&pcxl_res_lock);
pcxl_res_size = PCXL_DMA_MAP_SIZE >> (PAGE_SHIFT + 3); pcxl_res_size = PCXL_DMA_MAP_SIZE >> (PAGE_SHIFT + 3);
pcxl_res_hint = 0; pcxl_res_hint = 0;
pcxl_res_map = (char *)__get_free_pages(GFP_KERNEL, pcxl_res_map = (char *)__get_free_pages(GFP_KERNEL,
......
/* /*
* Page Deallocation Table (PDT) support * Page Deallocation Table (PDT) support
* *
* The Page Deallocation Table (PDT) holds a table with pointers to bad * The Page Deallocation Table (PDT) is maintained by firmware and holds a
* memory (broken RAM modules) which is maintained by firmware. * list of memory addresses in which memory errors were detected.
* The list contains both single-bit (correctable) and double-bit
* (uncorrectable) errors.
* *
* Copyright 2017 by Helge Deller <deller@gmx.de> * Copyright 2017 by Helge Deller <deller@gmx.de>
* *
* TODO: * possible future enhancements:
* - check regularily for new bad memory * - add userspace interface via procfs or sysfs to clear PDT
* - add userspace interface with procfs or sysfs
* - increase number of PDT entries dynamically
*/ */
#include <linux/memblock.h> #include <linux/memblock.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/kthread.h>
#include <asm/pdc.h> #include <asm/pdc.h>
#include <asm/pdcpat.h> #include <asm/pdcpat.h>
...@@ -24,11 +25,16 @@ enum pdt_access_type { ...@@ -24,11 +25,16 @@ enum pdt_access_type {
PDT_NONE, PDT_NONE,
PDT_PDC, PDT_PDC,
PDT_PAT_NEW, PDT_PAT_NEW,
PDT_PAT_OLD PDT_PAT_CELL
}; };
static enum pdt_access_type pdt_type; static enum pdt_access_type pdt_type;
/* PDT poll interval: 1 minute if errors, 5 minutes if everything OK. */
#define PDT_POLL_INTERVAL_DEFAULT (5*60*HZ)
#define PDT_POLL_INTERVAL_SHORT (1*60*HZ)
static unsigned long pdt_poll_interval = PDT_POLL_INTERVAL_DEFAULT;
/* global PDT status information */ /* global PDT status information */
static struct pdc_mem_retinfo pdt_status; static struct pdc_mem_retinfo pdt_status;
...@@ -36,6 +42,21 @@ static struct pdc_mem_retinfo pdt_status; ...@@ -36,6 +42,21 @@ static struct pdc_mem_retinfo pdt_status;
#define MAX_PDT_ENTRIES (MAX_PDT_TABLE_SIZE / sizeof(unsigned long)) #define MAX_PDT_ENTRIES (MAX_PDT_TABLE_SIZE / sizeof(unsigned long))
static unsigned long pdt_entry[MAX_PDT_ENTRIES] __page_aligned_bss; static unsigned long pdt_entry[MAX_PDT_ENTRIES] __page_aligned_bss;
/*
* Constants for the pdt_entry format:
* A pdt_entry holds the physical address in bits 0-57, bits 58-61 are
* reserved, bit 62 is the perm bit and bit 63 is the error_type bit.
* The perm bit indicates whether the error have been verified as a permanent
* error (value of 1) or has not been verified, and may be transient (value
* of 0). The error_type bit indicates whether the error is a single bit error
* (value of 1) or a multiple bit error.
* On non-PAT machines phys_addr is encoded in bits 0-59 and error_type in bit
* 63. Those machines don't provide the perm bit.
*/
#define PDT_ADDR_PHYS_MASK (pdt_type != PDT_PDC ? ~0x3f : ~0x0f)
#define PDT_ADDR_PERM_ERR (pdt_type != PDT_PDC ? 2UL : 0UL)
#define PDT_ADDR_SINGLE_ERR 1UL
/* report PDT entries via /proc/meminfo */ /* report PDT entries via /proc/meminfo */
void arch_report_meminfo(struct seq_file *m) void arch_report_meminfo(struct seq_file *m)
...@@ -49,6 +70,68 @@ void arch_report_meminfo(struct seq_file *m) ...@@ -49,6 +70,68 @@ void arch_report_meminfo(struct seq_file *m)
pdt_status.pdt_entries); pdt_status.pdt_entries);
} }
static int get_info_pat_new(void)
{
struct pdc_pat_mem_retinfo pat_rinfo;
int ret;
/* newer PAT machines like C8000 report info for all cells */
if (is_pdc_pat())
ret = pdc_pat_mem_pdt_info(&pat_rinfo);
else
return PDC_BAD_PROC;
pdt_status.pdt_size = pat_rinfo.max_pdt_entries;
pdt_status.pdt_entries = pat_rinfo.current_pdt_entries;
pdt_status.pdt_status = 0;
pdt_status.first_dbe_loc = pat_rinfo.first_dbe_loc;
pdt_status.good_mem = pat_rinfo.good_mem;
return ret;
}
static int get_info_pat_cell(void)
{
struct pdc_pat_mem_cell_pdt_retinfo cell_rinfo;
int ret;
/* older PAT machines like rp5470 report cell info only */
if (is_pdc_pat())
ret = pdc_pat_mem_pdt_cell_info(&cell_rinfo, parisc_cell_num);
else
return PDC_BAD_PROC;
pdt_status.pdt_size = cell_rinfo.max_pdt_entries;
pdt_status.pdt_entries = cell_rinfo.current_pdt_entries;
pdt_status.pdt_status = 0;
pdt_status.first_dbe_loc = cell_rinfo.first_dbe_loc;
pdt_status.good_mem = cell_rinfo.good_mem;
return ret;
}
static void report_mem_err(unsigned long pde)
{
struct pdc_pat_mem_phys_mem_location loc;
unsigned long addr;
char dimm_txt[32];
addr = pde & PDT_ADDR_PHYS_MASK;
/* show DIMM slot description on PAT machines */
if (is_pdc_pat()) {
pdc_pat_mem_get_dimm_phys_location(&loc, addr);
sprintf(dimm_txt, "DIMM slot %02x, ", loc.dimm_slot);
} else
dimm_txt[0] = 0;
pr_warn("PDT: BAD MEMORY at 0x%08lx, %s%s%s-bit error.\n",
addr, dimm_txt,
pde & PDT_ADDR_PERM_ERR ? "permanent ":"",
pde & PDT_ADDR_SINGLE_ERR ? "single":"multi");
}
/* /*
* pdc_pdt_init() * pdc_pdt_init()
* *
...@@ -63,18 +146,17 @@ void __init pdc_pdt_init(void) ...@@ -63,18 +146,17 @@ void __init pdc_pdt_init(void)
unsigned long entries; unsigned long entries;
struct pdc_mem_read_pdt pdt_read_ret; struct pdc_mem_read_pdt pdt_read_ret;
if (is_pdc_pat()) {
struct pdc_pat_mem_retinfo pat_rinfo;
pdt_type = PDT_PAT_NEW; pdt_type = PDT_PAT_NEW;
ret = pdc_pat_mem_pdt_info(&pat_rinfo); ret = get_info_pat_new();
pdt_status.pdt_size = pat_rinfo.max_pdt_entries;
pdt_status.pdt_entries = pat_rinfo.current_pdt_entries; if (ret != PDC_OK) {
pdt_status.pdt_status = 0; pdt_type = PDT_PAT_CELL;
pdt_status.first_dbe_loc = pat_rinfo.first_dbe_loc; ret = get_info_pat_cell();
pdt_status.good_mem = pat_rinfo.good_mem; }
} else {
if (ret != PDC_OK) {
pdt_type = PDT_PDC; pdt_type = PDT_PDC;
/* non-PAT machines provide the standard PDC call */
ret = pdc_mem_pdt_info(&pdt_status); ret = pdc_mem_pdt_info(&pdt_status);
} }
...@@ -86,13 +168,17 @@ void __init pdc_pdt_init(void) ...@@ -86,13 +168,17 @@ void __init pdc_pdt_init(void)
} }
entries = pdt_status.pdt_entries; entries = pdt_status.pdt_entries;
WARN_ON(entries > MAX_PDT_ENTRIES); if (WARN_ON(entries > MAX_PDT_ENTRIES))
entries = pdt_status.pdt_entries = MAX_PDT_ENTRIES;
pr_info("PDT: size %lu, entries %lu, status %lu, dbe_loc 0x%lx," pr_info("PDT: type %s, size %lu, entries %lu, status %lu, dbe_loc 0x%lx,"
" good_mem %lu\n", " good_mem %lu MB\n",
pdt_type == PDT_PDC ? __stringify(PDT_PDC) :
pdt_type == PDT_PAT_CELL ? __stringify(PDT_PAT_CELL)
: __stringify(PDT_PAT_NEW),
pdt_status.pdt_size, pdt_status.pdt_entries, pdt_status.pdt_size, pdt_status.pdt_entries,
pdt_status.pdt_status, pdt_status.first_dbe_loc, pdt_status.pdt_status, pdt_status.first_dbe_loc,
pdt_status.good_mem); pdt_status.good_mem / 1024 / 1024);
if (entries == 0) { if (entries == 0) {
pr_info("PDT: Firmware reports all memory OK.\n"); pr_info("PDT: Firmware reports all memory OK.\n");
...@@ -112,15 +198,12 @@ void __init pdc_pdt_init(void) ...@@ -112,15 +198,12 @@ void __init pdc_pdt_init(void)
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
struct pdc_pat_mem_read_pd_retinfo pat_pret; struct pdc_pat_mem_read_pd_retinfo pat_pret;
/* try old obsolete PAT firmware function first */ if (pdt_type == PDT_PAT_CELL)
pdt_type = PDT_PAT_OLD;
ret = pdc_pat_mem_read_cell_pdt(&pat_pret, pdt_entry, ret = pdc_pat_mem_read_cell_pdt(&pat_pret, pdt_entry,
MAX_PDT_ENTRIES); MAX_PDT_ENTRIES);
if (ret != PDC_OK) { else
pdt_type = PDT_PAT_NEW;
ret = pdc_pat_mem_read_pd_pdt(&pat_pret, pdt_entry, ret = pdc_pat_mem_read_pd_pdt(&pat_pret, pdt_entry,
MAX_PDT_TABLE_SIZE, 0); MAX_PDT_TABLE_SIZE, 0);
}
#else #else
ret = PDC_BAD_PROC; ret = PDC_BAD_PROC;
#endif #endif
...@@ -128,27 +211,142 @@ void __init pdc_pdt_init(void) ...@@ -128,27 +211,142 @@ void __init pdc_pdt_init(void)
if (ret != PDC_OK) { if (ret != PDC_OK) {
pdt_type = PDT_NONE; pdt_type = PDT_NONE;
pr_debug("PDT type %d, retval = %d\n", pdt_type, ret); pr_warn("PDT: Get PDT entries failed with %d\n", ret);
return; return;
} }
for (i = 0; i < pdt_status.pdt_entries; i++) { for (i = 0; i < pdt_status.pdt_entries; i++) {
struct pdc_pat_mem_phys_mem_location loc; report_mem_err(pdt_entry[i]);
/* mark memory page bad */
memblock_reserve(pdt_entry[i] & PAGE_MASK, PAGE_SIZE);
}
}
/*
* This is the PDT kernel thread main loop.
*/
static int pdt_mainloop(void *unused)
{
struct pdc_mem_read_pdt pdt_read_ret;
struct pdc_pat_mem_read_pd_retinfo pat_pret __maybe_unused;
unsigned long old_num_entries;
unsigned long *bad_mem_ptr;
int num, ret;
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
old_num_entries = pdt_status.pdt_entries;
schedule_timeout(pdt_poll_interval);
if (kthread_should_stop())
break;
/* Do we have new PDT entries? */
switch (pdt_type) {
case PDT_PAT_NEW:
ret = get_info_pat_new();
break;
case PDT_PAT_CELL:
ret = get_info_pat_cell();
break;
default:
ret = pdc_mem_pdt_info(&pdt_status);
break;
}
if (ret != PDC_OK) {
pr_warn("PDT: unexpected failure %d\n", ret);
return -EINVAL;
}
/* if no new PDT entries, just wait again */
num = pdt_status.pdt_entries - old_num_entries;
if (num <= 0)
continue;
/* decrease poll interval in case we found memory errors */
if (pdt_status.pdt_entries &&
pdt_poll_interval == PDT_POLL_INTERVAL_DEFAULT)
pdt_poll_interval = PDT_POLL_INTERVAL_SHORT;
/* get DIMM slot number */ /* limit entries to get */
loc.dimm_slot = 0xff; if (num > MAX_PDT_ENTRIES) {
num = MAX_PDT_ENTRIES;
pdt_status.pdt_entries = old_num_entries + num;
}
/* get new entries */
switch (pdt_type) {
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
pdc_pat_mem_get_dimm_phys_location(&loc, pdt_entry[i]); case PDT_PAT_CELL:
if (pdt_status.pdt_entries > MAX_PDT_ENTRIES) {
pr_crit("PDT: too many entries.\n");
return -ENOMEM;
}
ret = pdc_pat_mem_read_cell_pdt(&pat_pret, pdt_entry,
MAX_PDT_ENTRIES);
bad_mem_ptr = &pdt_entry[old_num_entries];
break;
case PDT_PAT_NEW:
ret = pdc_pat_mem_read_pd_pdt(&pat_pret,
pdt_entry,
num * sizeof(unsigned long),
old_num_entries * sizeof(unsigned long));
bad_mem_ptr = &pdt_entry[0];
break;
#endif #endif
default:
ret = pdc_mem_pdt_read_entries(&pdt_read_ret,
pdt_entry);
bad_mem_ptr = &pdt_entry[old_num_entries];
break;
}
pr_warn("PDT: BAD PAGE #%d at 0x%08lx, " /* report and mark memory broken */
"DIMM slot %02x (error_type = %lu)\n", while (num--) {
i, unsigned long pde = *bad_mem_ptr++;
pdt_entry[i] & PAGE_MASK,
loc.dimm_slot, report_mem_err(pde);
pdt_entry[i] & 1);
#ifdef CONFIG_MEMORY_FAILURE
if ((pde & PDT_ADDR_PERM_ERR) ||
((pde & PDT_ADDR_SINGLE_ERR) == 0))
memory_failure(pde >> PAGE_SHIFT, 0, 0);
else
soft_offline_page(
pfn_to_page(pde >> PAGE_SHIFT), 0);
#else
pr_crit("PDT: memory error at 0x%lx ignored.\n"
"Rebuild kernel with CONFIG_MEMORY_FAILURE=y "
"for real handling.\n",
pde & PDT_ADDR_PHYS_MASK);
#endif
/* mark memory page bad */
memblock_reserve(pdt_entry[i] & PAGE_MASK, PAGE_SIZE);
} }
}
return 0;
}
static int __init pdt_initcall(void)
{
struct task_struct *kpdtd_task;
if (pdt_type == PDT_NONE)
return -ENODEV;
kpdtd_task = kthread_create(pdt_mainloop, NULL, "kpdtd");
if (IS_ERR(kpdtd_task))
return PTR_ERR(kpdtd_task);
wake_up_process(kpdtd_task);
return 0;
} }
late_initcall(pdt_initcall);
...@@ -69,7 +69,7 @@ struct rdr_tbl_ent { ...@@ -69,7 +69,7 @@ struct rdr_tbl_ent {
static int perf_processor_interface __read_mostly = UNKNOWN_INTF; static int perf_processor_interface __read_mostly = UNKNOWN_INTF;
static int perf_enabled __read_mostly; static int perf_enabled __read_mostly;
static spinlock_t perf_lock; static DEFINE_SPINLOCK(perf_lock);
struct parisc_device *cpu_device __read_mostly; struct parisc_device *cpu_device __read_mostly;
/* RDRs to write for PCX-W */ /* RDRs to write for PCX-W */
...@@ -533,8 +533,6 @@ static int __init perf_init(void) ...@@ -533,8 +533,6 @@ static int __init perf_init(void)
/* Patch the images to match the system */ /* Patch the images to match the system */
perf_patch_images(); perf_patch_images();
spin_lock_init(&perf_lock);
/* TODO: this only lets us access the first cpu.. what to do for SMP? */ /* TODO: this only lets us access the first cpu.. what to do for SMP? */
cpu_device = per_cpu(cpu_data, 0).dev; cpu_device = per_cpu(cpu_data, 0).dev;
printk("Performance monitoring counters enabled for %s\n", printk("Performance monitoring counters enabled for %s\n",
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/random.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#include <asm/param.h> #include <asm/param.h>
...@@ -89,7 +90,7 @@ init_percpu_prof(unsigned long cpunum) ...@@ -89,7 +90,7 @@ init_percpu_prof(unsigned long cpunum)
* (return 1). If so, initialize the chip and tell other partners in crime * (return 1). If so, initialize the chip and tell other partners in crime
* they have work to do. * they have work to do.
*/ */
static int processor_probe(struct parisc_device *dev) static int __init processor_probe(struct parisc_device *dev)
{ {
unsigned long txn_addr; unsigned long txn_addr;
unsigned long cpuid; unsigned long cpuid;
...@@ -237,28 +238,45 @@ static int processor_probe(struct parisc_device *dev) ...@@ -237,28 +238,45 @@ static int processor_probe(struct parisc_device *dev)
*/ */
void __init collect_boot_cpu_data(void) void __init collect_boot_cpu_data(void)
{ {
unsigned long cr16_seed;
memset(&boot_cpu_data, 0, sizeof(boot_cpu_data)); memset(&boot_cpu_data, 0, sizeof(boot_cpu_data));
cr16_seed = get_cycles();
add_device_randomness(&cr16_seed, sizeof(cr16_seed));
boot_cpu_data.cpu_hz = 100 * PAGE0->mem_10msec; /* Hz of this PARISC */ boot_cpu_data.cpu_hz = 100 * PAGE0->mem_10msec; /* Hz of this PARISC */
/* get CPU-Model Information... */ /* get CPU-Model Information... */
#define p ((unsigned long *)&boot_cpu_data.pdc.model) #define p ((unsigned long *)&boot_cpu_data.pdc.model)
if (pdc_model_info(&boot_cpu_data.pdc.model) == PDC_OK) if (pdc_model_info(&boot_cpu_data.pdc.model) == PDC_OK) {
printk(KERN_INFO printk(KERN_INFO
"model %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", "model %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8]); p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8]);
add_device_randomness(&boot_cpu_data.pdc.model,
sizeof(boot_cpu_data.pdc.model));
}
#undef p #undef p
if (pdc_model_versions(&boot_cpu_data.pdc.versions, 0) == PDC_OK) if (pdc_model_versions(&boot_cpu_data.pdc.versions, 0) == PDC_OK) {
printk(KERN_INFO "vers %08lx\n", printk(KERN_INFO "vers %08lx\n",
boot_cpu_data.pdc.versions); boot_cpu_data.pdc.versions);
if (pdc_model_cpuid(&boot_cpu_data.pdc.cpuid) == PDC_OK) add_device_randomness(&boot_cpu_data.pdc.versions,
sizeof(boot_cpu_data.pdc.versions));
}
if (pdc_model_cpuid(&boot_cpu_data.pdc.cpuid) == PDC_OK) {
printk(KERN_INFO "CPUID vers %ld rev %ld (0x%08lx)\n", printk(KERN_INFO "CPUID vers %ld rev %ld (0x%08lx)\n",
(boot_cpu_data.pdc.cpuid >> 5) & 127, (boot_cpu_data.pdc.cpuid >> 5) & 127,
boot_cpu_data.pdc.cpuid & 31, boot_cpu_data.pdc.cpuid & 31,
boot_cpu_data.pdc.cpuid); boot_cpu_data.pdc.cpuid);
add_device_randomness(&boot_cpu_data.pdc.cpuid,
sizeof(boot_cpu_data.pdc.cpuid));
}
if (pdc_model_capabilities(&boot_cpu_data.pdc.capabilities) == PDC_OK) if (pdc_model_capabilities(&boot_cpu_data.pdc.capabilities) == PDC_OK)
printk(KERN_INFO "capabilities 0x%lx\n", printk(KERN_INFO "capabilities 0x%lx\n",
boot_cpu_data.pdc.capabilities); boot_cpu_data.pdc.capabilities);
...@@ -414,12 +432,12 @@ show_cpuinfo (struct seq_file *m, void *v) ...@@ -414,12 +432,12 @@ show_cpuinfo (struct seq_file *m, void *v)
return 0; return 0;
} }
static const struct parisc_device_id processor_tbl[] = { static const struct parisc_device_id processor_tbl[] __initconst = {
{ HPHW_NPROC, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, SVERSION_ANY_ID }, { HPHW_NPROC, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, SVERSION_ANY_ID },
{ 0, } { 0, }
}; };
static struct parisc_driver cpu_driver = { static struct parisc_driver cpu_driver __refdata = {
.name = "CPU", .name = "CPU",
.id_table = processor_tbl, .id_table = processor_tbl,
.probe = processor_probe .probe = processor_probe
......
...@@ -162,6 +162,7 @@ ENDPROC_CFI(restore_control_regs) ...@@ -162,6 +162,7 @@ ENDPROC_CFI(restore_control_regs)
.text .text
.align 128 .align 128
ENTRY_CFI(rfi_virt2real) ENTRY_CFI(rfi_virt2real)
#if !defined(BOOTLOADER)
/* switch to real mode... */ /* switch to real mode... */
rsm PSW_SM_I,%r0 rsm PSW_SM_I,%r0
load32 PA(rfi_v2r_1), %r1 load32 PA(rfi_v2r_1), %r1
...@@ -191,6 +192,7 @@ ENTRY_CFI(rfi_virt2real) ...@@ -191,6 +192,7 @@ ENTRY_CFI(rfi_virt2real)
nop nop
rfi_v2r_1: rfi_v2r_1:
tophys_r1 %r2 tophys_r1 %r2
#endif /* defined(BOOTLOADER) */
bv 0(%r2) bv 0(%r2)
nop nop
ENDPROC_CFI(rfi_virt2real) ENDPROC_CFI(rfi_virt2real)
...@@ -198,6 +200,7 @@ ENDPROC_CFI(rfi_virt2real) ...@@ -198,6 +200,7 @@ ENDPROC_CFI(rfi_virt2real)
.text .text
.align 128 .align 128
ENTRY_CFI(rfi_real2virt) ENTRY_CFI(rfi_real2virt)
#if !defined(BOOTLOADER)
rsm PSW_SM_I,%r0 rsm PSW_SM_I,%r0
load32 (rfi_r2v_1), %r1 load32 (rfi_r2v_1), %r1
nop nop
...@@ -226,6 +229,7 @@ ENTRY_CFI(rfi_real2virt) ...@@ -226,6 +229,7 @@ ENTRY_CFI(rfi_real2virt)
nop nop
rfi_r2v_1: rfi_r2v_1:
tovirt_r1 %r2 tovirt_r1 %r2
#endif /* defined(BOOTLOADER) */
bv 0(%r2) bv 0(%r2)
nop nop
ENDPROC_CFI(rfi_real2virt) ENDPROC_CFI(rfi_real2virt)
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
extern struct unwind_table_entry __start___unwind[]; extern struct unwind_table_entry __start___unwind[];
extern struct unwind_table_entry __stop___unwind[]; extern struct unwind_table_entry __stop___unwind[];
static spinlock_t unwind_lock; static DEFINE_SPINLOCK(unwind_lock);
/* /*
* the kernel unwind block is not dynamically allocated so that * the kernel unwind block is not dynamically allocated so that
* we can call unwind_init as early in the bootup process as * we can call unwind_init as early in the bootup process as
...@@ -181,8 +181,6 @@ int __init unwind_init(void) ...@@ -181,8 +181,6 @@ int __init unwind_init(void)
start = (long)&__start___unwind[0]; start = (long)&__start___unwind[0];
stop = (long)&__stop___unwind[0]; stop = (long)&__stop___unwind[0];
spin_lock_init(&unwind_lock);
printk("unwind_init: start = 0x%lx, end = 0x%lx, entries = %lu\n", printk("unwind_init: start = 0x%lx, end = 0x%lx, entries = %lu\n",
start, stop, start, stop,
(stop - start) / sizeof(struct unwind_table_entry)); (stop - start) / sizeof(struct unwind_table_entry));
......
...@@ -27,8 +27,6 @@ ...@@ -27,8 +27,6 @@
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
DECLARE_PER_CPU(struct exception_data, exception_data);
#define get_user_space() (uaccess_kernel() ? 0 : mfsp(3)) #define get_user_space() (uaccess_kernel() ? 0 : mfsp(3))
#define get_kernel_space() (0) #define get_kernel_space() (0)
......
...@@ -2812,7 +2812,7 @@ static struct platform_driver ipmi_driver = { ...@@ -2812,7 +2812,7 @@ static struct platform_driver ipmi_driver = {
}; };
#ifdef CONFIG_PARISC #ifdef CONFIG_PARISC
static int ipmi_parisc_probe(struct parisc_device *dev) static int __init ipmi_parisc_probe(struct parisc_device *dev)
{ {
struct smi_info *info; struct smi_info *info;
int rv; int rv;
...@@ -2850,22 +2850,24 @@ static int ipmi_parisc_probe(struct parisc_device *dev) ...@@ -2850,22 +2850,24 @@ static int ipmi_parisc_probe(struct parisc_device *dev)
return 0; return 0;
} }
static int ipmi_parisc_remove(struct parisc_device *dev) static int __exit ipmi_parisc_remove(struct parisc_device *dev)
{ {
cleanup_one_si(dev_get_drvdata(&dev->dev)); cleanup_one_si(dev_get_drvdata(&dev->dev));
return 0; return 0;
} }
static const struct parisc_device_id ipmi_parisc_tbl[] = { static const struct parisc_device_id ipmi_parisc_tbl[] __initconst = {
{ HPHW_MC, HVERSION_REV_ANY_ID, 0x004, 0xC0 }, { HPHW_MC, HVERSION_REV_ANY_ID, 0x004, 0xC0 },
{ 0, } { 0, }
}; };
static struct parisc_driver ipmi_parisc_driver = { MODULE_DEVICE_TABLE(parisc, ipmi_parisc_tbl);
static struct parisc_driver ipmi_parisc_driver __refdata = {
.name = "ipmi", .name = "ipmi",
.id_table = ipmi_parisc_tbl, .id_table = ipmi_parisc_tbl,
.probe = ipmi_parisc_probe, .probe = ipmi_parisc_probe,
.remove = ipmi_parisc_remove, .remove = __exit_p(ipmi_parisc_remove),
}; };
#endif /* CONFIG_PARISC */ #endif /* CONFIG_PARISC */
......
...@@ -299,7 +299,7 @@ static void hil_keyb_exit(void) ...@@ -299,7 +299,7 @@ static void hil_keyb_exit(void)
} }
#if defined(CONFIG_PARISC) #if defined(CONFIG_PARISC)
static int hil_probe_chip(struct parisc_device *dev) static int __init hil_probe_chip(struct parisc_device *dev)
{ {
/* Only allow one HIL keyboard */ /* Only allow one HIL keyboard */
if (hil_dev.dev) if (hil_dev.dev)
...@@ -320,14 +320,14 @@ static int hil_probe_chip(struct parisc_device *dev) ...@@ -320,14 +320,14 @@ static int hil_probe_chip(struct parisc_device *dev)
return hil_keyb_init(); return hil_keyb_init();
} }
static int hil_remove_chip(struct parisc_device *dev) static int __exit hil_remove_chip(struct parisc_device *dev)
{ {
hil_keyb_exit(); hil_keyb_exit();
return 0; return 0;
} }
static struct parisc_device_id hil_tbl[] = { static const struct parisc_device_id hil_tbl[] __initconst = {
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00073 }, { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00073 },
{ 0, } { 0, }
}; };
...@@ -337,11 +337,11 @@ static struct parisc_device_id hil_tbl[] = { ...@@ -337,11 +337,11 @@ static struct parisc_device_id hil_tbl[] = {
MODULE_DEVICE_TABLE(parisc, hil_tbl); MODULE_DEVICE_TABLE(parisc, hil_tbl);
#endif #endif
static struct parisc_driver hil_driver = { static struct parisc_driver hil_driver __refdata = {
.name = "hil", .name = "hil",
.id_table = hil_tbl, .id_table = hil_tbl,
.probe = hil_probe_chip, .probe = hil_probe_chip,
.remove = hil_remove_chip, .remove = __exit_p(hil_remove_chip),
}; };
static int __init hil_init(void) static int __init hil_init(void)
......
...@@ -325,7 +325,7 @@ static void gscps2_close(struct serio *port) ...@@ -325,7 +325,7 @@ static void gscps2_close(struct serio *port)
* @return: success/error report * @return: success/error report
*/ */
static int gscps2_probe(struct parisc_device *dev) static int __init gscps2_probe(struct parisc_device *dev)
{ {
struct gscps2port *ps2port; struct gscps2port *ps2port;
struct serio *serio; struct serio *serio;
...@@ -412,7 +412,7 @@ static int gscps2_probe(struct parisc_device *dev) ...@@ -412,7 +412,7 @@ static int gscps2_probe(struct parisc_device *dev)
* @return: success/error report * @return: success/error report
*/ */
static int gscps2_remove(struct parisc_device *dev) static int __exit gscps2_remove(struct parisc_device *dev)
{ {
struct gscps2port *ps2port = dev_get_drvdata(&dev->dev); struct gscps2port *ps2port = dev_get_drvdata(&dev->dev);
...@@ -430,7 +430,7 @@ static int gscps2_remove(struct parisc_device *dev) ...@@ -430,7 +430,7 @@ static int gscps2_remove(struct parisc_device *dev)
} }
static struct parisc_device_id gscps2_device_tbl[] = { static const struct parisc_device_id gscps2_device_tbl[] __initconst = {
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00084 }, /* LASI PS/2 */ { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00084 }, /* LASI PS/2 */
#ifdef DINO_TESTED #ifdef DINO_TESTED
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00096 }, /* DINO PS/2 */ { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00096 }, /* DINO PS/2 */
...@@ -439,11 +439,11 @@ static struct parisc_device_id gscps2_device_tbl[] = { ...@@ -439,11 +439,11 @@ static struct parisc_device_id gscps2_device_tbl[] = {
}; };
MODULE_DEVICE_TABLE(parisc, gscps2_device_tbl); MODULE_DEVICE_TABLE(parisc, gscps2_device_tbl);
static struct parisc_driver parisc_ps2_driver = { static struct parisc_driver parisc_ps2_driver __refdata = {
.name = "gsc_ps2", .name = "gsc_ps2",
.id_table = gscps2_device_tbl, .id_table = gscps2_device_tbl,
.probe = gscps2_probe, .probe = gscps2_probe,
.remove = gscps2_remove, .remove = __exit_p(gscps2_remove),
}; };
static int __init gscps2_init(void) static int __init gscps2_init(void)
......
...@@ -805,7 +805,7 @@ static void hp_sdc_kicker(unsigned long data) ...@@ -805,7 +805,7 @@ static void hp_sdc_kicker(unsigned long data)
#if defined(__hppa__) #if defined(__hppa__)
static const struct parisc_device_id hp_sdc_tbl[] = { static const struct parisc_device_id hp_sdc_tbl[] __initconst = {
{ {
.hw_type = HPHW_FIO, .hw_type = HPHW_FIO,
.hversion_rev = HVERSION_REV_ANY_ID, .hversion_rev = HVERSION_REV_ANY_ID,
...@@ -820,7 +820,7 @@ MODULE_DEVICE_TABLE(parisc, hp_sdc_tbl); ...@@ -820,7 +820,7 @@ MODULE_DEVICE_TABLE(parisc, hp_sdc_tbl);
static int __init hp_sdc_init_hppa(struct parisc_device *d); static int __init hp_sdc_init_hppa(struct parisc_device *d);
static struct delayed_work moduleloader_work; static struct delayed_work moduleloader_work;
static struct parisc_driver hp_sdc_driver = { static struct parisc_driver hp_sdc_driver __refdata = {
.name = "hp_sdc", .name = "hp_sdc",
.id_table = hp_sdc_tbl, .id_table = hp_sdc_tbl,
.probe = hp_sdc_init_hppa, .probe = hp_sdc_init_hppa,
......
...@@ -149,7 +149,7 @@ static void mpu_port(struct net_device *dev, int c, dma_addr_t x) ...@@ -149,7 +149,7 @@ static void mpu_port(struct net_device *dev, int c, dma_addr_t x)
#define LAN_PROM_ADDR 0xF0810000 #define LAN_PROM_ADDR 0xF0810000
static int static int __init
lan_init_chip(struct parisc_device *dev) lan_init_chip(struct parisc_device *dev)
{ {
struct net_device *netdevice; struct net_device *netdevice;
...@@ -194,7 +194,7 @@ lan_init_chip(struct parisc_device *dev) ...@@ -194,7 +194,7 @@ lan_init_chip(struct parisc_device *dev)
return retval; return retval;
} }
static int lan_remove_chip(struct parisc_device *pdev) static int __exit lan_remove_chip(struct parisc_device *pdev)
{ {
struct net_device *dev = parisc_get_drvdata(pdev); struct net_device *dev = parisc_get_drvdata(pdev);
struct i596_private *lp = netdev_priv(dev); struct i596_private *lp = netdev_priv(dev);
...@@ -206,7 +206,7 @@ static int lan_remove_chip(struct parisc_device *pdev) ...@@ -206,7 +206,7 @@ static int lan_remove_chip(struct parisc_device *pdev)
return 0; return 0;
} }
static struct parisc_device_id lan_tbl[] = { static const struct parisc_device_id lan_tbl[] __initconst = {
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008a }, { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008a },
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00072 }, { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00072 },
{ 0, } { 0, }
...@@ -214,11 +214,11 @@ static struct parisc_device_id lan_tbl[] = { ...@@ -214,11 +214,11 @@ static struct parisc_device_id lan_tbl[] = {
MODULE_DEVICE_TABLE(parisc, lan_tbl); MODULE_DEVICE_TABLE(parisc, lan_tbl);
static struct parisc_driver lan_driver = { static struct parisc_driver lan_driver __refdata = {
.name = "lasi_82596", .name = "lasi_82596",
.id_table = lan_tbl, .id_table = lan_tbl,
.probe = lan_init_chip, .probe = lan_init_chip,
.remove = lan_remove_chip, .remove = __exit_p(lan_remove_chip),
}; };
static int lasi_82596_init(void) static int lasi_82596_init(void)
......
...@@ -118,12 +118,12 @@ static int __init asp_init_chip(struct parisc_device *dev) ...@@ -118,12 +118,12 @@ static int __init asp_init_chip(struct parisc_device *dev)
return ret; return ret;
} }
static struct parisc_device_id asp_tbl[] = { static const struct parisc_device_id asp_tbl[] __initconst = {
{ HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00070 }, { HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00070 },
{ 0, } { 0, }
}; };
struct parisc_driver asp_driver = { struct parisc_driver asp_driver __refdata = {
.name = "asp", .name = "asp",
.id_table = asp_tbl, .id_table = asp_tbl,
.probe = asp_init_chip, .probe = asp_init_chip,
......
...@@ -1241,7 +1241,7 @@ ccio_get_iotlb_size(struct parisc_device *dev) ...@@ -1241,7 +1241,7 @@ ccio_get_iotlb_size(struct parisc_device *dev)
#endif /* 0 */ #endif /* 0 */
/* We *can't* support JAVA (T600). Venture there at your own risk. */ /* We *can't* support JAVA (T600). Venture there at your own risk. */
static const struct parisc_device_id ccio_tbl[] = { static const struct parisc_device_id ccio_tbl[] __initconst = {
{ HPHW_IOA, HVERSION_REV_ANY_ID, U2_IOA_RUNWAY, 0xb }, /* U2 */ { HPHW_IOA, HVERSION_REV_ANY_ID, U2_IOA_RUNWAY, 0xb }, /* U2 */
{ HPHW_IOA, HVERSION_REV_ANY_ID, UTURN_IOA_RUNWAY, 0xb }, /* UTurn */ { HPHW_IOA, HVERSION_REV_ANY_ID, UTURN_IOA_RUNWAY, 0xb }, /* UTurn */
{ 0, } { 0, }
...@@ -1249,7 +1249,7 @@ static const struct parisc_device_id ccio_tbl[] = { ...@@ -1249,7 +1249,7 @@ static const struct parisc_device_id ccio_tbl[] = {
static int ccio_probe(struct parisc_device *dev); static int ccio_probe(struct parisc_device *dev);
static struct parisc_driver ccio_driver = { static struct parisc_driver ccio_driver __refdata = {
.name = "ccio", .name = "ccio",
.id_table = ccio_tbl, .id_table = ccio_tbl,
.probe = ccio_probe, .probe = ccio_probe,
......
...@@ -163,7 +163,7 @@ static struct pci_dma_ops ccio_ops = { ...@@ -163,7 +163,7 @@ static struct pci_dma_ops ccio_ops = {
** If so, initialize the chip and tell other partners in crime they ** If so, initialize the chip and tell other partners in crime they
** have work to do. ** have work to do.
*/ */
static int static int __init
ccio_probe(struct parisc_device *dev) ccio_probe(struct parisc_device *dev)
{ {
printk(KERN_INFO "%s found %s at 0x%lx\n", MODULE_NAME, printk(KERN_INFO "%s found %s at 0x%lx\n", MODULE_NAME,
...@@ -184,13 +184,13 @@ ccio_probe(struct parisc_device *dev) ...@@ -184,13 +184,13 @@ ccio_probe(struct parisc_device *dev)
return 0; return 0;
} }
static struct parisc_device_id ccio_tbl[] = { static const struct parisc_device_id ccio_tbl[] __initconst = {
{ HPHW_BCPORT, HVERSION_REV_ANY_ID, U2_BC_GSC, 0xc }, { HPHW_BCPORT, HVERSION_REV_ANY_ID, U2_BC_GSC, 0xc },
{ HPHW_BCPORT, HVERSION_REV_ANY_ID, UTURN_BC_GSC, 0xc }, { HPHW_BCPORT, HVERSION_REV_ANY_ID, UTURN_BC_GSC, 0xc },
{ 0, } { 0, }
}; };
static struct parisc_driver ccio_driver = { static struct parisc_driver ccio_driver __refdata = {
.name = "U2/Uturn", .name = "U2/Uturn",
.id_table = ccio_tbl, .id_table = ccio_tbl,
.probe = ccio_probe, .probe = ccio_probe,
......
...@@ -1022,7 +1022,7 @@ static int __init dino_probe(struct parisc_device *dev) ...@@ -1022,7 +1022,7 @@ static int __init dino_probe(struct parisc_device *dev)
* and 725 firmware misreport it as 0x08080 for no adequately explained * and 725 firmware misreport it as 0x08080 for no adequately explained
* reason. * reason.
*/ */
static struct parisc_device_id dino_tbl[] = { static const struct parisc_device_id dino_tbl[] __initconst = {
{ HPHW_A_DMA, HVERSION_REV_ANY_ID, 0x004, 0x0009D },/* Card-mode Dino */ { HPHW_A_DMA, HVERSION_REV_ANY_ID, 0x004, 0x0009D },/* Card-mode Dino */
{ HPHW_A_DMA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x08080 }, /* XXX */ { HPHW_A_DMA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x08080 }, /* XXX */
{ HPHW_BRIDGE, HVERSION_REV_ANY_ID, 0x680, 0xa }, /* Bridge-mode Dino */ { HPHW_BRIDGE, HVERSION_REV_ANY_ID, 0x680, 0xa }, /* Bridge-mode Dino */
...@@ -1031,7 +1031,7 @@ static struct parisc_device_id dino_tbl[] = { ...@@ -1031,7 +1031,7 @@ static struct parisc_device_id dino_tbl[] = {
{ 0, } { 0, }
}; };
static struct parisc_driver dino_driver = { static struct parisc_driver dino_driver __refdata = {
.name = "dino", .name = "dino",
.id_table = dino_tbl, .id_table = dino_tbl,
.probe = dino_probe, .probe = dino_probe,
......
...@@ -393,7 +393,7 @@ static int __init eisa_probe(struct parisc_device *dev) ...@@ -393,7 +393,7 @@ static int __init eisa_probe(struct parisc_device *dev)
return result; return result;
} }
static const struct parisc_device_id eisa_tbl[] = { static const struct parisc_device_id eisa_tbl[] __initconst = {
{ HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00076 }, /* Mongoose */ { HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00076 }, /* Mongoose */
{ HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00090 }, /* Wax EISA */ { HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00090 }, /* Wax EISA */
{ 0, } { 0, }
...@@ -401,7 +401,7 @@ static const struct parisc_device_id eisa_tbl[] = { ...@@ -401,7 +401,7 @@ static const struct parisc_device_id eisa_tbl[] = {
MODULE_DEVICE_TABLE(parisc, eisa_tbl); MODULE_DEVICE_TABLE(parisc, eisa_tbl);
static struct parisc_driver eisa_driver = { static struct parisc_driver eisa_driver __refdata = {
.name = "eisa_ba", .name = "eisa_ba",
.id_table = eisa_tbl, .id_table = eisa_tbl,
.probe = eisa_probe, .probe = eisa_probe,
......
...@@ -45,7 +45,7 @@ static struct hppb_card hppb_card_head = { ...@@ -45,7 +45,7 @@ static struct hppb_card hppb_card_head = {
* (return 1). If so, initialize the chip and tell other partners in crime * (return 1). If so, initialize the chip and tell other partners in crime
* they have work to do. * they have work to do.
*/ */
static int hppb_probe(struct parisc_device *dev) static int __init hppb_probe(struct parisc_device *dev)
{ {
int status; int status;
struct hppb_card *card = &hppb_card_head; struct hppb_card *card = &hppb_card_head;
...@@ -81,7 +81,7 @@ static int hppb_probe(struct parisc_device *dev) ...@@ -81,7 +81,7 @@ static int hppb_probe(struct parisc_device *dev)
return 0; return 0;
} }
static struct parisc_device_id hppb_tbl[] = { static const struct parisc_device_id hppb_tbl[] __initconst = {
{ HPHW_BCPORT, HVERSION_REV_ANY_ID, 0x500, 0xc }, /* E25 and K */ { HPHW_BCPORT, HVERSION_REV_ANY_ID, 0x500, 0xc }, /* E25 and K */
{ HPHW_BCPORT, 0x0, 0x501, 0xc }, /* E35 */ { HPHW_BCPORT, 0x0, 0x501, 0xc }, /* E35 */
{ HPHW_BCPORT, 0x0, 0x502, 0xc }, /* E45 */ { HPHW_BCPORT, 0x0, 0x502, 0xc }, /* E45 */
...@@ -89,7 +89,7 @@ static struct parisc_device_id hppb_tbl[] = { ...@@ -89,7 +89,7 @@ static struct parisc_device_id hppb_tbl[] = {
{ 0, } { 0, }
}; };
static struct parisc_driver hppb_driver = { static struct parisc_driver hppb_driver __refdata = {
.name = "gecko_boa", .name = "gecko_boa",
.id_table = hppb_tbl, .id_table = hppb_tbl,
.probe = hppb_probe, .probe = hppb_probe,
......
...@@ -227,12 +227,12 @@ static int __init lasi_init_chip(struct parisc_device *dev) ...@@ -227,12 +227,12 @@ static int __init lasi_init_chip(struct parisc_device *dev)
return ret; return ret;
} }
static struct parisc_device_id lasi_tbl[] = { static struct parisc_device_id lasi_tbl[] __initdata = {
{ HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00081 }, { HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00081 },
{ 0, } { 0, }
}; };
struct parisc_driver lasi_driver = { struct parisc_driver lasi_driver __refdata = {
.name = "lasi", .name = "lasi",
.id_table = lasi_tbl, .id_table = lasi_tbl,
.probe = lasi_init_chip, .probe = lasi_init_chip,
......
...@@ -667,6 +667,42 @@ extend_lmmio_len(unsigned long start, unsigned long end, unsigned long lba_len) ...@@ -667,6 +667,42 @@ extend_lmmio_len(unsigned long start, unsigned long end, unsigned long lba_len)
#define truncate_pat_collision(r,n) (0) #define truncate_pat_collision(r,n) (0)
#endif #endif
static void pcibios_allocate_bridge_resources(struct pci_dev *dev)
{
int idx;
struct resource *r;
for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
r = &dev->resource[idx];
if (!r->flags)
continue;
if (r->parent) /* Already allocated */
continue;
if (!r->start || pci_claim_bridge_resource(dev, idx) < 0) {
/*
* Something is wrong with the region.
* Invalidate the resource to prevent
* child resource allocations in this
* range.
*/
r->start = r->end = 0;
r->flags = 0;
}
}
}
static void pcibios_allocate_bus_resources(struct pci_bus *bus)
{
struct pci_bus *child;
/* Depth-First Search on bus tree */
if (bus->self)
pcibios_allocate_bridge_resources(bus->self);
list_for_each_entry(child, &bus->children, node)
pcibios_allocate_bus_resources(child);
}
/* /*
** The algorithm is generic code. ** The algorithm is generic code.
** But it needs to access local data structures to get the IRQ base. ** But it needs to access local data structures to get the IRQ base.
...@@ -693,11 +729,11 @@ lba_fixup_bus(struct pci_bus *bus) ...@@ -693,11 +729,11 @@ lba_fixup_bus(struct pci_bus *bus)
** pci_alloc_primary_bus() mangles this. ** pci_alloc_primary_bus() mangles this.
*/ */
if (bus->parent) { if (bus->parent) {
int i;
/* PCI-PCI Bridge */ /* PCI-PCI Bridge */
pci_read_bridge_bases(bus); pci_read_bridge_bases(bus);
for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++)
pci_claim_bridge_resource(bus->self, i); /* check and allocate bridge resources */
pcibios_allocate_bus_resources(bus);
} else { } else {
/* Host-PCI Bridge */ /* Host-PCI Bridge */
int err; int err;
...@@ -1613,14 +1649,14 @@ lba_driver_probe(struct parisc_device *dev) ...@@ -1613,14 +1649,14 @@ lba_driver_probe(struct parisc_device *dev)
return 0; return 0;
} }
static struct parisc_device_id lba_tbl[] = { static const struct parisc_device_id lba_tbl[] __initconst = {
{ HPHW_BRIDGE, HVERSION_REV_ANY_ID, ELROY_HVERS, 0xa }, { HPHW_BRIDGE, HVERSION_REV_ANY_ID, ELROY_HVERS, 0xa },
{ HPHW_BRIDGE, HVERSION_REV_ANY_ID, MERCURY_HVERS, 0xa }, { HPHW_BRIDGE, HVERSION_REV_ANY_ID, MERCURY_HVERS, 0xa },
{ HPHW_BRIDGE, HVERSION_REV_ANY_ID, QUICKSILVER_HVERS, 0xa }, { HPHW_BRIDGE, HVERSION_REV_ANY_ID, QUICKSILVER_HVERS, 0xa },
{ 0, } { 0, }
}; };
static struct parisc_driver lba_driver = { static struct parisc_driver lba_driver __refdata = {
.name = MODULE_NAME, .name = MODULE_NAME,
.id_table = lba_tbl, .id_table = lba_tbl,
.probe = lba_driver_probe, .probe = lba_driver_probe,
......
...@@ -1905,7 +1905,7 @@ static const struct file_operations sba_proc_bitmap_fops = { ...@@ -1905,7 +1905,7 @@ static const struct file_operations sba_proc_bitmap_fops = {
}; };
#endif /* CONFIG_PROC_FS */ #endif /* CONFIG_PROC_FS */
static struct parisc_device_id sba_tbl[] = { static const struct parisc_device_id sba_tbl[] __initconst = {
{ HPHW_IOA, HVERSION_REV_ANY_ID, ASTRO_RUNWAY_PORT, 0xb }, { HPHW_IOA, HVERSION_REV_ANY_ID, ASTRO_RUNWAY_PORT, 0xb },
{ HPHW_BCPORT, HVERSION_REV_ANY_ID, IKE_MERCED_PORT, 0xc }, { HPHW_BCPORT, HVERSION_REV_ANY_ID, IKE_MERCED_PORT, 0xc },
{ HPHW_BCPORT, HVERSION_REV_ANY_ID, REO_MERCED_PORT, 0xc }, { HPHW_BCPORT, HVERSION_REV_ANY_ID, REO_MERCED_PORT, 0xc },
...@@ -1916,7 +1916,7 @@ static struct parisc_device_id sba_tbl[] = { ...@@ -1916,7 +1916,7 @@ static struct parisc_device_id sba_tbl[] = {
static int sba_driver_callback(struct parisc_device *); static int sba_driver_callback(struct parisc_device *);
static struct parisc_driver sba_driver = { static struct parisc_driver sba_driver __refdata = {
.name = MODULE_NAME, .name = MODULE_NAME,
.id_table = sba_tbl, .id_table = sba_tbl,
.probe = sba_driver_callback, .probe = sba_driver_callback,
...@@ -1927,7 +1927,7 @@ static struct parisc_driver sba_driver = { ...@@ -1927,7 +1927,7 @@ static struct parisc_driver sba_driver = {
** If so, initialize the chip and tell other partners in crime they ** If so, initialize the chip and tell other partners in crime they
** have work to do. ** have work to do.
*/ */
static int sba_driver_callback(struct parisc_device *dev) static int __init sba_driver_callback(struct parisc_device *dev)
{ {
struct sba_device *sba_dev; struct sba_device *sba_dev;
u32 func_class; u32 func_class;
......
...@@ -482,14 +482,14 @@ superio_probe(struct pci_dev *dev, const struct pci_device_id *id) ...@@ -482,14 +482,14 @@ superio_probe(struct pci_dev *dev, const struct pci_device_id *id)
return -ENODEV; return -ENODEV;
} }
static const struct pci_device_id superio_tbl[] = { static const struct pci_device_id superio_tbl[] __initconst = {
{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_LIO) }, { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_LIO) },
{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_USB) }, { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_USB) },
{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415) }, { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415) },
{ 0, } { 0, }
}; };
static struct pci_driver superio_driver = { static struct pci_driver superio_driver __refdata = {
.name = SUPERIO, .name = SUPERIO,
.id_table = superio_tbl, .id_table = superio_tbl,
.probe = superio_probe, .probe = superio_probe,
......
...@@ -125,14 +125,14 @@ static int __init wax_init_chip(struct parisc_device *dev) ...@@ -125,14 +125,14 @@ static int __init wax_init_chip(struct parisc_device *dev)
return ret; return ret;
} }
static struct parisc_device_id wax_tbl[] = { static const struct parisc_device_id wax_tbl[] __initconst = {
{ HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008e }, { HPHW_BA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008e },
{ 0, } { 0, }
}; };
MODULE_DEVICE_TABLE(parisc, wax_tbl); MODULE_DEVICE_TABLE(parisc, wax_tbl);
struct parisc_driver wax_driver = { struct parisc_driver wax_driver __refdata = {
.name = "wax", .name = "wax",
.id_table = wax_tbl, .id_table = wax_tbl,
.probe = wax_init_chip, .probe = wax_init_chip,
......
...@@ -346,7 +346,7 @@ struct parport *parport_gsc_probe_port(unsigned long base, ...@@ -346,7 +346,7 @@ struct parport *parport_gsc_probe_port(unsigned long base,
static int parport_count; static int parport_count;
static int parport_init_chip(struct parisc_device *dev) static int __init parport_init_chip(struct parisc_device *dev)
{ {
struct parport *p; struct parport *p;
unsigned long port; unsigned long port;
...@@ -381,7 +381,7 @@ static int parport_init_chip(struct parisc_device *dev) ...@@ -381,7 +381,7 @@ static int parport_init_chip(struct parisc_device *dev)
return 0; return 0;
} }
static int parport_remove_chip(struct parisc_device *dev) static int __exit parport_remove_chip(struct parisc_device *dev)
{ {
struct parport *p = dev_get_drvdata(&dev->dev); struct parport *p = dev_get_drvdata(&dev->dev);
if (p) { if (p) {
...@@ -403,18 +403,18 @@ static int parport_remove_chip(struct parisc_device *dev) ...@@ -403,18 +403,18 @@ static int parport_remove_chip(struct parisc_device *dev)
return 0; return 0;
} }
static struct parisc_device_id parport_tbl[] = { static const struct parisc_device_id parport_tbl[] __initconst = {
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x74 }, { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x74 },
{ 0, } { 0, }
}; };
MODULE_DEVICE_TABLE(parisc, parport_tbl); MODULE_DEVICE_TABLE(parisc, parport_tbl);
static struct parisc_driver parport_driver = { static struct parisc_driver parport_driver __refdata = {
.name = "Parallel", .name = "Parallel",
.id_table = parport_tbl, .id_table = parport_tbl,
.probe = parport_init_chip, .probe = parport_init_chip,
.remove = parport_remove_chip, .remove = __exit_p(parport_remove_chip),
}; };
int parport_gsc_init(void) int parport_gsc_init(void)
......
...@@ -81,7 +81,7 @@ MODULE_LICENSE("GPL"); ...@@ -81,7 +81,7 @@ MODULE_LICENSE("GPL");
#define LASI710_CLOCK 40 #define LASI710_CLOCK 40
#define LASI_SCSI_CORE_OFFSET 0x100 #define LASI_SCSI_CORE_OFFSET 0x100
static struct parisc_device_id lasi700_ids[] = { static const struct parisc_device_id lasi700_ids[] __initconst = {
LASI700_ID_TABLE, LASI700_ID_TABLE,
LASI710_ID_TABLE, LASI710_ID_TABLE,
{ 0 } { 0 }
...@@ -164,11 +164,11 @@ lasi700_driver_remove(struct parisc_device *dev) ...@@ -164,11 +164,11 @@ lasi700_driver_remove(struct parisc_device *dev)
return 0; return 0;
} }
static struct parisc_driver lasi700_driver = { static struct parisc_driver lasi700_driver __refdata = {
.name = "lasi_scsi", .name = "lasi_scsi",
.id_table = lasi700_ids, .id_table = lasi700_ids,
.probe = lasi700_probe, .probe = lasi700_probe,
.remove = lasi700_driver_remove, .remove = __exit_p(lasi700_driver_remove),
}; };
static int __init static int __init
......
...@@ -160,14 +160,14 @@ zalon_probe(struct parisc_device *dev) ...@@ -160,14 +160,14 @@ zalon_probe(struct parisc_device *dev)
return error; return error;
} }
static struct parisc_device_id zalon_tbl[] = { static const struct parisc_device_id zalon_tbl[] __initconst = {
{ HPHW_A_DMA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00089 }, { HPHW_A_DMA, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00089 },
{ 0, } { 0, }
}; };
MODULE_DEVICE_TABLE(parisc, zalon_tbl); MODULE_DEVICE_TABLE(parisc, zalon_tbl);
static int zalon_remove(struct parisc_device *dev) static int __exit zalon_remove(struct parisc_device *dev)
{ {
struct Scsi_Host *host = dev_get_drvdata(&dev->dev); struct Scsi_Host *host = dev_get_drvdata(&dev->dev);
...@@ -178,11 +178,11 @@ static int zalon_remove(struct parisc_device *dev) ...@@ -178,11 +178,11 @@ static int zalon_remove(struct parisc_device *dev)
return 0; return 0;
} }
static struct parisc_driver zalon_driver = { static struct parisc_driver zalon_driver __refdata = {
.name = "zalon", .name = "zalon",
.id_table = zalon_tbl, .id_table = zalon_tbl,
.probe = zalon_probe, .probe = zalon_probe,
.remove = zalon_remove, .remove = __exit_p(zalon_remove),
}; };
static int __init zalon7xx_init(void) static int __init zalon7xx_init(void)
......
...@@ -80,7 +80,7 @@ static int __init serial_init_chip(struct parisc_device *dev) ...@@ -80,7 +80,7 @@ static int __init serial_init_chip(struct parisc_device *dev)
return 0; return 0;
} }
static struct parisc_device_id serial_tbl[] = { static const struct parisc_device_id serial_tbl[] __initconst = {
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00075 }, { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00075 },
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008c }, { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008c },
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008d }, { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008d },
...@@ -94,7 +94,7 @@ static struct parisc_device_id serial_tbl[] = { ...@@ -94,7 +94,7 @@ static struct parisc_device_id serial_tbl[] = {
* which only knows about Lasi and then a second which will find all the * which only knows about Lasi and then a second which will find all the
* other serial ports. HPUX ignores this problem. * other serial ports. HPUX ignores this problem.
*/ */
static struct parisc_device_id lasi_tbl[] = { static const struct parisc_device_id lasi_tbl[] __initconst = {
{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03B, 0x0008C }, /* C1xx/C1xxL */ { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03B, 0x0008C }, /* C1xx/C1xxL */
{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03C, 0x0008C }, /* B132L */ { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03C, 0x0008C }, /* B132L */
{ HPHW_FIO, HVERSION_REV_ANY_ID, 0x03D, 0x0008C }, /* B160L */ { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03D, 0x0008C }, /* B160L */
...@@ -110,13 +110,13 @@ static struct parisc_device_id lasi_tbl[] = { ...@@ -110,13 +110,13 @@ static struct parisc_device_id lasi_tbl[] = {
MODULE_DEVICE_TABLE(parisc, serial_tbl); MODULE_DEVICE_TABLE(parisc, serial_tbl);
static struct parisc_driver lasi_driver = { static struct parisc_driver lasi_driver __refdata = {
.name = "serial_1", .name = "serial_1",
.id_table = lasi_tbl, .id_table = lasi_tbl,
.probe = serial_init_chip, .probe = serial_init_chip,
}; };
static struct parisc_driver serial_driver = { static struct parisc_driver serial_driver __refdata = {
.name = "serial", .name = "serial",
.id_table = serial_tbl, .id_table = serial_tbl,
.probe = serial_init_chip, .probe = serial_init_chip,
......
...@@ -503,7 +503,7 @@ static int __init mux_probe(struct parisc_device *dev) ...@@ -503,7 +503,7 @@ static int __init mux_probe(struct parisc_device *dev)
return 0; return 0;
} }
static int mux_remove(struct parisc_device *dev) static int __exit mux_remove(struct parisc_device *dev)
{ {
int i, j; int i, j;
int port_count = (long)dev_get_drvdata(&dev->dev); int port_count = (long)dev_get_drvdata(&dev->dev);
...@@ -536,13 +536,13 @@ static int mux_remove(struct parisc_device *dev) ...@@ -536,13 +536,13 @@ static int mux_remove(struct parisc_device *dev)
* This table only contains the parisc_device_id of known builtin mux * This table only contains the parisc_device_id of known builtin mux
* devices. All other mux cards will be detected by the generic mux_tbl. * devices. All other mux cards will be detected by the generic mux_tbl.
*/ */
static struct parisc_device_id builtin_mux_tbl[] = { static const struct parisc_device_id builtin_mux_tbl[] __initconst = {
{ HPHW_A_DIRECT, HVERSION_REV_ANY_ID, 0x15, 0x0000D }, /* All K-class */ { HPHW_A_DIRECT, HVERSION_REV_ANY_ID, 0x15, 0x0000D }, /* All K-class */
{ HPHW_A_DIRECT, HVERSION_REV_ANY_ID, 0x44, 0x0000D }, /* E35, E45, and E55 */ { HPHW_A_DIRECT, HVERSION_REV_ANY_ID, 0x44, 0x0000D }, /* E35, E45, and E55 */
{ 0, } { 0, }
}; };
static struct parisc_device_id mux_tbl[] = { static const struct parisc_device_id mux_tbl[] __initconst = {
{ HPHW_A_DIRECT, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0000D }, { HPHW_A_DIRECT, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0000D },
{ 0, } { 0, }
}; };
...@@ -550,18 +550,18 @@ static struct parisc_device_id mux_tbl[] = { ...@@ -550,18 +550,18 @@ static struct parisc_device_id mux_tbl[] = {
MODULE_DEVICE_TABLE(parisc, builtin_mux_tbl); MODULE_DEVICE_TABLE(parisc, builtin_mux_tbl);
MODULE_DEVICE_TABLE(parisc, mux_tbl); MODULE_DEVICE_TABLE(parisc, mux_tbl);
static struct parisc_driver builtin_serial_mux_driver = { static struct parisc_driver builtin_serial_mux_driver __refdata = {
.name = "builtin_serial_mux", .name = "builtin_serial_mux",
.id_table = builtin_mux_tbl, .id_table = builtin_mux_tbl,
.probe = mux_probe, .probe = mux_probe,
.remove = mux_remove, .remove = __exit_p(mux_remove),
}; };
static struct parisc_driver serial_mux_driver = { static struct parisc_driver serial_mux_driver __refdata = {
.name = "serial_mux", .name = "serial_mux",
.id_table = mux_tbl, .id_table = mux_tbl,
.probe = mux_probe, .probe = mux_probe,
.remove = mux_remove, .remove = __exit_p(mux_remove),
}; };
/** /**
......
...@@ -281,7 +281,7 @@ static void sti_rom_copy(unsigned long base, unsigned long count, void *dest) ...@@ -281,7 +281,7 @@ static void sti_rom_copy(unsigned long base, unsigned long count, void *dest)
static char default_sti_path[21] __read_mostly; static char default_sti_path[21] __read_mostly;
#ifndef MODULE #ifndef MODULE
static int sti_setup(char *str) static int __init sti_setup(char *str)
{ {
if (str) if (str)
strlcpy (default_sti_path, str, sizeof (default_sti_path)); strlcpy (default_sti_path, str, sizeof (default_sti_path));
...@@ -941,7 +941,7 @@ static void sticore_check_for_default_sti(struct sti_struct *sti, char *path) ...@@ -941,7 +941,7 @@ static void sticore_check_for_default_sti(struct sti_struct *sti, char *path)
* in the additional address field addr[1] while on * in the additional address field addr[1] while on
* older Systems the PDC stores it in page0->proc_sti * older Systems the PDC stores it in page0->proc_sti
*/ */
static int sticore_pa_init(struct parisc_device *dev) static int __init sticore_pa_init(struct parisc_device *dev)
{ {
char pa_path[21]; char pa_path[21];
struct sti_struct *sti = NULL; struct sti_struct *sti = NULL;
...@@ -1009,7 +1009,7 @@ static int sticore_pci_init(struct pci_dev *pd, const struct pci_device_id *ent) ...@@ -1009,7 +1009,7 @@ static int sticore_pci_init(struct pci_dev *pd, const struct pci_device_id *ent)
} }
static void sticore_pci_remove(struct pci_dev *pd) static void __exit sticore_pci_remove(struct pci_dev *pd)
{ {
BUG(); BUG();
} }
...@@ -1029,7 +1029,7 @@ static struct pci_driver pci_sti_driver = { ...@@ -1029,7 +1029,7 @@ static struct pci_driver pci_sti_driver = {
.name = "sti", .name = "sti",
.id_table = sti_pci_tbl, .id_table = sti_pci_tbl,
.probe = sticore_pci_init, .probe = sticore_pci_init,
.remove = sticore_pci_remove, .remove = __exit_p(sticore_pci_remove),
}; };
static struct parisc_device_id sti_pa_tbl[] = { static struct parisc_device_id sti_pa_tbl[] = {
...@@ -1037,8 +1037,9 @@ static struct parisc_device_id sti_pa_tbl[] = { ...@@ -1037,8 +1037,9 @@ static struct parisc_device_id sti_pa_tbl[] = {
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00085 }, { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00085 },
{ 0, } { 0, }
}; };
MODULE_DEVICE_TABLE(parisc, sti_pa_tbl);
static struct parisc_driver pa_sti_driver = { static struct parisc_driver pa_sti_driver __refdata = {
.name = "sti", .name = "sti",
.id_table = sti_pa_tbl, .id_table = sti_pa_tbl,
.probe = sticore_pa_init, .probe = sticore_pa_init,
......
...@@ -66,7 +66,7 @@ module_param(id, charp, 0444); ...@@ -66,7 +66,7 @@ module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for Harmony driver."); MODULE_PARM_DESC(id, "ID string for Harmony driver.");
static struct parisc_device_id snd_harmony_devtable[] = { static const struct parisc_device_id snd_harmony_devtable[] __initconst = {
/* bushmaster / flounder */ /* bushmaster / flounder */
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007A }, { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007A },
/* 712 / 715 */ /* 712 / 715 */
...@@ -960,7 +960,7 @@ snd_harmony_create(struct snd_card *card, ...@@ -960,7 +960,7 @@ snd_harmony_create(struct snd_card *card,
return err; return err;
} }
static int static int __init
snd_harmony_probe(struct parisc_device *padev) snd_harmony_probe(struct parisc_device *padev)
{ {
int err; int err;
...@@ -1000,18 +1000,18 @@ snd_harmony_probe(struct parisc_device *padev) ...@@ -1000,18 +1000,18 @@ snd_harmony_probe(struct parisc_device *padev)
return err; return err;
} }
static int static int __exit
snd_harmony_remove(struct parisc_device *padev) snd_harmony_remove(struct parisc_device *padev)
{ {
snd_card_free(parisc_get_drvdata(padev)); snd_card_free(parisc_get_drvdata(padev));
return 0; return 0;
} }
static struct parisc_driver snd_harmony_driver = { static struct parisc_driver snd_harmony_driver __refdata = {
.name = "harmony", .name = "harmony",
.id_table = snd_harmony_devtable, .id_table = snd_harmony_devtable,
.probe = snd_harmony_probe, .probe = snd_harmony_probe,
.remove = snd_harmony_remove, .remove = __exit_p(snd_harmony_remove),
}; };
static int __init static int __init
......
...@@ -36,9 +36,7 @@ ...@@ -36,9 +36,7 @@
#define PROT_READ 0x1 #define PROT_READ 0x1
#define PROT_SEM 0x8 #define PROT_SEM 0x8
#define PROT_WRITE 0x2 #define PROT_WRITE 0x2
/* MADV_HWPOISON is undefined on parisc, fix it for perf */
#define MADV_HWPOISON 100 #define MADV_HWPOISON 100
/* MADV_SOFT_OFFLINE is undefined on parisc, fix it for perf */
#define MADV_SOFT_OFFLINE 101 #define MADV_SOFT_OFFLINE 101
/* MAP_32BIT is undefined on parisc, fix it for perf */ /* MAP_32BIT is undefined on parisc, fix it for perf */
#define MAP_32BIT 0 #define MAP_32BIT 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