diff options
Diffstat (limited to 'arch/alpha/kernel')
68 files changed, 1965 insertions, 2399 deletions
diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile index 1ee9b5b629b..3ecac0106c8 100644 --- a/arch/alpha/kernel/Makefile +++ b/arch/alpha/kernel/Makefile @@ -3,10 +3,10 @@  #  extra-y		:= head.o vmlinux.lds -EXTRA_AFLAGS	:= $(KBUILD_CFLAGS) -EXTRA_CFLAGS	:= -Werror -Wno-sign-compare +asflags-y	:= $(KBUILD_CFLAGS) +ccflags-y	:= -Wno-sign-compare -obj-y    := entry.o traps.o process.o init_task.o osf_sys.o irq.o \ +obj-y    := entry.o traps.o process.o osf_sys.o irq.o \  	    irq_alpha.o signal.o setup.o ptrace.o time.o \  	    alpha_ksyms.o systbls.o err_common.o io.o @@ -16,6 +16,8 @@ obj-$(CONFIG_PCI)	+= pci.o pci_iommu.o pci-sysfs.o  obj-$(CONFIG_SRM_ENV)	+= srm_env.o  obj-$(CONFIG_MODULES)	+= module.o  obj-$(CONFIG_PERF_EVENTS) += perf_event.o +obj-$(CONFIG_RTC_DRV_ALPHA) += rtc.o +obj-$(CONFIG_AUDIT)	+= audit.o  ifdef CONFIG_ALPHA_GENERIC diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c index d96e742d4dc..f4c7ab6f43b 100644 --- a/arch/alpha/kernel/alpha_ksyms.c +++ b/arch/alpha/kernel/alpha_ksyms.c @@ -40,6 +40,7 @@ EXPORT_SYMBOL(strrchr);  EXPORT_SYMBOL(memmove);  EXPORT_SYMBOL(__memcpy);  EXPORT_SYMBOL(__memset); +EXPORT_SYMBOL(___memset);  EXPORT_SYMBOL(__memsetw);  EXPORT_SYMBOL(__constant_c_memset);  EXPORT_SYMBOL(copy_page); @@ -50,10 +51,6 @@ EXPORT_SYMBOL(alpha_read_fp_reg_s);  EXPORT_SYMBOL(alpha_write_fp_reg);  EXPORT_SYMBOL(alpha_write_fp_reg_s); -/* entry.S */ -EXPORT_SYMBOL(kernel_thread); -EXPORT_SYMBOL(kernel_execve); -  /* Networking helper routines. */  EXPORT_SYMBOL(csum_tcpudp_magic);  EXPORT_SYMBOL(ip_compute_csum); @@ -74,8 +71,6 @@ EXPORT_SYMBOL(alpha_fp_emul);   */  EXPORT_SYMBOL(__copy_user);  EXPORT_SYMBOL(__do_clear_user); -EXPORT_SYMBOL(__strncpy_from_user); -EXPORT_SYMBOL(__strnlen_user);  /*    * SMP-specific symbols. diff --git a/arch/alpha/kernel/audit.c b/arch/alpha/kernel/audit.c new file mode 100644 index 00000000000..96a9d18ff4c --- /dev/null +++ b/arch/alpha/kernel/audit.c @@ -0,0 +1,60 @@ +#include <linux/init.h> +#include <linux/types.h> +#include <linux/audit.h> +#include <asm/unistd.h> + +static unsigned dir_class[] = { +#include <asm-generic/audit_dir_write.h> +~0U +}; + +static unsigned read_class[] = { +#include <asm-generic/audit_read.h> +~0U +}; + +static unsigned write_class[] = { +#include <asm-generic/audit_write.h> +~0U +}; + +static unsigned chattr_class[] = { +#include <asm-generic/audit_change_attr.h> +~0U +}; + +static unsigned signal_class[] = { +#include <asm-generic/audit_signal.h> +~0U +}; + +int audit_classify_arch(int arch) +{ +	return 0; +} + +int audit_classify_syscall(int abi, unsigned syscall) +{ +	switch(syscall) { +	case __NR_open: +		return 2; +	case __NR_openat: +		return 3; +	case __NR_execve: +		return 5; +	default: +		return 0; +	} +} + +static int __init audit_classes_init(void) +{ +	audit_register_class(AUDIT_CLASS_WRITE, write_class); +	audit_register_class(AUDIT_CLASS_READ, read_class); +	audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class); +	audit_register_class(AUDIT_CLASS_CHATTR, chattr_class); +	audit_register_class(AUDIT_CLASS_SIGNAL, signal_class); +	return 0; +} + +__initcall(audit_classes_init); diff --git a/arch/alpha/kernel/binfmt_loader.c b/arch/alpha/kernel/binfmt_loader.c index 3fcfad41013..9525660c93c 100644 --- a/arch/alpha/kernel/binfmt_loader.c +++ b/arch/alpha/kernel/binfmt_loader.c @@ -5,7 +5,7 @@  #include <linux/binfmts.h>  #include <linux/a.out.h> -static int load_binary(struct linux_binprm *bprm, struct pt_regs *regs) +static int load_binary(struct linux_binprm *bprm)  {  	struct exec *eh = (struct exec *)bprm->buf;  	unsigned long loader; @@ -37,7 +37,7 @@ static int load_binary(struct linux_binprm *bprm, struct pt_regs *regs)  	retval = prepare_binprm(bprm);  	if (retval < 0)  		return retval; -	return search_binary_handler(bprm,regs); +	return search_binary_handler(bprm);  }  static struct linux_binfmt loader_format = { @@ -46,6 +46,7 @@ static struct linux_binfmt loader_format = {  static int __init init_loader_binfmt(void)  { -	return insert_binfmt(&loader_format); +	insert_binfmt(&loader_format); +	return 0;  }  arch_initcall(init_loader_binfmt); diff --git a/arch/alpha/kernel/console.c b/arch/alpha/kernel/console.c index da711e37fc9..6a61deed4a8 100644 --- a/arch/alpha/kernel/console.c +++ b/arch/alpha/kernel/console.c @@ -61,7 +61,9 @@ locate_and_init_vga(void *(*sel_func)(void *, void *))  	/* Set the VGA hose and init the new console. */  	pci_vga_hose = hose; -	take_over_console(&vga_con, 0, MAX_NR_CONSOLES-1, 1); +	console_lock(); +	do_take_over_console(&vga_con, 0, MAX_NR_CONSOLES-1, 1); +	console_unlock();  }  void __init diff --git a/arch/alpha/kernel/core_apecs.c b/arch/alpha/kernel/core_apecs.c index ca46b2c2445..708c831efa7 100644 --- a/arch/alpha/kernel/core_apecs.c +++ b/arch/alpha/kernel/core_apecs.c @@ -21,6 +21,7 @@  #include <asm/ptrace.h>  #include <asm/smp.h> +#include <asm/mce.h>  #include "proto.h"  #include "pci_impl.h" diff --git a/arch/alpha/kernel/core_cia.c b/arch/alpha/kernel/core_cia.c index 1d6ee6c985f..c44339e176c 100644 --- a/arch/alpha/kernel/core_cia.c +++ b/arch/alpha/kernel/core_cia.c @@ -23,6 +23,7 @@  #include <linux/bootmem.h>  #include <asm/ptrace.h> +#include <asm/mce.h>  #include "proto.h"  #include "pci_impl.h" diff --git a/arch/alpha/kernel/core_irongate.c b/arch/alpha/kernel/core_irongate.c index a872078497b..00096df0f6a 100644 --- a/arch/alpha/kernel/core_irongate.c +++ b/arch/alpha/kernel/core_irongate.c @@ -303,6 +303,7 @@ irongate_init_arch(void)  #include <linux/vmalloc.h>  #include <linux/agp_backend.h>  #include <linux/agpgart.h> +#include <linux/export.h>  #include <asm/pgalloc.h>  #define GET_PAGE_DIR_OFF(addr) (addr >> 22) diff --git a/arch/alpha/kernel/core_lca.c b/arch/alpha/kernel/core_lca.c index 4843f6ec9f3..cb2801cfd3d 100644 --- a/arch/alpha/kernel/core_lca.c +++ b/arch/alpha/kernel/core_lca.c @@ -133,7 +133,7 @@ conf_read(unsigned long addr)  	local_irq_save(flags); -	/* Reset status register to avoid loosing errors.  */ +	/* Reset status register to avoid losing errors.  */  	stat0 = *(vulp)LCA_IOC_STAT0;  	*(vulp)LCA_IOC_STAT0 = stat0;  	mb(); @@ -170,7 +170,7 @@ conf_write(unsigned long addr, unsigned int value)  	local_irq_save(flags);	/* avoid getting hit by machine check */ -	/* Reset status register to avoid loosing errors.  */ +	/* Reset status register to avoid losing errors.  */  	stat0 = *(vulp)LCA_IOC_STAT0;  	*(vulp)LCA_IOC_STAT0 = stat0;  	mb(); diff --git a/arch/alpha/kernel/core_mcpcia.c b/arch/alpha/kernel/core_mcpcia.c index 381fec0af52..da7bcc372f1 100644 --- a/arch/alpha/kernel/core_mcpcia.c +++ b/arch/alpha/kernel/core_mcpcia.c @@ -88,7 +88,7 @@ conf_read(unsigned long addr, unsigned char type1,  {  	unsigned long flags;  	unsigned long mid = MCPCIA_HOSE2MID(hose->index); -	unsigned int stat0, value, temp, cpu; +	unsigned int stat0, value, cpu;  	cpu = smp_processor_id(); @@ -101,7 +101,7 @@ conf_read(unsigned long addr, unsigned char type1,  	stat0 = *(vuip)MCPCIA_CAP_ERR(mid);  	*(vuip)MCPCIA_CAP_ERR(mid) = stat0;  	mb(); -	temp = *(vuip)MCPCIA_CAP_ERR(mid); +	*(vuip)MCPCIA_CAP_ERR(mid);  	DBG_CFG(("conf_read: MCPCIA_CAP_ERR(%d) was 0x%x\n", mid, stat0));  	mb(); @@ -136,7 +136,7 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1,  {  	unsigned long flags;  	unsigned long mid = MCPCIA_HOSE2MID(hose->index); -	unsigned int stat0, temp, cpu; +	unsigned int stat0, cpu;  	cpu = smp_processor_id(); @@ -145,7 +145,7 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1,  	/* Reset status register to avoid losing errors.  */  	stat0 = *(vuip)MCPCIA_CAP_ERR(mid);  	*(vuip)MCPCIA_CAP_ERR(mid) = stat0; mb(); -	temp = *(vuip)MCPCIA_CAP_ERR(mid); +	*(vuip)MCPCIA_CAP_ERR(mid);  	DBG_CFG(("conf_write: MCPCIA CAP_ERR(%d) was 0x%x\n", mid, stat0));  	draina(); @@ -157,7 +157,7 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1,  	*((vuip)addr) = value;  	mb();  	mb();  /* magic */ -	temp = *(vuip)MCPCIA_CAP_ERR(mid); /* read to force the write */ +	*(vuip)MCPCIA_CAP_ERR(mid); /* read to force the write */  	mcheck_expected(cpu) = 0;  	mb(); @@ -572,12 +572,10 @@ mcpcia_print_system_area(unsigned long la_ptr)  void  mcpcia_machine_check(unsigned long vector, unsigned long la_ptr)  { -	struct el_common *mchk_header;  	struct el_MCPCIA_uncorrected_frame_mcheck *mchk_logout;  	unsigned int cpu = smp_processor_id();  	int expected; -	mchk_header = (struct el_common *)la_ptr;  	mchk_logout = (struct el_MCPCIA_uncorrected_frame_mcheck *)la_ptr;  	expected = mcheck_expected(cpu); diff --git a/arch/alpha/kernel/core_t2.c b/arch/alpha/kernel/core_t2.c index 2f770e99428..3ada4f7b085 100644 --- a/arch/alpha/kernel/core_t2.c +++ b/arch/alpha/kernel/core_t2.c @@ -21,6 +21,7 @@  #include <asm/ptrace.h>  #include <asm/delay.h> +#include <asm/mce.h>  #include "proto.h"  #include "pci_impl.h" diff --git a/arch/alpha/kernel/core_tsunami.c b/arch/alpha/kernel/core_tsunami.c index 5e7c28f92f1..61893d7bdda 100644 --- a/arch/alpha/kernel/core_tsunami.c +++ b/arch/alpha/kernel/core_tsunami.c @@ -11,6 +11,7 @@  #include <asm/core_tsunami.h>  #undef __EXTERN_INLINE +#include <linux/module.h>  #include <linux/types.h>  #include <linux/pci.h>  #include <linux/sched.h> diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index 6d159cee5f2..98703d99b56 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S @@ -12,11 +12,32 @@  	.text  	.set noat +	.cfi_sections	.debug_frame  /* Stack offsets.  */  #define SP_OFF			184  #define SWITCH_STACK_SIZE	320 +.macro	CFI_START_OSF_FRAME	func +	.align	4 +	.globl	\func +	.type	\func,@function +\func: +	.cfi_startproc simple +	.cfi_return_column 64 +	.cfi_def_cfa	$sp, 48 +	.cfi_rel_offset	64, 8 +	.cfi_rel_offset	$gp, 16 +	.cfi_rel_offset	$16, 24 +	.cfi_rel_offset	$17, 32 +	.cfi_rel_offset	$18, 40 +.endm + +.macro	CFI_END_OSF_FRAME	func +	.cfi_endproc +	.size	\func, . - \func +.endm +  /*   * This defines the normal kernel pt-regs layout.   * @@ -27,100 +48,158 @@   * the palcode-provided values are available to the signal handler.   */ -#define SAVE_ALL			\ -	subq	$sp, SP_OFF, $sp;	\ -	stq	$0, 0($sp);		\ -	stq	$1, 8($sp);		\ -	stq	$2, 16($sp);		\ -	stq	$3, 24($sp);		\ -	stq	$4, 32($sp);		\ -	stq	$28, 144($sp);		\ -	lda	$2, alpha_mv;		\ -	stq	$5, 40($sp);		\ -	stq	$6, 48($sp);		\ -	stq	$7, 56($sp);		\ -	stq	$8, 64($sp);		\ -	stq	$19, 72($sp);		\ -	stq	$20, 80($sp);		\ -	stq	$21, 88($sp);		\ -	ldq	$2, HAE_CACHE($2);	\ -	stq	$22, 96($sp);		\ -	stq	$23, 104($sp);		\ -	stq	$24, 112($sp);		\ -	stq	$25, 120($sp);		\ -	stq	$26, 128($sp);		\ -	stq	$27, 136($sp);		\ -	stq	$2, 152($sp);		\ -	stq	$16, 160($sp);		\ -	stq	$17, 168($sp);		\ +.macro	SAVE_ALL +	subq	$sp, SP_OFF, $sp +	.cfi_adjust_cfa_offset	SP_OFF +	stq	$0, 0($sp) +	stq	$1, 8($sp) +	stq	$2, 16($sp) +	stq	$3, 24($sp) +	stq	$4, 32($sp) +	stq	$28, 144($sp) +	.cfi_rel_offset	$0, 0 +	.cfi_rel_offset $1, 8 +	.cfi_rel_offset	$2, 16 +	.cfi_rel_offset	$3, 24 +	.cfi_rel_offset	$4, 32 +	.cfi_rel_offset	$28, 144 +	lda	$2, alpha_mv +	stq	$5, 40($sp) +	stq	$6, 48($sp) +	stq	$7, 56($sp) +	stq	$8, 64($sp) +	stq	$19, 72($sp) +	stq	$20, 80($sp) +	stq	$21, 88($sp) +	ldq	$2, HAE_CACHE($2) +	stq	$22, 96($sp) +	stq	$23, 104($sp) +	stq	$24, 112($sp) +	stq	$25, 120($sp) +	stq	$26, 128($sp) +	stq	$27, 136($sp) +	stq	$2, 152($sp) +	stq	$16, 160($sp) +	stq	$17, 168($sp)  	stq	$18, 176($sp) - -#define RESTORE_ALL			\ -	lda	$19, alpha_mv;		\ -	ldq	$0, 0($sp);		\ -	ldq	$1, 8($sp);		\ -	ldq	$2, 16($sp);		\ -	ldq	$3, 24($sp);		\ -	ldq	$21, 152($sp);		\ -	ldq	$20, HAE_CACHE($19);	\ -	ldq	$4, 32($sp);		\ -	ldq	$5, 40($sp);		\ -	ldq	$6, 48($sp);		\ -	ldq	$7, 56($sp);		\ -	subq	$20, $21, $20;		\ -	ldq	$8, 64($sp);		\ -	beq	$20, 99f;		\ -	ldq	$20, HAE_REG($19);	\ -	stq	$21, HAE_CACHE($19);	\ -	stq	$21, 0($20);		\ -99:;					\ -	ldq	$19, 72($sp);		\ -	ldq	$20, 80($sp);		\ -	ldq	$21, 88($sp);		\ -	ldq	$22, 96($sp);		\ -	ldq	$23, 104($sp);		\ -	ldq	$24, 112($sp);		\ -	ldq	$25, 120($sp);		\ -	ldq	$26, 128($sp);		\ -	ldq	$27, 136($sp);		\ -	ldq	$28, 144($sp);		\ +	.cfi_rel_offset	$5, 40 +	.cfi_rel_offset	$6, 48 +	.cfi_rel_offset	$7, 56 +	.cfi_rel_offset	$8, 64 +	.cfi_rel_offset $19, 72 +	.cfi_rel_offset	$20, 80 +	.cfi_rel_offset	$21, 88 +	.cfi_rel_offset $22, 96 +	.cfi_rel_offset	$23, 104 +	.cfi_rel_offset	$24, 112 +	.cfi_rel_offset	$25, 120 +	.cfi_rel_offset	$26, 128 +	.cfi_rel_offset	$27, 136 +.endm + +.macro	RESTORE_ALL +	lda	$19, alpha_mv +	ldq	$0, 0($sp) +	ldq	$1, 8($sp) +	ldq	$2, 16($sp) +	ldq	$3, 24($sp) +	ldq	$21, 152($sp) +	ldq	$20, HAE_CACHE($19) +	ldq	$4, 32($sp) +	ldq	$5, 40($sp) +	ldq	$6, 48($sp) +	ldq	$7, 56($sp) +	subq	$20, $21, $20 +	ldq	$8, 64($sp) +	beq	$20, 99f +	ldq	$20, HAE_REG($19) +	stq	$21, HAE_CACHE($19) +	stq	$21, 0($20) +99:	ldq	$19, 72($sp) +	ldq	$20, 80($sp) +	ldq	$21, 88($sp) +	ldq	$22, 96($sp) +	ldq	$23, 104($sp) +	ldq	$24, 112($sp) +	ldq	$25, 120($sp) +	ldq	$26, 128($sp) +	ldq	$27, 136($sp) +	ldq	$28, 144($sp)  	addq	$sp, SP_OFF, $sp +	.cfi_restore	$0 +	.cfi_restore	$1 +	.cfi_restore	$2 +	.cfi_restore	$3 +	.cfi_restore	$4 +	.cfi_restore	$5 +	.cfi_restore	$6 +	.cfi_restore	$7 +	.cfi_restore	$8 +	.cfi_restore	$19 +	.cfi_restore	$20 +	.cfi_restore	$21 +	.cfi_restore	$22 +	.cfi_restore	$23 +	.cfi_restore	$24 +	.cfi_restore	$25 +	.cfi_restore	$26 +	.cfi_restore	$27 +	.cfi_restore	$28 +	.cfi_adjust_cfa_offset	-SP_OFF +.endm + +.macro	DO_SWITCH_STACK +	bsr	$1, do_switch_stack +	.cfi_adjust_cfa_offset	SWITCH_STACK_SIZE +	.cfi_rel_offset	$9, 0 +	.cfi_rel_offset	$10, 8 +	.cfi_rel_offset	$11, 16 +	.cfi_rel_offset	$12, 24 +	.cfi_rel_offset	$13, 32 +	.cfi_rel_offset	$14, 40 +	.cfi_rel_offset	$15, 48 +	/* We don't really care about the FP registers for debugging.  */ +.endm + +.macro	UNDO_SWITCH_STACK +	bsr	$1, undo_switch_stack +	.cfi_restore	$9 +	.cfi_restore	$10 +	.cfi_restore	$11 +	.cfi_restore	$12 +	.cfi_restore	$13 +	.cfi_restore	$14 +	.cfi_restore	$15 +	.cfi_adjust_cfa_offset	-SWITCH_STACK_SIZE +.endm  /*   * Non-syscall kernel entry points.   */ -	.align	4 -	.globl	entInt -	.ent	entInt -entInt: +CFI_START_OSF_FRAME entInt  	SAVE_ALL  	lda	$8, 0x3fff  	lda	$26, ret_from_sys_call  	bic	$sp, $8, $8  	mov	$sp, $19  	jsr	$31, do_entInt -.end entInt +CFI_END_OSF_FRAME entInt -	.align	4 -	.globl	entArith -	.ent	entArith -entArith: +CFI_START_OSF_FRAME entArith  	SAVE_ALL  	lda	$8, 0x3fff  	lda	$26, ret_from_sys_call  	bic	$sp, $8, $8  	mov	$sp, $18  	jsr	$31, do_entArith -.end entArith +CFI_END_OSF_FRAME entArith -	.align	4 -	.globl	entMM -	.ent	entMM -entMM: +CFI_START_OSF_FRAME entMM  	SAVE_ALL  /* save $9 - $15 so the inline exception code can manipulate them.  */  	subq	$sp, 56, $sp +	.cfi_adjust_cfa_offset	56  	stq	$9, 0($sp)  	stq	$10, 8($sp)  	stq	$11, 16($sp) @@ -128,6 +207,13 @@ entMM:  	stq	$13, 32($sp)  	stq	$14, 40($sp)  	stq	$15, 48($sp) +	.cfi_rel_offset	$9, 0 +	.cfi_rel_offset	$10, 8 +	.cfi_rel_offset	$11, 16 +	.cfi_rel_offset	$12, 24 +	.cfi_rel_offset	$13, 32 +	.cfi_rel_offset	$14, 40 +	.cfi_rel_offset	$15, 48  	addq	$sp, 56, $19  /* handle the fault */  	lda	$8, 0x3fff @@ -142,28 +228,33 @@ entMM:  	ldq	$14, 40($sp)  	ldq	$15, 48($sp)  	addq	$sp, 56, $sp +	.cfi_restore	$9 +	.cfi_restore	$10 +	.cfi_restore	$11 +	.cfi_restore	$12 +	.cfi_restore	$13 +	.cfi_restore	$14 +	.cfi_restore	$15 +	.cfi_adjust_cfa_offset	-56  /* finish up the syscall as normal.  */  	br	ret_from_sys_call -.end entMM +CFI_END_OSF_FRAME entMM -	.align	4 -	.globl	entIF -	.ent	entIF -entIF: +CFI_START_OSF_FRAME entIF  	SAVE_ALL  	lda	$8, 0x3fff  	lda	$26, ret_from_sys_call  	bic	$sp, $8, $8  	mov	$sp, $17  	jsr	$31, do_entIF -.end entIF +CFI_END_OSF_FRAME entIF -	.align	4 -	.globl	entUna -	.ent	entUna -entUna: +CFI_START_OSF_FRAME entUna  	lda	$sp, -256($sp) +	.cfi_adjust_cfa_offset	256  	stq	$0, 0($sp) +	.cfi_rel_offset	$0, 0 +	.cfi_remember_state  	ldq	$0, 256($sp)	/* get PS */  	stq	$1, 8($sp)  	stq	$2, 16($sp) @@ -195,6 +286,32 @@ entUna:  	stq	$28, 224($sp)  	mov	$sp, $19  	stq	$gp, 232($sp) +	.cfi_rel_offset	$1, 1*8 +	.cfi_rel_offset	$2, 2*8 +	.cfi_rel_offset	$3, 3*8 +	.cfi_rel_offset	$4, 4*8 +	.cfi_rel_offset	$5, 5*8 +	.cfi_rel_offset	$6, 6*8 +	.cfi_rel_offset	$7, 7*8 +	.cfi_rel_offset	$8, 8*8 +	.cfi_rel_offset	$9, 9*8 +	.cfi_rel_offset	$10, 10*8 +	.cfi_rel_offset	$11, 11*8 +	.cfi_rel_offset	$12, 12*8 +	.cfi_rel_offset	$13, 13*8 +	.cfi_rel_offset	$14, 14*8 +	.cfi_rel_offset	$15, 15*8 +	.cfi_rel_offset	$19, 19*8 +	.cfi_rel_offset	$20, 20*8 +	.cfi_rel_offset	$21, 21*8 +	.cfi_rel_offset	$22, 22*8 +	.cfi_rel_offset	$23, 23*8 +	.cfi_rel_offset	$24, 24*8 +	.cfi_rel_offset	$25, 25*8 +	.cfi_rel_offset	$26, 26*8 +	.cfi_rel_offset	$27, 27*8 +	.cfi_rel_offset	$28, 28*8 +	.cfi_rel_offset	$29, 29*8  	lda	$8, 0x3fff  	stq	$31, 248($sp)  	bic	$sp, $8, $8 @@ -228,16 +345,45 @@ entUna:  	ldq	$28, 224($sp)  	ldq	$gp, 232($sp)  	lda	$sp, 256($sp) +	.cfi_restore	$1 +	.cfi_restore	$2 +	.cfi_restore	$3 +	.cfi_restore	$4 +	.cfi_restore	$5 +	.cfi_restore	$6 +	.cfi_restore	$7 +	.cfi_restore	$8 +	.cfi_restore	$9 +	.cfi_restore	$10 +	.cfi_restore	$11 +	.cfi_restore	$12 +	.cfi_restore	$13 +	.cfi_restore	$14 +	.cfi_restore	$15 +	.cfi_restore	$19 +	.cfi_restore	$20 +	.cfi_restore	$21 +	.cfi_restore	$22 +	.cfi_restore	$23 +	.cfi_restore	$24 +	.cfi_restore	$25 +	.cfi_restore	$26 +	.cfi_restore	$27 +	.cfi_restore	$28 +	.cfi_restore	$29 +	.cfi_adjust_cfa_offset	-256  	call_pal PAL_rti -.end entUna  	.align	4 -	.ent	entUnaUser  entUnaUser: +	.cfi_restore_state  	ldq	$0, 0($sp)	/* restore original $0 */  	lda	$sp, 256($sp)	/* pop entUna's stack frame */ +	.cfi_restore	$0 +	.cfi_adjust_cfa_offset	-256  	SAVE_ALL		/* setup normal kernel stack */  	lda	$sp, -56($sp) +	.cfi_adjust_cfa_offset	56  	stq	$9, 0($sp)  	stq	$10, 8($sp)  	stq	$11, 16($sp) @@ -245,6 +391,13 @@ entUnaUser:  	stq	$13, 32($sp)  	stq	$14, 40($sp)  	stq	$15, 48($sp) +	.cfi_rel_offset	$9, 0 +	.cfi_rel_offset	$10, 8 +	.cfi_rel_offset	$11, 16 +	.cfi_rel_offset	$12, 24 +	.cfi_rel_offset	$13, 32 +	.cfi_rel_offset	$14, 40 +	.cfi_rel_offset	$15, 48  	lda	$8, 0x3fff  	addq	$sp, 56, $19  	bic	$sp, $8, $8 @@ -257,20 +410,25 @@ entUnaUser:  	ldq	$14, 40($sp)  	ldq	$15, 48($sp)  	lda	$sp, 56($sp) +	.cfi_restore	$9 +	.cfi_restore	$10 +	.cfi_restore	$11 +	.cfi_restore	$12 +	.cfi_restore	$13 +	.cfi_restore	$14 +	.cfi_restore	$15 +	.cfi_adjust_cfa_offset	-56  	br	ret_from_sys_call -.end entUnaUser +CFI_END_OSF_FRAME entUna -	.align	4 -	.globl	entDbg -	.ent	entDbg -entDbg: +CFI_START_OSF_FRAME entDbg  	SAVE_ALL  	lda	$8, 0x3fff  	lda	$26, ret_from_sys_call  	bic	$sp, $8, $8  	mov	$sp, $16  	jsr	$31, do_entDbg -.end entDbg +CFI_END_OSF_FRAME entDbg  /*   * The system call entry point is special.  Most importantly, it looks @@ -285,8 +443,12 @@ entDbg:  	.align	4  	.globl	entSys -	.globl	ret_from_sys_call -	.ent	entSys +	.type	entSys, @function +	.cfi_startproc simple +	.cfi_return_column 64 +	.cfi_def_cfa	$sp, 48 +	.cfi_rel_offset	64, 8 +	.cfi_rel_offset	$gp, 16  entSys:  	SAVE_ALL  	lda	$8, 0x3fff @@ -300,7 +462,14 @@ entSys:  	stq	$17, SP_OFF+32($sp)  	s8addq	$0, $5, $5  	stq	$18, SP_OFF+40($sp) -	blbs	$3, strace +	.cfi_rel_offset	$16, SP_OFF+24 +	.cfi_rel_offset	$17, SP_OFF+32 +	.cfi_rel_offset	$18, SP_OFF+40 +#ifdef CONFIG_AUDITSYSCALL +	lda     $6, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT +	and     $3, $6, $3 +#endif +	bne     $3, strace  	beq	$4, 1f  	ldq	$27, 0($5)  1:	jsr	$26, ($27), alpha_ni_syscall @@ -310,8 +479,9 @@ entSys:  	stq	$31, 72($sp)		/* a3=0 => no error */  	.align	4 +	.globl	ret_from_sys_call  ret_from_sys_call: -	cmovne	$26, 0, $19		/* $19 = 0 => non-restartable */ +	cmovne	$26, 0, $18		/* $18 = 0 => non-restartable */  	ldq	$0, SP_OFF($sp)  	and	$0, 8, $0  	beq	$0, ret_to_kernel @@ -320,14 +490,16 @@ ret_to_user:  		sampling and the rti.  */  	lda	$16, 7  	call_pal PAL_swpipl -	ldl	$5, TI_FLAGS($8) -	and	$5, _TIF_WORK_MASK, $2 +	ldl	$17, TI_FLAGS($8) +	and	$17, _TIF_WORK_MASK, $2  	bne	$2, work_pending  restore_all: +	.cfi_remember_state  	RESTORE_ALL  	call_pal PAL_rti  ret_to_kernel: +	.cfi_restore_state  	lda	$16, 7  	call_pal PAL_swpipl  	br restore_all @@ -341,10 +513,10 @@ $syscall_error:  	 * frame to indicate that a negative return value wasn't an  	 * error number..  	 */ -	ldq	$19, 0($sp)	/* old syscall nr (zero if success) */ -	beq	$19, $ret_success +	ldq	$18, 0($sp)	/* old syscall nr (zero if success) */ +	beq	$18, $ret_success -	ldq	$20, 72($sp)	/* .. and this a3 */ +	ldq	$19, 72($sp)	/* .. and this a3 */  	subq	$31, $0, $0	/* with error in v0 */  	addq	$31, 1, $1	/* set a3 for errno return */  	stq	$0, 0($sp) @@ -356,73 +528,54 @@ $ret_success:  	stq	$0, 0($sp)  	stq	$31, 72($sp)	/* a3=0 => no error */  	br	ret_from_sys_call -.end entSys  /*   * Do all cleanup when returning from all interrupts and system calls.   *   * Arguments: - *       $5: TI_FLAGS.   *       $8: current. - *      $19: The old syscall number, or zero if this is not a return + *      $17: TI_FLAGS. + *      $18: The old syscall number, or zero if this is not a return   *           from a syscall that errored and is possibly restartable. - *      $20: The old a3 value + *      $19: The old a3 value   */  	.align	4 -	.ent	work_pending +	.type	work_pending, @function  work_pending: -	and	$5, _TIF_NEED_RESCHED, $2 -	beq	$2, $work_notifysig +	and	$17, _TIF_NOTIFY_RESUME | _TIF_SIGPENDING, $2 +	bne	$2, $work_notifysig  $work_resched: -	subq	$sp, 16, $sp -	stq	$19, 0($sp)              /* save syscall nr */ -	stq	$20, 8($sp)              /* and error indication (a3) */ +	/* +	 * We can get here only if we returned from syscall without SIGPENDING +	 * or got through work_notifysig already.  Either case means no syscall +	 * restarts for us, so let $18 and $19 burn. +	 */  	jsr	$26, schedule -	ldq	$19, 0($sp) -	ldq	$20, 8($sp) -	addq	$sp, 16, $sp -	/* Make sure need_resched and sigpending don't change between -		sampling and the rti.  */ -	lda	$16, 7 -	call_pal PAL_swpipl -	ldl	$5, TI_FLAGS($8) -	and	$5, _TIF_WORK_MASK, $2 -	beq	$2, restore_all -	and	$5, _TIF_NEED_RESCHED, $2 -	bne	$2, $work_resched +	mov	0, $18 +	br	ret_to_user  $work_notifysig:  	mov	$sp, $16 -	bsr	$1, do_switch_stack -	mov	$sp, $17 -	mov	$5, $18 -	mov	$19, $9		/* save old syscall number */ -	mov	$20, $10	/* save old a3 */ -	and	$5, _TIF_SIGPENDING, $2 -	cmovne	$2, 0, $9	/* we don't want double syscall restarts */ -	jsr	$26, do_notify_resume -	mov	$9, $19 -	mov	$10, $20 -	bsr	$1, undo_switch_stack -	br	ret_to_user -.end work_pending +	DO_SWITCH_STACK +	jsr	$26, do_work_pending +	UNDO_SWITCH_STACK +	br	restore_all  /*   * PTRACE syscall handler   */  	.align	4 -	.ent	strace +	.type	strace, @function  strace:  	/* set up signal stack, call syscall_trace */ -	bsr	$1, do_switch_stack -	jsr	$26, syscall_trace -	bsr	$1, undo_switch_stack +	DO_SWITCH_STACK +	jsr	$26, syscall_trace_enter /* returns the syscall number */ +	UNDO_SWITCH_STACK -	/* get the system call number and the arguments back.. */ -	ldq	$0, 0($sp) +	/* get the arguments back.. */  	ldq	$16, SP_OFF+24($sp)  	ldq	$17, SP_OFF+32($sp)  	ldq	$18, SP_OFF+40($sp) @@ -448,42 +601,47 @@ ret_from_straced:  $strace_success:  	stq	$0, 0($sp)		/* save return value */ -	bsr	$1, do_switch_stack -	jsr	$26, syscall_trace -	bsr	$1, undo_switch_stack +	DO_SWITCH_STACK +	jsr	$26, syscall_trace_leave +	UNDO_SWITCH_STACK  	br	$31, ret_from_sys_call  	.align	3  $strace_error: -	ldq	$19, 0($sp)	/* old syscall nr (zero if success) */ -	beq	$19, $strace_success -	ldq	$20, 72($sp)	/* .. and this a3 */ +	ldq	$18, 0($sp)	/* old syscall nr (zero if success) */ +	beq	$18, $strace_success +	ldq	$19, 72($sp)	/* .. and this a3 */  	subq	$31, $0, $0	/* with error in v0 */  	addq	$31, 1, $1	/* set a3 for errno return */  	stq	$0, 0($sp)  	stq	$1, 72($sp)	/* a3 for return */ -	bsr	$1, do_switch_stack -	mov	$19, $9		/* save old syscall number */ -	mov	$20, $10	/* save old a3 */ -	jsr	$26, syscall_trace -	mov	$9, $19 -	mov	$10, $20 -	bsr	$1, undo_switch_stack +	DO_SWITCH_STACK +	mov	$18, $9		/* save old syscall number */ +	mov	$19, $10	/* save old a3 */ +	jsr	$26, syscall_trace_leave +	mov	$9, $18 +	mov	$10, $19 +	UNDO_SWITCH_STACK  	mov	$31, $26	/* tell "ret_from_sys_call" we can restart */  	br	ret_from_sys_call -.end strace +CFI_END_OSF_FRAME entSys  /*   * Save and restore the switch stack -- aka the balance of the user context.   */  	.align	4 -	.ent	do_switch_stack +	.type	do_switch_stack, @function +	.cfi_startproc simple +	.cfi_return_column 64 +	.cfi_def_cfa $sp, 0 +	.cfi_register 64, $1  do_switch_stack:  	lda	$sp, -SWITCH_STACK_SIZE($sp) +	.cfi_adjust_cfa_offset	SWITCH_STACK_SIZE  	stq	$9, 0($sp)  	stq	$10, 8($sp)  	stq	$11, 16($sp) @@ -527,10 +685,14 @@ do_switch_stack:  	stt	$f0, 312($sp)	# save fpcr in slot of $f31  	ldt	$f0, 64($sp)	# dont let "do_switch_stack" change fp state.  	ret	$31, ($1), 1 -.end do_switch_stack +	.cfi_endproc +	.size	do_switch_stack, .-do_switch_stack  	.align	4 -	.ent	undo_switch_stack +	.type	undo_switch_stack, @function +	.cfi_startproc simple +	.cfi_def_cfa $sp, 0 +	.cfi_register 64, $1  undo_switch_stack:  	ldq	$9, 0($sp)  	ldq	$10, 8($sp) @@ -575,7 +737,8 @@ undo_switch_stack:  	ldt	$f30, 304($sp)  	lda	$sp, SWITCH_STACK_SIZE($sp)  	ret	$31, ($1), 1 -.end undo_switch_stack +	.cfi_endproc +	.size	undo_switch_stack, .-undo_switch_stack  /*   * The meat of the context switch code. @@ -583,17 +746,18 @@ undo_switch_stack:  	.align	4  	.globl	alpha_switch_to -	.ent	alpha_switch_to +	.type	alpha_switch_to, @function +	.cfi_startproc  alpha_switch_to: -	.prologue 0 -	bsr	$1, do_switch_stack +	DO_SWITCH_STACK  	call_pal PAL_swpctx  	lda	$8, 0x3fff -	bsr	$1, undo_switch_stack +	UNDO_SWITCH_STACK  	bic	$sp, $8, $8  	mov	$17, $0  	ret -.end alpha_switch_to +	.cfi_endproc +	.size	alpha_switch_to, .-alpha_switch_to  /*   * New processes begin life here. @@ -609,158 +773,44 @@ ret_from_fork:  .end ret_from_fork  /* - * kernel_thread(fn, arg, clone_flags) + * ... and new kernel threads - here   */  	.align 4 -	.globl	kernel_thread -	.ent	kernel_thread -kernel_thread: -	/* We can be called from a module.  */ -	ldgp	$gp, 0($27) -	.prologue 1 -	subq	$sp, SP_OFF+6*8, $sp -	br	$1, 2f		/* load start address */ - -	/* We've now "returned" from a fake system call.  */ -	unop -	blt	$0, 1f		/* error?  */ -	ldi	$1, 0x3fff -	beq	$20, 1f		/* parent or child?  */ - -	bic	$sp, $1, $8	/* in child.  */ -	jsr	$26, ($27) -	ldgp	$gp, 0($26) -	mov	$0, $16 -	mov	$31, $26 -	jmp	$31, sys_exit - -1:	ret			/* in parent.  */ - -	.align 4 -2:	/* Fake a system call stack frame, as we can't do system calls -	   from kernel space.  Note that we store FN and ARG as they -	   need to be set up in the child for the call.  Also store $8 -	   and $26 for use in the parent.  */ -	stq	$31, SP_OFF($sp)	/* ps */ -	stq	$1, SP_OFF+8($sp)	/* pc */ -	stq	$gp, SP_OFF+16($sp)	/* gp */ -	stq	$16, 136($sp)		/* $27; FN for child */ -	stq	$17, SP_OFF+24($sp)	/* $16; ARG for child */ -	stq	$8, 64($sp)		/* $8 */ -	stq	$26, 128($sp)		/* $26 */ -	/* Avoid the HAE being gratuitously wrong, to avoid restoring it.  */ -	ldq	$2, alpha_mv+HAE_CACHE -	stq	$2, 152($sp)		/* HAE */ - -	/* Shuffle FLAGS to the front; add CLONE_VM.  */ -	ldi	$1, CLONE_VM|CLONE_UNTRACED -	or	$18, $1, $16 -	bsr	$26, sys_clone - -	/* We don't actually care for a3 success widgetry in the kernel. -	   Not for positive errno values.  */ -	stq	$0, 0($sp)		/* $0 */ -	br	ret_to_kernel -.end kernel_thread - -/* - * kernel_execve(path, argv, envp) - */ -	.align	4 -	.globl	kernel_execve -	.ent	kernel_execve -kernel_execve: -	/* We can be called from a module.  */ -	ldgp	$gp, 0($27) -	lda	$sp, -(32+SIZEOF_PT_REGS+8)($sp) -	.frame	$sp, 32+SIZEOF_PT_REGS+8, $26, 0 -	stq	$26, 0($sp) -	stq	$16, 8($sp) -	stq	$17, 16($sp) -	stq	$18, 24($sp) -	.prologue 1 - -	lda	$16, 32($sp) -	lda	$17, 0 -	lda	$18, SIZEOF_PT_REGS -	bsr	$26, memset		!samegp - -	/* Avoid the HAE being gratuitously wrong, which would cause us -	   to do the whole turn off interrupts thing and restore it.  */ -	ldq	$2, alpha_mv+HAE_CACHE -	stq	$2, 152+32($sp) - -	ldq	$16, 8($sp) -	ldq	$17, 16($sp) -	ldq	$18, 24($sp) -	lda	$19, 32($sp) -	bsr	$26, do_execve		!samegp - -	ldq	$26, 0($sp) -	bne	$0, 1f			/* error! */ - -	/* Move the temporary pt_regs struct from its current location -	   to the top of the kernel stack frame.  See copy_thread for -	   details for a normal process.  */ -	lda	$16, 0x4000 - SIZEOF_PT_REGS($8) -	lda	$17, 32($sp) -	lda	$18, SIZEOF_PT_REGS -	bsr	$26, memmove		!samegp - -	/* Take that over as our new stack frame and visit userland!  */ -	lda	$sp, 0x4000 - SIZEOF_PT_REGS($8) -	br	$31, ret_from_sys_call - -1:	lda	$sp, 32+SIZEOF_PT_REGS+8($sp) -	ret -.end kernel_execve +	.globl	ret_from_kernel_thread +	.ent	ret_from_kernel_thread +ret_from_kernel_thread: +	mov	$17, $16 +	jsr	$26, schedule_tail +	mov	$9, $27 +	mov	$10, $16 +	jsr	$26, ($9) +	mov	$31, $19		/* to disable syscall restarts */ +	br	$31, ret_to_user +.end ret_from_kernel_thread  /*   * Special system calls.  Most of these are special in that they either   * have to play switch_stack games or in some way use the pt_regs struct.   */ -	.align	4 -	.globl	sys_fork -	.ent	sys_fork -sys_fork: -	.prologue 0 -	mov	$sp, $21 -	bsr	$1, do_switch_stack -	bis	$31, SIGCHLD, $16 -	mov	$31, $17 -	mov	$31, $18 -	mov	$31, $19 -	mov	$31, $20 -	jsr	$26, alpha_clone -	bsr	$1, undo_switch_stack -	ret -.end sys_fork +.macro	fork_like name  	.align	4 -	.globl	sys_clone -	.ent	sys_clone -sys_clone: +	.globl	alpha_\name +	.ent	alpha_\name +alpha_\name:  	.prologue 0 -	mov	$sp, $21  	bsr	$1, do_switch_stack -	/* $16, $17, $18, $19, $20 come from the user.  */ -	jsr	$26, alpha_clone -	bsr	$1, undo_switch_stack +	jsr	$26, sys_\name +	ldq	$26, 56($sp) +	lda	$sp, SWITCH_STACK_SIZE($sp)  	ret -.end sys_clone +.end	alpha_\name +.endm -	.align	4 -	.globl	sys_vfork -	.ent	sys_vfork -sys_vfork: -	.prologue 0 -	mov	$sp, $16 -	bsr	$1, do_switch_stack -	jsr	$26, alpha_vfork -	bsr	$1, undo_switch_stack -	ret -.end sys_vfork +fork_like fork +fork_like vfork +fork_like clone  	.align	4  	.globl	sys_sigreturn @@ -769,12 +819,10 @@ sys_sigreturn:  	.prologue 0  	lda	$9, ret_from_straced  	cmpult	$26, $9, $9 -	mov	$sp, $17 -	lda	$18, -SWITCH_STACK_SIZE($sp)  	lda	$sp, -SWITCH_STACK_SIZE($sp)  	jsr	$26, do_sigreturn  	bne	$9, 1f -	jsr	$26, syscall_trace +	jsr	$26, syscall_trace_leave  1:	br	$1, undo_switch_stack  	br	ret_from_sys_call  .end sys_sigreturn @@ -786,135 +834,15 @@ sys_rt_sigreturn:  	.prologue 0  	lda	$9, ret_from_straced  	cmpult	$26, $9, $9 -	mov	$sp, $17 -	lda	$18, -SWITCH_STACK_SIZE($sp)  	lda	$sp, -SWITCH_STACK_SIZE($sp)  	jsr	$26, do_rt_sigreturn  	bne	$9, 1f -	jsr	$26, syscall_trace +	jsr	$26, syscall_trace_leave  1:	br	$1, undo_switch_stack  	br	ret_from_sys_call  .end sys_rt_sigreturn  	.align	4 -	.globl	sys_sethae -	.ent	sys_sethae -sys_sethae: -	.prologue 0 -	stq	$16, 152($sp) -	ret -.end sys_sethae - -	.align	4 -	.globl	osf_getpriority -	.ent	osf_getpriority -osf_getpriority: -	lda	$sp, -16($sp) -	stq	$26, 0($sp) -	.prologue 0 - -	jsr	$26, sys_getpriority - -	ldq	$26, 0($sp) -	blt	$0, 1f - -	/* Return value is the unbiased priority, i.e. 20 - prio. -	   This does result in negative return values, so signal -	   no error by writing into the R0 slot.  */ -	lda	$1, 20 -	stq	$31, 16($sp) -	subl	$1, $0, $0 -	unop - -1:	lda	$sp, 16($sp) -	ret -.end osf_getpriority - -	.align	4 -	.globl	sys_getxuid -	.ent	sys_getxuid -sys_getxuid: -	.prologue 0 -	ldq	$2, TI_TASK($8) -	ldq	$3, TASK_CRED($2) -	ldl	$0, CRED_UID($3) -	ldl	$1, CRED_EUID($3) -	stq	$1, 80($sp) -	ret -.end sys_getxuid - -	.align	4 -	.globl	sys_getxgid -	.ent	sys_getxgid -sys_getxgid: -	.prologue 0 -	ldq	$2, TI_TASK($8) -	ldq	$3, TASK_CRED($2) -	ldl	$0, CRED_GID($3) -	ldl	$1, CRED_EGID($3) -	stq	$1, 80($sp) -	ret -.end sys_getxgid - -	.align	4 -	.globl	sys_getxpid -	.ent	sys_getxpid -sys_getxpid: -	.prologue 0 -	ldq	$2, TI_TASK($8) - -	/* See linux/kernel/timer.c sys_getppid for discussion -	   about this loop.  */ -	ldq	$3, TASK_GROUP_LEADER($2) -	ldq	$4, TASK_REAL_PARENT($3) -	ldl	$0, TASK_TGID($2) -1:	ldl	$1, TASK_TGID($4) -#ifdef CONFIG_SMP -	mov	$4, $5 -	mb -	ldq	$3, TASK_GROUP_LEADER($2) -	ldq	$4, TASK_REAL_PARENT($3) -	cmpeq	$4, $5, $5 -	beq	$5, 1b -#endif -	stq	$1, 80($sp) -	ret -.end sys_getxpid - -	.align	4 -	.globl	sys_alpha_pipe -	.ent	sys_alpha_pipe -sys_alpha_pipe: -	lda	$sp, -16($sp) -	stq	$26, 0($sp) -	.prologue 0 - -	mov	$31, $17 -	lda	$16, 8($sp) -	jsr	$26, do_pipe_flags - -	ldq	$26, 0($sp) -	bne	$0, 1f - -	/* The return values are in $0 and $20.  */ -	ldl	$1, 12($sp) -	ldl	$0, 8($sp) - -	stq	$1, 80+16($sp) -1:	lda	$sp, 16($sp) -	ret -.end sys_alpha_pipe - -	.align	4 -	.globl	sys_execve -	.ent	sys_execve -sys_execve: -	.prologue 0 -	mov	$sp, $19 -	jmp	$31, do_sys_execve -.end sys_execve - -	.align	4  	.globl	alpha_ni_syscall  	.ent	alpha_ni_syscall  alpha_ni_syscall: diff --git a/arch/alpha/kernel/err_impl.h b/arch/alpha/kernel/err_impl.h index 0c010ca4611..ae529c41603 100644 --- a/arch/alpha/kernel/err_impl.h +++ b/arch/alpha/kernel/err_impl.h @@ -7,6 +7,8 @@   * 	implementations.   */ +#include <asm/mce.h> +  union el_timestamp;  struct el_subpacket;  struct ev7_lf_subpackets; diff --git a/arch/alpha/kernel/err_marvel.c b/arch/alpha/kernel/err_marvel.c index 648ae88aeb8..ae54ad91e18 100644 --- a/arch/alpha/kernel/err_marvel.c +++ b/arch/alpha/kernel/err_marvel.c @@ -1027,7 +1027,7 @@ marvel_process_logout_frame(struct ev7_lf_subpackets *lf_subpackets, int print)  	 * normal operation, dismiss them.  	 *  	 * Dismiss if: -	 *	C_STAT		= 0x14 		(Error Reponse) +	 *	C_STAT		= 0x14 		(Error Response)  	 *	C_STS<3>	= 0    		(C_ADDR valid)  	 *	C_ADDR<42>	= 1    		(I/O)  	 *	C_ADDR<31:22>	= 111110xxb	(PCI Config space) diff --git a/arch/alpha/kernel/err_titan.c b/arch/alpha/kernel/err_titan.c index c3b3781a03d..14b26c466c8 100644 --- a/arch/alpha/kernel/err_titan.c +++ b/arch/alpha/kernel/err_titan.c @@ -533,8 +533,6 @@ static struct el_subpacket_annotation el_titan_annotations[] = {  static struct el_subpacket *  el_process_regatta_subpacket(struct el_subpacket *header)  { -	int status; -  	if (header->class != EL_CLASS__REGATTA_FAMILY) {  		printk("%s  ** Unexpected header CLASS %d TYPE %d, aborting\n",  		       err_print_prefix, @@ -551,7 +549,7 @@ el_process_regatta_subpacket(struct el_subpacket *header)  		printk("%s  ** Occurred on CPU %d:\n",   		       err_print_prefix,  		       (int)header->by_type.regatta_frame.cpuid); -		status = privateer_process_logout_frame((struct el_common *) +		privateer_process_logout_frame((struct el_common *)  			header->by_type.regatta_frame.data_start, 1);  		break;  	default: diff --git a/arch/alpha/kernel/head.S b/arch/alpha/kernel/head.S index 4bdd1d2ff35..c352499ab9f 100644 --- a/arch/alpha/kernel/head.S +++ b/arch/alpha/kernel/head.S @@ -8,14 +8,12 @@   */  #include <linux/init.h> -#include <asm/system.h>  #include <asm/asm-offsets.h> +#include <asm/pal.h> +#include <asm/setup.h>  __HEAD -.globl swapper_pg_dir  .globl _stext -swapper_pg_dir=SWAPPER_PGD -  	.set noreorder  	.globl	__start  	.ent	__start diff --git a/arch/alpha/kernel/init_task.c b/arch/alpha/kernel/init_task.c deleted file mode 100644 index 6f80ca4f976..00000000000 --- a/arch/alpha/kernel/init_task.c +++ /dev/null @@ -1,17 +0,0 @@ -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/sched.h> -#include <linux/init.h> -#include <linux/init_task.h> -#include <linux/fs.h> -#include <linux/mqueue.h> -#include <asm/uaccess.h> - - -static struct signal_struct init_signals = INIT_SIGNALS(init_signals); -static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); -struct task_struct init_task = INIT_TASK(init_task); -EXPORT_SYMBOL(init_task); - -union thread_union init_thread_union __init_task_data = -	{ INIT_THREAD_INFO(init_task) }; diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c index fe912984d9b..7b2be251c30 100644 --- a/arch/alpha/kernel/irq.c +++ b/arch/alpha/kernel/irq.c @@ -26,7 +26,6 @@  #include <linux/profile.h>  #include <linux/bitops.h> -#include <asm/system.h>  #include <asm/io.h>  #include <asm/uaccess.h> @@ -44,10 +43,16 @@ static char irq_user_affinity[NR_IRQS];  int irq_select_affinity(unsigned int irq)  { +	struct irq_data *data = irq_get_irq_data(irq); +	struct irq_chip *chip;  	static int last_cpu;  	int cpu = last_cpu + 1; -	if (!irq_desc[irq].chip->set_affinity || irq_user_affinity[irq]) +	if (!data) +		return 1; +	chip = irq_data_get_irq_chip(data); + +	if (!chip->irq_set_affinity || irq_user_affinity[irq])  		return 1;  	while (!cpu_possible(cpu) || @@ -55,68 +60,27 @@ int irq_select_affinity(unsigned int irq)  		cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0);  	last_cpu = cpu; -	cpumask_copy(irq_desc[irq].affinity, cpumask_of(cpu)); -	irq_desc[irq].chip->set_affinity(irq, cpumask_of(cpu)); +	cpumask_copy(data->affinity, cpumask_of(cpu)); +	chip->irq_set_affinity(data, cpumask_of(cpu), false);  	return 0;  }  #endif /* CONFIG_SMP */ -int -show_interrupts(struct seq_file *p, void *v) +int arch_show_interrupts(struct seq_file *p, int prec)  {  	int j; -	int irq = *(loff_t *) v; -	struct irqaction * action; -	unsigned long flags;  #ifdef CONFIG_SMP -	if (irq == 0) { -		seq_puts(p, "           "); -		for_each_online_cpu(j) -			seq_printf(p, "CPU%d       ", j); -		seq_putc(p, '\n'); -	} -#endif - -	if (irq < ACTUAL_NR_IRQS) { -		raw_spin_lock_irqsave(&irq_desc[irq].lock, flags); -		action = irq_desc[irq].action; -		if (!action)  -			goto unlock; -		seq_printf(p, "%3d: ", irq); -#ifndef CONFIG_SMP -		seq_printf(p, "%10u ", kstat_irqs(irq)); -#else -		for_each_online_cpu(j) -			seq_printf(p, "%10u ", kstat_irqs_cpu(irq, j)); +	seq_puts(p, "IPI: "); +	for_each_online_cpu(j) +		seq_printf(p, "%10lu ", cpu_data[j].ipi_count); +	seq_putc(p, '\n');  #endif -		seq_printf(p, " %14s", irq_desc[irq].chip->name); -		seq_printf(p, "  %c%s", -			(action->flags & IRQF_DISABLED)?'+':' ', -			action->name); - -		for (action=action->next; action; action = action->next) { -			seq_printf(p, ", %c%s", -				  (action->flags & IRQF_DISABLED)?'+':' ', -				   action->name); -		} - -		seq_putc(p, '\n'); -unlock: -		raw_spin_unlock_irqrestore(&irq_desc[irq].lock, flags); -	} else if (irq == ACTUAL_NR_IRQS) { -#ifdef CONFIG_SMP -		seq_puts(p, "IPI: "); -		for_each_online_cpu(j) -			seq_printf(p, "%10lu ", cpu_data[j].ipi_count); -		seq_putc(p, '\n'); -#endif -		seq_puts(p, "PMI: "); -		for_each_online_cpu(j) -			seq_printf(p, "%10lu ", per_cpu(irq_pmi_count, j)); -		seq_puts(p, "          Performance Monitoring\n"); -		seq_printf(p, "ERR: %10lu\n", irq_err_count); -	} +	seq_puts(p, "PMI: "); +	for_each_online_cpu(j) +		seq_printf(p, "%10lu ", per_cpu(irq_pmi_count, j)); +	seq_puts(p, "          Performance Monitoring\n"); +	seq_printf(p, "ERR: %10lu\n", irq_err_count);  	return 0;  } @@ -142,8 +106,10 @@ handle_irq(int irq)  	 * handled by some other CPU. (or is disabled)  	 */  	static unsigned int illegal_count=0; +	struct irq_desc *desc = irq_to_desc(irq); -	if ((unsigned) irq > ACTUAL_NR_IRQS && illegal_count < MAX_ILLEGAL_IRQS ) { +	if (!desc || ((unsigned) irq > ACTUAL_NR_IRQS && +	    illegal_count < MAX_ILLEGAL_IRQS)) {  		irq_err_count++;  		illegal_count++;  		printk(KERN_CRIT "device_interrupt: invalid interrupt %d\n", @@ -152,13 +118,6 @@ handle_irq(int irq)  	}  	irq_enter(); -	/* -	 * __do_IRQ() must be called with IPL_MAX. Note that we do not -	 * explicitly enable interrupts afterwards - some MILO PALcode -	 * (namely LX164 one) seems to have severe problems with RTI -	 * at IPL 0. -	 */ -	local_irq_disable(); -	__do_IRQ(irq); +	generic_handle_irq_desc(irq, desc);  	irq_exit();  } diff --git a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c index 5f77afb88e8..1c8625cb0e2 100644 --- a/arch/alpha/kernel/irq_alpha.c +++ b/arch/alpha/kernel/irq_alpha.c @@ -11,6 +11,7 @@  #include <asm/machvec.h>  #include <asm/dma.h>  #include <asm/perf_event.h> +#include <asm/mce.h>  #include "proto.h"  #include "irq_impl.h" @@ -44,6 +45,14 @@ do_entInt(unsigned long type, unsigned long vector,  	  unsigned long la_ptr, struct pt_regs *regs)  {  	struct pt_regs *old_regs; + +	/* +	 * Disable interrupts during IRQ handling. +	 * Note that there is no matching local_irq_enable() due to +	 * severe problems with RTI at IPL0 and some MILO PALcode +	 * (namely LX164). +	 */ +	local_irq_disable();  	switch (type) {  	case 0:  #ifdef CONFIG_SMP @@ -57,22 +66,7 @@ do_entInt(unsigned long type, unsigned long vector,  		break;  	case 1:  		old_regs = set_irq_regs(regs); -#ifdef CONFIG_SMP -	  { -		long cpu; - -		local_irq_disable(); -		smp_percpu_timer_interrupt(regs); -		cpu = smp_processor_id(); -		if (cpu != boot_cpuid) { -		        kstat_incr_irqs_this_cpu(RTC_IRQ, irq_to_desc(RTC_IRQ)); -		} else { -			handle_irq(RTC_IRQ); -		} -	  } -#else  		handle_irq(RTC_IRQ); -#endif  		set_irq_regs(old_regs);  		return;  	case 2: @@ -112,8 +106,6 @@ init_IRQ(void)  	wrent(entInt, 0);  	alpha_mv.init_irq(); - -	init_hw_perf_events();  }  /* @@ -221,30 +213,16 @@ process_mcheck_info(unsigned long vector, unsigned long la_ptr,   * processed by PALcode, and comes in via entInt vector 1.   */ -static void rtc_enable_disable(unsigned int irq) { } -static unsigned int rtc_startup(unsigned int irq) { return 0; } -  struct irqaction timer_irqaction = { -	.handler	= timer_interrupt, -	.flags		= IRQF_DISABLED, +	.handler	= rtc_timer_interrupt,  	.name		= "timer",  }; -static struct irq_chip rtc_irq_type = { -	.name		= "RTC", -	.startup	= rtc_startup, -	.shutdown	= rtc_enable_disable, -	.enable		= rtc_enable_disable, -	.disable	= rtc_enable_disable, -	.ack		= rtc_enable_disable, -	.end		= rtc_enable_disable, -}; -  void __init  init_rtc_irq(void)  { -	irq_desc[RTC_IRQ].status = IRQ_DISABLED; -	irq_desc[RTC_IRQ].chip = &rtc_irq_type; +	irq_set_chip_and_handler_name(RTC_IRQ, &dummy_irq_chip, +				      handle_percpu_irq, "RTC");  	setup_irq(RTC_IRQ, &timer_irqaction);  } diff --git a/arch/alpha/kernel/irq_i8259.c b/arch/alpha/kernel/irq_i8259.c index 83a9ac28089..e1861c77dab 100644 --- a/arch/alpha/kernel/irq_i8259.c +++ b/arch/alpha/kernel/irq_i8259.c @@ -33,10 +33,10 @@ i8259_update_irq_hw(unsigned int irq, unsigned long mask)  }  inline void -i8259a_enable_irq(unsigned int irq) +i8259a_enable_irq(struct irq_data *d)  {  	spin_lock(&i8259_irq_lock); -	i8259_update_irq_hw(irq, cached_irq_mask &= ~(1 << irq)); +	i8259_update_irq_hw(d->irq, cached_irq_mask &= ~(1 << d->irq));  	spin_unlock(&i8259_irq_lock);  } @@ -47,16 +47,18 @@ __i8259a_disable_irq(unsigned int irq)  }  void -i8259a_disable_irq(unsigned int irq) +i8259a_disable_irq(struct irq_data *d)  {  	spin_lock(&i8259_irq_lock); -	__i8259a_disable_irq(irq); +	__i8259a_disable_irq(d->irq);  	spin_unlock(&i8259_irq_lock);  }  void -i8259a_mask_and_ack_irq(unsigned int irq) +i8259a_mask_and_ack_irq(struct irq_data *d)  { +	unsigned int irq = d->irq; +  	spin_lock(&i8259_irq_lock);  	__i8259a_disable_irq(irq); @@ -69,28 +71,11 @@ i8259a_mask_and_ack_irq(unsigned int irq)  	spin_unlock(&i8259_irq_lock);  } -unsigned int -i8259a_startup_irq(unsigned int irq) -{ -	i8259a_enable_irq(irq); -	return 0; /* never anything pending */ -} - -void -i8259a_end_irq(unsigned int irq) -{ -	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) -		i8259a_enable_irq(irq); -} -  struct irq_chip i8259a_irq_type = {  	.name		= "XT-PIC", -	.startup	= i8259a_startup_irq, -	.shutdown	= i8259a_disable_irq, -	.enable		= i8259a_enable_irq, -	.disable	= i8259a_disable_irq, -	.ack		= i8259a_mask_and_ack_irq, -	.end		= i8259a_end_irq, +	.irq_unmask	= i8259a_enable_irq, +	.irq_mask	= i8259a_disable_irq, +	.irq_mask_ack	= i8259a_mask_and_ack_irq,  };  void __init @@ -107,8 +92,7 @@ init_i8259a_irqs(void)  	outb(0xff, 0xA1);	/* mask all of 8259A-2 */  	for (i = 0; i < 16; i++) { -		irq_desc[i].status = IRQ_DISABLED; -		irq_desc[i].chip = &i8259a_irq_type; +		irq_set_chip_and_handler(i, &i8259a_irq_type, handle_level_irq);  	}  	setup_irq(2, &cascade); diff --git a/arch/alpha/kernel/irq_impl.h b/arch/alpha/kernel/irq_impl.h index b63ccd7386f..d507a234b05 100644 --- a/arch/alpha/kernel/irq_impl.h +++ b/arch/alpha/kernel/irq_impl.h @@ -31,11 +31,9 @@ extern void init_rtc_irq(void);  extern void common_init_isa_dma(void); -extern void i8259a_enable_irq(unsigned int); -extern void i8259a_disable_irq(unsigned int); -extern void i8259a_mask_and_ack_irq(unsigned int); -extern unsigned int i8259a_startup_irq(unsigned int); -extern void i8259a_end_irq(unsigned int); +extern void i8259a_enable_irq(struct irq_data *d); +extern void i8259a_disable_irq(struct irq_data *d); +extern void i8259a_mask_and_ack_irq(struct irq_data *d);  extern struct irq_chip i8259a_irq_type;  extern void init_i8259a_irqs(void); diff --git a/arch/alpha/kernel/irq_pyxis.c b/arch/alpha/kernel/irq_pyxis.c index 989ce46a0cf..13c97a5b31e 100644 --- a/arch/alpha/kernel/irq_pyxis.c +++ b/arch/alpha/kernel/irq_pyxis.c @@ -29,35 +29,21 @@ pyxis_update_irq_hw(unsigned long mask)  }  static inline void -pyxis_enable_irq(unsigned int irq) +pyxis_enable_irq(struct irq_data *d)  { -	pyxis_update_irq_hw(cached_irq_mask |= 1UL << (irq - 16)); +	pyxis_update_irq_hw(cached_irq_mask |= 1UL << (d->irq - 16));  }  static void -pyxis_disable_irq(unsigned int irq) +pyxis_disable_irq(struct irq_data *d)  { -	pyxis_update_irq_hw(cached_irq_mask &= ~(1UL << (irq - 16))); -} - -static unsigned int -pyxis_startup_irq(unsigned int irq) -{ -	pyxis_enable_irq(irq); -	return 0; -} - -static void -pyxis_end_irq(unsigned int irq) -{ -	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) -		pyxis_enable_irq(irq); +	pyxis_update_irq_hw(cached_irq_mask &= ~(1UL << (d->irq - 16)));  }  static void -pyxis_mask_and_ack_irq(unsigned int irq) +pyxis_mask_and_ack_irq(struct irq_data *d)  { -	unsigned long bit = 1UL << (irq - 16); +	unsigned long bit = 1UL << (d->irq - 16);  	unsigned long mask = cached_irq_mask &= ~bit;  	/* Disable the interrupt.  */ @@ -72,12 +58,9 @@ pyxis_mask_and_ack_irq(unsigned int irq)  static struct irq_chip pyxis_irq_type = {  	.name		= "PYXIS", -	.startup	= pyxis_startup_irq, -	.shutdown	= pyxis_disable_irq, -	.enable		= pyxis_enable_irq, -	.disable	= pyxis_disable_irq, -	.ack		= pyxis_mask_and_ack_irq, -	.end		= pyxis_end_irq, +	.irq_mask_ack	= pyxis_mask_and_ack_irq, +	.irq_mask	= pyxis_disable_irq, +	.irq_unmask	= pyxis_enable_irq,  };  void  @@ -119,8 +102,8 @@ init_pyxis_irqs(unsigned long ignore_mask)  	for (i = 16; i < 48; ++i) {  		if ((ignore_mask >> i) & 1)  			continue; -		irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; -		irq_desc[i].chip = &pyxis_irq_type; +		irq_set_chip_and_handler(i, &pyxis_irq_type, handle_level_irq); +		irq_set_status_flags(i, IRQ_LEVEL);  	}  	setup_irq(16+7, &isa_cascade_irqaction); diff --git a/arch/alpha/kernel/irq_srm.c b/arch/alpha/kernel/irq_srm.c index d63e93e1e8b..a79fa30e755 100644 --- a/arch/alpha/kernel/irq_srm.c +++ b/arch/alpha/kernel/irq_srm.c @@ -18,44 +18,27 @@  DEFINE_SPINLOCK(srm_irq_lock);  static inline void -srm_enable_irq(unsigned int irq) +srm_enable_irq(struct irq_data *d)  {  	spin_lock(&srm_irq_lock); -	cserve_ena(irq - 16); +	cserve_ena(d->irq - 16);  	spin_unlock(&srm_irq_lock);  }  static void -srm_disable_irq(unsigned int irq) +srm_disable_irq(struct irq_data *d)  {  	spin_lock(&srm_irq_lock); -	cserve_dis(irq - 16); +	cserve_dis(d->irq - 16);  	spin_unlock(&srm_irq_lock);  } -static unsigned int -srm_startup_irq(unsigned int irq) -{ -	srm_enable_irq(irq); -	return 0; -} - -static void -srm_end_irq(unsigned int irq) -{ -	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) -		srm_enable_irq(irq); -} -  /* Handle interrupts from the SRM, assuming no additional weirdness.  */  static struct irq_chip srm_irq_type = {  	.name		= "SRM", -	.startup	= srm_startup_irq, -	.shutdown	= srm_disable_irq, -	.enable		= srm_enable_irq, -	.disable	= srm_disable_irq, -	.ack		= srm_disable_irq, -	.end		= srm_end_irq, +	.irq_unmask	= srm_enable_irq, +	.irq_mask	= srm_disable_irq, +	.irq_mask_ack	= srm_disable_irq,  };  void __init @@ -68,8 +51,8 @@ init_srm_irqs(long max, unsigned long ignore_mask)  	for (i = 16; i < max; ++i) {  		if (i < 64 && ((ignore_mask >> i) & 1))  			continue; -		irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; -		irq_desc[i].chip = &srm_irq_type; +		irq_set_chip_and_handler(i, &srm_irq_type, handle_level_irq); +		irq_set_status_flags(i, IRQ_LEVEL);  	}  } diff --git a/arch/alpha/kernel/machvec_impl.h b/arch/alpha/kernel/machvec_impl.h index 7fa62488bd1..f54bdf658cd 100644 --- a/arch/alpha/kernel/machvec_impl.h +++ b/arch/alpha/kernel/machvec_impl.h @@ -43,10 +43,7 @@  #define CAT1(x,y)  x##y  #define CAT(x,y)   CAT1(x,y) -#define DO_DEFAULT_RTC \ -	.rtc_port = 0x70, \ -	.rtc_get_time = common_get_rtc_time, \ -	.rtc_set_time = common_set_rtc_time +#define DO_DEFAULT_RTC			.rtc_port = 0x70  #define DO_EV4_MMU							\  	.max_asn =			EV4_MAX_ASN,			\ diff --git a/arch/alpha/kernel/module.c b/arch/alpha/kernel/module.c index ebc3c894b5a..2fd00b7077e 100644 --- a/arch/alpha/kernel/module.c +++ b/arch/alpha/kernel/module.c @@ -29,20 +29,6 @@  #define DEBUGP(fmt...)  #endif -void * -module_alloc(unsigned long size) -{ -	if (size == 0) -		return NULL; -	return vmalloc(size); -} - -void -module_free(struct module *mod, void *module_region) -{ -	vfree(module_region); -} -  /* Allocate the GOT at the end of the core sections.  */  struct got_entry { @@ -156,14 +142,6 @@ module_frob_arch_sections(Elf64_Ehdr *hdr, Elf64_Shdr *sechdrs,  }  int -apply_relocate(Elf64_Shdr *sechdrs, const char *strtab, unsigned int symindex, -	       unsigned int relsec, struct module *me) -{ -	printk(KERN_ERR "module %s: REL relocation unsupported\n", me->name); -	return -ENOEXEC; -} - -int  apply_relocate_add(Elf64_Shdr *sechdrs, const char *strtab,  		   unsigned int symindex, unsigned int relsec,  		   struct module *me) @@ -302,15 +280,3 @@ apply_relocate_add(Elf64_Shdr *sechdrs, const char *strtab,  	return 0;  } - -int -module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, -		struct module *me) -{ -	return 0; -} - -void -module_arch_cleanup(struct module *mod) -{ -} diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 547e8b84b2f..1402fcc11c2 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -40,8 +40,8 @@  #include <asm/fpu.h>  #include <asm/io.h>  #include <asm/uaccess.h> -#include <asm/system.h>  #include <asm/sysinfo.h> +#include <asm/thread_info.h>  #include <asm/hwrpb.h>  #include <asm/processor.h> @@ -96,6 +96,7 @@ struct osf_dirent {  };  struct osf_dirent_callback { +	struct dir_context ctx;  	struct osf_dirent __user *dirent;  	long __user *basep;  	unsigned int count; @@ -145,27 +146,24 @@ SYSCALL_DEFINE4(osf_getdirentries, unsigned int, fd,  		long __user *, basep)  {  	int error; -	struct file *file; -	struct osf_dirent_callback buf; - -	error = -EBADF; -	file = fget(fd); -	if (!file) -		goto out; +	struct fd arg = fdget(fd); +	struct osf_dirent_callback buf = { +		.ctx.actor = osf_filldir, +		.dirent = dirent, +		.basep = basep, +		.count = count +	}; -	buf.dirent = dirent; -	buf.basep = basep; -	buf.count = count; -	buf.error = 0; +	if (!arg.file) +		return -EBADF; -	error = vfs_readdir(file, osf_filldir, &buf); +	error = iterate_dir(arg.file, &buf.ctx);  	if (error >= 0)  		error = buf.error;  	if (count != buf.count)  		error = count - buf.count; -	fput(file); - out: +	fdput(arg);  	return error;  } @@ -191,6 +189,39 @@ SYSCALL_DEFINE6(osf_mmap, unsigned long, addr, unsigned long, len,  	return ret;  } +struct osf_stat { +	int		st_dev; +	int		st_pad1; +	unsigned	st_mode; +	unsigned short	st_nlink; +	short		st_nlink_reserved; +	unsigned	st_uid; +	unsigned	st_gid; +	int		st_rdev; +	int		st_ldev; +	long		st_size; +	int		st_pad2; +	int		st_uatime; +	int		st_pad3; +	int		st_umtime; +	int		st_pad4; +	int		st_uctime; +	int		st_pad5; +	int		st_pad6; +	unsigned	st_flags; +	unsigned	st_gen; +	long		st_spare[4]; +	unsigned	st_ino; +	int		st_ino_reserved; +	int		st_atime; +	int		st_atime_reserved; +	int		st_mtime; +	int		st_mtime_reserved; +	int		st_ctime; +	int		st_ctime_reserved; +	long		st_blksize; +	long		st_blocks; +};  /*   * The OSF/1 statfs structure is much larger, but this should @@ -209,6 +240,60 @@ struct osf_statfs {  	__kernel_fsid_t f_fsid;  }; +struct osf_statfs64 { +	short f_type; +	short f_flags; +	int f_pad1; +	int f_pad2; +	int f_pad3; +	int f_pad4; +	int f_pad5; +	int f_pad6; +	int f_pad7; +	__kernel_fsid_t f_fsid; +	u_short f_namemax; +	short f_reserved1; +	int f_spare[8]; +	char f_pad8[90]; +	char f_pad9[90]; +	long mount_info[10]; +	u_long f_flags2; +	long f_spare2[14]; +	long f_fsize; +	long f_bsize; +	long f_blocks; +	long f_bfree; +	long f_bavail; +	long f_files; +	long f_ffree; +}; + +static int +linux_to_osf_stat(struct kstat *lstat, struct osf_stat __user *osf_stat) +{ +	struct osf_stat tmp = { 0 }; + +	tmp.st_dev	= lstat->dev; +	tmp.st_mode	= lstat->mode; +	tmp.st_nlink	= lstat->nlink; +	tmp.st_uid	= from_kuid_munged(current_user_ns(), lstat->uid); +	tmp.st_gid	= from_kgid_munged(current_user_ns(), lstat->gid); +	tmp.st_rdev	= lstat->rdev; +	tmp.st_ldev	= lstat->rdev; +	tmp.st_size	= lstat->size; +	tmp.st_uatime	= lstat->atime.tv_nsec / 1000; +	tmp.st_umtime	= lstat->mtime.tv_nsec / 1000; +	tmp.st_uctime	= lstat->ctime.tv_nsec / 1000; +	tmp.st_ino	= lstat->ino; +	tmp.st_atime	= lstat->atime.tv_sec; +	tmp.st_mtime	= lstat->mtime.tv_sec; +	tmp.st_ctime	= lstat->ctime.tv_sec; +	tmp.st_blksize	= lstat->blksize; +	tmp.st_blocks	= lstat->blocks; + +	return copy_to_user(osf_stat, &tmp, sizeof(tmp)) ? -EFAULT : 0; +} +  static int  linux_to_osf_statfs(struct kstatfs *linux_stat, struct osf_statfs __user *osf_stat,  		    unsigned long bufsiz) @@ -231,43 +316,99 @@ linux_to_osf_statfs(struct kstatfs *linux_stat, struct osf_statfs __user *osf_st  }  static int -do_osf_statfs(struct path *path, struct osf_statfs __user *buffer, -	      unsigned long bufsiz) +linux_to_osf_statfs64(struct kstatfs *linux_stat, struct osf_statfs64 __user *osf_stat, +		      unsigned long bufsiz) +{ +	struct osf_statfs64 tmp_stat = { 0 }; + +	tmp_stat.f_type = linux_stat->f_type; +	tmp_stat.f_fsize = linux_stat->f_frsize; +	tmp_stat.f_bsize = linux_stat->f_bsize; +	tmp_stat.f_blocks = linux_stat->f_blocks; +	tmp_stat.f_bfree = linux_stat->f_bfree; +	tmp_stat.f_bavail = linux_stat->f_bavail; +	tmp_stat.f_files = linux_stat->f_files; +	tmp_stat.f_ffree = linux_stat->f_ffree; +	tmp_stat.f_fsid = linux_stat->f_fsid; +	if (bufsiz > sizeof(tmp_stat)) +		bufsiz = sizeof(tmp_stat); +	return copy_to_user(osf_stat, &tmp_stat, bufsiz) ? -EFAULT : 0; +} + +SYSCALL_DEFINE3(osf_statfs, const char __user *, pathname, +		struct osf_statfs __user *, buffer, unsigned long, bufsiz)  {  	struct kstatfs linux_stat; -	int error = vfs_statfs(path, &linux_stat); +	int error = user_statfs(pathname, &linux_stat);  	if (!error)  		error = linux_to_osf_statfs(&linux_stat, buffer, bufsiz);  	return error;	  } -SYSCALL_DEFINE3(osf_statfs, const char __user *, pathname, -		struct osf_statfs __user *, buffer, unsigned long, bufsiz) +SYSCALL_DEFINE2(osf_stat, char __user *, name, struct osf_stat __user *, buf)  { -	struct path path; -	int retval; +	struct kstat stat; +	int error; -	retval = user_path(pathname, &path); -	if (!retval) { -		retval = do_osf_statfs(&path, buffer, bufsiz); -		path_put(&path); -	} -	return retval; +	error = vfs_stat(name, &stat); +	if (error) +		return error; + +	return linux_to_osf_stat(&stat, buf); +} + +SYSCALL_DEFINE2(osf_lstat, char __user *, name, struct osf_stat __user *, buf) +{ +	struct kstat stat; +	int error; + +	error = vfs_lstat(name, &stat); +	if (error) +		return error; + +	return linux_to_osf_stat(&stat, buf); +} + +SYSCALL_DEFINE2(osf_fstat, int, fd, struct osf_stat __user *, buf) +{ +	struct kstat stat; +	int error; + +	error = vfs_fstat(fd, &stat); +	if (error) +		return error; + +	return linux_to_osf_stat(&stat, buf);  }  SYSCALL_DEFINE3(osf_fstatfs, unsigned long, fd,  		struct osf_statfs __user *, buffer, unsigned long, bufsiz)  { -	struct file *file; -	int retval; +	struct kstatfs linux_stat; +	int error = fd_statfs(fd, &linux_stat); +	if (!error) +		error = linux_to_osf_statfs(&linux_stat, buffer, bufsiz); +	return error; +} -	retval = -EBADF; -	file = fget(fd); -	if (file) { -		retval = do_osf_statfs(&file->f_path, buffer, bufsiz); -		fput(file); -	} -	return retval; +SYSCALL_DEFINE3(osf_statfs64, char __user *, pathname, +		struct osf_statfs64 __user *, buffer, unsigned long, bufsiz) +{ +	struct kstatfs linux_stat; +	int error = user_statfs(pathname, &linux_stat); +	if (!error) +		error = linux_to_osf_statfs64(&linux_stat, buffer, bufsiz); +	return error; +} + +SYSCALL_DEFINE3(osf_fstatfs64, unsigned long, fd, +		struct osf_statfs64 __user *, buffer, unsigned long, bufsiz) +{ +	struct kstatfs linux_stat; +	int error = fd_statfs(fd, &linux_stat); +	if (!error) +		error = linux_to_osf_statfs64(&linux_stat, buffer, bufsiz); +	return error;  }  /* @@ -305,11 +446,11 @@ struct procfs_args {   * unhappy with OSF UFS. [CHECKME]   */  static int -osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags) +osf_ufs_mount(const char *dirname, struct ufs_args __user *args, int flags)  {  	int retval;  	struct cdfs_args tmp; -	char *devname; +	struct filename *devname;  	retval = -EFAULT;  	if (copy_from_user(&tmp, args, sizeof(tmp))) @@ -318,18 +459,18 @@ osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags)  	retval = PTR_ERR(devname);  	if (IS_ERR(devname))  		goto out; -	retval = do_mount(devname, dirname, "ext2", flags, NULL); +	retval = do_mount(devname->name, dirname, "ext2", flags, NULL);  	putname(devname);   out:  	return retval;  }  static int -osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags) +osf_cdfs_mount(const char *dirname, struct cdfs_args __user *args, int flags)  {  	int retval;  	struct cdfs_args tmp; -	char *devname; +	struct filename *devname;  	retval = -EFAULT;  	if (copy_from_user(&tmp, args, sizeof(tmp))) @@ -338,14 +479,14 @@ osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags)  	retval = PTR_ERR(devname);  	if (IS_ERR(devname))  		goto out; -	retval = do_mount(devname, dirname, "iso9660", flags, NULL); +	retval = do_mount(devname->name, dirname, "iso9660", flags, NULL);  	putname(devname);   out:  	return retval;  }  static int -osf_procfs_mount(char *dirname, struct procfs_args __user *args, int flags) +osf_procfs_mount(const char *dirname, struct procfs_args __user *args, int flags)  {  	struct procfs_args tmp; @@ -359,7 +500,7 @@ SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, const char __user *, path,  		int, flag, void __user *, data)  {  	int retval; -	char *name; +	struct filename *name;  	name = getname(path);  	retval = PTR_ERR(name); @@ -367,13 +508,13 @@ SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, const char __user *, path,  		goto out;  	switch (typenr) {  	case 1: -		retval = osf_ufs_mount(name, data, flag); +		retval = osf_ufs_mount(name->name, data, flag);  		break;  	case 6: -		retval = osf_cdfs_mount(name, data, flag); +		retval = osf_cdfs_mount(name->name, data, flag);  		break;  	case 9: -		retval = osf_procfs_mount(name, data, flag); +		retval = osf_procfs_mount(name->name, data, flag);  		break;  	default:  		retval = -EINVAL; @@ -429,7 +570,7 @@ SYSCALL_DEFINE2(osf_getdomainname, char __user *, name, int, namelen)  		return -EFAULT;  	len = namelen; -	if (namelen > 32) +	if (len > 32)  		len = 32;  	down_read(&uts_sem); @@ -614,7 +755,7 @@ SYSCALL_DEFINE3(osf_sysinfo, int, command, char __user *, buf, long, count)  	down_read(&uts_sem);  	res = sysinfo_table[offset];  	len = strlen(res)+1; -	if (len > count) +	if ((unsigned long)len > (unsigned long)count)  		len = count;  	if (copy_to_user(buf, res, len))  		err = -EFAULT; @@ -653,9 +794,9 @@ SYSCALL_DEFINE5(osf_getsysinfo, unsigned long, op, void __user *, buffer,   	case GSI_UACPROC:  		if (nbytes < sizeof(unsigned int))  			return -EINVAL; - 		w = (current_thread_info()->flags >> UAC_SHIFT) & UAC_BITMASK; - 		if (put_user(w, (unsigned int __user *)buffer)) - 			return -EFAULT; +		w = current_thread_info()->status & UAC_BITMASK; +		if (put_user(w, (unsigned int __user *)buffer)) +			return -EFAULT;   		return 1;  	case GSI_PROC_TYPE: @@ -669,7 +810,7 @@ SYSCALL_DEFINE5(osf_getsysinfo, unsigned long, op, void __user *, buffer,  		return 1;  	case GSI_GET_HWRPB: -		if (nbytes < sizeof(*hwrpb)) +		if (nbytes > sizeof(*hwrpb))  			return -EINVAL;  		if (copy_to_user(buffer, hwrpb, nbytes) != 0)  			return -EFAULT; @@ -763,24 +904,20 @@ SYSCALL_DEFINE5(osf_setsysinfo, unsigned long, op, void __user *, buffer,  		break;   	case SSI_NVPAIRS: { -		unsigned long v, w, i; -		unsigned int old, new; +		unsigned __user *p = buffer; +		unsigned i; - 		for (i = 0; i < nbytes; ++i) { +		for (i = 0, p = buffer; i < nbytes; ++i, p += 2) { +			unsigned v, w, status; - 			if (get_user(v, 2*i + (unsigned int __user *)buffer)) - 				return -EFAULT; - 			if (get_user(w, 2*i + 1 + (unsigned int __user *)buffer)) +			if (get_user(v, p) || get_user(w, p + 1))   				return -EFAULT;   			switch (v) {   			case SSIN_UACPROC: -			again: -				old = current_thread_info()->flags; -				new = old & ~(UAC_BITMASK << UAC_SHIFT); -				new = new | (w & UAC_BITMASK) << UAC_SHIFT; -				if (cmpxchg(¤t_thread_info()->flags, -					    old, new) != old) -					goto again; +				w &= UAC_BITMASK; +				status = current_thread_info()->status; +				status = (status & ~UAC_BITMASK) | w; +				current_thread_info()->status = status;   				break;   			default: @@ -790,6 +927,9 @@ SYSCALL_DEFINE5(osf_setsysinfo, unsigned long, op, void __user *, buffer,   		return 0;  	} +	case SSI_LMF: +		return 0; +  	default:  		break;  	} @@ -951,9 +1091,6 @@ SYSCALL_DEFINE2(osf_utimes, const char __user *, filename,  	return do_utimes(AT_FDCWD, filename, tvs ? tv : NULL, 0);  } -#define MAX_SELECT_SECONDS \ -	((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1) -  SYSCALL_DEFINE5(osf_select, int, n, fd_set __user *, inp, fd_set __user *, outp,  		fd_set __user *, exp, struct timeval32 __user *, tvp)  { @@ -1003,6 +1140,7 @@ struct rusage32 {  SYSCALL_DEFINE2(osf_getrusage, int, who, struct rusage32 __user *, ru)  {  	struct rusage32 r; +	cputime_t utime, stime;  	if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN)  		return -EINVAL; @@ -1010,8 +1148,9 @@ SYSCALL_DEFINE2(osf_getrusage, int, who, struct rusage32 __user *, ru)  	memset(&r, 0, sizeof(r));  	switch (who) {  	case RUSAGE_SELF: -		jiffies_to_timeval32(current->utime, &r.ru_utime); -		jiffies_to_timeval32(current->stime, &r.ru_stime); +		task_cputime(current, &utime, &stime); +		jiffies_to_timeval32(utime, &r.ru_utime); +		jiffies_to_timeval32(stime, &r.ru_stime);  		r.ru_minflt = current->min_flt;  		r.ru_majflt = current->maj_flt;  		break; @@ -1031,6 +1170,7 @@ SYSCALL_DEFINE4(osf_wait4, pid_t, pid, int __user *, ustatus, int, options,  {  	struct rusage r;  	long ret, err; +	unsigned int status = 0;  	mm_segment_t old_fs;  	if (!ur) @@ -1039,13 +1179,15 @@ SYSCALL_DEFINE4(osf_wait4, pid_t, pid, int __user *, ustatus, int, options,  	old_fs = get_fs();  	set_fs (KERNEL_DS); -	ret = sys_wait4(pid, ustatus, options, (struct rusage __user *) &r); +	ret = sys_wait4(pid, (unsigned int __user *) &status, options, +			(struct rusage __user *) &r);  	set_fs (old_fs);  	if (!access_ok(VERIFY_WRITE, ur, sizeof(*ur)))  		return -EFAULT;  	err = 0; +	err |= put_user(status, ustatus);  	err |= __put_user(r.ru_utime.tv_sec, &ur->ru_utime.tv_sec);  	err |= __put_user(r.ru_utime.tv_usec, &ur->ru_utime.tv_usec);  	err |= __put_user(r.ru_stime.tv_sec, &ur->ru_stime.tv_sec); @@ -1159,17 +1301,15 @@ static unsigned long  arch_get_unmapped_area_1(unsigned long addr, unsigned long len,  		         unsigned long limit)  { -	struct vm_area_struct *vma = find_vma(current->mm, addr); - -	while (1) { -		/* At this point:  (!vma || addr < vma->vm_end). */ -		if (limit - len < addr) -			return -ENOMEM; -		if (!vma || addr + len <= vma->vm_start) -			return addr; -		addr = vma->vm_end; -		vma = vma->vm_next; -	} +	struct vm_unmapped_area_info info; + +	info.flags = 0; +	info.length = len; +	info.low_limit = addr; +	info.high_limit = limit; +	info.align_mask = 0; +	info.align_offset = 0; +	return vm_unmapped_area(&info);  }  unsigned long @@ -1257,3 +1397,52 @@ SYSCALL_DEFINE3(osf_writev, unsigned long, fd,  }  #endif + +SYSCALL_DEFINE2(osf_getpriority, int, which, int, who) +{ +	int prio = sys_getpriority(which, who); +	if (prio >= 0) { +		/* Return value is the unbiased priority, i.e. 20 - prio. +		   This does result in negative return values, so signal +		   no error */ +		force_successful_syscall_return(); +		prio = 20 - prio; +	} +	return prio; +} + +SYSCALL_DEFINE0(getxuid) +{ +	current_pt_regs()->r20 = sys_geteuid(); +	return sys_getuid(); +} + +SYSCALL_DEFINE0(getxgid) +{ +	current_pt_regs()->r20 = sys_getegid(); +	return sys_getgid(); +} + +SYSCALL_DEFINE0(getxpid) +{ +	current_pt_regs()->r20 = sys_getppid(); +	return sys_getpid(); +} + +SYSCALL_DEFINE0(alpha_pipe) +{ +	int fd[2]; +	int res = do_pipe_flags(fd, 0); +	if (!res) { +		/* The return values are in $0 and $20.  */ +		current_pt_regs()->r20 = fd[1]; +		res = fd[0]; +	} +	return res; +} + +SYSCALL_DEFINE1(sethae, unsigned long, val) +{ +	current_pt_regs()->hae = val; +	return 0; +} diff --git a/arch/alpha/kernel/pci-noop.c b/arch/alpha/kernel/pci-noop.c index 246100ef07c..df24b76f924 100644 --- a/arch/alpha/kernel/pci-noop.c +++ b/arch/alpha/kernel/pci-noop.c @@ -108,7 +108,8 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn,  }  static void *alpha_noop_alloc_coherent(struct device *dev, size_t size, -				       dma_addr_t *dma_handle, gfp_t gfp) +				       dma_addr_t *dma_handle, gfp_t gfp, +				       struct dma_attrs *attrs)  {  	void *ret; @@ -123,7 +124,8 @@ static void *alpha_noop_alloc_coherent(struct device *dev, size_t size,  }  static void alpha_noop_free_coherent(struct device *dev, size_t size, -				     void *cpu_addr, dma_addr_t dma_addr) +				     void *cpu_addr, dma_addr_t dma_addr, +				     struct dma_attrs *attrs)  {  	free_pages((unsigned long)cpu_addr, get_order(size));  } @@ -174,8 +176,8 @@ static int alpha_noop_set_mask(struct device *dev, u64 mask)  }  struct dma_map_ops alpha_noop_ops = { -	.alloc_coherent		= alpha_noop_alloc_coherent, -	.free_coherent		= alpha_noop_free_coherent, +	.alloc			= alpha_noop_alloc_coherent, +	.free			= alpha_noop_free_coherent,  	.map_page		= alpha_noop_map_page,  	.map_sg			= alpha_noop_map_sg,  	.mapping_error		= alpha_noop_mapping_error, @@ -185,15 +187,3 @@ struct dma_map_ops alpha_noop_ops = {  struct dma_map_ops *dma_ops = &alpha_noop_ops;  EXPORT_SYMBOL(dma_ops); - -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) -{ -	return NULL; -} - -void pci_iounmap(struct pci_dev *dev, void __iomem * addr) -{ -} - -EXPORT_SYMBOL(pci_iomap); -EXPORT_SYMBOL(pci_iounmap); diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c index b899e95f79f..99e8d4796c9 100644 --- a/arch/alpha/kernel/pci-sysfs.c +++ b/arch/alpha/kernel/pci-sysfs.c @@ -10,6 +10,7 @@   */  #include <linux/sched.h> +#include <linux/stat.h>  #include <linux/slab.h>  #include <linux/pci.h> @@ -25,7 +26,6 @@ static int hose_mmap_page_range(struct pci_controller *hose,  		base = sparse ? hose->sparse_io_base : hose->dense_io_base;  	vma->vm_pgoff += base >> PAGE_SHIFT; -	vma->vm_flags |= (VM_IO | VM_RESERVED);  	return io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,  				  vma->vm_end - vma->vm_start, @@ -83,7 +83,7 @@ static int pci_mmap_resource(struct kobject *kobj,  	if (iomem_is_exclusive(res->start))  		return -EINVAL; -	pcibios_resource_to_bus(pdev, &bar, res); +	pcibios_resource_to_bus(pdev->bus, &bar, res);  	vma->vm_pgoff += bar.start >> (PAGE_SHIFT - (sparse ? 5 : 0));  	mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io; @@ -139,7 +139,7 @@ static int sparse_mem_mmap_fits(struct pci_dev *pdev, int num)  	long dense_offset;  	unsigned long sparse_size; -	pcibios_resource_to_bus(pdev, &bar, &pdev->resource[num]); +	pcibios_resource_to_bus(pdev->bus, &bar, &pdev->resource[num]);  	/* All core logic chips have 4G sparse address space, except  	   CIA which has 16G (see xxx_SPARSE_MEM and xxx_DENSE_MEM diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index c9ab94ee1ca..076c35cd6cd 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c @@ -43,12 +43,10 @@ const char *const pci_mem_names[] = {  const char pci_hae0_name[] = "HAE0"; -/* Indicate whether we respect the PCI setup left by console. */  /* - * Make this long-lived  so that we know when shutting down - * whether we probed only or not. + * If PCI_PROBE_ONLY in pci_flags is set, we don't change any PCI resource + * assignments.   */ -int pci_probe_only;  /*   * The PCI controller list. @@ -61,15 +59,13 @@ struct pci_controller *pci_isa_hose;   * Quirks.   */ -static void __init -quirk_isa_bridge(struct pci_dev *dev) +static void quirk_isa_bridge(struct pci_dev *dev)  {  	dev->class = PCI_CLASS_BRIDGE_ISA << 8;  }  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82378, quirk_isa_bridge); -static void __init -quirk_cypress(struct pci_dev *dev) +static void quirk_cypress(struct pci_dev *dev)  {  	/* The Notorious Cy82C693 chip.  */ @@ -108,8 +104,7 @@ quirk_cypress(struct pci_dev *dev)  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, quirk_cypress);  /* Called for each device after PCI setup is done. */ -static void __init -pcibios_fixup_final(struct pci_dev *dev) +static void pcibios_fixup_final(struct pci_dev *dev)  {  	unsigned int class = dev->class >> 8; @@ -200,22 +195,15 @@ pcibios_init(void)  subsys_initcall(pcibios_init); -char * __devinit -pcibios_setup(char *str) -{ -	return str; -} -  #ifdef ALPHA_RESTORE_SRM_SETUP  static struct pdev_srm_saved_conf *srm_saved_configs; -void __devinit -pdev_save_srm_config(struct pci_dev *dev) +void pdev_save_srm_config(struct pci_dev *dev)  {  	struct pdev_srm_saved_conf *tmp;  	static int printed = 0; -	if (!alpha_using_srm || pci_probe_only) +	if (!alpha_using_srm || pci_has_flag(PCI_PROBE_ONLY))  		return;  	if (!printed) { @@ -242,7 +230,7 @@ pci_restore_srm_config(void)  	struct pdev_srm_saved_conf *tmp;  	/* No need to restore if probed only. */ -	if (pci_probe_only) +	if (pci_has_flag(PCI_PROBE_ONLY))  		return;  	/* Restore SRM config. */ @@ -252,116 +240,20 @@ pci_restore_srm_config(void)  }  #endif -void __devinit -pcibios_fixup_resource(struct resource *res, struct resource *root) -{ -	res->start += root->start; -	res->end += root->start; -} - -void __devinit -pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus) +void pcibios_fixup_bus(struct pci_bus *bus)  { -	/* Update device resources.  */ -	struct pci_controller *hose = (struct pci_controller *)bus->sysdata; -	int i; - -	for (i = 0; i < PCI_NUM_RESOURCES; i++) { -		if (!dev->resource[i].start) -			continue; -		if (dev->resource[i].flags & IORESOURCE_IO) -			pcibios_fixup_resource(&dev->resource[i], -					       hose->io_space); -		else if (dev->resource[i].flags & IORESOURCE_MEM) -			pcibios_fixup_resource(&dev->resource[i], -					       hose->mem_space); -	} -} - -void __devinit -pcibios_fixup_bus(struct pci_bus *bus) -{ -	/* Propagate hose info into the subordinate devices.  */ - -	struct pci_controller *hose = bus->sysdata;  	struct pci_dev *dev = bus->self; -	if (!dev) { -		/* Root bus. */ -		u32 pci_mem_end; -		u32 sg_base = hose->sg_pci ? hose->sg_pci->dma_base : ~0; -		unsigned long end; - -		bus->resource[0] = hose->io_space; -		bus->resource[1] = hose->mem_space; - -		/* Adjust hose mem_space limit to prevent PCI allocations -		   in the iommu windows. */ -		pci_mem_end = min((u32)__direct_map_base, sg_base) - 1; -		end = hose->mem_space->start + pci_mem_end; -		if (hose->mem_space->end > end) -			hose->mem_space->end = end; - 	} else if (pci_probe_only && +	if (pci_has_flag(PCI_PROBE_ONLY) && dev &&   		   (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {   		pci_read_bridge_bases(bus); - 		pcibios_fixup_device_resources(dev, bus);  	}   	list_for_each_entry(dev, &bus->devices, bus_list) {  		pdev_save_srm_config(dev); -		if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) -			pcibios_fixup_device_resources(dev, bus);  	}  } -void __init -pcibios_update_irq(struct pci_dev *dev, int irq) -{ -	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); -} - -void -pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, -			 struct resource *res) -{ -	struct pci_controller *hose = (struct pci_controller *)dev->sysdata; -	unsigned long offset = 0; - -	if (res->flags & IORESOURCE_IO) -		offset = hose->io_space->start; -	else if (res->flags & IORESOURCE_MEM) -		offset = hose->mem_space->start; - -	region->start = res->start - offset; -	region->end = res->end - offset; -} - -void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, -			     struct pci_bus_region *region) -{ -	struct pci_controller *hose = (struct pci_controller *)dev->sysdata; -	unsigned long offset = 0; - -	if (res->flags & IORESOURCE_IO) -		offset = hose->io_space->start; -	else if (res->flags & IORESOURCE_MEM) -		offset = hose->mem_space->start; - -	res->start = region->start + offset; -	res->end = region->end + offset; -} - -#ifdef CONFIG_HOTPLUG -EXPORT_SYMBOL(pcibios_resource_to_bus); -EXPORT_SYMBOL(pcibios_bus_to_resource); -#endif - -int -pcibios_enable_device(struct pci_dev *dev, int mask) -{ -	return pci_enable_resources(dev, mask); -} -  /*   *  If we set up a device for bus mastering, we need to check the latency   *  timer as certain firmware forgets to set it properly, as seen @@ -392,7 +284,8 @@ pcibios_claim_one_bus(struct pci_bus *b)  			if (r->parent || !r->start || !r->flags)  				continue; -			if (pci_probe_only || (r->flags & IORESOURCE_PCI_FIXED)) +			if (pci_has_flag(PCI_PROBE_ONLY) || +			    (r->flags & IORESOURCE_PCI_FIXED))  				pci_claim_resource(dev, i);  		}  	} @@ -414,16 +307,36 @@ void __init  common_init_pci(void)  {  	struct pci_controller *hose; +	struct list_head resources;  	struct pci_bus *bus;  	int next_busno;  	int need_domain_info = 0; +	u32 pci_mem_end; +	u32 sg_base; +	unsigned long end;  	/* Scan all of the recorded PCI controllers.  */  	for (next_busno = 0, hose = hose_head; hose; hose = hose->next) { -		bus = pci_scan_bus(next_busno, alpha_mv.pci_ops, hose); +		sg_base = hose->sg_pci ? hose->sg_pci->dma_base : ~0; + +		/* Adjust hose mem_space limit to prevent PCI allocations +		   in the iommu windows. */ +		pci_mem_end = min((u32)__direct_map_base, sg_base) - 1; +		end = hose->mem_space->start + pci_mem_end; +		if (hose->mem_space->end > end) +			hose->mem_space->end = end; + +		INIT_LIST_HEAD(&resources); +		pci_add_resource_offset(&resources, hose->io_space, +					hose->io_space->start); +		pci_add_resource_offset(&resources, hose->mem_space, +					hose->mem_space->start); + +		bus = pci_scan_root_bus(NULL, next_busno, alpha_mv.pci_ops, +					hose, &resources);  		hose->bus = bus;  		hose->need_domain_info = need_domain_info; -		next_busno = bus->subordinate + 1; +		next_busno = bus->busn_res.end + 1;  		/* Don't allow 8-bit bus number overflow inside the hose -  		   reserve some space for bridges. */   		if (next_busno > 224) { @@ -508,30 +421,7 @@ sys_pciconfig_iobase(long which, unsigned long bus, unsigned long dfn)  	return -EOPNOTSUPP;  } -/* Create an __iomem token from a PCI BAR.  Copied from lib/iomap.c with -   no changes, since we don't want the other things in that object file.  */ - -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) -{ -	resource_size_t start = pci_resource_start(dev, bar); -	resource_size_t len = pci_resource_len(dev, bar); -	unsigned long flags = pci_resource_flags(dev, bar); - -	if (!len || !start) -		return NULL; -	if (maxlen && len > maxlen) -		len = maxlen; -	if (flags & IORESOURCE_IO) -		return ioport_map(start, len); -	if (flags & IORESOURCE_MEM) { -		/* Not checking IORESOURCE_CACHEABLE because alpha does -		   not distinguish between ioremap and ioremap_nocache.  */ -		return ioremap(start, len); -	} -	return NULL; -} - -/* Destroy that token.  Not copied from lib/iomap.c.  */ +/* Destroy an __iomem token.  Not copied from lib/iomap.c.  */  void pci_iounmap(struct pci_dev *dev, void __iomem * addr)  { @@ -539,7 +429,6 @@ void pci_iounmap(struct pci_dev *dev, void __iomem * addr)  		iounmap(addr);  } -EXPORT_SYMBOL(pci_iomap);  EXPORT_SYMBOL(pci_iounmap);  /* FIXME: Some boxes have multiple ISA bridges! */ diff --git a/arch/alpha/kernel/pci_impl.h b/arch/alpha/kernel/pci_impl.h index 85457b2d451..2b0ac429f5e 100644 --- a/arch/alpha/kernel/pci_impl.h +++ b/arch/alpha/kernel/pci_impl.h @@ -173,9 +173,6 @@ extern void pci_restore_srm_config(void);  extern struct pci_controller *hose_head, **hose_tail;  extern struct pci_controller *pci_isa_hose; -/* Indicate that we trust the console to configure things properly.  */ -extern int pci_probe_only; -  extern unsigned long alpha_agpgart_size;  extern void common_init_pci(void); diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c index 022c2748fa4..eddee772034 100644 --- a/arch/alpha/kernel/pci_iommu.c +++ b/arch/alpha/kernel/pci_iommu.c @@ -7,6 +7,7 @@  #include <linux/pci.h>  #include <linux/gfp.h>  #include <linux/bootmem.h> +#include <linux/export.h>  #include <linux/scatterlist.h>  #include <linux/log2.h>  #include <linux/dma-mapping.h> @@ -235,7 +236,7 @@ static int pci_dac_dma_supported(struct pci_dev *dev, u64 mask)  		ok = 0;  	/* If both conditions above are met, we are fine. */ -	DBGA("pci_dac_dma_supported %s from %p\n", +	DBGA("pci_dac_dma_supported %s from %pf\n",  	     ok ? "yes" : "no", __builtin_return_address(0));  	return ok; @@ -267,7 +268,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,  	    && paddr + size <= __direct_map_size) {  		ret = paddr + __direct_map_base; -		DBGA2("pci_map_single: [%p,%zx] -> direct %llx from %p\n", +		DBGA2("pci_map_single: [%p,%zx] -> direct %llx from %pf\n",  		      cpu_addr, size, ret, __builtin_return_address(0));  		return ret; @@ -278,7 +279,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,  	if (dac_allowed) {  		ret = paddr + alpha_mv.pci_dac_offset; -		DBGA2("pci_map_single: [%p,%zx] -> DAC %llx from %p\n", +		DBGA2("pci_map_single: [%p,%zx] -> DAC %llx from %pf\n",  		      cpu_addr, size, ret, __builtin_return_address(0));  		return ret; @@ -315,7 +316,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,  	ret = arena->dma_base + dma_ofs * PAGE_SIZE;  	ret += (unsigned long)cpu_addr & ~PAGE_MASK; -	DBGA2("pci_map_single: [%p,%zx] np %ld -> sg %llx from %p\n", +	DBGA2("pci_map_single: [%p,%zx] np %ld -> sg %llx from %pf\n",  	      cpu_addr, size, npages, ret, __builtin_return_address(0));  	return ret; @@ -324,7 +325,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,  /* Helper for generic DMA-mapping functions. */  static struct pci_dev *alpha_gendev_to_pci(struct device *dev)  { -	if (dev && dev->bus == &pci_bus_type) +	if (dev && dev_is_pci(dev))  		return to_pci_dev(dev);  	/* Assume that non-PCI devices asking for DMA are either ISA or EISA, @@ -353,8 +354,7 @@ static dma_addr_t alpha_pci_map_page(struct device *dev, struct page *page,  	struct pci_dev *pdev = alpha_gendev_to_pci(dev);  	int dac_allowed; -	if (dir == PCI_DMA_NONE) -		BUG(); +	BUG_ON(dir == PCI_DMA_NONE);  	dac_allowed = pdev ? pci_dac_dma_supported(pdev, pdev->dma_mask) : 0;   	return pci_map_single_1(pdev, (char *)page_address(page) + offset,  @@ -377,21 +377,20 @@ static void alpha_pci_unmap_page(struct device *dev, dma_addr_t dma_addr,  	struct pci_iommu_arena *arena;  	long dma_ofs, npages; -	if (dir == PCI_DMA_NONE) -		BUG(); +	BUG_ON(dir == PCI_DMA_NONE);  	if (dma_addr >= __direct_map_base  	    && dma_addr < __direct_map_base + __direct_map_size) {  		/* Nothing to do.  */ -		DBGA2("pci_unmap_single: direct [%llx,%zx] from %p\n", +		DBGA2("pci_unmap_single: direct [%llx,%zx] from %pf\n",  		      dma_addr, size, __builtin_return_address(0));  		return;  	}  	if (dma_addr > 0xffffffff) { -		DBGA2("pci64_unmap_single: DAC [%llx,%zx] from %p\n", +		DBGA2("pci64_unmap_single: DAC [%llx,%zx] from %pf\n",  		      dma_addr, size, __builtin_return_address(0));  		return;  	} @@ -423,7 +422,7 @@ static void alpha_pci_unmap_page(struct device *dev, dma_addr_t dma_addr,  	spin_unlock_irqrestore(&arena->lock, flags); -	DBGA2("pci_unmap_single: sg [%llx,%zx] np %ld from %p\n", +	DBGA2("pci_unmap_single: sg [%llx,%zx] np %ld from %pf\n",  	      dma_addr, size, npages, __builtin_return_address(0));  } @@ -433,7 +432,8 @@ static void alpha_pci_unmap_page(struct device *dev, dma_addr_t dma_addr,     else DMA_ADDRP is undefined.  */  static void *alpha_pci_alloc_coherent(struct device *dev, size_t size, -				      dma_addr_t *dma_addrp, gfp_t gfp) +				      dma_addr_t *dma_addrp, gfp_t gfp, +				      struct dma_attrs *attrs)  {  	struct pci_dev *pdev = alpha_gendev_to_pci(dev);  	void *cpu_addr; @@ -445,7 +445,7 @@ try_again:  	cpu_addr = (void *)__get_free_pages(gfp, order);  	if (! cpu_addr) {  		printk(KERN_INFO "pci_alloc_consistent: " -		       "get_free_pages failed from %p\n", +		       "get_free_pages failed from %pf\n",  			__builtin_return_address(0));  		/* ??? Really atomic allocation?  Otherwise we could play  		   with vmalloc and sg if we can't find contiguous memory.  */ @@ -464,7 +464,7 @@ try_again:  		goto try_again;  	} -	DBGA2("pci_alloc_consistent: %zx -> [%p,%llx] from %p\n", +	DBGA2("pci_alloc_consistent: %zx -> [%p,%llx] from %pf\n",  	      size, cpu_addr, *dma_addrp, __builtin_return_address(0));  	return cpu_addr; @@ -477,13 +477,14 @@ try_again:     DMA_ADDR past this call are illegal.  */  static void alpha_pci_free_coherent(struct device *dev, size_t size, -				    void *cpu_addr, dma_addr_t dma_addr) +				    void *cpu_addr, dma_addr_t dma_addr, +				    struct dma_attrs *attrs)  {  	struct pci_dev *pdev = alpha_gendev_to_pci(dev);  	pci_unmap_single(pdev, dma_addr, size, PCI_DMA_BIDIRECTIONAL);  	free_pages((unsigned long)cpu_addr, get_order(size)); -	DBGA2("pci_free_consistent: [%llx,%zx] from %p\n", +	DBGA2("pci_free_consistent: [%llx,%zx] from %pf\n",  	      dma_addr, size, __builtin_return_address(0));  } @@ -659,8 +660,7 @@ static int alpha_pci_map_sg(struct device *dev, struct scatterlist *sg,  	dma_addr_t max_dma;  	int dac_allowed; -	if (dir == PCI_DMA_NONE) -		BUG(); +	BUG_ON(dir == PCI_DMA_NONE);  	dac_allowed = dev ? pci_dac_dma_supported(pdev, pdev->dma_mask) : 0; @@ -739,8 +739,7 @@ static void alpha_pci_unmap_sg(struct device *dev, struct scatterlist *sg,  	dma_addr_t max_dma;  	dma_addr_t fbeg, fend; -	if (dir == PCI_DMA_NONE) -		BUG(); +	BUG_ON(dir == PCI_DMA_NONE);  	if (! alpha_mv.mv_pci_tbi)  		return; @@ -951,8 +950,8 @@ static int alpha_pci_set_mask(struct device *dev, u64 mask)  }  struct dma_map_ops alpha_pci_ops = { -	.alloc_coherent		= alpha_pci_alloc_coherent, -	.free_coherent		= alpha_pci_free_coherent, +	.alloc			= alpha_pci_alloc_coherent, +	.free			= alpha_pci_free_coherent,  	.map_page		= alpha_pci_map_page,  	.unmap_page		= alpha_pci_unmap_page,  	.map_sg			= alpha_pci_map_sg, diff --git a/arch/alpha/kernel/perf_event.c b/arch/alpha/kernel/perf_event.c index 1cc49683fb6..c52e7f0ee5f 100644 --- a/arch/alpha/kernel/perf_event.c +++ b/arch/alpha/kernel/perf_event.c @@ -14,9 +14,10 @@  #include <linux/kernel.h>  #include <linux/kdebug.h>  #include <linux/mutex.h> +#include <linux/init.h>  #include <asm/hwrpb.h> -#include <asm/atomic.h> +#include <linux/atomic.h>  #include <asm/irq.h>  #include <asm/irq_regs.h>  #include <asm/pal.h> @@ -82,6 +83,8 @@ struct alpha_pmu_t {  	long pmc_left[3];  	 /* Subroutine for allocation of PMCs.  Enforces constraints. */  	int (*check_constraints)(struct perf_event **, unsigned long *, int); +	/* Subroutine for checking validity of a raw event for this PMU. */ +	int (*raw_event_valid)(u64 config);  };  /* @@ -202,6 +205,12 @@ success:  } +static int ev67_raw_event_valid(u64 config) +{ +	return config >= EV67_CYCLES && config < EV67_LAST_ET; +}; + +  static const struct alpha_pmu_t ev67_pmu = {  	.event_map = ev67_perfmon_event_map,  	.max_events = ARRAY_SIZE(ev67_perfmon_event_map), @@ -210,7 +219,8 @@ static const struct alpha_pmu_t ev67_pmu = {  	.pmc_count_mask = {EV67_PCTR_0_COUNT_MASK,  EV67_PCTR_1_COUNT_MASK,  0},  	.pmc_max_period = {(1UL<<20) - 1, (1UL<<20) - 1, 0},  	.pmc_left = {16, 4, 0}, -	.check_constraints = ev67_check_constraints +	.check_constraints = ev67_check_constraints, +	.raw_event_valid = ev67_raw_event_valid,  }; @@ -608,7 +618,9 @@ static int __hw_perf_event_init(struct perf_event *event)  	} else if (attr->type == PERF_TYPE_HW_CACHE) {  		return -EOPNOTSUPP;  	} else if (attr->type == PERF_TYPE_RAW) { -		ev = attr->config & 0xff; +		if (!alpha_pmu->raw_event_valid(attr->config)) +			return -EINVAL; +		ev = attr->config;  	} else {  		return -EOPNOTSUPP;  	} @@ -684,6 +696,10 @@ static int alpha_pmu_event_init(struct perf_event *event)  {  	int err; +	/* does not support taken branch sampling */ +	if (has_branch_stack(event)) +		return -EOPNOTSUPP; +  	switch (event->attr.type) {  	case PERF_TYPE_RAW:  	case PERF_TYPE_HARDWARE: @@ -819,7 +835,6 @@ static void alpha_perf_event_irq_handler(unsigned long la_ptr,  	idx = la_ptr; -	perf_sample_data_init(&data, 0);  	for (j = 0; j < cpuc->n_events; j++) {  		if (cpuc->current_idx[j] == idx)  			break; @@ -843,10 +858,10 @@ static void alpha_perf_event_irq_handler(unsigned long la_ptr,  	hwc = &event->hw;  	alpha_perf_event_update(event, hwc, idx, alpha_pmu->pmc_max_period[idx]+1); -	data.period = event->hw.last_period; +	perf_sample_data_init(&data, 0, hwc->last_period);  	if (alpha_perf_event_set_period(event, hwc, idx)) { -		if (perf_event_overflow(event, 1, &data, regs)) { +		if (perf_event_overflow(event, &data, regs)) {  			/* Interrupts coming too quickly; "throttle" the  			 * counter, i.e., disable it for a little while.  			 */ @@ -863,13 +878,13 @@ static void alpha_perf_event_irq_handler(unsigned long la_ptr,  /*   * Init call to initialise performance events at kernel startup.   */ -void __init init_hw_perf_events(void) +int __init init_hw_perf_events(void)  {  	pr_info("Performance events: ");  	if (!supported_cpu()) {  		pr_cont("No support for your CPU.\n"); -		return; +		return 0;  	}  	pr_cont("Supported CPU type!\n"); @@ -881,6 +896,8 @@ void __init init_hw_perf_events(void)  	/* And set up PMU specification */  	alpha_pmu = &ev67_pmu; -	perf_pmu_register(&pmu); -} +	perf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW); +	return 0; +} +early_initcall(init_hw_perf_events); diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index 3ec35066f1d..1941a07b581 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -28,10 +28,10 @@  #include <linux/tty.h>  #include <linux/console.h>  #include <linux/slab.h> +#include <linux/rcupdate.h>  #include <asm/reg.h>  #include <asm/uaccess.h> -#include <asm/system.h>  #include <asm/io.h>  #include <asm/pgtable.h>  #include <asm/hwrpb.h> @@ -46,21 +46,22 @@  void (*pm_power_off)(void) = machine_power_off;  EXPORT_SYMBOL(pm_power_off); -void -cpu_idle(void) +#ifdef CONFIG_ALPHA_WTINT +/* + * Sleep the CPU. + * EV6, LCA45 and QEMU know how to power down, skipping N timer interrupts. + */ +void arch_cpu_idle(void)  { -	set_thread_flag(TIF_POLLING_NRFLAG); - -	while (1) { -		/* FIXME -- EV6 and LCA45 know how to power down -		   the CPU.  */ - -		while (!need_resched()) -			cpu_relax(); -		schedule(); -	} +	wtint(0); +	local_irq_enable();  } +void arch_cpu_idle_dead(void) +{ +	wtint(INT_MAX); +} +#endif /* ALPHA_WTINT */  struct halt_info {  	int mode; @@ -121,7 +122,7 @@ common_shutdown_1(void *generic_ptr)  	/* Wait for the secondaries to halt. */  	set_cpu_present(boot_cpuid, false);  	set_cpu_possible(boot_cpuid, false); -	while (cpus_weight(cpu_present_map)) +	while (cpumask_weight(cpu_present_mask))  		barrier();  #endif @@ -133,7 +134,9 @@ common_shutdown_1(void *generic_ptr)  		if (in_interrupt())  			irq_exit();  		/* This has the effect of resetting the VGA video origin.  */ -		take_over_console(&dummy_con, 0, MAX_NR_CONSOLES-1, 1); +		console_lock(); +		do_take_over_console(&dummy_con, 0, MAX_NR_CONSOLES-1, 1); +		console_unlock();  #endif  		pci_restore_srm_config();  		set_hae(srm_hae); @@ -191,6 +194,7 @@ machine_power_off(void)  void  show_regs(struct pt_regs *regs)  { +	show_regs_print_info(KERN_DEFAULT);  	dik_show_regs(regs, NULL);  } @@ -200,7 +204,6 @@ show_regs(struct pt_regs *regs)  void  start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)  { -	set_fs(USER_DS);  	regs->pc = pc;  	regs->ps = 8;  	wrusp(sp); @@ -233,87 +236,53 @@ release_thread(struct task_struct *dead_task)  }  /* - * "alpha_clone()".. By the time we get here, the - * non-volatile registers have also been saved on the - * stack. We do some ugly pointer stuff here.. (see - * also copy_thread) - * - * Notice that "fork()" is implemented in terms of clone, - * with parameters (SIGCHLD, 0). - */ -int -alpha_clone(unsigned long clone_flags, unsigned long usp, -	    int __user *parent_tid, int __user *child_tid, -	    unsigned long tls_value, struct pt_regs *regs) -{ -	if (!usp) -		usp = rdusp(); - -	return do_fork(clone_flags, usp, regs, 0, parent_tid, child_tid); -} - -int -alpha_vfork(struct pt_regs *regs) -{ -	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), -		       regs, 0, NULL, NULL); -} - -/*   * Copy an alpha thread.. - * - * Note the "stack_offset" stuff: when returning to kernel mode, we need - * to have some extra stack-space for the kernel stack that still exists - * after the "ret_from_fork".  When returning to user mode, we only want - * the space needed by the syscall stack frame (ie "struct pt_regs"). - * Use the passed "regs" pointer to determine how much space we need - * for a kernel fork().   */  int  copy_thread(unsigned long clone_flags, unsigned long usp, -	    unsigned long unused, -	    struct task_struct * p, struct pt_regs * regs) +	    unsigned long arg, +	    struct task_struct *p)  {  	extern void ret_from_fork(void); +	extern void ret_from_kernel_thread(void);  	struct thread_info *childti = task_thread_info(p); -	struct pt_regs * childregs; -	struct switch_stack * childstack, *stack; -	unsigned long stack_offset, settls; - -	stack_offset = PAGE_SIZE - sizeof(struct pt_regs); -	if (!(regs->ps & 8)) -		stack_offset = (PAGE_SIZE-1) & (unsigned long) regs; -	childregs = (struct pt_regs *) -	  (stack_offset + PAGE_SIZE + task_stack_page(p)); -		 -	*childregs = *regs; -	settls = regs->r20; -	childregs->r0 = 0; -	childregs->r19 = 0; -	childregs->r20 = 1;	/* OSF/1 has some strange fork() semantics.  */ -	regs->r20 = 0; -	stack = ((struct switch_stack *) regs) - 1; +	struct pt_regs *childregs = task_pt_regs(p); +	struct pt_regs *regs = current_pt_regs(); +	struct switch_stack *childstack, *stack; +  	childstack = ((struct switch_stack *) childregs) - 1; -	*childstack = *stack; -	childstack->r26 = (unsigned long) ret_from_fork; -	childti->pcb.usp = usp;  	childti->pcb.ksp = (unsigned long) childstack;  	childti->pcb.flags = 1;	/* set FEN, clear everything else */ -	/* Set a new TLS for the child thread?  Peek back into the -	   syscall arguments that we saved on syscall entry.  Oops, -	   except we'd have clobbered it with the parent/child set -	   of r20.  Read the saved copy.  */ +	if (unlikely(p->flags & PF_KTHREAD)) { +		/* kernel thread */ +		memset(childstack, 0, +			sizeof(struct switch_stack) + sizeof(struct pt_regs)); +		childstack->r26 = (unsigned long) ret_from_kernel_thread; +		childstack->r9 = usp;	/* function */ +		childstack->r10 = arg; +		childregs->hae = alpha_mv.hae_cache, +		childti->pcb.usp = 0; +		return 0; +	}  	/* Note: if CLONE_SETTLS is not set, then we must inherit the  	   value from the parent, which will have been set by the block  	   copy in dup_task_struct.  This is non-intuitive, but is  	   required for proper operation in the case of a threaded  	   application calling fork.  */  	if (clone_flags & CLONE_SETTLS) -		childti->pcb.unique = settls; - +		childti->pcb.unique = regs->r20; +	childti->pcb.usp = usp ?: rdusp(); +	*childregs = *regs; +	childregs->r0 = 0; +	childregs->r19 = 0; +	childregs->r20 = 1;	/* OSF/1 has some strange fork() semantics.  */ +	regs->r20 = 0; +	stack = ((struct switch_stack *) regs) - 1; +	*childstack = *stack; +	childstack->r26 = (unsigned long) ret_from_fork;  	return 0;  } @@ -384,27 +353,6 @@ dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task)  EXPORT_SYMBOL(dump_elf_task_fp);  /* - * sys_execve() executes a new program. - */ -asmlinkage int -do_sys_execve(const char __user *ufilename, -	      const char __user *const __user *argv, -	      const char __user *const __user *envp, struct pt_regs *regs) -{ -	int error; -	char *filename; - -	filename = getname(ufilename); -	error = PTR_ERR(filename); -	if (IS_ERR(filename)) -		goto out; -	error = do_execve(filename, argv, envp, regs); -	putname(filename); -out: -	return error; -} - -/*   * Return saved PC of a blocked thread.  This assumes the frame   * pointer is the 6th saved long on the kernel stack and that the   * saved return address is the first long in the frame.  This all diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h index d3e52d3fd59..da2d6ec9c37 100644 --- a/arch/alpha/kernel/proto.h +++ b/arch/alpha/kernel/proto.h @@ -135,17 +135,15 @@ extern void unregister_srm_console(void);  /* smp.c */  extern void setup_smp(void);  extern void handle_ipi(struct pt_regs *); -extern void smp_percpu_timer_interrupt(struct pt_regs *);  /* bios32.c */  /* extern void reset_for_srm(void); */  /* time.c */ -extern irqreturn_t timer_interrupt(int irq, void *dev); +extern irqreturn_t rtc_timer_interrupt(int irq, void *dev); +extern void init_clockevent(void);  extern void common_init_rtc(void);  extern unsigned long est_cycle_freq; -extern unsigned int common_get_rtc_time(struct rtc_time *time); -extern int common_set_rtc_time(struct rtc_time *time);  /* smc37c93x.c */  extern void SMC93x_Init(void); diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c index e2af5eb59bb..86d835157b5 100644 --- a/arch/alpha/kernel/ptrace.c +++ b/arch/alpha/kernel/ptrace.c @@ -13,10 +13,11 @@  #include <linux/user.h>  #include <linux/security.h>  #include <linux/signal.h> +#include <linux/tracehook.h> +#include <linux/audit.h>  #include <asm/uaccess.h>  #include <asm/pgtable.h> -#include <asm/system.h>  #include <asm/fpu.h>  #include "proto.h" @@ -313,25 +314,21 @@ long arch_ptrace(struct task_struct *child, long request,  	return ret;  } +asmlinkage unsigned long syscall_trace_enter(void) +{ +	unsigned long ret = 0; +	struct pt_regs *regs = current_pt_regs(); +	if (test_thread_flag(TIF_SYSCALL_TRACE) && +	    tracehook_report_syscall_entry(current_pt_regs())) +		ret = -1UL; +	audit_syscall_entry(AUDIT_ARCH_ALPHA, regs->r0, regs->r16, regs->r17, regs->r18, regs->r19); +	return ret ?: current_pt_regs()->r0; +} +  asmlinkage void -syscall_trace(void) +syscall_trace_leave(void)  { -	if (!test_thread_flag(TIF_SYSCALL_TRACE)) -		return; -	if (!(current->ptrace & PT_PTRACED)) -		return; -	/* The 0x80 provides a way for the tracing parent to distinguish -	   between a syscall stop and SIGTRAP delivery */ -	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) -				 ? 0x80 : 0)); - -	/* -	 * This isn't the same as continuing with a signal, but it will do -	 * for normal use.  strace only continues with a signal if the -	 * stopping signal is not SIGTRAP.  -brl -	 */ -	if (current->exit_code) { -		send_sig(current->exit_code, current, 1); -		current->exit_code = 0; -	} +	audit_syscall_exit(current_pt_regs()); +	if (test_thread_flag(TIF_SYSCALL_TRACE)) +		tracehook_report_syscall_exit(current_pt_regs(), 0);  } diff --git a/arch/alpha/kernel/rtc.c b/arch/alpha/kernel/rtc.c new file mode 100644 index 00000000000..c8d284d8521 --- /dev/null +++ b/arch/alpha/kernel/rtc.c @@ -0,0 +1,323 @@ +/* + *  linux/arch/alpha/kernel/rtc.c + * + *  Copyright (C) 1991, 1992, 1995, 1999, 2000  Linus Torvalds + * + * This file contains date handling. + */ +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/param.h> +#include <linux/string.h> +#include <linux/mc146818rtc.h> +#include <linux/bcd.h> +#include <linux/rtc.h> +#include <linux/platform_device.h> + +#include <asm/rtc.h> + +#include "proto.h" + + +/* + * Support for the RTC device. + * + * We don't want to use the rtc-cmos driver, because we don't want to support + * alarms, as that would be indistinguishable from timer interrupts. + * + * Further, generic code is really, really tied to a 1900 epoch.  This is + * true in __get_rtc_time as well as the users of struct rtc_time e.g. + * rtc_tm_to_time.  Thankfully all of the other epochs in use are later + * than 1900, and so it's easy to adjust. + */ + +static unsigned long rtc_epoch; + +static int __init +specifiy_epoch(char *str) +{ +	unsigned long epoch = simple_strtoul(str, NULL, 0); +	if (epoch < 1900) +		printk("Ignoring invalid user specified epoch %lu\n", epoch); +	else +		rtc_epoch = epoch; +	return 1; +} +__setup("epoch=", specifiy_epoch); + +static void __init +init_rtc_epoch(void) +{ +	int epoch, year, ctrl; + +	if (rtc_epoch != 0) { +		/* The epoch was specified on the command-line.  */ +		return; +	} + +	/* Detect the epoch in use on this computer.  */ +	ctrl = CMOS_READ(RTC_CONTROL); +	year = CMOS_READ(RTC_YEAR); +	if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) +		year = bcd2bin(year); + +	/* PC-like is standard; used for year >= 70 */ +	epoch = 1900; +	if (year < 20) { +		epoch = 2000; +	} else if (year >= 20 && year < 48) { +		/* NT epoch */ +		epoch = 1980; +	} else if (year >= 48 && year < 70) { +		/* Digital UNIX epoch */ +		epoch = 1952; +	} +	rtc_epoch = epoch; + +	printk(KERN_INFO "Using epoch %d for rtc year %d\n", epoch, year); +} + +static int +alpha_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ +	__get_rtc_time(tm); + +	/* Adjust for non-default epochs.  It's easier to depend on the +	   generic __get_rtc_time and adjust the epoch here than create +	   a copy of __get_rtc_time with the edits we need.  */ +	if (rtc_epoch != 1900) { +		int year = tm->tm_year; +		/* Undo the century adjustment made in __get_rtc_time.  */ +		if (year >= 100) +			year -= 100; +		year += rtc_epoch - 1900; +		/* Redo the century adjustment with the epoch in place.  */ +		if (year <= 69) +			year += 100; +		tm->tm_year = year; +	} + +	return rtc_valid_tm(tm); +} + +static int +alpha_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ +	struct rtc_time xtm; + +	if (rtc_epoch != 1900) { +		xtm = *tm; +		xtm.tm_year -= rtc_epoch - 1900; +		tm = &xtm; +	} + +	return __set_rtc_time(tm); +} + +static int +alpha_rtc_set_mmss(struct device *dev, unsigned long nowtime) +{ +	int retval = 0; +	int real_seconds, real_minutes, cmos_minutes; +	unsigned char save_control, save_freq_select; + +	/* Note: This code only updates minutes and seconds.  Comments +	   indicate this was to avoid messing with unknown time zones, +	   and with the epoch nonsense described above.  In order for +	   this to work, the existing clock cannot be off by more than +	   15 minutes. + +	   ??? This choice is may be out of date.  The x86 port does +	   not have problems with timezones, and the epoch processing has +	   now been fixed in alpha_set_rtc_time. + +	   In either case, one can always force a full rtc update with +	   the userland hwclock program, so surely 15 minute accuracy +	   is no real burden.  */ + +	/* In order to set the CMOS clock precisely, we have to be called +	   500 ms after the second nowtime has started, because when +	   nowtime is written into the registers of the CMOS clock, it will +	   jump to the next second precisely 500 ms later. Check the Motorola +	   MC146818A or Dallas DS12887 data sheet for details.  */ + +	/* irq are locally disabled here */ +	spin_lock(&rtc_lock); +	/* Tell the clock it's being set */ +	save_control = CMOS_READ(RTC_CONTROL); +	CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); + +	/* Stop and reset prescaler */ +	save_freq_select = CMOS_READ(RTC_FREQ_SELECT); +	CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); + +	cmos_minutes = CMOS_READ(RTC_MINUTES); +	if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) +		cmos_minutes = bcd2bin(cmos_minutes); + +	real_seconds = nowtime % 60; +	real_minutes = nowtime / 60; +	if (((abs(real_minutes - cmos_minutes) + 15) / 30) & 1) { +		/* correct for half hour time zone */ +		real_minutes += 30; +	} +	real_minutes %= 60; + +	if (abs(real_minutes - cmos_minutes) < 30) { +		if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { +			real_seconds = bin2bcd(real_seconds); +			real_minutes = bin2bcd(real_minutes); +		} +		CMOS_WRITE(real_seconds,RTC_SECONDS); +		CMOS_WRITE(real_minutes,RTC_MINUTES); +	} else { +		printk_once(KERN_NOTICE +			    "set_rtc_mmss: can't update from %d to %d\n", +			    cmos_minutes, real_minutes); +		retval = -1; +	} + +	/* The following flags have to be released exactly in this order, +	 * otherwise the DS12887 (popular MC146818A clone with integrated +	 * battery and quartz) will not reset the oscillator and will not +	 * update precisely 500 ms later. You won't find this mentioned in +	 * the Dallas Semiconductor data sheets, but who believes data +	 * sheets anyway ...                           -- Markus Kuhn +	 */ +	CMOS_WRITE(save_control, RTC_CONTROL); +	CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); +	spin_unlock(&rtc_lock); + +	return retval; +} + +static int +alpha_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) +{ +	switch (cmd) { +	case RTC_EPOCH_READ: +		return put_user(rtc_epoch, (unsigned long __user *)arg); +	case RTC_EPOCH_SET: +		if (arg < 1900) +			return -EINVAL; +		rtc_epoch = arg; +		return 0; +	default: +		return -ENOIOCTLCMD; +	} +} + +static const struct rtc_class_ops alpha_rtc_ops = { +	.read_time = alpha_rtc_read_time, +	.set_time = alpha_rtc_set_time, +	.set_mmss = alpha_rtc_set_mmss, +	.ioctl = alpha_rtc_ioctl, +}; + +/* + * Similarly, except do the actual CMOS access on the boot cpu only. + * This requires marshalling the data across an interprocessor call. + */ + +#if defined(CONFIG_SMP) && \ +    (defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_MARVEL)) +# define HAVE_REMOTE_RTC 1 + +union remote_data { +	struct rtc_time *tm; +	unsigned long now; +	long retval; +}; + +static void +do_remote_read(void *data) +{ +	union remote_data *x = data; +	x->retval = alpha_rtc_read_time(NULL, x->tm); +} + +static int +remote_read_time(struct device *dev, struct rtc_time *tm) +{ +	union remote_data x; +	if (smp_processor_id() != boot_cpuid) { +		x.tm = tm; +		smp_call_function_single(boot_cpuid, do_remote_read, &x, 1); +		return x.retval; +	} +	return alpha_rtc_read_time(NULL, tm); +} + +static void +do_remote_set(void *data) +{ +	union remote_data *x = data; +	x->retval = alpha_rtc_set_time(NULL, x->tm); +} + +static int +remote_set_time(struct device *dev, struct rtc_time *tm) +{ +	union remote_data x; +	if (smp_processor_id() != boot_cpuid) { +		x.tm = tm; +		smp_call_function_single(boot_cpuid, do_remote_set, &x, 1); +		return x.retval; +	} +	return alpha_rtc_set_time(NULL, tm); +} + +static void +do_remote_mmss(void *data) +{ +	union remote_data *x = data; +	x->retval = alpha_rtc_set_mmss(NULL, x->now); +} + +static int +remote_set_mmss(struct device *dev, unsigned long now) +{ +	union remote_data x; +	if (smp_processor_id() != boot_cpuid) { +		x.now = now; +		smp_call_function_single(boot_cpuid, do_remote_mmss, &x, 1); +		return x.retval; +	} +	return alpha_rtc_set_mmss(NULL, now); +} + +static const struct rtc_class_ops remote_rtc_ops = { +	.read_time = remote_read_time, +	.set_time = remote_set_time, +	.set_mmss = remote_set_mmss, +	.ioctl = alpha_rtc_ioctl, +}; +#endif + +static int __init +alpha_rtc_init(void) +{ +	const struct rtc_class_ops *ops; +	struct platform_device *pdev; +	struct rtc_device *rtc; +	const char *name; + +	init_rtc_epoch(); +	name = "rtc-alpha"; +	ops = &alpha_rtc_ops; + +#ifdef HAVE_REMOTE_RTC +	if (alpha_mv.rtc_boot_cpu_only) +		ops = &remote_rtc_ops; +#endif + +	pdev = platform_device_register_simple(name, -1, NULL, 0); +	rtc = devm_rtc_device_register(&pdev->dev, name, ops, THIS_MODULE); +	if (IS_ERR(rtc)) +		return PTR_ERR(rtc); + +	platform_set_drvdata(pdev, rtc); +	return 0; +} +device_initcall(alpha_rtc_init); diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index d2634e4476b..b20af76f12c 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -43,6 +43,7 @@  #include <asm/setup.h>  #include <asm/io.h>  #include <linux/log2.h> +#include <linux/export.h>  extern struct atomic_notifier_head panic_notifier_list;  static int alpha_panic_event(struct notifier_block *, unsigned long, void *); @@ -54,7 +55,6 @@ static struct notifier_block alpha_panic_block = {  #include <asm/uaccess.h>  #include <asm/pgtable.h> -#include <asm/system.h>  #include <asm/hwrpb.h>  #include <asm/dma.h>  #include <asm/mmu_context.h> @@ -115,10 +115,17 @@ unsigned long alpha_agpgart_size = DEFAULT_AGP_APER_SIZE;  #ifdef CONFIG_ALPHA_GENERIC  struct alpha_machine_vector alpha_mv; +#endif + +#ifndef alpha_using_srm  int alpha_using_srm;  EXPORT_SYMBOL(alpha_using_srm);  #endif +#ifndef alpha_using_qemu +int alpha_using_qemu; +#endif +  static struct alpha_machine_vector *get_sysvec(unsigned long, unsigned long,  					       unsigned long);  static struct alpha_machine_vector *get_sysvec_byname(const char *); @@ -529,11 +536,15 @@ setup_arch(char **cmdline_p)  	atomic_notifier_chain_register(&panic_notifier_list,  			&alpha_panic_block); -#ifdef CONFIG_ALPHA_GENERIC +#ifndef alpha_using_srm  	/* Assume that we've booted from SRM if we haven't booted from MILO.  	   Detect the later by looking for "MILO" in the system serial nr.  */  	alpha_using_srm = strncmp((const char *)hwrpb->ssn, "MILO", 4) != 0;  #endif +#ifndef alpha_using_qemu +	/* Similarly, look for QEMU.  */ +	alpha_using_qemu = strstr((const char *)hwrpb->ssn, "QEMU") != 0; +#endif  	/* If we are using SRM, we want to allow callbacks  	   as early as possible, so do this NOW, and then @@ -1207,6 +1218,7 @@ show_cpuinfo(struct seq_file *f, void *slot)  	char *systype_name;  	char *sysvariation_name;  	int nr_processors; +	unsigned long timer_freq;  	cpu_index = (unsigned) (cpu->type - 1);  	cpu_name = "Unknown"; @@ -1218,6 +1230,12 @@ show_cpuinfo(struct seq_file *f, void *slot)  	nr_processors = get_nr_processors(cpu, hwrpb->nr_processors); +#if CONFIG_HZ == 1024 || CONFIG_HZ == 1200 +	timer_freq = (100UL * hwrpb->intr_freq) / 4096; +#else +	timer_freq = 100UL * CONFIG_HZ; +#endif +  	seq_printf(f, "cpu\t\t\t: Alpha\n"  		      "cpu model\t\t: %s\n"  		      "cpu variation\t\t: %ld\n" @@ -1243,8 +1261,7 @@ show_cpuinfo(struct seq_file *f, void *slot)  		       (char*)hwrpb->ssn,  		       est_cycle_freq ? : hwrpb->cycle_freq,  		       est_cycle_freq ? "est." : "", -		       hwrpb->intr_freq / 4096, -		       (100 * hwrpb->intr_freq / 4096) % 100, +		       timer_freq / 100, timer_freq % 100,  		       hwrpb->pagesize,  		       hwrpb->pa_bits,  		       hwrpb->max_asn, @@ -1257,7 +1274,7 @@ show_cpuinfo(struct seq_file *f, void *slot)  #ifdef CONFIG_SMP  	seq_printf(f, "cpus active\t\t: %u\n"  		      "cpu active mask\t\t: %016lx\n", -		       num_online_cpus(), cpus_addr(cpu_possible_map)[0]); +		       num_online_cpus(), cpumask_bits(cpu_possible_mask)[0]);  #endif  	show_cache_size (f, "L1 Icache", alpha_l1i_cacheshape); @@ -1404,8 +1421,6 @@ determine_cpu_caches (unsigned int cpu_type)  	case PCA56_CPU:  	case PCA57_CPU:  	  { -		unsigned long cbox_config, size; -  		if (cpu_type == PCA56_CPU) {  			L1I = CSHAPE(16*1024, 6, 1);  			L1D = CSHAPE(8*1024, 5, 1); @@ -1415,10 +1430,12 @@ determine_cpu_caches (unsigned int cpu_type)  		}  		L3 = -1; +#if 0 +		unsigned long cbox_config, size; +  		cbox_config = *(vulp) phys_to_virt (0xfffff00008UL);  		size = 512*1024 * (1 << ((cbox_config >> 12) & 3)); -#if 0  		L2 = ((cbox_config >> 31) & 1 ? CSHAPE (size, 6, 1) : -1);  #else  		L2 = external_cache_probe(512*1024, 6); diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c index 6f7feb5db27..6cec2881acb 100644 --- a/arch/alpha/kernel/signal.c +++ b/arch/alpha/kernel/signal.c @@ -34,9 +34,6 @@  #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))  asmlinkage void ret_from_sys_call(void); -static void do_signal(struct pt_regs *, struct switch_stack *, -		      unsigned long, unsigned long); -  /*   * The OSF/1 sigprocmask calling sequence is different from the @@ -116,30 +113,6 @@ SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act,  }  /* - * Atomically swap in the new signal mask, and wait for a signal. - */ -SYSCALL_DEFINE1(sigsuspend, old_sigset_t, mask) -{ -	mask &= _BLOCKABLE; -	spin_lock_irq(¤t->sighand->siglock); -	current->saved_sigmask = current->blocked; -	siginitset(¤t->blocked, mask); -	recalc_sigpending(); -	spin_unlock_irq(¤t->sighand->siglock); - -	current->state = TASK_INTERRUPTIBLE; -	schedule(); -	set_thread_flag(TIF_RESTORE_SIGMASK); -	return -ERESTARTNOHAND; -} - -asmlinkage int -sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) -{ -	return do_sigaltstack(uss, uoss, rdusp()); -} - -/*   * Do a signal return; undo the signal stack.   */ @@ -171,10 +144,10 @@ extern char compile_time_assert  #define INSN_CALLSYS		0x00000083  static long -restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, -		   struct switch_stack *sw) +restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs)  {  	unsigned long usp; +	struct switch_stack *sw = (struct switch_stack *)regs - 1;  	long i, err = __get_user(regs->pc, &sc->sc_pc);  	current_thread_info()->restart_block.fn = do_no_restart_syscall; @@ -226,9 +199,9 @@ restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,     registers and transfer control from userland.  */  asmlinkage void -do_sigreturn(struct sigcontext __user *sc, struct pt_regs *regs, -	     struct switch_stack *sw) +do_sigreturn(struct sigcontext __user *sc)  { +	struct pt_regs *regs = current_pt_regs();  	sigset_t set;  	/* Verify that it's a good sigcontext before using it */ @@ -237,13 +210,9 @@ do_sigreturn(struct sigcontext __user *sc, struct pt_regs *regs,  	if (__get_user(set.sig[0], &sc->sc_mask))  		goto give_sigsegv; -	sigdelsetmask(&set, ~_BLOCKABLE); -	spin_lock_irq(¤t->sighand->siglock); -	current->blocked = set; -	recalc_sigpending(); -	spin_unlock_irq(¤t->sighand->siglock); +	set_current_blocked(&set); -	if (restore_sigcontext(sc, regs, sw)) +	if (restore_sigcontext(sc, regs))  		goto give_sigsegv;  	/* Send SIGTRAP if we're single-stepping: */ @@ -264,9 +233,9 @@ give_sigsegv:  }  asmlinkage void -do_rt_sigreturn(struct rt_sigframe __user *frame, struct pt_regs *regs, -		struct switch_stack *sw) +do_rt_sigreturn(struct rt_sigframe __user *frame)  { +	struct pt_regs *regs = current_pt_regs();  	sigset_t set;  	/* Verify that it's a good ucontext_t before using it */ @@ -275,13 +244,9 @@ do_rt_sigreturn(struct rt_sigframe __user *frame, struct pt_regs *regs,  	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))  		goto give_sigsegv; -	sigdelsetmask(&set, ~_BLOCKABLE); -	spin_lock_irq(¤t->sighand->siglock); -	current->blocked = set; -	recalc_sigpending(); -	spin_unlock_irq(¤t->sighand->siglock); +	set_current_blocked(&set); -	if (restore_sigcontext(&frame->uc.uc_mcontext, regs, sw)) +	if (restore_sigcontext(&frame->uc.uc_mcontext, regs))  		goto give_sigsegv;  	/* Send SIGTRAP if we're single-stepping: */ @@ -307,18 +272,16 @@ give_sigsegv:   */  static inline void __user * -get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) +get_sigframe(struct ksignal *ksig, unsigned long sp, size_t frame_size)  { -	if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp)) -		sp = current->sas_ss_sp + current->sas_ss_size; - -	return (void __user *)((sp - frame_size) & -32ul); +	return (void __user *)((sigsp(sp, ksig) - frame_size) & -32ul);  }  static long  setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,  -		 struct switch_stack *sw, unsigned long mask, unsigned long sp) +		 unsigned long mask, unsigned long sp)  { +	struct switch_stack *sw = (struct switch_stack *)regs - 1;  	long i, err = 0;  	err |= __put_user(on_sig_stack((unsigned long)sc), &sc->sc_onstack); @@ -372,26 +335,24 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,  }  static int -setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, -	    struct pt_regs *regs, struct switch_stack * sw) +setup_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)  {  	unsigned long oldsp, r26, err = 0;  	struct sigframe __user *frame;  	oldsp = rdusp(); -	frame = get_sigframe(ka, oldsp, sizeof(*frame)); +	frame = get_sigframe(ksig, oldsp, sizeof(*frame));  	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) -		goto give_sigsegv; +		return -EFAULT; -	err |= setup_sigcontext(&frame->sc, regs, sw, set->sig[0], oldsp); +	err |= setup_sigcontext(&frame->sc, regs, set->sig[0], oldsp);  	if (err) -		goto give_sigsegv; +		return -EFAULT;  	/* Set up to return from userspace.  If provided, use a stub  	   already in userspace.  */ -	if (ka->ka_restorer) { -		r26 = (unsigned long) ka->ka_restorer; -	} else { +	r26 = (unsigned long) ksig->ka.ka_restorer; +	if (!r26) {  		err |= __put_user(INSN_MOV_R30_R16, frame->retcode+0);  		err |= __put_user(INSN_LDI_R0+__NR_sigreturn, frame->retcode+1);  		err |= __put_user(INSN_CALLSYS, frame->retcode+2); @@ -401,12 +362,12 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,  	/* Check that everything was written properly.  */  	if (err) -		goto give_sigsegv; +		return err;  	/* "Return" to the handler */  	regs->r26 = r26; -	regs->r27 = regs->pc = (unsigned long) ka->sa.sa_handler; -	regs->r16 = sig;			/* a0: signal number */ +	regs->r27 = regs->pc = (unsigned long) ksig->ka.sa.sa_handler; +	regs->r16 = ksig->sig;			/* a0: signal number */  	regs->r17 = 0;				/* a1: exception code */  	regs->r18 = (unsigned long) &frame->sc;	/* a2: sigcontext pointer */  	wrusp((unsigned long) frame); @@ -415,46 +376,37 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,  	printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",  		current->comm, current->pid, frame, regs->pc, regs->r26);  #endif -  	return 0; - -give_sigsegv: -	force_sigsegv(sig, current); -	return -EFAULT;  }  static int -setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, -	       sigset_t *set, struct pt_regs *regs, struct switch_stack * sw) +setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)  {  	unsigned long oldsp, r26, err = 0;  	struct rt_sigframe __user *frame;  	oldsp = rdusp(); -	frame = get_sigframe(ka, oldsp, sizeof(*frame)); +	frame = get_sigframe(ksig, oldsp, sizeof(*frame));  	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) -		goto give_sigsegv; +		return -EFAULT; -	err |= copy_siginfo_to_user(&frame->info, info); +	err |= copy_siginfo_to_user(&frame->info, &ksig->info);  	/* Create the ucontext.  */  	err |= __put_user(0, &frame->uc.uc_flags);  	err |= __put_user(0, &frame->uc.uc_link);  	err |= __put_user(set->sig[0], &frame->uc.uc_osf_sigmask); -	err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); -	err |= __put_user(sas_ss_flags(oldsp), &frame->uc.uc_stack.ss_flags); -	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); -	err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, sw, +	err |= __save_altstack(&frame->uc.uc_stack, oldsp); +	err |= setup_sigcontext(&frame->uc.uc_mcontext, regs,   				set->sig[0], oldsp);  	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));  	if (err) -		goto give_sigsegv; +		return -EFAULT;  	/* Set up to return from userspace.  If provided, use a stub  	   already in userspace.  */ -	if (ka->ka_restorer) { -		r26 = (unsigned long) ka->ka_restorer; -	} else { +	r26 = (unsigned long) ksig->ka.ka_restorer; +	if (!r26) {  		err |= __put_user(INSN_MOV_R30_R16, frame->retcode+0);  		err |= __put_user(INSN_LDI_R0+__NR_rt_sigreturn,  				  frame->retcode+1); @@ -464,12 +416,12 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,  	}  	if (err) -		goto give_sigsegv; +		return -EFAULT;  	/* "Return" to the handler */  	regs->r26 = r26; -	regs->r27 = regs->pc = (unsigned long) ka->sa.sa_handler; -	regs->r16 = sig;			  /* a0: signal number */ +	regs->r27 = regs->pc = (unsigned long) ksig->ka.sa.sa_handler; +	regs->r16 = ksig->sig;			  /* a0: signal number */  	regs->r17 = (unsigned long) &frame->info; /* a1: siginfo pointer */  	regs->r18 = (unsigned long) &frame->uc;	  /* a2: ucontext pointer */  	wrusp((unsigned long) frame); @@ -480,37 +432,24 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,  #endif  	return 0; - -give_sigsegv: -	force_sigsegv(sig, current); -	return -EFAULT;  }  /*   * OK, we're invoking a handler.   */ -static inline int -handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, -	      sigset_t *oldset, struct pt_regs * regs, struct switch_stack *sw) +static inline void +handle_signal(struct ksignal *ksig, struct pt_regs *regs)  { +	sigset_t *oldset = sigmask_to_save();  	int ret; -	if (ka->sa.sa_flags & SA_SIGINFO) -		ret = setup_rt_frame(sig, ka, info, oldset, regs, sw); +	if (ksig->ka.sa.sa_flags & SA_SIGINFO) +		ret = setup_rt_frame(ksig, oldset, regs);  	else -		ret = setup_frame(sig, ka, oldset, regs, sw); - -	if (ret == 0) { -		spin_lock_irq(¤t->sighand->siglock); -		sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); -		if (!(ka->sa.sa_flags & SA_NODEFER))  -			sigaddset(¤t->blocked,sig); -		recalc_sigpending(); -		spin_unlock_irq(¤t->sighand->siglock); -	} +		ret = setup_frame(ksig, oldset, regs); -	return ret; +	signal_setup_done(ret, ksig, 0);  }  static inline void @@ -551,83 +490,62 @@ syscall_restart(unsigned long r0, unsigned long r19,   * all (if we get here from anything but a syscall return, it will be 0)   */  static void -do_signal(struct pt_regs * regs, struct switch_stack * sw, -	  unsigned long r0, unsigned long r19) +do_signal(struct pt_regs *regs, unsigned long r0, unsigned long r19)  { -	siginfo_t info; -	int signr;  	unsigned long single_stepping = ptrace_cancel_bpt(current); -	struct k_sigaction ka; -	sigset_t *oldset; - -	if (test_thread_flag(TIF_RESTORE_SIGMASK)) -		oldset = ¤t->saved_sigmask; -	else -		oldset = ¤t->blocked; +	struct ksignal ksig;  	/* This lets the debugger run, ... */ -	signr = get_signal_to_deliver(&info, &ka, regs, NULL); - -	/* ... so re-check the single stepping. */ -	single_stepping |= ptrace_cancel_bpt(current); - -	if (signr > 0) { +	if (get_signal(&ksig)) { +		/* ... so re-check the single stepping. */ +		single_stepping |= ptrace_cancel_bpt(current);  		/* Whee!  Actually deliver the signal.  */  		if (r0) -			syscall_restart(r0, r19, regs, &ka); -		if (handle_signal(signr, &ka, &info, oldset, regs, sw) == 0) { -			/* A signal was successfully delivered, and the -			   saved sigmask was stored on the signal frame, -			   and will be restored by sigreturn.  So we can -			   simply clear the restore sigmask flag.  */ -			if (test_thread_flag(TIF_RESTORE_SIGMASK)) -				clear_thread_flag(TIF_RESTORE_SIGMASK); -		} -		if (single_stepping)  -			ptrace_set_bpt(current); /* re-set bpt */ -		return; -	} - -	if (r0) { -	  	switch (regs->r0) { -		case ERESTARTNOHAND: -		case ERESTARTSYS: -		case ERESTARTNOINTR: -			/* Reset v0 and a3 and replay syscall.  */ -			regs->r0 = r0; -			regs->r19 = r19; -			regs->pc -= 4; -			break; -		case ERESTART_RESTARTBLOCK: -			/* Force v0 to the restart syscall and reply.  */ -			regs->r0 = __NR_restart_syscall; -			regs->pc -= 4; -			break; +			syscall_restart(r0, r19, regs, &ksig.ka); +		handle_signal(&ksig, regs); +	} else { +		single_stepping |= ptrace_cancel_bpt(current); +		if (r0) { +			switch (regs->r0) { +			case ERESTARTNOHAND: +			case ERESTARTSYS: +			case ERESTARTNOINTR: +				/* Reset v0 and a3 and replay syscall.  */ +				regs->r0 = r0; +				regs->r19 = r19; +				regs->pc -= 4; +				break; +			case ERESTART_RESTARTBLOCK: +				/* Set v0 to the restart_syscall and replay */ +				regs->r0 = __NR_restart_syscall; +				regs->pc -= 4; +				break; +			}  		} +		restore_saved_sigmask();  	} - -	/* If there's no signal to deliver, we just restore the saved mask.  */ -	if (test_thread_flag(TIF_RESTORE_SIGMASK)) { -		clear_thread_flag(TIF_RESTORE_SIGMASK); -		sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); -	} -  	if (single_stepping)  		ptrace_set_bpt(current);	/* re-set breakpoint */  }  void -do_notify_resume(struct pt_regs *regs, struct switch_stack *sw, -		 unsigned long thread_info_flags, +do_work_pending(struct pt_regs *regs, unsigned long thread_flags,  		 unsigned long r0, unsigned long r19)  { -	if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) -		do_signal(regs, sw, r0, r19); - -	if (thread_info_flags & _TIF_NOTIFY_RESUME) { -		clear_thread_flag(TIF_NOTIFY_RESUME); -		tracehook_notify_resume(regs); -		if (current->replacement_session_keyring) -			key_replace_session_keyring(); -	} +	do { +		if (thread_flags & _TIF_NEED_RESCHED) { +			schedule(); +		} else { +			local_irq_enable(); +			if (thread_flags & _TIF_SIGPENDING) { +				do_signal(regs, r0, r19); +				r0 = 0; +			} else { +				clear_thread_flag(TIF_NOTIFY_RESUME); +				tracehook_notify_resume(regs); +			} +		} +		local_irq_disable(); +		thread_flags = current_thread_info()->flags; +	} while (thread_flags & _TIF_WORK_MASK);  } diff --git a/arch/alpha/kernel/smc37c669.c b/arch/alpha/kernel/smc37c669.c index 0435921d41c..c803fc76ae4 100644 --- a/arch/alpha/kernel/smc37c669.c +++ b/arch/alpha/kernel/smc37c669.c @@ -933,18 +933,6 @@ void SMC37c669_display_device_info(   *   *--   */ -#if 0 -/* $INCLUDE_OPTIONS$ */ -#include    "cp$inc:platform_io.h" -/* $INCLUDE_OPTIONS_END$ */ -#include    "cp$src:common.h" -#include    "cp$inc:prototypes.h" -#include    "cp$src:kernel_def.h" -#include    "cp$src:msg_def.h" -#include    "cp$src:smcc669_def.h" -/* Platform-specific includes */ -#include    "cp$src:platform.h" -#endif  #ifndef TRUE  #define TRUE 1 diff --git a/arch/alpha/kernel/smc37c93x.c b/arch/alpha/kernel/smc37c93x.c index 3e6a2893af9..6886b834f48 100644 --- a/arch/alpha/kernel/smc37c93x.c +++ b/arch/alpha/kernel/smc37c93x.c @@ -79,7 +79,6 @@  static unsigned long __init SMCConfigState(unsigned long baseAddr)  {  	unsigned char devId; -	unsigned char devRev;  	unsigned long configPort;  	unsigned long indexPort; @@ -100,7 +99,7 @@ static unsigned long __init SMCConfigState(unsigned long baseAddr)  		devId = inb(dataPort);  		if (devId == VALID_DEVICE_ID) {  			outb(DEVICE_REV, indexPort); -			devRev = inb(dataPort); +			/* unsigned char devRev = */ inb(dataPort);  			break;  		}  		else diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index 42aa078a5e4..99ac36d5de4 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c @@ -31,7 +31,7 @@  #include <asm/hwrpb.h>  #include <asm/ptrace.h> -#include <asm/atomic.h> +#include <linux/atomic.h>  #include <asm/io.h>  #include <asm/irq.h> @@ -68,7 +68,7 @@ enum ipi_message_type {  };  /* Set to a secondary's cpuid when it comes online.  */ -static int smp_secondary_alive __devinitdata = 0; +static int smp_secondary_alive = 0;  int smp_num_probed;		/* Internal processor count */  int smp_num_cpus = 1;		/* Number that came online.  */ @@ -116,7 +116,7 @@ wait_boot_cpu_to_stop(int cpuid)  /*   * Where secondaries begin a life of C.   */ -void __cpuinit +void  smp_callin(void)  {  	int cpuid = hard_smp_processor_id(); @@ -138,9 +138,11 @@ smp_callin(void)  	/* Get our local ticker going. */  	smp_setup_percpu_timer(cpuid); +	init_clockevent();  	/* Call platform-specific callin, if specified */ -	if (alpha_mv.smp_callin) alpha_mv.smp_callin(); +	if (alpha_mv.smp_callin) +		alpha_mv.smp_callin();  	/* All kernel threads share the same mm context.  */  	atomic_inc(&init_mm.mm_count); @@ -166,12 +168,12 @@ smp_callin(void)  	DBGS(("smp_callin: commencing CPU %d current %p active_mm %p\n",  	      cpuid, current, current->active_mm)); -	/* Do nothing.  */ -	cpu_idle(); +	preempt_disable(); +	cpu_startup_entry(CPUHP_ONLINE);  }  /* Wait until hwrpb->txrdy is clear for cpu.  Return -1 on timeout.  */ -static int __devinit +static int  wait_for_txrdy (unsigned long cpumask)  {  	unsigned long timeout; @@ -194,7 +196,7 @@ wait_for_txrdy (unsigned long cpumask)   * Send a message to a secondary's console.  "START" is one such   * interesting message.  ;-)   */ -static void __cpuinit +static void  send_secondary_console_msg(char *str, int cpuid)  {  	struct percpu_struct *cpu; @@ -264,9 +266,10 @@ recv_secondary_console_msg(void)  		if (cnt <= 0 || cnt >= 80)  			strcpy(buf, "<<< BOGUS MSG >>>");  		else { -			cp1 = (char *) &cpu->ipc_buffer[11]; +			cp1 = (char *) &cpu->ipc_buffer[1];  			cp2 = buf; -			strcpy(cp2, cp1); +			memcpy(cp2, cp1, cnt); +			cp2[cnt] = '\0';  			while ((cp2 = strchr(cp2, '\r')) != 0) {  				*cp2 = ' '; @@ -285,7 +288,7 @@ recv_secondary_console_msg(void)  /*   * Convince the console to have a secondary cpu begin execution.   */ -static int __cpuinit +static int  secondary_cpu_start(int cpuid, struct task_struct *idle)  {  	struct percpu_struct *cpu; @@ -356,25 +359,11 @@ secondary_cpu_start(int cpuid, struct task_struct *idle)  /*   * Bring one cpu online.   */ -static int __cpuinit -smp_boot_one_cpu(int cpuid) +static int +smp_boot_one_cpu(int cpuid, struct task_struct *idle)  { -	struct task_struct *idle;  	unsigned long timeout; -	/* Cook up an idler for this guy.  Note that the address we -	   give to kernel_thread is irrelevant -- it's going to start -	   where HWRPB.CPU_restart says to start.  But this gets all -	   the other task-y sort of data structures set up like we -	   wish.  We can't use kernel_thread since we must avoid -	   rescheduling the child.  */ -	idle = fork_idle(cpuid); -	if (IS_ERR(idle)) -		panic("failed fork for CPU %d", cpuid); - -	DBGS(("smp_boot_one_cpu: CPU %d state 0x%lx flags 0x%lx\n", -	      cpuid, idle->state, idle->flags)); -  	/* Signal the secondary to wait a moment.  */  	smp_secondary_alive = -1; @@ -450,8 +439,8 @@ setup_smp(void)  		smp_num_probed = 1;  	} -	printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_map = %lx\n", -	       smp_num_probed, cpu_present_map.bits[0]); +	printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n", +	       smp_num_probed, cpumask_bits(cpu_present_mask)[0]);  }  /* @@ -481,15 +470,15 @@ smp_prepare_cpus(unsigned int max_cpus)  	smp_num_cpus = smp_num_probed;  } -void __devinit +void  smp_prepare_boot_cpu(void)  {  } -int __cpuinit -__cpu_up(unsigned int cpu) +int +__cpu_up(unsigned int cpu, struct task_struct *tidle)  { -	smp_boot_one_cpu(cpu); +	smp_boot_one_cpu(cpu, tidle);  	return cpu_online(cpu) ? 0 : -ENOSYS;  } @@ -511,35 +500,6 @@ smp_cpus_done(unsigned int max_cpus)  	       ((bogosum + 2500) / (5000/HZ)) % 100);  } - -void -smp_percpu_timer_interrupt(struct pt_regs *regs) -{ -	struct pt_regs *old_regs; -	int cpu = smp_processor_id(); -	unsigned long user = user_mode(regs); -	struct cpuinfo_alpha *data = &cpu_data[cpu]; - -	old_regs = set_irq_regs(regs); - -	/* Record kernel PC.  */ -	profile_tick(CPU_PROFILING); - -	if (!--data->prof_counter) { -		/* We need to make like a normal interrupt -- otherwise -		   timer interrupts ignore the global interrupt lock, -		   which would be a Bad Thing.  */ -		irq_enter(); - -		update_process_times(user); - -		data->prof_counter = data->prof_multiplier; - -		irq_exit(); -	} -	set_irq_regs(old_regs); -} -  int  setup_profiling_timer(unsigned int multiplier)  { @@ -585,8 +545,7 @@ handle_ipi(struct pt_regs *regs)  		switch (which) {  		case IPI_RESCHEDULE: -			/* Reschedule callback.  Everything to be done -			   is done by the interrupt return path.  */ +			scheduler_ipi();  			break;  		case IPI_CALL_FUNC: @@ -630,8 +589,9 @@ smp_send_reschedule(int cpu)  void  smp_send_stop(void)  { -	cpumask_t to_whom = cpu_possible_map; -	cpu_clear(smp_processor_id(), to_whom); +	cpumask_t to_whom; +	cpumask_copy(&to_whom, cpu_possible_mask); +	cpumask_clear_cpu(smp_processor_id(), &to_whom);  #ifdef DEBUG_IPI_MSG  	if (hard_smp_processor_id() != boot_cpu_id)  		printk(KERN_WARNING "smp_send_stop: Not on boot cpu.\n"); diff --git a/arch/alpha/kernel/srm_env.c b/arch/alpha/kernel/srm_env.c index f0df3fbd840..ffe996a54fa 100644 --- a/arch/alpha/kernel/srm_env.c +++ b/arch/alpha/kernel/srm_env.c @@ -4,9 +4,8 @@   *   * (C) 2001,2002,2006 by Jan-Benedict Glaw <jbglaw@lug-owl.de>   * - * This driver is at all a modified version of Erik Mouw's - * Documentation/DocBook/procfs_example.c, so: thank - * you, Erik! He can be reached via email at + * This driver is a modified version of Erik Mouw's example proc + * interface, so: thank you, Erik! He can be reached via email at   * <J.A.K.Mouw@its.tudelft.nl>. It is based on an idea   * provided by DEC^WCompaq^WIntel's "Jumpstart" CD. They   * included a patch like this as well. Thanks for idea! @@ -52,13 +51,11 @@ MODULE_LICENSE("GPL");  typedef struct _srm_env {  	char			*name;  	unsigned long		id; -	struct proc_dir_entry	*proc_entry;  } srm_env_t;  static struct proc_dir_entry	*base_dir;  static struct proc_dir_entry	*named_dir;  static struct proc_dir_entry	*numbered_dir; -static char			number[256][4];  static srm_env_t	srm_named_entries[] = {  	{ "auto_action",	ENV_AUTO_ACTION		}, @@ -78,21 +75,18 @@ static srm_env_t	srm_named_entries[] = {  	{ "tty_dev",		ENV_TTY_DEV		},  	{ NULL,			0			},  }; -static srm_env_t	srm_numbered_entries[256]; -  static int srm_env_proc_show(struct seq_file *m, void *v)  {  	unsigned long	ret; -	srm_env_t	*entry; +	unsigned long	id = (unsigned long)m->private;  	char		*page; -	entry = m->private;  	page = (char *)__get_free_page(GFP_USER);  	if (!page)  		return -ENOMEM; -	ret = callback_getenv(entry->id, page, PAGE_SIZE); +	ret = callback_getenv(id, page, PAGE_SIZE);  	if ((ret >> 61) == 0) {  		seq_write(m, page, ret); @@ -105,14 +99,14 @@ static int srm_env_proc_show(struct seq_file *m, void *v)  static int srm_env_proc_open(struct inode *inode, struct file *file)  { -	return single_open(file, srm_env_proc_show, PDE(inode)->data); +	return single_open(file, srm_env_proc_show, PDE_DATA(inode));  }  static ssize_t srm_env_proc_write(struct file *file, const char __user *buffer,  				  size_t count, loff_t *pos)  {  	int res; -	srm_env_t	*entry = PDE(file->f_path.dentry->d_inode)->data; +	unsigned long	id = (unsigned long)PDE_DATA(file_inode(file));  	char		*buf = (char *) __get_free_page(GFP_USER);  	unsigned long	ret1, ret2; @@ -128,7 +122,7 @@ static ssize_t srm_env_proc_write(struct file *file, const char __user *buffer,  		goto out;  	buf[count] = '\0'; -	ret1 = callback_setenv(entry->id, buf, count); +	ret1 = callback_setenv(id, buf, count);  	if ((ret1 >> 61) == 0) {  		do  			ret2 = callback_save_env(); @@ -150,52 +144,6 @@ static const struct file_operations srm_env_proc_fops = {  	.write		= srm_env_proc_write,  }; -static void -srm_env_cleanup(void) -{ -	srm_env_t	*entry; -	unsigned long	var_num; - -	if (base_dir) { -		/* -		 * Remove named entries -		 */ -		if (named_dir) { -			entry = srm_named_entries; -			while (entry->name != NULL && entry->id != 0) { -				if (entry->proc_entry) { -					remove_proc_entry(entry->name, -							named_dir); -					entry->proc_entry = NULL; -				} -				entry++; -			} -			remove_proc_entry(NAMED_DIR, base_dir); -		} - -		/* -		 * Remove numbered entries -		 */ -		if (numbered_dir) { -			for (var_num = 0; var_num <= 255; var_num++) { -				entry =	&srm_numbered_entries[var_num]; - -				if (entry->proc_entry) { -					remove_proc_entry(entry->name, -							numbered_dir); -					entry->proc_entry	= NULL; -					entry->name		= NULL; -				} -			} -			remove_proc_entry(NUMBERED_DIR, base_dir); -		} - -		remove_proc_entry(BASE_DIR, NULL); -	} - -	return; -} -  static int __init  srm_env_init(void)  { @@ -214,19 +162,13 @@ srm_env_init(void)  	}  	/* -	 * Init numbers -	 */ -	for (var_num = 0; var_num <= 255; var_num++) -		sprintf(number[var_num], "%ld", var_num); - -	/*  	 * Create base directory  	 */  	base_dir = proc_mkdir(BASE_DIR, NULL);  	if (!base_dir) {  		printk(KERN_ERR "Couldn't create base dir /proc/%s\n",  				BASE_DIR); -		goto cleanup; +		return -ENOMEM;  	}  	/* @@ -255,9 +197,8 @@ srm_env_init(void)  	 */  	entry = srm_named_entries;  	while (entry->name && entry->id) { -		entry->proc_entry = proc_create_data(entry->name, 0644, named_dir, -						     &srm_env_proc_fops, entry); -		if (!entry->proc_entry) +		if (!proc_create_data(entry->name, 0644, named_dir, +			     &srm_env_proc_fops, (void *)entry->id))  			goto cleanup;  		entry++;  	} @@ -266,15 +207,11 @@ srm_env_init(void)  	 * Create all numbered nodes  	 */  	for (var_num = 0; var_num <= 255; var_num++) { -		entry = &srm_numbered_entries[var_num]; -		entry->name = number[var_num]; - -		entry->proc_entry = proc_create_data(entry->name, 0644, numbered_dir, -						     &srm_env_proc_fops, entry); -		if (!entry->proc_entry) +		char name[4]; +		sprintf(name, "%ld", var_num); +		if (!proc_create_data(name, 0644, numbered_dir, +			     &srm_env_proc_fops, (void *)var_num))  			goto cleanup; - -		entry->id			= var_num;  	}  	printk(KERN_INFO "%s: version %s loaded successfully\n", NAME, @@ -283,18 +220,15 @@ srm_env_init(void)  	return 0;  cleanup: -	srm_env_cleanup(); - +	remove_proc_subtree(BASE_DIR, NULL);  	return -ENOMEM;  }  static void __exit  srm_env_exit(void)  { -	srm_env_cleanup(); +	remove_proc_subtree(BASE_DIR, NULL);  	printk(KERN_INFO "%s: unloaded successfully\n", NAME); - -	return;  }  module_init(srm_env_init); diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c index 783f4e50c11..6f01d9ad7b8 100644 --- a/arch/alpha/kernel/srmcons.c +++ b/arch/alpha/kernel/srmcons.c @@ -30,10 +30,9 @@ static int srm_is_registered_console = 0;  #define MAX_SRM_CONSOLE_DEVICES 1	/* only support 1 console device */  struct srmcons_private { -	struct tty_struct *tty; +	struct tty_port port;  	struct timer_list timer; -	spinlock_t lock; -}; +} srmcons_singleton;  typedef union _srmcons_result {  	struct { @@ -45,7 +44,7 @@ typedef union _srmcons_result {  /* called with callback_lock held */  static int -srmcons_do_receive_chars(struct tty_struct *tty) +srmcons_do_receive_chars(struct tty_port *port)  {  	srmcons_result result;  	int count = 0, loops = 0; @@ -53,13 +52,13 @@ srmcons_do_receive_chars(struct tty_struct *tty)  	do {  		result.as_long = callback_getc(0);  		if (result.bits.status < 2) { -			tty_insert_flip_char(tty, (char)result.bits.c, 0); +			tty_insert_flip_char(port, (char)result.bits.c, 0);  			count++;  		}  	} while((result.bits.status & 1) && (++loops < 10));  	if (count) -		tty_schedule_flip(tty); +		tty_schedule_flip(port);  	return count;  } @@ -68,29 +67,28 @@ static void  srmcons_receive_chars(unsigned long data)  {  	struct srmcons_private *srmconsp = (struct srmcons_private *)data; +	struct tty_port *port = &srmconsp->port;  	unsigned long flags;  	int incr = 10;  	local_irq_save(flags);  	if (spin_trylock(&srmcons_callback_lock)) { -		if (!srmcons_do_receive_chars(srmconsp->tty)) +		if (!srmcons_do_receive_chars(port))  			incr = 100;  		spin_unlock(&srmcons_callback_lock);  	}  -	spin_lock(&srmconsp->lock); -	if (srmconsp->tty) { -		srmconsp->timer.expires = jiffies + incr; -		add_timer(&srmconsp->timer); -	} -	spin_unlock(&srmconsp->lock); +	spin_lock(&port->lock); +	if (port->tty) +		mod_timer(&srmconsp->timer, jiffies + incr); +	spin_unlock(&port->lock);  	local_irq_restore(flags);  }  /* called with callback_lock held */  static int -srmcons_do_write(struct tty_struct *tty, const char *buf, int count) +srmcons_do_write(struct tty_port *port, const char *buf, int count)  {  	static char str_cr[1] = "\r";  	long c, remaining = count; @@ -115,10 +113,10 @@ srmcons_do_write(struct tty_struct *tty, const char *buf, int count)  			cur += result.bits.c;  			/* -			 * Check for pending input iff a tty was provided +			 * Check for pending input iff a tty port was provided  			 */ -			if (tty) -				srmcons_do_receive_chars(tty); +			if (port) +				srmcons_do_receive_chars(port);  		}  		while (need_cr) { @@ -137,7 +135,7 @@ srmcons_write(struct tty_struct *tty,  	unsigned long flags;  	spin_lock_irqsave(&srmcons_callback_lock, flags); -	srmcons_do_write(tty, (const char *) buf, count); +	srmcons_do_write(tty->port, (const char *) buf, count);  	spin_unlock_irqrestore(&srmcons_callback_lock, flags);  	return count; @@ -156,56 +154,22 @@ srmcons_chars_in_buffer(struct tty_struct *tty)  }  static int -srmcons_get_private_struct(struct srmcons_private **ps) -{ -	static struct srmcons_private *srmconsp = NULL; -	static DEFINE_SPINLOCK(srmconsp_lock); -	unsigned long flags; -	int retval = 0; - -	if (srmconsp == NULL) { -		srmconsp = kmalloc(sizeof(*srmconsp), GFP_KERNEL); -		spin_lock_irqsave(&srmconsp_lock, flags); - -		if (srmconsp == NULL) -			retval = -ENOMEM; -		else { -			srmconsp->tty = NULL; -			spin_lock_init(&srmconsp->lock); -			init_timer(&srmconsp->timer); -		} - -		spin_unlock_irqrestore(&srmconsp_lock, flags); -	} - -	*ps = srmconsp; -	return retval; -} - -static int  srmcons_open(struct tty_struct *tty, struct file *filp)  { -	struct srmcons_private *srmconsp; +	struct srmcons_private *srmconsp = &srmcons_singleton; +	struct tty_port *port = &srmconsp->port;  	unsigned long flags; -	int retval; - -	retval = srmcons_get_private_struct(&srmconsp); -	if (retval) -		return retval; -	spin_lock_irqsave(&srmconsp->lock, flags); +	spin_lock_irqsave(&port->lock, flags); -	if (!srmconsp->tty) { +	if (!port->tty) {  		tty->driver_data = srmconsp; - -		srmconsp->tty = tty; -		srmconsp->timer.function = srmcons_receive_chars; -		srmconsp->timer.data = (unsigned long)srmconsp; -		srmconsp->timer.expires = jiffies + 10; -		add_timer(&srmconsp->timer); +		tty->port = port; +		port->tty = tty; /* XXX proper refcounting */ +		mod_timer(&srmconsp->timer, jiffies + 10);  	} -	spin_unlock_irqrestore(&srmconsp->lock, flags); +	spin_unlock_irqrestore(&port->lock, flags);  	return 0;  } @@ -214,16 +178,17 @@ static void  srmcons_close(struct tty_struct *tty, struct file *filp)  {  	struct srmcons_private *srmconsp = tty->driver_data; +	struct tty_port *port = &srmconsp->port;  	unsigned long flags; -	spin_lock_irqsave(&srmconsp->lock, flags); +	spin_lock_irqsave(&port->lock, flags);  	if (tty->count == 1) { -		srmconsp->tty = NULL; +		port->tty = NULL;  		del_timer(&srmconsp->timer);  	} -	spin_unlock_irqrestore(&srmconsp->lock, flags); +	spin_unlock_irqrestore(&port->lock, flags);  } @@ -240,6 +205,8 @@ static const struct tty_operations srmcons_ops = {  static int __init  srmcons_init(void)  { +	setup_timer(&srmcons_singleton.timer, srmcons_receive_chars, +			(unsigned long)&srmcons_singleton);  	if (srm_is_registered_console) {  		struct tty_driver *driver;  		int err; @@ -247,6 +214,9 @@ srmcons_init(void)  		driver = alloc_tty_driver(MAX_SRM_CONSOLE_DEVICES);  		if (!driver)  			return -ENOMEM; + +		tty_port_init(&srmcons_singleton.port); +  		driver->driver_name = "srm";  		driver->name = "srm";  		driver->major = 0; 	/* dynamic */ @@ -255,9 +225,11 @@ srmcons_init(void)  		driver->subtype = SYSTEM_TYPE_SYSCONS;  		driver->init_termios = tty_std_termios;  		tty_set_operations(driver, &srmcons_ops); +		tty_port_link_device(&srmcons_singleton.port, driver, 0);  		err = tty_register_driver(driver);  		if (err) {  			put_tty_driver(driver); +			tty_port_destroy(&srmcons_singleton.port);  			return err;  		}  		srmcons_driver = driver; diff --git a/arch/alpha/kernel/sys_alcor.c b/arch/alpha/kernel/sys_alcor.c index 20a30b8b965..118dc6af180 100644 --- a/arch/alpha/kernel/sys_alcor.c +++ b/arch/alpha/kernel/sys_alcor.c @@ -18,7 +18,6 @@  #include <linux/bitops.h>  #include <asm/ptrace.h> -#include <asm/system.h>  #include <asm/io.h>  #include <asm/dma.h>  #include <asm/mmu_context.h> @@ -44,59 +43,42 @@ alcor_update_irq_hw(unsigned long mask)  }  static inline void -alcor_enable_irq(unsigned int irq) +alcor_enable_irq(struct irq_data *d)  { -	alcor_update_irq_hw(cached_irq_mask |= 1UL << (irq - 16)); +	alcor_update_irq_hw(cached_irq_mask |= 1UL << (d->irq - 16));  }  static void -alcor_disable_irq(unsigned int irq) +alcor_disable_irq(struct irq_data *d)  { -	alcor_update_irq_hw(cached_irq_mask &= ~(1UL << (irq - 16))); +	alcor_update_irq_hw(cached_irq_mask &= ~(1UL << (d->irq - 16)));  }  static void -alcor_mask_and_ack_irq(unsigned int irq) +alcor_mask_and_ack_irq(struct irq_data *d)  { -	alcor_disable_irq(irq); +	alcor_disable_irq(d);  	/* On ALCOR/XLT, need to dismiss interrupt via GRU. */ -	*(vuip)GRU_INT_CLEAR = 1 << (irq - 16); mb(); +	*(vuip)GRU_INT_CLEAR = 1 << (d->irq - 16); mb();  	*(vuip)GRU_INT_CLEAR = 0; mb();  } -static unsigned int -alcor_startup_irq(unsigned int irq) -{ -	alcor_enable_irq(irq); -	return 0; -} -  static void -alcor_isa_mask_and_ack_irq(unsigned int irq) +alcor_isa_mask_and_ack_irq(struct irq_data *d)  { -	i8259a_mask_and_ack_irq(irq); +	i8259a_mask_and_ack_irq(d);  	/* On ALCOR/XLT, need to dismiss interrupt via GRU. */  	*(vuip)GRU_INT_CLEAR = 0x80000000; mb();  	*(vuip)GRU_INT_CLEAR = 0; mb();  } -static void -alcor_end_irq(unsigned int irq) -{ -	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) -		alcor_enable_irq(irq); -} -  static struct irq_chip alcor_irq_type = {  	.name		= "ALCOR", -	.startup	= alcor_startup_irq, -	.shutdown	= alcor_disable_irq, -	.enable		= alcor_enable_irq, -	.disable	= alcor_disable_irq, -	.ack		= alcor_mask_and_ack_irq, -	.end		= alcor_end_irq, +	.irq_unmask	= alcor_enable_irq, +	.irq_mask	= alcor_disable_irq, +	.irq_mask_ack	= alcor_mask_and_ack_irq,  };  static void @@ -142,10 +124,10 @@ alcor_init_irq(void)  		   on while IRQ probing.  */  		if (i >= 16+20 && i <= 16+30)  			continue; -		irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; -		irq_desc[i].chip = &alcor_irq_type; +		irq_set_chip_and_handler(i, &alcor_irq_type, handle_level_irq); +		irq_set_status_flags(i, IRQ_LEVEL);  	} -	i8259a_irq_type.ack = alcor_isa_mask_and_ack_irq; +	i8259a_irq_type.irq_ack = alcor_isa_mask_and_ack_irq;  	init_i8259a_irqs();  	common_init_isa_dma(); @@ -200,7 +182,7 @@ alcor_init_irq(void)   */  static int __init -alcor_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +alcor_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	static char irq_tab[7][5] __initdata = {  		/*INT    INTA   INTB   INTC   INTD */ diff --git a/arch/alpha/kernel/sys_cabriolet.c b/arch/alpha/kernel/sys_cabriolet.c index 14c8898d19e..4c50f8f40cb 100644 --- a/arch/alpha/kernel/sys_cabriolet.c +++ b/arch/alpha/kernel/sys_cabriolet.c @@ -18,7 +18,6 @@  #include <linux/bitops.h>  #include <asm/ptrace.h> -#include <asm/system.h>  #include <asm/dma.h>  #include <asm/irq.h>  #include <asm/mmu_context.h> @@ -46,39 +45,22 @@ cabriolet_update_irq_hw(unsigned int irq, unsigned long mask)  }  static inline void -cabriolet_enable_irq(unsigned int irq) +cabriolet_enable_irq(struct irq_data *d)  { -	cabriolet_update_irq_hw(irq, cached_irq_mask &= ~(1UL << irq)); +	cabriolet_update_irq_hw(d->irq, cached_irq_mask &= ~(1UL << d->irq));  }  static void -cabriolet_disable_irq(unsigned int irq) +cabriolet_disable_irq(struct irq_data *d)  { -	cabriolet_update_irq_hw(irq, cached_irq_mask |= 1UL << irq); -} - -static unsigned int -cabriolet_startup_irq(unsigned int irq) -{  -	cabriolet_enable_irq(irq); -	return 0; /* never anything pending */ -} - -static void -cabriolet_end_irq(unsigned int irq) -{  -	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) -		cabriolet_enable_irq(irq); +	cabriolet_update_irq_hw(d->irq, cached_irq_mask |= 1UL << d->irq);  }  static struct irq_chip cabriolet_irq_type = {  	.name		= "CABRIOLET", -	.startup	= cabriolet_startup_irq, -	.shutdown	= cabriolet_disable_irq, -	.enable		= cabriolet_enable_irq, -	.disable	= cabriolet_disable_irq, -	.ack		= cabriolet_disable_irq, -	.end		= cabriolet_end_irq, +	.irq_unmask	= cabriolet_enable_irq, +	.irq_mask	= cabriolet_disable_irq, +	.irq_mask_ack	= cabriolet_disable_irq,  };  static void  @@ -122,8 +104,9 @@ common_init_irq(void (*srm_dev_int)(unsigned long v))  		outb(0xff, 0x806);  		for (i = 16; i < 35; ++i) { -			irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; -			irq_desc[i].chip = &cabriolet_irq_type; +			irq_set_chip_and_handler(i, &cabriolet_irq_type, +						 handle_level_irq); +			irq_set_status_flags(i, IRQ_LEVEL);  		}  	} @@ -191,7 +174,7 @@ pc164_init_irq(void)   */  static inline int __init -eb66p_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +eb66p_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	static char irq_tab[5][5] __initdata = {  		/*INT  INTA  INTB  INTC   INTD */ @@ -221,7 +204,7 @@ eb66p_map_irq(struct pci_dev *dev, u8 slot, u8 pin)   */  static inline int __init -cabriolet_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +cabriolet_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	static char irq_tab[5][5] __initdata = {  		/*INT   INTA  INTB  INTC   INTD */ @@ -305,7 +288,7 @@ cia_cab_init_pci(void)   */  static inline int __init -alphapc164_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +alphapc164_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	static char irq_tab[7][5] __initdata = {  		/*INT   INTA  INTB   INTC   INTD */ diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c index 4026502ab70..6c35159bc00 100644 --- a/arch/alpha/kernel/sys_dp264.c +++ b/arch/alpha/kernel/sys_dp264.c @@ -21,7 +21,6 @@  #include <linux/bitops.h>  #include <asm/ptrace.h> -#include <asm/system.h>  #include <asm/dma.h>  #include <asm/irq.h>  #include <asm/mmu_context.h> @@ -98,69 +97,41 @@ tsunami_update_irq_hw(unsigned long mask)  }  static void -dp264_enable_irq(unsigned int irq) +dp264_enable_irq(struct irq_data *d)  {  	spin_lock(&dp264_irq_lock); -	cached_irq_mask |= 1UL << irq; +	cached_irq_mask |= 1UL << d->irq;  	tsunami_update_irq_hw(cached_irq_mask);  	spin_unlock(&dp264_irq_lock);  }  static void -dp264_disable_irq(unsigned int irq) +dp264_disable_irq(struct irq_data *d)  {  	spin_lock(&dp264_irq_lock); -	cached_irq_mask &= ~(1UL << irq); +	cached_irq_mask &= ~(1UL << d->irq);  	tsunami_update_irq_hw(cached_irq_mask);  	spin_unlock(&dp264_irq_lock);  } -static unsigned int -dp264_startup_irq(unsigned int irq) -{  -	dp264_enable_irq(irq); -	return 0; /* never anything pending */ -} - -static void -dp264_end_irq(unsigned int irq) -{  -	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) -		dp264_enable_irq(irq); -} -  static void -clipper_enable_irq(unsigned int irq) +clipper_enable_irq(struct irq_data *d)  {  	spin_lock(&dp264_irq_lock); -	cached_irq_mask |= 1UL << (irq - 16); +	cached_irq_mask |= 1UL << (d->irq - 16);  	tsunami_update_irq_hw(cached_irq_mask);  	spin_unlock(&dp264_irq_lock);  }  static void -clipper_disable_irq(unsigned int irq) +clipper_disable_irq(struct irq_data *d)  {  	spin_lock(&dp264_irq_lock); -	cached_irq_mask &= ~(1UL << (irq - 16)); +	cached_irq_mask &= ~(1UL << (d->irq - 16));  	tsunami_update_irq_hw(cached_irq_mask);  	spin_unlock(&dp264_irq_lock);  } -static unsigned int -clipper_startup_irq(unsigned int irq) -{  -	clipper_enable_irq(irq); -	return 0; /* never anything pending */ -} - -static void -clipper_end_irq(unsigned int irq) -{  -	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) -		clipper_enable_irq(irq); -} -  static void  cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity)  { @@ -168,7 +139,7 @@ cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity)  	for (cpu = 0; cpu < 4; cpu++) {  		unsigned long aff = cpu_irq_affinity[cpu]; -		if (cpu_isset(cpu, affinity)) +		if (cpumask_test_cpu(cpu, &affinity))  			aff |= 1UL << irq;  		else  			aff &= ~(1UL << irq); @@ -177,10 +148,11 @@ cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity)  }  static int -dp264_set_affinity(unsigned int irq, const struct cpumask *affinity) -{  +dp264_set_affinity(struct irq_data *d, const struct cpumask *affinity, +		   bool force) +{  	spin_lock(&dp264_irq_lock); -	cpu_set_irq_affinity(irq, *affinity); +	cpu_set_irq_affinity(d->irq, *affinity);  	tsunami_update_irq_hw(cached_irq_mask);  	spin_unlock(&dp264_irq_lock); @@ -188,10 +160,11 @@ dp264_set_affinity(unsigned int irq, const struct cpumask *affinity)  }  static int -clipper_set_affinity(unsigned int irq, const struct cpumask *affinity) -{  +clipper_set_affinity(struct irq_data *d, const struct cpumask *affinity, +		     bool force) +{  	spin_lock(&dp264_irq_lock); -	cpu_set_irq_affinity(irq - 16, *affinity); +	cpu_set_irq_affinity(d->irq - 16, *affinity);  	tsunami_update_irq_hw(cached_irq_mask);  	spin_unlock(&dp264_irq_lock); @@ -199,33 +172,24 @@ clipper_set_affinity(unsigned int irq, const struct cpumask *affinity)  }  static struct irq_chip dp264_irq_type = { -	.name		= "DP264", -	.startup	= dp264_startup_irq, -	.shutdown	= dp264_disable_irq, -	.enable		= dp264_enable_irq, -	.disable	= dp264_disable_irq, -	.ack		= dp264_disable_irq, -	.end		= dp264_end_irq, -	.set_affinity	= dp264_set_affinity, +	.name			= "DP264", +	.irq_unmask		= dp264_enable_irq, +	.irq_mask		= dp264_disable_irq, +	.irq_mask_ack		= dp264_disable_irq, +	.irq_set_affinity	= dp264_set_affinity,  };  static struct irq_chip clipper_irq_type = { -	.name		= "CLIPPER", -	.startup	= clipper_startup_irq, -	.shutdown	= clipper_disable_irq, -	.enable		= clipper_enable_irq, -	.disable	= clipper_disable_irq, -	.ack		= clipper_disable_irq, -	.end		= clipper_end_irq, -	.set_affinity	= clipper_set_affinity, +	.name			= "CLIPPER", +	.irq_unmask		= clipper_enable_irq, +	.irq_mask		= clipper_disable_irq, +	.irq_mask_ack		= clipper_disable_irq, +	.irq_set_affinity	= clipper_set_affinity,  };  static void  dp264_device_interrupt(unsigned long vector)  { -#if 1 -	printk("dp264_device_interrupt: NOT IMPLEMENTED YET!!\n"); -#else  	unsigned long pld;  	unsigned int i; @@ -243,12 +207,7 @@ dp264_device_interrupt(unsigned long vector)  			isa_device_interrupt(vector);  		else  			handle_irq(16 + i); -#if 0 -		TSUNAMI_cchip->dir0.csr = 1UL << i; mb(); -		tmp = TSUNAMI_cchip->dir0.csr; -#endif  	} -#endif  }  static void  @@ -302,8 +261,8 @@ init_tsunami_irqs(struct irq_chip * ops, int imin, int imax)  {  	long i;  	for (i = imin; i <= imax; ++i) { -		irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; -		irq_desc[i].chip = ops; +		irq_set_chip_and_handler(i, ops, handle_level_irq); +		irq_set_status_flags(i, IRQ_LEVEL);  	}  } @@ -398,7 +357,7 @@ clipper_init_irq(void)   */  static int __init -isa_irq_fixup(struct pci_dev *dev, int irq) +isa_irq_fixup(const struct pci_dev *dev, int irq)  {  	u8 irq8; @@ -414,7 +373,7 @@ isa_irq_fixup(struct pci_dev *dev, int irq)  }  static int __init -dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +dp264_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	static char irq_tab[6][5] __initdata = {  		/*INT    INTA   INTB   INTC   INTD */ @@ -436,7 +395,7 @@ dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin)  }  static int __init -monet_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +monet_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	static char irq_tab[13][5] __initdata = {  		/*INT    INTA   INTB   INTC   INTD */ @@ -498,7 +457,7 @@ monet_swizzle(struct pci_dev *dev, u8 *pinp)  }  static int __init -webbrick_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +webbrick_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	static char irq_tab[13][5] __initdata = {  		/*INT    INTA   INTB   INTC   INTD */ @@ -520,7 +479,7 @@ webbrick_map_irq(struct pci_dev *dev, u8 slot, u8 pin)  }  static int __init -clipper_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +clipper_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	static char irq_tab[7][5] __initdata = {  		/*INT    INTA   INTB   INTC   INTD */ diff --git a/arch/alpha/kernel/sys_eb64p.c b/arch/alpha/kernel/sys_eb64p.c index df2090ce5e7..ad40a425e84 100644 --- a/arch/alpha/kernel/sys_eb64p.c +++ b/arch/alpha/kernel/sys_eb64p.c @@ -17,7 +17,6 @@  #include <linux/bitops.h>  #include <asm/ptrace.h> -#include <asm/system.h>  #include <asm/dma.h>  #include <asm/irq.h>  #include <asm/mmu_context.h> @@ -44,39 +43,22 @@ eb64p_update_irq_hw(unsigned int irq, unsigned long mask)  }  static inline void -eb64p_enable_irq(unsigned int irq) +eb64p_enable_irq(struct irq_data *d)  { -	eb64p_update_irq_hw(irq, cached_irq_mask &= ~(1 << irq)); +	eb64p_update_irq_hw(d->irq, cached_irq_mask &= ~(1 << d->irq));  }  static void -eb64p_disable_irq(unsigned int irq) +eb64p_disable_irq(struct irq_data *d)  { -	eb64p_update_irq_hw(irq, cached_irq_mask |= 1 << irq); -} - -static unsigned int -eb64p_startup_irq(unsigned int irq) -{ -	eb64p_enable_irq(irq); -	return 0; /* never anything pending */ -} - -static void -eb64p_end_irq(unsigned int irq) -{ -	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) -		eb64p_enable_irq(irq); +	eb64p_update_irq_hw(d->irq, cached_irq_mask |= 1 << d->irq);  }  static struct irq_chip eb64p_irq_type = {  	.name		= "EB64P", -	.startup	= eb64p_startup_irq, -	.shutdown	= eb64p_disable_irq, -	.enable		= eb64p_enable_irq, -	.disable	= eb64p_disable_irq, -	.ack		= eb64p_disable_irq, -	.end		= eb64p_end_irq, +	.irq_unmask	= eb64p_enable_irq, +	.irq_mask	= eb64p_disable_irq, +	.irq_mask_ack	= eb64p_disable_irq,  };  static void  @@ -135,9 +117,9 @@ eb64p_init_irq(void)  	init_i8259a_irqs();  	for (i = 16; i < 32; ++i) { -		irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; -		irq_desc[i].chip = &eb64p_irq_type; -	}		 +		irq_set_chip_and_handler(i, &eb64p_irq_type, handle_level_irq); +		irq_set_status_flags(i, IRQ_LEVEL); +	}  	common_init_isa_dma();  	setup_irq(16+5, &isa_cascade_irqaction); @@ -186,7 +168,7 @@ eb64p_init_irq(void)   */  static int __init -eb64p_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +eb64p_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	static char irq_tab[5][5] __initdata = {  		/*INT  INTA  INTB  INTC   INTD */ diff --git a/arch/alpha/kernel/sys_eiger.c b/arch/alpha/kernel/sys_eiger.c index 3ca1dbcf404..79d69d7f63f 100644 --- a/arch/alpha/kernel/sys_eiger.c +++ b/arch/alpha/kernel/sys_eiger.c @@ -18,7 +18,6 @@  #include <linux/bitops.h>  #include <asm/ptrace.h> -#include <asm/system.h>  #include <asm/dma.h>  #include <asm/irq.h>  #include <asm/mmu_context.h> @@ -51,43 +50,28 @@ eiger_update_irq_hw(unsigned long irq, unsigned long mask)  }  static inline void -eiger_enable_irq(unsigned int irq) +eiger_enable_irq(struct irq_data *d)  { +	unsigned int irq = d->irq;  	unsigned long mask;  	mask = (cached_irq_mask[irq >= 64] &= ~(1UL << (irq & 63)));  	eiger_update_irq_hw(irq, mask);  }  static void -eiger_disable_irq(unsigned int irq) +eiger_disable_irq(struct irq_data *d)  { +	unsigned int irq = d->irq;  	unsigned long mask;  	mask = (cached_irq_mask[irq >= 64] |= 1UL << (irq & 63));  	eiger_update_irq_hw(irq, mask);  } -static unsigned int -eiger_startup_irq(unsigned int irq) -{ -	eiger_enable_irq(irq); -	return 0; /* never anything pending */ -} - -static void -eiger_end_irq(unsigned int irq) -{ -	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) -		eiger_enable_irq(irq); -} -  static struct irq_chip eiger_irq_type = {  	.name		= "EIGER", -	.startup	= eiger_startup_irq, -	.shutdown	= eiger_disable_irq, -	.enable		= eiger_enable_irq, -	.disable	= eiger_disable_irq, -	.ack		= eiger_disable_irq, -	.end		= eiger_end_irq, +	.irq_unmask	= eiger_enable_irq, +	.irq_mask	= eiger_disable_irq, +	.irq_mask_ack	= eiger_disable_irq,  };  static void @@ -153,13 +137,13 @@ eiger_init_irq(void)  	init_i8259a_irqs();  	for (i = 16; i < 128; ++i) { -		irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; -		irq_desc[i].chip = &eiger_irq_type; +		irq_set_chip_and_handler(i, &eiger_irq_type, handle_level_irq); +		irq_set_status_flags(i, IRQ_LEVEL);  	}  }  static int __init -eiger_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +eiger_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	u8 irq_orig; diff --git a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c index 7a7ae36fff9..608f2a7fa0a 100644 --- a/arch/alpha/kernel/sys_jensen.c +++ b/arch/alpha/kernel/sys_jensen.c @@ -15,7 +15,6 @@  #include <linux/init.h>  #include <asm/ptrace.h> -#include <asm/system.h>  #define __EXTERN_INLINE inline  #include <asm/io.h> @@ -62,70 +61,35 @@   * world.   */ -static unsigned int -jensen_local_startup(unsigned int irq) -{ -	/* the parport is really hw IRQ 1, silly Jensen.  */ -	if (irq == 7) -		i8259a_startup_irq(1); -	else -		/* -		 * For all true local interrupts, set the flag that prevents -		 * the IPL from being dropped during handler processing. -		 */ -		if (irq_desc[irq].action) -			irq_desc[irq].action->flags |= IRQF_DISABLED; -	return 0; -} - -static void -jensen_local_shutdown(unsigned int irq) -{ -	/* the parport is really hw IRQ 1, silly Jensen.  */ -	if (irq == 7) -		i8259a_disable_irq(1); -} - -static void -jensen_local_enable(unsigned int irq) -{ -	/* the parport is really hw IRQ 1, silly Jensen.  */ -	if (irq == 7) -		i8259a_enable_irq(1); -} -  static void -jensen_local_disable(unsigned int irq) +jensen_local_enable(struct irq_data *d)  {  	/* the parport is really hw IRQ 1, silly Jensen.  */ -	if (irq == 7) -		i8259a_disable_irq(1); +	if (d->irq == 7) +		i8259a_enable_irq(d);  }  static void -jensen_local_ack(unsigned int irq) +jensen_local_disable(struct irq_data *d)  {  	/* the parport is really hw IRQ 1, silly Jensen.  */ -	if (irq == 7) -		i8259a_mask_and_ack_irq(1); +	if (d->irq == 7) +		i8259a_disable_irq(d);  }  static void -jensen_local_end(unsigned int irq) +jensen_local_mask_ack(struct irq_data *d)  {  	/* the parport is really hw IRQ 1, silly Jensen.  */ -	if (irq == 7) -		i8259a_end_irq(1); +	if (d->irq == 7) +		i8259a_mask_and_ack_irq(d);  }  static struct irq_chip jensen_local_irq_type = {  	.name		= "LOCAL", -	.startup	= jensen_local_startup, -	.shutdown	= jensen_local_shutdown, -	.enable		= jensen_local_enable, -	.disable	= jensen_local_disable, -	.ack		= jensen_local_ack, -	.end		= jensen_local_end, +	.irq_unmask	= jensen_local_enable, +	.irq_mask	= jensen_local_disable, +	.irq_mask_ack	= jensen_local_mask_ack,  };  static void  @@ -158,7 +122,7 @@ jensen_device_interrupt(unsigned long vector)  	}  	/* If there is no handler yet... */ -	if (irq_desc[irq].action == NULL) { +	if (!irq_has_action(irq)) {  	    /* If it is a local interrupt that cannot be masked... */  	    if (vector >= 0x900)  	    { @@ -206,11 +170,11 @@ jensen_init_irq(void)  {  	init_i8259a_irqs(); -	irq_desc[1].chip = &jensen_local_irq_type; -	irq_desc[4].chip = &jensen_local_irq_type; -	irq_desc[3].chip = &jensen_local_irq_type; -	irq_desc[7].chip = &jensen_local_irq_type; -	irq_desc[9].chip = &jensen_local_irq_type; +	irq_set_chip_and_handler(1, &jensen_local_irq_type, handle_level_irq); +	irq_set_chip_and_handler(4, &jensen_local_irq_type, handle_level_irq); +	irq_set_chip_and_handler(3, &jensen_local_irq_type, handle_level_irq); +	irq_set_chip_and_handler(7, &jensen_local_irq_type, handle_level_irq); +	irq_set_chip_and_handler(9, &jensen_local_irq_type, handle_level_irq);  	common_init_isa_dma();  } @@ -260,8 +224,6 @@ struct alpha_machine_vector jensen_mv __initmv = {  	.machine_check		= jensen_machine_check,  	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,  	.rtc_port		= 0x170, -	.rtc_get_time		= common_get_rtc_time, -	.rtc_set_time		= common_set_rtc_time,  	.nr_irqs		= 16,  	.device_interrupt	= jensen_device_interrupt, diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c index 0bb3b5c4f69..f21d61fab67 100644 --- a/arch/alpha/kernel/sys_marvel.c +++ b/arch/alpha/kernel/sys_marvel.c @@ -13,7 +13,6 @@  #include <linux/bitops.h>  #include <asm/ptrace.h> -#include <asm/system.h>  #include <asm/dma.h>  #include <asm/irq.h>  #include <asm/mmu_context.h> @@ -23,7 +22,6 @@  #include <asm/hwrpb.h>  #include <asm/tlbflush.h>  #include <asm/vga.h> -#include <asm/rtc.h>  #include "proto.h"  #include "err_impl.h" @@ -104,9 +102,10 @@ io7_get_irq_ctl(unsigned int irq, struct io7 **pio7)  }  static void -io7_enable_irq(unsigned int irq) +io7_enable_irq(struct irq_data *d)  {  	volatile unsigned long *ctl; +	unsigned int irq = d->irq;  	struct io7 *io7;  	ctl = io7_get_irq_ctl(irq, &io7); @@ -115,7 +114,7 @@ io7_enable_irq(unsigned int irq)  		       __func__, irq);  		return;  	} -		 +  	spin_lock(&io7->irq_lock);  	*ctl |= 1UL << 24;  	mb(); @@ -124,9 +123,10 @@ io7_enable_irq(unsigned int irq)  }  static void -io7_disable_irq(unsigned int irq) +io7_disable_irq(struct irq_data *d)  {  	volatile unsigned long *ctl; +	unsigned int irq = d->irq;  	struct io7 *io7;  	ctl = io7_get_irq_ctl(irq, &io7); @@ -135,7 +135,7 @@ io7_disable_irq(unsigned int irq)  		       __func__, irq);  		return;  	} -		 +  	spin_lock(&io7->irq_lock);  	*ctl &= ~(1UL << 24);  	mb(); @@ -143,60 +143,30 @@ io7_disable_irq(unsigned int irq)  	spin_unlock(&io7->irq_lock);  } -static unsigned int -io7_startup_irq(unsigned int irq) -{ -	io7_enable_irq(irq); -	return 0;	/* never anything pending */ -} -  static void -io7_end_irq(unsigned int irq) +marvel_irq_noop(struct irq_data *d)  { -	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) -		io7_enable_irq(irq); -} - -static void -marvel_irq_noop(unsigned int irq)  -{  -	return;  -} - -static unsigned int -marvel_irq_noop_return(unsigned int irq)  -{  -	return 0;  +	return;  }  static struct irq_chip marvel_legacy_irq_type = {  	.name		= "LEGACY", -	.startup	= marvel_irq_noop_return, -	.shutdown	= marvel_irq_noop, -	.enable		= marvel_irq_noop, -	.disable	= marvel_irq_noop, -	.ack		= marvel_irq_noop, -	.end		= marvel_irq_noop, +	.irq_mask	= marvel_irq_noop, +	.irq_unmask	= marvel_irq_noop,  };  static struct irq_chip io7_lsi_irq_type = {  	.name		= "LSI", -	.startup	= io7_startup_irq, -	.shutdown	= io7_disable_irq, -	.enable		= io7_enable_irq, -	.disable	= io7_disable_irq, -	.ack		= io7_disable_irq, -	.end		= io7_end_irq, +	.irq_unmask	= io7_enable_irq, +	.irq_mask	= io7_disable_irq, +	.irq_mask_ack	= io7_disable_irq,  };  static struct irq_chip io7_msi_irq_type = {  	.name		= "MSI", -	.startup	= io7_startup_irq, -	.shutdown	= io7_disable_irq, -	.enable		= io7_enable_irq, -	.disable	= io7_disable_irq, -	.ack		= marvel_irq_noop, -	.end		= io7_end_irq, +	.irq_unmask	= io7_enable_irq, +	.irq_mask	= io7_disable_irq, +	.irq_ack	= marvel_irq_noop,  };  static void @@ -304,8 +274,8 @@ init_io7_irqs(struct io7 *io7,  	/* Set up the lsi irqs.  */  	for (i = 0; i < 128; ++i) { -		irq_desc[base + i].status = IRQ_DISABLED | IRQ_LEVEL; -		irq_desc[base + i].chip = lsi_ops; +		irq_set_chip_and_handler(base + i, lsi_ops, handle_level_irq); +		irq_set_status_flags(i, IRQ_LEVEL);  	}  	/* Disable the implemented irqs in hardware.  */ @@ -318,8 +288,8 @@ init_io7_irqs(struct io7 *io7,  	/* Set up the msi irqs.  */  	for (i = 128; i < (128 + 512); ++i) { -		irq_desc[base + i].status = IRQ_DISABLED | IRQ_LEVEL; -		irq_desc[base + i].chip = msi_ops; +		irq_set_chip_and_handler(base + i, msi_ops, handle_level_irq); +		irq_set_status_flags(i, IRQ_LEVEL);  	}  	for (i = 0; i < 16; ++i) @@ -336,8 +306,8 @@ marvel_init_irq(void)  	/* Reserve the legacy irqs.  */  	for (i = 0; i < 16; ++i) { -		irq_desc[i].status = IRQ_DISABLED; -		irq_desc[i].chip = &marvel_legacy_irq_type; +		irq_set_chip_and_handler(i, &marvel_legacy_irq_type, +					 handle_level_irq);  	}  	/* Init the io7 irqs.  */ @@ -346,8 +316,9 @@ marvel_init_irq(void)  }  static int  -marvel_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +marvel_map_irq(const struct pci_dev *cdev, u8 slot, u8 pin)  { +	struct pci_dev *dev = (struct pci_dev *)cdev;  	struct pci_controller *hose = dev->sysdata;  	struct io7_port *io7_port = hose->sysdata;  	struct io7 *io7 = io7_port->io7; @@ -412,7 +383,8 @@ marvel_init_pci(void)  	marvel_register_error_handlers(); -	pci_probe_only = 1; +	/* Indicate that we trust the console to configure things properly */ +	pci_set_flags(PCI_PROBE_ONLY);  	common_init_pci();  	locate_and_init_vga(NULL); @@ -427,57 +399,6 @@ marvel_init_rtc(void)  	init_rtc_irq();  } -struct marvel_rtc_time { -	struct rtc_time *time; -	int retval; -}; - -#ifdef CONFIG_SMP -static void -smp_get_rtc_time(void *data) -{ -	struct marvel_rtc_time *mrt = data; -	mrt->retval = __get_rtc_time(mrt->time); -} - -static void -smp_set_rtc_time(void *data) -{ -	struct marvel_rtc_time *mrt = data; -	mrt->retval = __set_rtc_time(mrt->time); -} -#endif - -static unsigned int -marvel_get_rtc_time(struct rtc_time *time) -{ -#ifdef CONFIG_SMP -	struct marvel_rtc_time mrt; - -	if (smp_processor_id() != boot_cpuid) { -		mrt.time = time; -		smp_call_function_single(boot_cpuid, smp_get_rtc_time, &mrt, 1); -		return mrt.retval; -	} -#endif -	return __get_rtc_time(time); -} - -static int -marvel_set_rtc_time(struct rtc_time *time) -{ -#ifdef CONFIG_SMP -	struct marvel_rtc_time mrt; - -	if (smp_processor_id() != boot_cpuid) { -		mrt.time = time; -		smp_call_function_single(boot_cpuid, smp_set_rtc_time, &mrt, 1); -		return mrt.retval; -	} -#endif -	return __set_rtc_time(time); -} -  static void  marvel_smp_callin(void)  { @@ -519,8 +440,7 @@ struct alpha_machine_vector marvel_ev7_mv __initmv = {  	.vector_name		= "MARVEL/EV7",  	DO_EV7_MMU,  	.rtc_port		= 0x70, -	.rtc_get_time		= marvel_get_rtc_time, -	.rtc_set_time		= marvel_set_rtc_time, +	.rtc_boot_cpu_only	= 1,  	DO_MARVEL_IO,  	.machine_check		= marvel_machine_check,  	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS, diff --git a/arch/alpha/kernel/sys_miata.c b/arch/alpha/kernel/sys_miata.c index 61ccd95579e..d5b9776a608 100644 --- a/arch/alpha/kernel/sys_miata.c +++ b/arch/alpha/kernel/sys_miata.c @@ -17,7 +17,6 @@  #include <linux/reboot.h>  #include <asm/ptrace.h> -#include <asm/system.h>  #include <asm/dma.h>  #include <asm/irq.h>  #include <asm/mmu_context.h> @@ -151,7 +150,7 @@ miata_init_irq(void)   */  static int __init -miata_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +miata_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {          static char irq_tab[18][5] __initdata = {  		/*INT    INTA   INTB   INTC   INTD */ diff --git a/arch/alpha/kernel/sys_mikasa.c b/arch/alpha/kernel/sys_mikasa.c index ee886516981..5e82dc1ad6f 100644 --- a/arch/alpha/kernel/sys_mikasa.c +++ b/arch/alpha/kernel/sys_mikasa.c @@ -17,7 +17,7 @@  #include <linux/bitops.h>  #include <asm/ptrace.h> -#include <asm/system.h> +#include <asm/mce.h>  #include <asm/dma.h>  #include <asm/irq.h>  #include <asm/mmu_context.h> @@ -43,39 +43,22 @@ mikasa_update_irq_hw(int mask)  }  static inline void -mikasa_enable_irq(unsigned int irq) +mikasa_enable_irq(struct irq_data *d)  { -	mikasa_update_irq_hw(cached_irq_mask |= 1 << (irq - 16)); +	mikasa_update_irq_hw(cached_irq_mask |= 1 << (d->irq - 16));  }  static void -mikasa_disable_irq(unsigned int irq) +mikasa_disable_irq(struct irq_data *d)  { -	mikasa_update_irq_hw(cached_irq_mask &= ~(1 << (irq - 16))); -} - -static unsigned int -mikasa_startup_irq(unsigned int irq) -{ -	mikasa_enable_irq(irq); -	return 0; -} - -static void -mikasa_end_irq(unsigned int irq) -{ -	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) -		mikasa_enable_irq(irq); +	mikasa_update_irq_hw(cached_irq_mask &= ~(1 << (d->irq - 16)));  }  static struct irq_chip mikasa_irq_type = {  	.name		= "MIKASA", -	.startup	= mikasa_startup_irq, -	.shutdown	= mikasa_disable_irq, -	.enable		= mikasa_enable_irq, -	.disable	= mikasa_disable_irq, -	.ack		= mikasa_disable_irq, -	.end		= mikasa_end_irq, +	.irq_unmask	= mikasa_enable_irq, +	.irq_mask	= mikasa_disable_irq, +	.irq_mask_ack	= mikasa_disable_irq,  };  static void  @@ -115,8 +98,9 @@ mikasa_init_irq(void)  	mikasa_update_irq_hw(0);  	for (i = 16; i < 32; ++i) { -		irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; -		irq_desc[i].chip = &mikasa_irq_type; +		irq_set_chip_and_handler(i, &mikasa_irq_type, +					 handle_level_irq); +		irq_set_status_flags(i, IRQ_LEVEL);  	}  	init_i8259a_irqs(); @@ -162,7 +146,7 @@ mikasa_init_irq(void)   */  static int __init -mikasa_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +mikasa_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	static char irq_tab[8][5] __initdata = {  		/*INT    INTA   INTB   INTC   INTD */ diff --git a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c index 99c0f46f6b9..837c0fa5831 100644 --- a/arch/alpha/kernel/sys_nautilus.c +++ b/arch/alpha/kernel/sys_nautilus.c @@ -35,7 +35,6 @@  #include <linux/bitops.h>  #include <asm/ptrace.h> -#include <asm/system.h>  #include <asm/dma.h>  #include <asm/irq.h>  #include <asm/mmu_context.h> @@ -65,7 +64,7 @@ nautilus_init_irq(void)  }  static int __init -nautilus_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +nautilus_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	/* Preserve the IRQ set up by the console.  */ @@ -186,9 +185,12 @@ nautilus_machine_check(unsigned long vector, unsigned long la_ptr)  	mb();  } -extern void free_reserved_mem(void *, void *);  extern void pcibios_claim_one_bus(struct pci_bus *); +static struct resource irongate_io = { +	.name	= "Irongate PCI IO", +	.flags	= IORESOURCE_IO, +};  static struct resource irongate_mem = {  	.name	= "Irongate PCI MEM",  	.flags	= IORESOURCE_MEM, @@ -210,6 +212,7 @@ nautilus_init_pci(void)  	irongate = pci_get_bus_and_slot(0, 0);  	bus->self = irongate; +	bus->resource[0] = &irongate_io;  	bus->resource[1] = &irongate_mem;  	pci_bus_size_bridges(bus); @@ -235,8 +238,8 @@ nautilus_init_pci(void)  	if (pci_mem < memtop)  		memtop = pci_mem;  	if (memtop > alpha_mv.min_mem_address) { -		free_reserved_mem(__va(alpha_mv.min_mem_address), -				  __va(memtop)); +		free_reserved_area(__va(alpha_mv.min_mem_address), +				   __va(memtop), -1, NULL);  		printk("nautilus_init_pci: %ldk freed\n",  			(memtop - alpha_mv.min_mem_address) >> 10);  	} diff --git a/arch/alpha/kernel/sys_noritake.c b/arch/alpha/kernel/sys_noritake.c index 86503fe73a8..063e594fd96 100644 --- a/arch/alpha/kernel/sys_noritake.c +++ b/arch/alpha/kernel/sys_noritake.c @@ -18,7 +18,7 @@  #include <linux/bitops.h>  #include <asm/ptrace.h> -#include <asm/system.h> +#include <asm/mce.h>  #include <asm/dma.h>  #include <asm/irq.h>  #include <asm/mmu_context.h> @@ -48,39 +48,22 @@ noritake_update_irq_hw(int irq, int mask)  }  static void -noritake_enable_irq(unsigned int irq) +noritake_enable_irq(struct irq_data *d)  { -	noritake_update_irq_hw(irq, cached_irq_mask |= 1 << (irq - 16)); +	noritake_update_irq_hw(d->irq, cached_irq_mask |= 1 << (d->irq - 16));  }  static void -noritake_disable_irq(unsigned int irq) +noritake_disable_irq(struct irq_data *d)  { -	noritake_update_irq_hw(irq, cached_irq_mask &= ~(1 << (irq - 16))); -} - -static unsigned int -noritake_startup_irq(unsigned int irq) -{ -	noritake_enable_irq(irq); -	return 0; -} - -static void -noritake_end_irq(unsigned int irq) -{ -        if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) -                noritake_enable_irq(irq); +	noritake_update_irq_hw(d->irq, cached_irq_mask &= ~(1 << (d->irq - 16)));  }  static struct irq_chip noritake_irq_type = {  	.name		= "NORITAKE", -	.startup	= noritake_startup_irq, -	.shutdown	= noritake_disable_irq, -	.enable		= noritake_enable_irq, -	.disable	= noritake_disable_irq, -	.ack		= noritake_disable_irq, -	.end		= noritake_end_irq, +	.irq_unmask	= noritake_enable_irq, +	.irq_mask	= noritake_disable_irq, +	.irq_mask_ack	= noritake_disable_irq,  };  static void  @@ -144,8 +127,9 @@ noritake_init_irq(void)  	outw(0, 0x54c);  	for (i = 16; i < 48; ++i) { -		irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; -		irq_desc[i].chip = &noritake_irq_type; +		irq_set_chip_and_handler(i, &noritake_irq_type, +					 handle_level_irq); +		irq_set_status_flags(i, IRQ_LEVEL);  	}  	init_i8259a_irqs(); @@ -210,7 +194,7 @@ noritake_init_irq(void)   */  static int __init -noritake_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +noritake_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	static char irq_tab[15][5] __initdata = {  		/*INT    INTA   INTB   INTC   INTD */ diff --git a/arch/alpha/kernel/sys_rawhide.c b/arch/alpha/kernel/sys_rawhide.c index 26c322bf89e..dfd510ae5d8 100644 --- a/arch/alpha/kernel/sys_rawhide.c +++ b/arch/alpha/kernel/sys_rawhide.c @@ -16,7 +16,6 @@  #include <linux/init.h>  #include <asm/ptrace.h> -#include <asm/system.h>  #include <asm/dma.h>  #include <asm/irq.h>  #include <asm/mmu_context.h> @@ -56,9 +55,10 @@ rawhide_update_irq_hw(int hose, int mask)    (((h) < MCPCIA_MAX_HOSES) && (cached_irq_masks[(h)] != 0))  static inline void  -rawhide_enable_irq(unsigned int irq) +rawhide_enable_irq(struct irq_data *d)  {  	unsigned int mask, hose; +	unsigned int irq = d->irq;  	irq -= 16;  	hose = irq / 24; @@ -76,9 +76,10 @@ rawhide_enable_irq(unsigned int irq)  }  static void  -rawhide_disable_irq(unsigned int irq) +rawhide_disable_irq(struct irq_data *d)  {  	unsigned int mask, hose; +	unsigned int irq = d->irq;  	irq -= 16;  	hose = irq / 24; @@ -96,9 +97,10 @@ rawhide_disable_irq(unsigned int irq)  }  static void -rawhide_mask_and_ack_irq(unsigned int irq) +rawhide_mask_and_ack_irq(struct irq_data *d)  {  	unsigned int mask, mask1, hose; +	unsigned int irq = d->irq;  	irq -= 16;  	hose = irq / 24; @@ -121,28 +123,11 @@ rawhide_mask_and_ack_irq(unsigned int irq)  	spin_unlock(&rawhide_irq_lock);  } -static unsigned int -rawhide_startup_irq(unsigned int irq) -{ -	rawhide_enable_irq(irq); -	return 0; -} - -static void -rawhide_end_irq(unsigned int irq) -{ -	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) -		rawhide_enable_irq(irq); -} -  static struct irq_chip rawhide_irq_type = {  	.name		= "RAWHIDE", -	.startup	= rawhide_startup_irq, -	.shutdown	= rawhide_disable_irq, -	.enable		= rawhide_enable_irq, -	.disable	= rawhide_disable_irq, -	.ack		= rawhide_mask_and_ack_irq, -	.end		= rawhide_end_irq, +	.irq_unmask	= rawhide_enable_irq, +	.irq_mask	= rawhide_disable_irq, +	.irq_mask_ack	= rawhide_mask_and_ack_irq,  };  static void  @@ -194,8 +179,9 @@ rawhide_init_irq(void)  	}  	for (i = 16; i < 128; ++i) { -		irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; -		irq_desc[i].chip = &rawhide_irq_type; +		irq_set_chip_and_handler(i, &rawhide_irq_type, +					 handle_level_irq); +		irq_set_status_flags(i, IRQ_LEVEL);  	}  	init_i8259a_irqs(); @@ -236,7 +222,7 @@ rawhide_init_irq(void)   */  static int __init -rawhide_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +rawhide_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	static char irq_tab[5][5] __initdata = {  		/*INT    INTA   INTB   INTC   INTD */ diff --git a/arch/alpha/kernel/sys_ruffian.c b/arch/alpha/kernel/sys_ruffian.c index 8de1046fe91..a3f48525717 100644 --- a/arch/alpha/kernel/sys_ruffian.c +++ b/arch/alpha/kernel/sys_ruffian.c @@ -18,7 +18,6 @@  #include <linux/init.h>  #include <asm/ptrace.h> -#include <asm/system.h>  #include <asm/dma.h>  #include <asm/irq.h>  #include <asm/mmu_context.h> @@ -26,7 +25,6 @@  #include <asm/pgtable.h>  #include <asm/core_cia.h>  #include <asm/tlbflush.h> -#include <asm/8253pit.h>  #include "proto.h"  #include "irq_impl.h" @@ -120,7 +118,7 @@ ruffian_kill_arch (int mode)   */  static int __init -ruffian_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +ruffian_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {          static char irq_tab[11][5] __initdata = {  	      /*INT  INTA INTB INTC INTD */ diff --git a/arch/alpha/kernel/sys_rx164.c b/arch/alpha/kernel/sys_rx164.c index be161129eab..08ee737d4fb 100644 --- a/arch/alpha/kernel/sys_rx164.c +++ b/arch/alpha/kernel/sys_rx164.c @@ -17,7 +17,6 @@  #include <linux/bitops.h>  #include <asm/ptrace.h> -#include <asm/system.h>  #include <asm/dma.h>  #include <asm/irq.h>  #include <asm/mmu_context.h> @@ -47,39 +46,22 @@ rx164_update_irq_hw(unsigned long mask)  }  static inline void -rx164_enable_irq(unsigned int irq) +rx164_enable_irq(struct irq_data *d)  { -	rx164_update_irq_hw(cached_irq_mask |= 1UL << (irq - 16)); +	rx164_update_irq_hw(cached_irq_mask |= 1UL << (d->irq - 16));  }  static void -rx164_disable_irq(unsigned int irq) +rx164_disable_irq(struct irq_data *d)  { -	rx164_update_irq_hw(cached_irq_mask &= ~(1UL << (irq - 16))); -} - -static unsigned int -rx164_startup_irq(unsigned int irq) -{ -	rx164_enable_irq(irq); -	return 0; -} - -static void -rx164_end_irq(unsigned int irq) -{ -	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) -		rx164_enable_irq(irq); +	rx164_update_irq_hw(cached_irq_mask &= ~(1UL << (d->irq - 16)));  }  static struct irq_chip rx164_irq_type = {  	.name		= "RX164", -	.startup	= rx164_startup_irq, -	.shutdown	= rx164_disable_irq, -	.enable		= rx164_enable_irq, -	.disable	= rx164_disable_irq, -	.ack		= rx164_disable_irq, -	.end		= rx164_end_irq, +	.irq_unmask	= rx164_enable_irq, +	.irq_mask	= rx164_disable_irq, +	.irq_mask_ack	= rx164_disable_irq,  };  static void  @@ -116,8 +98,8 @@ rx164_init_irq(void)  	rx164_update_irq_hw(0);  	for (i = 16; i < 40; ++i) { -		irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; -		irq_desc[i].chip = &rx164_irq_type; +		irq_set_chip_and_handler(i, &rx164_irq_type, handle_level_irq); +		irq_set_status_flags(i, IRQ_LEVEL);  	}  	init_i8259a_irqs(); @@ -161,7 +143,7 @@ rx164_init_irq(void)   */  static int __init -rx164_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +rx164_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  #if 0  	static char irq_tab_pass1[6][5] __initdata = { diff --git a/arch/alpha/kernel/sys_sable.c b/arch/alpha/kernel/sys_sable.c index b2abe27a23c..8a0aa6d67b5 100644 --- a/arch/alpha/kernel/sys_sable.c +++ b/arch/alpha/kernel/sys_sable.c @@ -16,7 +16,6 @@  #include <linux/init.h>  #include <asm/ptrace.h> -#include <asm/system.h>  #include <asm/dma.h>  #include <asm/irq.h>  #include <asm/mmu_context.h> @@ -194,7 +193,7 @@ sable_init_irq(void)   */  static int __init -sable_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +sable_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	static char irq_tab[9][5] __initdata = {  		/*INT    INTA   INTB   INTC   INTD */ @@ -376,7 +375,7 @@ lynx_init_irq(void)   */  static int __init -lynx_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +lynx_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	static char irq_tab[19][5] __initdata = {  		/*INT    INTA   INTB   INTC   INTD */ @@ -443,11 +442,11 @@ lynx_swizzle(struct pci_dev *dev, u8 *pinp)  /* GENERIC irq routines */  static inline void -sable_lynx_enable_irq(unsigned int irq) +sable_lynx_enable_irq(struct irq_data *d)  {  	unsigned long bit, mask; -	bit = sable_lynx_irq_swizzle->irq_to_mask[irq]; +	bit = sable_lynx_irq_swizzle->irq_to_mask[d->irq];  	spin_lock(&sable_lynx_irq_lock);  	mask = sable_lynx_irq_swizzle->shadow_mask &= ~(1UL << bit);  	sable_lynx_irq_swizzle->update_irq_hw(bit, mask); @@ -459,11 +458,11 @@ sable_lynx_enable_irq(unsigned int irq)  }  static void -sable_lynx_disable_irq(unsigned int irq) +sable_lynx_disable_irq(struct irq_data *d)  {  	unsigned long bit, mask; -	bit = sable_lynx_irq_swizzle->irq_to_mask[irq]; +	bit = sable_lynx_irq_swizzle->irq_to_mask[d->irq];  	spin_lock(&sable_lynx_irq_lock);  	mask = sable_lynx_irq_swizzle->shadow_mask |= 1UL << bit;  	sable_lynx_irq_swizzle->update_irq_hw(bit, mask); @@ -474,26 +473,12 @@ sable_lynx_disable_irq(unsigned int irq)  #endif  } -static unsigned int -sable_lynx_startup_irq(unsigned int irq) -{ -	sable_lynx_enable_irq(irq); -	return 0; -} - -static void -sable_lynx_end_irq(unsigned int irq) -{ -	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) -		sable_lynx_enable_irq(irq); -} -  static void -sable_lynx_mask_and_ack_irq(unsigned int irq) +sable_lynx_mask_and_ack_irq(struct irq_data *d)  {  	unsigned long bit, mask; -	bit = sable_lynx_irq_swizzle->irq_to_mask[irq]; +	bit = sable_lynx_irq_swizzle->irq_to_mask[d->irq];  	spin_lock(&sable_lynx_irq_lock);  	mask = sable_lynx_irq_swizzle->shadow_mask |= 1UL << bit;  	sable_lynx_irq_swizzle->update_irq_hw(bit, mask); @@ -503,12 +488,9 @@ sable_lynx_mask_and_ack_irq(unsigned int irq)  static struct irq_chip sable_lynx_irq_type = {  	.name		= "SABLE/LYNX", -	.startup	= sable_lynx_startup_irq, -	.shutdown	= sable_lynx_disable_irq, -	.enable		= sable_lynx_enable_irq, -	.disable	= sable_lynx_disable_irq, -	.ack		= sable_lynx_mask_and_ack_irq, -	.end		= sable_lynx_end_irq, +	.irq_unmask	= sable_lynx_enable_irq, +	.irq_mask	= sable_lynx_disable_irq, +	.irq_mask_ack	= sable_lynx_mask_and_ack_irq,  };  static void  @@ -535,8 +517,9 @@ sable_lynx_init_irq(int nr_of_irqs)  	long i;  	for (i = 0; i < nr_of_irqs; ++i) { -		irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; -		irq_desc[i].chip = &sable_lynx_irq_type; +		irq_set_chip_and_handler(i, &sable_lynx_irq_type, +					 handle_level_irq); +		irq_set_status_flags(i, IRQ_LEVEL);  	}  	common_init_isa_dma(); diff --git a/arch/alpha/kernel/sys_sio.c b/arch/alpha/kernel/sys_sio.c index 85b4aea01ef..febd24eba7a 100644 --- a/arch/alpha/kernel/sys_sio.c +++ b/arch/alpha/kernel/sys_sio.c @@ -20,7 +20,6 @@  #include <asm/compiler.h>  #include <asm/ptrace.h> -#include <asm/system.h>  #include <asm/dma.h>  #include <asm/irq.h>  #include <asm/mmu_context.h> @@ -146,7 +145,7 @@ sio_fixup_irq_levels(unsigned int level_bits)  }  static inline int __init -noname_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +noname_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	/*  	 * The Noname board has 5 PCI slots with each of the 4 @@ -185,7 +184,7 @@ noname_map_irq(struct pci_dev *dev, u8 slot, u8 pin)  }  static inline int __init -p2k_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +p2k_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	static char irq_tab[][5] __initdata = {  		/*INT A   B   C   D */ diff --git a/arch/alpha/kernel/sys_sx164.c b/arch/alpha/kernel/sys_sx164.c index 41d4ad4c7c4..d063b360efe 100644 --- a/arch/alpha/kernel/sys_sx164.c +++ b/arch/alpha/kernel/sys_sx164.c @@ -17,7 +17,6 @@  #include <linux/bitops.h>  #include <asm/ptrace.h> -#include <asm/system.h>  #include <asm/dma.h>  #include <asm/irq.h>  #include <asm/mmu_context.h> @@ -26,6 +25,7 @@  #include <asm/core_cia.h>  #include <asm/hwrpb.h>  #include <asm/tlbflush.h> +#include <asm/special_insns.h>  #include "proto.h"  #include "irq_impl.h" @@ -95,7 +95,7 @@ sx164_init_irq(void)   */  static int __init -sx164_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +sx164_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	static char irq_tab[5][5] __initdata = {  		/*INT    INTA   INTB   INTC   INTD */ diff --git a/arch/alpha/kernel/sys_takara.c b/arch/alpha/kernel/sys_takara.c index 4da596b6adb..dd0f1eae3c6 100644 --- a/arch/alpha/kernel/sys_takara.c +++ b/arch/alpha/kernel/sys_takara.c @@ -16,7 +16,6 @@  #include <linux/init.h>  #include <asm/ptrace.h> -#include <asm/system.h>  #include <asm/dma.h>  #include <asm/irq.h>  #include <asm/mmu_context.h> @@ -45,43 +44,28 @@ takara_update_irq_hw(unsigned long irq, unsigned long mask)  }  static inline void -takara_enable_irq(unsigned int irq) +takara_enable_irq(struct irq_data *d)  { +	unsigned int irq = d->irq;  	unsigned long mask;  	mask = (cached_irq_mask[irq >= 64] &= ~(1UL << (irq & 63)));  	takara_update_irq_hw(irq, mask);  }  static void -takara_disable_irq(unsigned int irq) +takara_disable_irq(struct irq_data *d)  { +	unsigned int irq = d->irq;  	unsigned long mask;  	mask = (cached_irq_mask[irq >= 64] |= 1UL << (irq & 63));  	takara_update_irq_hw(irq, mask);  } -static unsigned int -takara_startup_irq(unsigned int irq) -{ -	takara_enable_irq(irq); -	return 0; /* never anything pending */ -} - -static void -takara_end_irq(unsigned int irq) -{ -	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) -		takara_enable_irq(irq); -} -  static struct irq_chip takara_irq_type = {  	.name		= "TAKARA", -	.startup	= takara_startup_irq, -	.shutdown	= takara_disable_irq, -	.enable		= takara_enable_irq, -	.disable	= takara_disable_irq, -	.ack		= takara_disable_irq, -	.end		= takara_end_irq, +	.irq_unmask	= takara_enable_irq, +	.irq_mask	= takara_disable_irq, +	.irq_mask_ack	= takara_disable_irq,  };  static void @@ -153,8 +137,9 @@ takara_init_irq(void)  		takara_update_irq_hw(i, -1);  	for (i = 16; i < 128; ++i) { -		irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; -		irq_desc[i].chip = &takara_irq_type; +		irq_set_chip_and_handler(i, &takara_irq_type, +					 handle_level_irq); +		irq_set_status_flags(i, IRQ_LEVEL);  	}  	common_init_isa_dma(); @@ -171,7 +156,7 @@ takara_init_irq(void)   */  static int __init -takara_map_irq_srm(struct pci_dev *dev, u8 slot, u8 pin) +takara_map_irq_srm(const struct pci_dev *dev, u8 slot, u8 pin)  {  	static char irq_tab[15][5] __initdata = {  		{ 16+3, 16+3, 16+3, 16+3, 16+3},   /* slot  6 == device 3 */ @@ -202,7 +187,7 @@ takara_map_irq_srm(struct pci_dev *dev, u8 slot, u8 pin)  }  static int __init -takara_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +takara_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	static char irq_tab[15][5] __initdata = {  		{ 16+3, 16+3, 16+3, 16+3, 16+3},   /* slot  6 == device 3 */ diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c index 9008d0f20c5..a53cf03f49d 100644 --- a/arch/alpha/kernel/sys_titan.c +++ b/arch/alpha/kernel/sys_titan.c @@ -21,7 +21,6 @@  #include <linux/bitops.h>  #include <asm/ptrace.h> -#include <asm/system.h>  #include <asm/dma.h>  #include <asm/irq.h>  #include <asm/mmu_context.h> @@ -65,10 +64,11 @@ titan_update_irq_hw(unsigned long mask)  	register int bcpu = boot_cpuid;  #ifdef CONFIG_SMP -	cpumask_t cpm = cpu_present_map; +	cpumask_t cpm;  	volatile unsigned long *dim0, *dim1, *dim2, *dim3;  	unsigned long mask0, mask1, mask2, mask3, dummy; +	cpumask_copy(&cpm, cpu_present_mask);  	mask &= ~isa_enable;  	mask0 = mask & titan_cpu_irq_affinity[0];  	mask1 = mask & titan_cpu_irq_affinity[1]; @@ -84,10 +84,10 @@ titan_update_irq_hw(unsigned long mask)  	dim1 = &cchip->dim1.csr;  	dim2 = &cchip->dim2.csr;  	dim3 = &cchip->dim3.csr; -	if (!cpu_isset(0, cpm)) dim0 = &dummy; -	if (!cpu_isset(1, cpm)) dim1 = &dummy; -	if (!cpu_isset(2, cpm)) dim2 = &dummy; -	if (!cpu_isset(3, cpm)) dim3 = &dummy; +	if (!cpumask_test_cpu(0, &cpm)) dim0 = &dummy; +	if (!cpumask_test_cpu(1, &cpm)) dim1 = &dummy; +	if (!cpumask_test_cpu(2, &cpm)) dim2 = &dummy; +	if (!cpumask_test_cpu(3, &cpm)) dim3 = &dummy;  	*dim0 = mask0;  	*dim1 = mask1; @@ -112,8 +112,9 @@ titan_update_irq_hw(unsigned long mask)  }  static inline void -titan_enable_irq(unsigned int irq) +titan_enable_irq(struct irq_data *d)  { +	unsigned int irq = d->irq;  	spin_lock(&titan_irq_lock);  	titan_cached_irq_mask |= 1UL << (irq - 16);  	titan_update_irq_hw(titan_cached_irq_mask); @@ -121,35 +122,22 @@ titan_enable_irq(unsigned int irq)  }  static inline void -titan_disable_irq(unsigned int irq) +titan_disable_irq(struct irq_data *d)  { +	unsigned int irq = d->irq;  	spin_lock(&titan_irq_lock);  	titan_cached_irq_mask &= ~(1UL << (irq - 16));  	titan_update_irq_hw(titan_cached_irq_mask);  	spin_unlock(&titan_irq_lock);  } -static unsigned int -titan_startup_irq(unsigned int irq) -{ -	titan_enable_irq(irq); -	return 0;	/* never anything pending */ -} - -static void -titan_end_irq(unsigned int irq) -{ -	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) -		titan_enable_irq(irq); -} -  static void  titan_cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity)  {  	int cpu;  	for (cpu = 0; cpu < 4; cpu++) { -		if (cpu_isset(cpu, affinity)) +		if (cpumask_test_cpu(cpu, &affinity))  			titan_cpu_irq_affinity[cpu] |= 1UL << irq;  		else  			titan_cpu_irq_affinity[cpu] &= ~(1UL << irq); @@ -158,8 +146,10 @@ titan_cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity)  }  static int -titan_set_irq_affinity(unsigned int irq, const struct cpumask *affinity) +titan_set_irq_affinity(struct irq_data *d, const struct cpumask *affinity, +		       bool force)  {  +	unsigned int irq = d->irq;  	spin_lock(&titan_irq_lock);  	titan_cpu_set_irq_affinity(irq - 16, *affinity);  	titan_update_irq_hw(titan_cached_irq_mask); @@ -189,20 +179,17 @@ init_titan_irqs(struct irq_chip * ops, int imin, int imax)  {  	long i;  	for (i = imin; i <= imax; ++i) { -		irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; -		irq_desc[i].chip = ops; +		irq_set_chip_and_handler(i, ops, handle_level_irq); +		irq_set_status_flags(i, IRQ_LEVEL);  	}  }  static struct irq_chip titan_irq_type = { -       .name	       = "TITAN", -       .startup        = titan_startup_irq, -       .shutdown       = titan_disable_irq, -       .enable         = titan_enable_irq, -       .disable        = titan_disable_irq, -       .ack            = titan_disable_irq, -       .end            = titan_end_irq, -       .set_affinity   = titan_set_irq_affinity, +       .name			= "TITAN", +       .irq_unmask		= titan_enable_irq, +       .irq_mask		= titan_disable_irq, +       .irq_mask_ack		= titan_disable_irq, +       .irq_set_affinity	= titan_set_irq_affinity,  };  static irqreturn_t @@ -293,15 +280,15 @@ titan_late_init(void)  	 * all reported to the kernel as machine checks, so the handler  	 * is a nop so it can be called to count the individual events.  	 */ -	titan_request_irq(63+16, titan_intr_nop, IRQF_DISABLED, +	titan_request_irq(63+16, titan_intr_nop, 0,  		    "CChip Error", NULL); -	titan_request_irq(62+16, titan_intr_nop, IRQF_DISABLED, +	titan_request_irq(62+16, titan_intr_nop, 0,  		    "PChip 0 H_Error", NULL); -	titan_request_irq(61+16, titan_intr_nop, IRQF_DISABLED, +	titan_request_irq(61+16, titan_intr_nop, 0,  		    "PChip 1 H_Error", NULL); -	titan_request_irq(60+16, titan_intr_nop, IRQF_DISABLED, +	titan_request_irq(60+16, titan_intr_nop, 0,  		    "PChip 0 C_Error", NULL); -	titan_request_irq(59+16, titan_intr_nop, IRQF_DISABLED, +	titan_request_irq(59+16, titan_intr_nop, 0,  		    "PChip 1 C_Error", NULL);  	/*  @@ -316,8 +303,8 @@ titan_late_init(void)  } -static int __devinit -titan_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +static int +titan_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	u8 intline;  	int irq; @@ -343,7 +330,8 @@ titan_init_pci(void)   	 */   	titan_late_init(); -	pci_probe_only = 1; +	/* Indicate that we trust the console to configure things properly */ +	pci_set_flags(PCI_PROBE_ONLY);  	common_init_pci();  	SMC669_Init(0);  	locate_and_init_vga(NULL); @@ -360,9 +348,9 @@ privateer_init_pci(void)  	 * Hook a couple of extra err interrupts that the  	 * common titan code won't.  	 */ -	titan_request_irq(53+16, titan_intr_nop, IRQF_DISABLED, +	titan_request_irq(53+16, titan_intr_nop, 0,  		    "NMI", NULL); -	titan_request_irq(50+16, titan_intr_nop, IRQF_DISABLED, +	titan_request_irq(50+16, titan_intr_nop, 0,  		    "Temperature Warning", NULL);  	/* diff --git a/arch/alpha/kernel/sys_wildfire.c b/arch/alpha/kernel/sys_wildfire.c index 62fd972e18e..ee187488777 100644 --- a/arch/alpha/kernel/sys_wildfire.c +++ b/arch/alpha/kernel/sys_wildfire.c @@ -15,7 +15,6 @@  #include <linux/bitops.h>  #include <asm/ptrace.h> -#include <asm/system.h>  #include <asm/dma.h>  #include <asm/irq.h>  #include <asm/mmu_context.h> @@ -104,10 +103,12 @@ wildfire_init_irq_hw(void)  }  static void -wildfire_enable_irq(unsigned int irq) +wildfire_enable_irq(struct irq_data *d)  { +	unsigned int irq = d->irq; +  	if (irq < 16) -		i8259a_enable_irq(irq); +		i8259a_enable_irq(d);  	spin_lock(&wildfire_irq_lock);  	set_bit(irq, &cached_irq_mask); @@ -116,10 +117,12 @@ wildfire_enable_irq(unsigned int irq)  }  static void -wildfire_disable_irq(unsigned int irq) +wildfire_disable_irq(struct irq_data *d)  { +	unsigned int irq = d->irq; +  	if (irq < 16) -		i8259a_disable_irq(irq); +		i8259a_disable_irq(d);  	spin_lock(&wildfire_irq_lock);  	clear_bit(irq, &cached_irq_mask); @@ -128,10 +131,12 @@ wildfire_disable_irq(unsigned int irq)  }  static void -wildfire_mask_and_ack_irq(unsigned int irq) +wildfire_mask_and_ack_irq(struct irq_data *d)  { +	unsigned int irq = d->irq; +  	if (irq < 16) -		i8259a_mask_and_ack_irq(irq); +		i8259a_mask_and_ack_irq(d);  	spin_lock(&wildfire_irq_lock);  	clear_bit(irq, &cached_irq_mask); @@ -139,39 +144,17 @@ wildfire_mask_and_ack_irq(unsigned int irq)  	spin_unlock(&wildfire_irq_lock);  } -static unsigned int -wildfire_startup_irq(unsigned int irq) -{  -	wildfire_enable_irq(irq); -	return 0; /* never anything pending */ -} - -static void -wildfire_end_irq(unsigned int irq) -{  -#if 0 -	if (!irq_desc[irq].action) -		printk("got irq %d\n", irq); -#endif -	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) -		wildfire_enable_irq(irq); -} -  static struct irq_chip wildfire_irq_type = {  	.name		= "WILDFIRE", -	.startup	= wildfire_startup_irq, -	.shutdown	= wildfire_disable_irq, -	.enable		= wildfire_enable_irq, -	.disable	= wildfire_disable_irq, -	.ack		= wildfire_mask_and_ack_irq, -	.end		= wildfire_end_irq, +	.irq_unmask	= wildfire_enable_irq, +	.irq_mask	= wildfire_disable_irq, +	.irq_mask_ack	= wildfire_mask_and_ack_irq,  };  static void __init  wildfire_init_irq_per_pca(int qbbno, int pcano)  {  	int i, irq_bias; -	unsigned long io_bias;  	static struct irqaction isa_enable = {  		.handler	= no_action,  		.name		= "isa_enable", @@ -180,10 +163,12 @@ wildfire_init_irq_per_pca(int qbbno, int pcano)  	irq_bias = qbbno * (WILDFIRE_PCA_PER_QBB * WILDFIRE_IRQ_PER_PCA)  		 + pcano * WILDFIRE_IRQ_PER_PCA; +#if 0 +	unsigned long io_bias; +  	/* Only need the following for first PCI bus per PCA. */  	io_bias = WILDFIRE_IO(qbbno, pcano<<1) - WILDFIRE_IO_BIAS; -#if 0  	outb(0, DMA1_RESET_REG + io_bias);  	outb(0, DMA2_RESET_REG + io_bias);  	outb(DMA_MODE_CASCADE, DMA2_MODE_REG + io_bias); @@ -198,18 +183,21 @@ wildfire_init_irq_per_pca(int qbbno, int pcano)  	for (i = 0; i < 16; ++i) {  		if (i == 2)  			continue; -		irq_desc[i+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL; -		irq_desc[i+irq_bias].chip = &wildfire_irq_type; +		irq_set_chip_and_handler(i + irq_bias, &wildfire_irq_type, +					 handle_level_irq); +		irq_set_status_flags(i + irq_bias, IRQ_LEVEL);  	} -	irq_desc[36+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL; -	irq_desc[36+irq_bias].chip = &wildfire_irq_type; +	irq_set_chip_and_handler(36 + irq_bias, &wildfire_irq_type, +				 handle_level_irq); +	irq_set_status_flags(36 + irq_bias, IRQ_LEVEL);  	for (i = 40; i < 64; ++i) { -		irq_desc[i+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL; -		irq_desc[i+irq_bias].chip = &wildfire_irq_type; +		irq_set_chip_and_handler(i + irq_bias, &wildfire_irq_type, +					 handle_level_irq); +		irq_set_status_flags(i + irq_bias, IRQ_LEVEL);  	} -	setup_irq(32+irq_bias, &isa_enable);	 +	setup_irq(32+irq_bias, &isa_enable);  }  static void __init @@ -301,7 +289,7 @@ wildfire_device_interrupt(unsigned long vector)   */  static int __init -wildfire_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +wildfire_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	static char irq_tab[8][5] __initdata = {  		/*INT    INTA   INTB   INTC   INTD */ diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S index a6a1de9db16..dca9b3fb007 100644 --- a/arch/alpha/kernel/systbls.S +++ b/arch/alpha/kernel/systbls.S @@ -12,7 +12,7 @@  sys_call_table:  	.quad alpha_ni_syscall			/* 0 */  	.quad sys_exit -	.quad sys_fork +	.quad alpha_fork  	.quad sys_read  	.quad sys_write  	.quad alpha_ni_syscall			/* 5 */ @@ -76,7 +76,7 @@ sys_call_table:  	.quad sys_getpgrp  	.quad sys_getpagesize  	.quad alpha_ni_syscall			/* 65 */ -	.quad sys_vfork +	.quad alpha_vfork  	.quad sys_newstat  	.quad sys_newlstat  	.quad alpha_ni_syscall @@ -111,7 +111,7 @@ sys_call_table:  	.quad sys_socket  	.quad sys_connect  	.quad sys_accept -	.quad osf_getpriority			/* 100 */ +	.quad sys_osf_getpriority			/* 100 */  	.quad sys_send  	.quad sys_recv  	.quad sys_sigreturn @@ -241,11 +241,11 @@ sys_call_table:  	.quad alpha_ni_syscall  	.quad alpha_ni_syscall  	.quad alpha_ni_syscall -	.quad alpha_ni_syscall -	.quad alpha_ni_syscall			/* 225 */ -	.quad alpha_ni_syscall -	.quad alpha_ni_syscall -	.quad alpha_ni_syscall +	.quad sys_osf_stat +	.quad sys_osf_lstat			/* 225 */ +	.quad sys_osf_fstat +	.quad sys_osf_statfs64 +	.quad sys_osf_fstatfs64  	.quad alpha_ni_syscall  	.quad alpha_ni_syscall			/* 230 */  	.quad alpha_ni_syscall @@ -330,7 +330,7 @@ sys_call_table:  	.quad sys_ni_syscall			/* 309: old get_kernel_syms */  	.quad sys_syslog			/* 310 */  	.quad sys_reboot -	.quad sys_clone +	.quad alpha_clone  	.quad sys_uselib  	.quad sys_mlock  	.quad sys_munlock			/* 315 */ @@ -360,7 +360,7 @@ sys_call_table:  	.quad sys_newuname  	.quad sys_nanosleep			/* 340 */  	.quad sys_mremap -	.quad sys_nfsservctl +	.quad sys_ni_syscall			/* old nfsservctl */  	.quad sys_setresuid  	.quad sys_getresuid  	.quad sys_pciconfig_read		/* 345 */ @@ -498,23 +498,34 @@ sys_call_table:  	.quad sys_ni_syscall			/* sys_timerfd */  	.quad sys_eventfd  	.quad sys_recvmmsg -	.quad sys_fallocate				/* 480 */ +	.quad sys_fallocate			/* 480 */  	.quad sys_timerfd_create  	.quad sys_timerfd_settime  	.quad sys_timerfd_gettime  	.quad sys_signalfd4 -	.quad sys_eventfd2				/* 485 */ +	.quad sys_eventfd2			/* 485 */  	.quad sys_epoll_create1  	.quad sys_dup3  	.quad sys_pipe2  	.quad sys_inotify_init1 -	.quad sys_preadv				/* 490 */ +	.quad sys_preadv			/* 490 */  	.quad sys_pwritev  	.quad sys_rt_tgsigqueueinfo  	.quad sys_perf_event_open  	.quad sys_fanotify_init -	.quad sys_fanotify_mark				/* 495 */ +	.quad sys_fanotify_mark			/* 495 */  	.quad sys_prlimit64 +	.quad sys_name_to_handle_at +	.quad sys_open_by_handle_at +	.quad sys_clock_adjtime +	.quad sys_syncfs			/* 500 */ +	.quad sys_setns +	.quad sys_accept4 +	.quad sys_sendmmsg +	.quad sys_process_vm_readv +	.quad sys_process_vm_writev		/* 505 */ +	.quad sys_kcmp +	.quad sys_finit_module  	.size sys_call_table, . - sys_call_table  	.type sys_call_table, @object diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index 0f1d8493cfc..ee39cee8064 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c @@ -3,13 +3,7 @@   *   *  Copyright (C) 1991, 1992, 1995, 1999, 2000  Linus Torvalds   * - * This file contains the PC-specific time handling details: - * reading the RTC at bootup, etc.. - * 1994-07-02    Alan Modra - *	fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime - * 1995-03-26    Markus Kuhn - *      fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887 - *      precision CMOS clock update + * This file contains the clocksource time handling.   * 1997-09-10	Updated NTP code according to technical memorandum Jan '96   *		"A Kernel Model for Precision Timekeeping" by Dave Mills   * 1997-01-09    Adrian Sun @@ -21,9 +15,6 @@   * 1999-04-16	Thorsten Kranzkowski (dl8bcu@gmx.net)   *	fixed algorithm in do_gettimeofday() for calculating the precise time   *	from processor cycle counter (now taking lost_ticks into account) - * 2000-08-13	Jan-Benedict Glaw <jbglaw@lug-owl.de> - * 	Fixed time_init to be aware of epoches != 1900. This prevents - * 	booting up in 2048 for me;) Code is stolen from rtc.c.   * 2003-06-03	R. Scott Bailey <scott.bailey@eds.com>   *	Tighten sanity in time_init from 1% (10,000 PPM) to 250 PPM   */ @@ -46,41 +37,19 @@  #include <asm/uaccess.h>  #include <asm/io.h>  #include <asm/hwrpb.h> -#include <asm/8253pit.h> -#include <asm/rtc.h>  #include <linux/mc146818rtc.h>  #include <linux/time.h>  #include <linux/timex.h>  #include <linux/clocksource.h> +#include <linux/clockchips.h>  #include "proto.h"  #include "irq_impl.h" -static int set_rtc_mmss(unsigned long); -  DEFINE_SPINLOCK(rtc_lock);  EXPORT_SYMBOL(rtc_lock); -#define TICK_SIZE (tick_nsec / 1000) - -/* - * Shift amount by which scaled_ticks_per_cycle is scaled.  Shifting - * by 48 gives us 16 bits for HZ while keeping the accuracy good even - * for large CPU clock rates. - */ -#define FIX_SHIFT	48 - -/* lump static variables together for more efficient access: */ -static struct { -	/* cycle counter last time it got invoked */ -	__u32 last_time; -	/* ticks/cycle * 2^48 */ -	unsigned long scaled_ticks_per_cycle; -	/* partial unused tick */ -	unsigned long partial_tick; -} state; -  unsigned long est_cycle_freq;  #ifdef CONFIG_IRQ_WORK @@ -91,7 +60,7 @@ DEFINE_PER_CPU(u8, irq_work_pending);  #define test_irq_work_pending()      __get_cpu_var(irq_work_pending)  #define clear_irq_work_pending()     __get_cpu_var(irq_work_pending) = 0 -void set_irq_work_pending(void) +void arch_irq_work_raise(void)  {  	set_irq_work_pending_flag();  } @@ -106,117 +75,159 @@ void set_irq_work_pending(void)  static inline __u32 rpcc(void)  { -    __u32 result; -    asm volatile ("rpcc %0" : "=r"(result)); -    return result; +	return __builtin_alpha_rpcc();  } -int update_persistent_clock(struct timespec now) -{ -	return set_rtc_mmss(now.tv_sec); -} -void read_persistent_clock(struct timespec *ts) + +/* + * The RTC as a clock_event_device primitive. + */ + +static DEFINE_PER_CPU(struct clock_event_device, cpu_ce); + +irqreturn_t +rtc_timer_interrupt(int irq, void *dev)  { -	unsigned int year, mon, day, hour, min, sec, epoch; - -	sec = CMOS_READ(RTC_SECONDS); -	min = CMOS_READ(RTC_MINUTES); -	hour = CMOS_READ(RTC_HOURS); -	day = CMOS_READ(RTC_DAY_OF_MONTH); -	mon = CMOS_READ(RTC_MONTH); -	year = CMOS_READ(RTC_YEAR); - -	if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { -		sec = bcd2bin(sec); -		min = bcd2bin(min); -		hour = bcd2bin(hour); -		day = bcd2bin(day); -		mon = bcd2bin(mon); -		year = bcd2bin(year); -	} +	int cpu = smp_processor_id(); +	struct clock_event_device *ce = &per_cpu(cpu_ce, cpu); -	/* PC-like is standard; used for year >= 70 */ -	epoch = 1900; -	if (year < 20) -		epoch = 2000; -	else if (year >= 20 && year < 48) -		/* NT epoch */ -		epoch = 1980; -	else if (year >= 48 && year < 70) -		/* Digital UNIX epoch */ -		epoch = 1952; +	/* Don't run the hook for UNUSED or SHUTDOWN.  */ +	if (likely(ce->mode == CLOCK_EVT_MODE_PERIODIC)) +		ce->event_handler(ce); -	printk(KERN_INFO "Using epoch = %d\n", epoch); +	if (test_irq_work_pending()) { +		clear_irq_work_pending(); +		irq_work_run(); +	} -	if ((year += epoch) < 1970) -		year += 100; +	return IRQ_HANDLED; +} -	ts->tv_sec = mktime(year, mon, day, hour, min, sec); +static void +rtc_ce_set_mode(enum clock_event_mode mode, struct clock_event_device *ce) +{ +	/* The mode member of CE is updated in generic code. +	   Since we only support periodic events, nothing to do.  */ +} + +static int +rtc_ce_set_next_event(unsigned long evt, struct clock_event_device *ce) +{ +	/* This hook is for oneshot mode, which we don't support.  */ +	return -EINVAL;  } +static void __init +init_rtc_clockevent(void) +{ +	int cpu = smp_processor_id(); +	struct clock_event_device *ce = &per_cpu(cpu_ce, cpu); + +	*ce = (struct clock_event_device){ +		.name = "rtc", +		.features = CLOCK_EVT_FEAT_PERIODIC, +		.rating = 100, +		.cpumask = cpumask_of(cpu), +		.set_mode = rtc_ce_set_mode, +		.set_next_event = rtc_ce_set_next_event, +	}; +	clockevents_config_and_register(ce, CONFIG_HZ, 0, 0); +} +  /* - * timer_interrupt() needs to keep up the real-time clock, - * as well as call the "do_timer()" routine every clocktick + * The QEMU clock as a clocksource primitive.   */ -irqreturn_t timer_interrupt(int irq, void *dev) -{ -	unsigned long delta; -	__u32 now; -	long nticks; -#ifndef CONFIG_SMP -	/* Not SMP, do kernel PC profiling here.  */ -	profile_tick(CPU_PROFILING); -#endif +static cycle_t +qemu_cs_read(struct clocksource *cs) +{ +	return qemu_get_vmtime(); +} -	write_seqlock(&xtime_lock); +static struct clocksource qemu_cs = { +	.name                   = "qemu", +	.rating                 = 400, +	.read                   = qemu_cs_read, +	.mask                   = CLOCKSOURCE_MASK(64), +	.flags                  = CLOCK_SOURCE_IS_CONTINUOUS, +	.max_idle_ns		= LONG_MAX +}; -	/* -	 * Calculate how many ticks have passed since the last update, -	 * including any previous partial leftover.  Save any resulting -	 * fraction for the next pass. -	 */ -	now = rpcc(); -	delta = now - state.last_time; -	state.last_time = now; -	delta = delta * state.scaled_ticks_per_cycle + state.partial_tick; -	state.partial_tick = delta & ((1UL << FIX_SHIFT) - 1);  -	nticks = delta >> FIX_SHIFT; -	if (nticks) -		do_timer(nticks); +/* + * The QEMU alarm as a clock_event_device primitive. + */ -	write_sequnlock(&xtime_lock); +static void +qemu_ce_set_mode(enum clock_event_mode mode, struct clock_event_device *ce) +{ +	/* The mode member of CE is updated for us in generic code. +	   Just make sure that the event is disabled.  */ +	qemu_set_alarm_abs(0); +} -	if (test_irq_work_pending()) { -		clear_irq_work_pending(); -		irq_work_run(); -	} +static int +qemu_ce_set_next_event(unsigned long evt, struct clock_event_device *ce) +{ +	qemu_set_alarm_rel(evt); +	return 0; +} -#ifndef CONFIG_SMP -	while (nticks--) -		update_process_times(user_mode(get_irq_regs())); -#endif +static irqreturn_t +qemu_timer_interrupt(int irq, void *dev) +{ +	int cpu = smp_processor_id(); +	struct clock_event_device *ce = &per_cpu(cpu_ce, cpu); +	ce->event_handler(ce);  	return IRQ_HANDLED;  } +static void __init +init_qemu_clockevent(void) +{ +	int cpu = smp_processor_id(); +	struct clock_event_device *ce = &per_cpu(cpu_ce, cpu); + +	*ce = (struct clock_event_device){ +		.name = "qemu", +		.features = CLOCK_EVT_FEAT_ONESHOT, +		.rating = 400, +		.cpumask = cpumask_of(cpu), +		.set_mode = qemu_ce_set_mode, +		.set_next_event = qemu_ce_set_next_event, +	}; + +	clockevents_config_and_register(ce, NSEC_PER_SEC, 1000, LONG_MAX); +} + +  void __init  common_init_rtc(void)  { -	unsigned char x; +	unsigned char x, sel = 0;  	/* Reset periodic interrupt frequency.  */ -	x = CMOS_READ(RTC_FREQ_SELECT) & 0x3f; -        /* Test includes known working values on various platforms -           where 0x26 is wrong; we refuse to change those. */ -	if (x != 0x26 && x != 0x25 && x != 0x19 && x != 0x06) { -		printk("Setting RTC_FREQ to 1024 Hz (%x)\n", x); -		CMOS_WRITE(0x26, RTC_FREQ_SELECT); +#if CONFIG_HZ == 1024 || CONFIG_HZ == 1200 + 	x = CMOS_READ(RTC_FREQ_SELECT) & 0x3f; +	/* Test includes known working values on various platforms +	   where 0x26 is wrong; we refuse to change those. */ + 	if (x != 0x26 && x != 0x25 && x != 0x19 && x != 0x06) { +		sel = RTC_REF_CLCK_32KHZ + 6;  	} +#elif CONFIG_HZ == 256 || CONFIG_HZ == 128 || CONFIG_HZ == 64 || CONFIG_HZ == 32 +	sel = RTC_REF_CLCK_32KHZ + __builtin_ffs(32768 / CONFIG_HZ); +#else +# error "Unknown HZ from arch/alpha/Kconfig" +#endif +	if (sel) { +		printk(KERN_INFO "Setting RTC_FREQ to %d Hz (%x)\n", +		       CONFIG_HZ, sel); +		CMOS_WRITE(sel, RTC_FREQ_SELECT); + 	}  	/* Turn on periodic interrupts.  */  	x = CMOS_READ(RTC_CONTROL); @@ -239,16 +250,37 @@ common_init_rtc(void)  	init_rtc_irq();  } -unsigned int common_get_rtc_time(struct rtc_time *time) -{ -	return __get_rtc_time(time); -} + +#ifndef CONFIG_ALPHA_WTINT +/* + * The RPCC as a clocksource primitive. + * + * While we have free-running timecounters running on all CPUs, and we make + * a half-hearted attempt in init_rtc_rpcc_info to sync the timecounter + * with the wall clock, that initialization isn't kept up-to-date across + * different time counters in SMP mode.  Therefore we can only use this + * method when there's only one CPU enabled. + * + * When using the WTINT PALcall, the RPCC may shift to a lower frequency, + * or stop altogether, while waiting for the interrupt.  Therefore we cannot + * use this method when WTINT is in use. + */ -int common_set_rtc_time(struct rtc_time *time) +static cycle_t read_rpcc(struct clocksource *cs)  { -	return __set_rtc_time(time); +	return rpcc();  } +static struct clocksource clocksource_rpcc = { +	.name                   = "rpcc", +	.rating                 = 300, +	.read                   = read_rpcc, +	.mask                   = CLOCKSOURCE_MASK(32), +	.flags                  = CLOCK_SOURCE_IS_CONTINUOUS +}; +#endif /* ALPHA_WTINT */ + +  /* Validate a computed cycle counter result against the known bounds for     the given processor core.  There's too much brokenness in the way of     timing hardware for any one method to work everywhere.  :-( @@ -359,34 +391,6 @@ rpcc_after_update_in_progress(void)  	return rpcc();  } -#ifndef CONFIG_SMP -/* Until and unless we figure out how to get cpu cycle counters -   in sync and keep them there, we can't use the rpcc.  */ -static cycle_t read_rpcc(struct clocksource *cs) -{ -	cycle_t ret = (cycle_t)rpcc(); -	return ret; -} - -static struct clocksource clocksource_rpcc = { -	.name                   = "rpcc", -	.rating                 = 300, -	.read                   = read_rpcc, -	.mask                   = CLOCKSOURCE_MASK(32), -	.flags                  = CLOCK_SOURCE_IS_CONTINUOUS -}; - -static inline void register_rpcc_clocksource(long cycle_freq) -{ -	clocksource_calc_mult_shift(&clocksource_rpcc, cycle_freq, 4); -	clocksource_register(&clocksource_rpcc); -} -#else /* !CONFIG_SMP */ -static inline void register_rpcc_clocksource(long cycle_freq) -{ -} -#endif /* !CONFIG_SMP */ -  void __init  time_init(void)  { @@ -394,6 +398,15 @@ time_init(void)  	unsigned long cycle_freq, tolerance;  	long diff; +	if (alpha_using_qemu) { +		clocksource_register_hz(&qemu_cs, NSEC_PER_SEC); +		init_qemu_clockevent(); + +		timer_irqaction.handler = qemu_timer_interrupt; +		init_rtc_irq(); +		return; +	} +  	/* Calibrate CPU clock -- attempt #1.  */  	if (!est_cycle_freq)  		est_cycle_freq = validate_cc_value(calibrate_cc_with_pit()); @@ -428,100 +441,25 @@ time_init(void)  		       "and unable to estimate a proper value!\n");  	} -	/* From John Bowman <bowman@math.ualberta.ca>: allow the values -	   to settle, as the Update-In-Progress bit going low isn't good -	   enough on some hardware.  2ms is our guess; we haven't found  -	   bogomips yet, but this is close on a 500Mhz box.  */ -	__delay(1000000); - - -	if (HZ > (1<<16)) { -		extern void __you_loose (void); -		__you_loose(); -	} - -	register_rpcc_clocksource(cycle_freq); - -	state.last_time = cc1; -	state.scaled_ticks_per_cycle -		= ((unsigned long) HZ << FIX_SHIFT) / cycle_freq; -	state.partial_tick = 0L; +	/* See above for restrictions on using clocksource_rpcc.  */ +#ifndef CONFIG_ALPHA_WTINT +	if (hwrpb->nr_processors == 1) +		clocksource_register_hz(&clocksource_rpcc, cycle_freq); +#endif  	/* Startup the timer source. */  	alpha_mv.init_rtc(); +	init_rtc_clockevent();  } -/* - * In order to set the CMOS clock precisely, set_rtc_mmss has to be - * called 500 ms after the second nowtime has started, because when - * nowtime is written into the registers of the CMOS clock, it will - * jump to the next second precisely 500 ms later. Check the Motorola - * MC146818A or Dallas DS12887 data sheet for details. - * - * BUG: This routine does not handle hour overflow properly; it just - *      sets the minutes. Usually you won't notice until after reboot! - */ - - -static int -set_rtc_mmss(unsigned long nowtime) +/* Initialize the clock_event_device for secondary cpus.  */ +#ifdef CONFIG_SMP +void __init +init_clockevent(void)  { -	int retval = 0; -	int real_seconds, real_minutes, cmos_minutes; -	unsigned char save_control, save_freq_select; - -	/* irq are locally disabled here */ -	spin_lock(&rtc_lock); -	/* Tell the clock it's being set */ -	save_control = CMOS_READ(RTC_CONTROL); -	CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); - -	/* Stop and reset prescaler */ -	save_freq_select = CMOS_READ(RTC_FREQ_SELECT); -	CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); - -	cmos_minutes = CMOS_READ(RTC_MINUTES); -	if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) -		cmos_minutes = bcd2bin(cmos_minutes); - -	/* -	 * since we're only adjusting minutes and seconds, -	 * don't interfere with hour overflow. This avoids -	 * messing with unknown time zones but requires your -	 * RTC not to be off by more than 15 minutes -	 */ -	real_seconds = nowtime % 60; -	real_minutes = nowtime / 60; -	if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) { -		/* correct for half hour time zone */ -		real_minutes += 30; -	} -	real_minutes %= 60; - -	if (abs(real_minutes - cmos_minutes) < 30) { -		if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { -			real_seconds = bin2bcd(real_seconds); -			real_minutes = bin2bcd(real_minutes); -		} -		CMOS_WRITE(real_seconds,RTC_SECONDS); -		CMOS_WRITE(real_minutes,RTC_MINUTES); -	} else { -		printk(KERN_WARNING -		       "set_rtc_mmss: can't update from %d to %d\n", -		       cmos_minutes, real_minutes); - 		retval = -1; -	} - -	/* The following flags have to be released exactly in this order, -	 * otherwise the DS12887 (popular MC146818A clone with integrated -	 * battery and quartz) will not reset the oscillator and will not -	 * update precisely 500 ms later. You won't find this mentioned in -	 * the Dallas Semiconductor data sheets, but who believes data -	 * sheets anyway ...                           -- Markus Kuhn -	 */ -	CMOS_WRITE(save_control, RTC_CONTROL); -	CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); -	spin_unlock(&rtc_lock); - -	return retval; +	if (alpha_using_qemu) +		init_qemu_clockevent(); +	else +		init_rtc_clockevent();  } +#endif diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c index 0414e021a91..9c4c189eb22 100644 --- a/arch/alpha/kernel/traps.c +++ b/arch/alpha/kernel/traps.c @@ -24,6 +24,7 @@  #include <asm/sysinfo.h>  #include <asm/hwrpb.h>  #include <asm/mmu_context.h> +#include <asm/special_insns.h>  #include "proto.h" @@ -31,7 +32,7 @@  static int opDEC_fix; -static void __cpuinit +static void  opDEC_check(void)  {  	__asm__ __volatile__ ( @@ -65,8 +66,8 @@ dik_show_regs(struct pt_regs *regs, unsigned long *r9_15)  {  	printk("pc = [<%016lx>]  ra = [<%016lx>]  ps = %04lx    %s\n",  	       regs->pc, regs->r26, regs->ps, print_tainted()); -	print_symbol("pc is at %s\n", regs->pc); -	print_symbol("ra is at %s\n", regs->r26 ); +	printk("pc is at %pSR\n", (void *)regs->pc); +	printk("ra is at %pSR\n", (void *)regs->r26);  	printk("v0 = %016lx  t0 = %016lx  t1 = %016lx\n",  	       regs->r0, regs->r1, regs->r2);  	printk("t2 = %016lx  t3 = %016lx  t4 = %016lx\n", @@ -131,9 +132,7 @@ dik_show_trace(unsigned long *sp)  			continue;  		if (tmp >= (unsigned long) &_etext)  			continue; -		printk("[<%lx>]", tmp); -		print_symbol(" %s", tmp); -		printk("\n"); +		printk("[<%lx>] %pSR\n", tmp, (void *)tmp);  		if (i > 40) {  			printk(" ...");  			break; @@ -168,13 +167,6 @@ void show_stack(struct task_struct *task, unsigned long *sp)  	dik_show_trace(sp);  } -void dump_stack(void) -{ -	show_stack(NULL, NULL); -} - -EXPORT_SYMBOL(dump_stack); -  void  die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15)  { @@ -185,7 +177,7 @@ die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15)  #endif  	printk("%s(%d): %s %ld\n", current->comm, task_pid_nr(current), str, err);  	dik_show_regs(regs, r9_15); -	add_taint(TAINT_DIE); +	add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);  	dik_show_trace((unsigned long *)(regs+1));  	dik_show_code((unsigned int *)regs->pc); @@ -249,6 +241,21 @@ do_entIF(unsigned long type, struct pt_regs *regs)  			       (const char *)(data[1] | (long)data[2] << 32),   			       data[0]);  		} +#ifdef CONFIG_ALPHA_WTINT +		if (type == 4) { +			/* If CALL_PAL WTINT is totally unsupported by the +			   PALcode, e.g. MILO, "emulate" it by overwriting +			   the insn.  */ +			unsigned int *pinsn +			  = (unsigned int *) regs->pc - 1; +			if (*pinsn == PAL_wtint) { +				*pinsn = 0x47e01400; /* mov 0,$0 */ +				imb(); +				regs->r0 = 0; +				return; +			} +		} +#endif /* ALPHA_WTINT */  		die_if_kernel((type == 1 ? "Kernel Bug" : "Instruction fault"),  			      regs, type, NULL);  	} @@ -779,17 +786,17 @@ do_entUnaUser(void __user * va, unsigned long opcode,  	/* Check the UAC bits to decide what the user wants us to do  	   with the unaliged access.  */ -	if (!test_thread_flag (TIF_UAC_NOPRINT)) { +	if (!(current_thread_info()->status & TS_UAC_NOPRINT)) {  		if (__ratelimit(&ratelimit)) {  			printk("%s(%d): unaligned trap at %016lx: %p %lx %ld\n",  			       current->comm, task_pid_nr(current),  			       regs->pc - 4, va, opcode, reg);  		}  	} -	if (test_thread_flag (TIF_UAC_SIGBUS)) +	if ((current_thread_info()->status & TS_UAC_SIGBUS))  		goto give_sigbus;  	/* Not sure why you'd want to use this, but... */ -	if (test_thread_flag (TIF_UAC_NOFIX)) +	if ((current_thread_info()->status & TS_UAC_NOFIX))  		return;  	/* Don't bother reading ds in the access check since we already @@ -1065,7 +1072,7 @@ give_sigbus:  	return;  } -void __cpuinit +void  trap_init(void)  {  	/* Tell PAL-code what global pointer we want in the kernel.  */ diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S index 003ef4c0258..647b84c1538 100644 --- a/arch/alpha/kernel/vmlinux.lds.S +++ b/arch/alpha/kernel/vmlinux.lds.S @@ -1,6 +1,8 @@  #include <asm-generic/vmlinux.lds.h>  #include <asm/thread_info.h> +#include <asm/cache.h>  #include <asm/page.h> +#include <asm/setup.h>  OUTPUT_FORMAT("elf64-alpha")  OUTPUT_ARCH(alpha) @@ -24,6 +26,7 @@ SECTIONS  		*(.fixup)  		*(.gnu.warning)  	} :kernel +	swapper_pg_dir = SWAPPER_PGD;  	_etext = .;	/* End of text section */  	NOTES :kernel :note @@ -38,15 +41,16 @@ SECTIONS  	__init_begin = ALIGN(PAGE_SIZE);  	INIT_TEXT_SECTION(PAGE_SIZE)  	INIT_DATA_SECTION(16) -	PERCPU(PAGE_SIZE) +	PERCPU_SECTION(L1_CACHE_BYTES)  	/* Align to THREAD_SIZE rather than PAGE_SIZE here so any padding page  	   needed for the THREAD_SIZE aligned init_task gets freed after init */  	. = ALIGN(THREAD_SIZE);  	__init_end = .;  	/* Freed after init ends here */ +	_sdata = .;	/* Start of rw data section */  	_data = .; -	RW_DATA_SECTION(64, PAGE_SIZE, THREAD_SIZE) +	RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)  	.got : {  		*(.got)  | 
