diff --git a/[refs] b/[refs] index 2007faeb5f93..49480df00ba8 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 1bd64d42abdd4f9d44f77011a31f0292112f4c3b +refs/heads/master: a4084c147bd06ecc13d787eec626ff1faf8f5851 diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index f2a2b8e647c5..7679bf32f7bb 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -3162,7 +3162,7 @@ F: drivers/net/ioc3-eth.c IOC3 SERIAL DRIVER M: Pat Gefre -L: linux-serial@vger.kernel.org +L: linux-mips@linux-mips.org S: Maintained F: drivers/serial/ioc3_serial.c diff --git a/trunk/Makefile b/trunk/Makefile index 860c26af52c3..7583116e5d9a 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 36 -EXTRAVERSION = +EXTRAVERSION = -rc8 NAME = Flesh-Eating Bats with Fangs # *DOCUMENTATION* diff --git a/trunk/arch/m32r/include/asm/elf.h b/trunk/arch/m32r/include/asm/elf.h index b8da7d0574d2..2f85412ef730 100644 --- a/trunk/arch/m32r/include/asm/elf.h +++ b/trunk/arch/m32r/include/asm/elf.h @@ -82,9 +82,9 @@ typedef elf_fpreg_t elf_fpregset_t; * These are used to set parameters in the core dumps. */ #define ELF_CLASS ELFCLASS32 -#if defined(__LITTLE_ENDIAN__) +#if defined(__LITTLE_ENDIAN) #define ELF_DATA ELFDATA2LSB -#elif defined(__BIG_ENDIAN__) +#elif defined(__BIG_ENDIAN) #define ELF_DATA ELFDATA2MSB #else #error no endian defined diff --git a/trunk/arch/m32r/kernel/.gitignore b/trunk/arch/m32r/kernel/.gitignore deleted file mode 100644 index c5f676c3c224..000000000000 --- a/trunk/arch/m32r/kernel/.gitignore +++ /dev/null @@ -1 +0,0 @@ -vmlinux.lds diff --git a/trunk/arch/m32r/kernel/signal.c b/trunk/arch/m32r/kernel/signal.c index a08697f0886d..7bbe38645ed5 100644 --- a/trunk/arch/m32r/kernel/signal.c +++ b/trunk/arch/m32r/kernel/signal.c @@ -28,8 +28,6 @@ #define DEBUG_SIG 0 -#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) - asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, unsigned long r2, unsigned long r3, unsigned long r4, @@ -256,7 +254,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, static int prev_insn(struct pt_regs *regs) { u16 inst; - if (get_user(inst, (u16 __user *)(regs->bpc - 2))) + if (get_user(&inst, (u16 __user *)(regs->bpc - 2))) return -EFAULT; if ((inst & 0xfff0) == 0x10f0) /* trap ? */ regs->bpc -= 2; diff --git a/trunk/arch/mips/Kbuild b/trunk/arch/mips/Kbuild index 7dd65cfae837..e322d65f33a4 100644 --- a/trunk/arch/mips/Kbuild +++ b/trunk/arch/mips/Kbuild @@ -7,10 +7,6 @@ subdir-ccflags-y := -Werror include arch/mips/Kbuild.platforms obj-y := $(platform-y) -# make clean traverses $(obj-) without having included .config, so -# everything ends up here -obj- := $(platform-) - # mips object files # The object files are linked as core-y files would be linked diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index 4c9f402295dd..5526faabfc21 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -881,15 +881,11 @@ config NO_IOPORT config GENERIC_ISA_DMA bool select ZONE_DMA if GENERIC_ISA_DMA_SUPPORT_BROKEN=n - select ISA_DMA_API config GENERIC_ISA_DMA_SUPPORT_BROKEN bool select GENERIC_ISA_DMA -config ISA_DMA_API - bool - config GENERIC_GPIO bool diff --git a/trunk/arch/mips/boot/compressed/Makefile b/trunk/arch/mips/boot/compressed/Makefile index 5042d51b0512..5fd7f7a58b7e 100644 --- a/trunk/arch/mips/boot/compressed/Makefile +++ b/trunk/arch/mips/boot/compressed/Makefile @@ -105,4 +105,4 @@ OBJCOPYFLAGS_vmlinuz.srec := $(OBJCOPYFLAGS) -S -O srec vmlinuz.srec: vmlinuz $(call cmd,objcopy) -clean-files := $(objtree)/vmlinuz $(objtree)/vmlinuz.{32,ecoff,bin,srec} +clean-files := $(objtree)/vmlinuz.* diff --git a/trunk/arch/mips/dec/Platform b/trunk/arch/mips/dec/Platform index cf55a6f4e720..3adbcbd95db1 100644 --- a/trunk/arch/mips/dec/Platform +++ b/trunk/arch/mips/dec/Platform @@ -1,7 +1,7 @@ # # DECstation family # -platform-$(CONFIG_MACH_DECSTATION) += dec/ +platform-$(CONFIG_MACH_DECSTATION) = dec/ cflags-$(CONFIG_MACH_DECSTATION) += \ -I$(srctree)/arch/mips/include/asm/mach-dec libs-$(CONFIG_MACH_DECSTATION) += arch/mips/dec/prom/ diff --git a/trunk/arch/mips/include/asm/fcntl.h b/trunk/arch/mips/include/asm/fcntl.h index 75eddedcfc3e..e482fe90fe88 100644 --- a/trunk/arch/mips/include/asm/fcntl.h +++ b/trunk/arch/mips/include/asm/fcntl.h @@ -56,7 +56,6 @@ */ #ifdef CONFIG_32BIT -#include struct flock { short l_type; diff --git a/trunk/arch/mips/jz4740/Platform b/trunk/arch/mips/jz4740/Platform index ba91be9c21ef..6a97230e3d05 100644 --- a/trunk/arch/mips/jz4740/Platform +++ b/trunk/arch/mips/jz4740/Platform @@ -1,3 +1,3 @@ -platform-$(CONFIG_MACH_JZ4740) += jz4740/ +core-$(CONFIG_MACH_JZ4740) += arch/mips/jz4740/ cflags-$(CONFIG_MACH_JZ4740) += -I$(srctree)/arch/mips/include/asm/mach-jz4740 load-$(CONFIG_MACH_JZ4740) += 0xffffffff80010000 diff --git a/trunk/arch/mips/kernel/branch.c b/trunk/arch/mips/kernel/branch.c index 32103cc2a257..0176ed015c89 100644 --- a/trunk/arch/mips/kernel/branch.c +++ b/trunk/arch/mips/kernel/branch.c @@ -40,6 +40,7 @@ int __compute_return_epc(struct pt_regs *regs) return -EFAULT; } + regs->regs[0] = 0; switch (insn.i_format.opcode) { /* * jr and jalr are in r_format format. diff --git a/trunk/arch/mips/kernel/ptrace.c b/trunk/arch/mips/kernel/ptrace.c index c8777333e198..c51b95ff8644 100644 --- a/trunk/arch/mips/kernel/ptrace.c +++ b/trunk/arch/mips/kernel/ptrace.c @@ -536,7 +536,7 @@ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) { /* do the secure computing check first */ if (!entryexit) - secure_computing(regs->regs[2]); + secure_computing(regs->regs[0]); if (unlikely(current->audit_context) && entryexit) audit_syscall_exit(AUDITSC_RESULT(regs->regs[2]), @@ -565,7 +565,7 @@ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) out: if (unlikely(current->audit_context) && !entryexit) - audit_syscall_entry(audit_arch(), regs->regs[2], + audit_syscall_entry(audit_arch(), regs->regs[0], regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]); } diff --git a/trunk/arch/mips/kernel/scall32-o32.S b/trunk/arch/mips/kernel/scall32-o32.S index fbaabad0e6e2..584415eef8c9 100644 --- a/trunk/arch/mips/kernel/scall32-o32.S +++ b/trunk/arch/mips/kernel/scall32-o32.S @@ -63,9 +63,9 @@ stack_done: sw t0, PT_R7(sp) # set error flag beqz t0, 1f - lw t1, PT_R2(sp) # syscall number negu v0 # error - sw t1, PT_R0(sp) # save it for syscall restarting + sw v0, PT_R0(sp) # set flag for syscall + # restarting 1: sw v0, PT_R2(sp) # result o32_syscall_exit: @@ -104,9 +104,9 @@ syscall_trace_entry: sw t0, PT_R7(sp) # set error flag beqz t0, 1f - lw t1, PT_R2(sp) # syscall number negu v0 # error - sw t1, PT_R0(sp) # save it for syscall restarting + sw v0, PT_R0(sp) # set flag for syscall + # restarting 1: sw v0, PT_R2(sp) # result j syscall_exit @@ -169,7 +169,8 @@ stackargs: * We probably should handle this case a bit more drastic. */ bad_stack: - li v0, EFAULT + negu v0 # error + sw v0, PT_R0(sp) sw v0, PT_R2(sp) li t0, 1 # set error flag sw t0, PT_R7(sp) diff --git a/trunk/arch/mips/kernel/scall64-64.S b/trunk/arch/mips/kernel/scall64-64.S index 3f4179283207..5573f8e4e326 100644 --- a/trunk/arch/mips/kernel/scall64-64.S +++ b/trunk/arch/mips/kernel/scall64-64.S @@ -66,9 +66,9 @@ NESTED(handle_sys64, PT_SIZE, sp) sd t0, PT_R7(sp) # set error flag beqz t0, 1f - ld t1, PT_R2(sp) # syscall number dnegu v0 # error - sd t1, PT_R0(sp) # save it for syscall restarting + sd v0, PT_R0(sp) # set flag for syscall + # restarting 1: sd v0, PT_R2(sp) # result n64_syscall_exit: @@ -109,9 +109,8 @@ syscall_trace_entry: sd t0, PT_R7(sp) # set error flag beqz t0, 1f - ld t1, PT_R2(sp) # syscall number dnegu v0 # error - sd t1, PT_R0(sp) # save it for syscall restarting + sd v0, PT_R0(sp) # set flag for syscall restarting 1: sd v0, PT_R2(sp) # result j syscall_exit diff --git a/trunk/arch/mips/kernel/scall64-n32.S b/trunk/arch/mips/kernel/scall64-n32.S index f08ece6d8acc..1e38ec97672e 100644 --- a/trunk/arch/mips/kernel/scall64-n32.S +++ b/trunk/arch/mips/kernel/scall64-n32.S @@ -65,9 +65,8 @@ NESTED(handle_sysn32, PT_SIZE, sp) sd t0, PT_R7(sp) # set error flag beqz t0, 1f - ld t1, PT_R2(sp) # syscall number dnegu v0 # error - sd t1, PT_R0(sp) # save it for syscall restarting + sd v0, PT_R0(sp) # set flag for syscall restarting 1: sd v0, PT_R2(sp) # result local_irq_disable # make sure need_resched and @@ -107,9 +106,8 @@ n32_syscall_trace_entry: sd t0, PT_R7(sp) # set error flag beqz t0, 1f - ld t1, PT_R2(sp) # syscall number dnegu v0 # error - sd t1, PT_R0(sp) # save it for syscall restarting + sd v0, PT_R0(sp) # set flag for syscall restarting 1: sd v0, PT_R2(sp) # result j syscall_exit @@ -322,10 +320,10 @@ EXPORT(sysn32_call_table) PTR sys_cacheflush PTR sys_cachectl PTR sys_sysmips - PTR compat_sys_io_setup /* 6200 */ + PTR sys_io_setup /* 6200 */ PTR sys_io_destroy - PTR compat_sys_io_getevents - PTR compat_sys_io_submit + PTR sys_io_getevents + PTR sys_io_submit PTR sys_io_cancel PTR sys_exit_group /* 6205 */ PTR sys_lookup_dcookie diff --git a/trunk/arch/mips/kernel/scall64-o32.S b/trunk/arch/mips/kernel/scall64-o32.S index 78d768a3e19d..171979fc98e5 100644 --- a/trunk/arch/mips/kernel/scall64-o32.S +++ b/trunk/arch/mips/kernel/scall64-o32.S @@ -93,9 +93,8 @@ NESTED(handle_sys, PT_SIZE, sp) sd t0, PT_R7(sp) # set error flag beqz t0, 1f - ld t1, PT_R2(sp) # syscall number dnegu v0 # error - sd t1, PT_R0(sp) # save it for syscall restarting + sd v0, PT_R0(sp) # flag for syscall restarting 1: sd v0, PT_R2(sp) # result o32_syscall_exit: @@ -143,9 +142,8 @@ trace_a_syscall: sd t0, PT_R7(sp) # set error flag beqz t0, 1f - ld t1, PT_R2(sp) # syscall number dnegu v0 # error - sd t1, PT_R0(sp) # save it for syscall restarting + sd v0, PT_R0(sp) # set flag for syscall restarting 1: sd v0, PT_R2(sp) # result j syscall_exit @@ -156,7 +154,8 @@ trace_a_syscall: * The stackpointer for a call with more than 4 arguments is bad. */ bad_stack: - li v0, EFAULT + dnegu v0 # error + sd v0, PT_R0(sp) sd v0, PT_R2(sp) li t0, 1 # set error flag sd t0, PT_R7(sp) @@ -445,10 +444,10 @@ sys_call_table: PTR compat_sys_futex PTR compat_sys_sched_setaffinity PTR compat_sys_sched_getaffinity /* 4240 */ - PTR compat_sys_io_setup + PTR sys_io_setup PTR sys_io_destroy - PTR compat_sys_io_getevents - PTR compat_sys_io_submit + PTR sys_io_getevents + PTR sys_io_submit PTR sys_io_cancel /* 4245 */ PTR sys_exit_group PTR sys32_lookup_dcookie diff --git a/trunk/arch/mips/kernel/signal.c b/trunk/arch/mips/kernel/signal.c index 5922342bca39..2099d5a4c4b7 100644 --- a/trunk/arch/mips/kernel/signal.c +++ b/trunk/arch/mips/kernel/signal.c @@ -390,6 +390,7 @@ asmlinkage void sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs) { struct rt_sigframe __user *frame; sigset_t set; + stack_t st; int sig; frame = (struct rt_sigframe __user *) regs.regs[29]; @@ -410,9 +411,11 @@ asmlinkage void sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs) else if (sig) force_sig(sig, current); + if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st))) + goto badframe; /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - do_sigaltstack(&frame->rs_uc.uc_stack, NULL, regs.regs[29]); + do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]); /* * Don't let your children do this ... @@ -547,27 +550,24 @@ static int handle_signal(unsigned long sig, siginfo_t *info, struct mips_abi *abi = current->thread.abi; void *vdso = current->mm->context.vdso; - if (regs->regs[0]) { - switch(regs->regs[2]) { - case ERESTART_RESTARTBLOCK: - case ERESTARTNOHAND: + switch(regs->regs[0]) { + case ERESTART_RESTARTBLOCK: + case ERESTARTNOHAND: + regs->regs[2] = EINTR; + break; + case ERESTARTSYS: + if (!(ka->sa.sa_flags & SA_RESTART)) { regs->regs[2] = EINTR; break; - case ERESTARTSYS: - if (!(ka->sa.sa_flags & SA_RESTART)) { - regs->regs[2] = EINTR; - break; - } - /* fallthrough */ - case ERESTARTNOINTR: - regs->regs[7] = regs->regs[26]; - regs->regs[2] = regs->regs[0]; - regs->cp0_epc -= 4; } - - regs->regs[0] = 0; /* Don't deal with this again. */ + /* fallthrough */ + case ERESTARTNOINTR: /* Userland will reload $v0. */ + regs->regs[7] = regs->regs[26]; + regs->cp0_epc -= 8; } + regs->regs[0] = 0; /* Don't deal with this again. */ + if (sig_uses_siginfo(ka)) ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset, ka, regs, sig, oldset, info); @@ -575,9 +575,6 @@ static int handle_signal(unsigned long sig, siginfo_t *info, ret = abi->setup_frame(vdso + abi->signal_return_offset, ka, regs, sig, oldset); - if (ret) - return ret; - spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); if (!(ka->sa.sa_flags & SA_NODEFER)) @@ -625,13 +622,17 @@ static void do_signal(struct pt_regs *regs) return; } + /* + * Who's code doesn't conform to the restartable syscall convention + * dies here!!! The li instruction, a single machine instruction, + * must directly be followed by the syscall instruction. + */ if (regs->regs[0]) { if (regs->regs[2] == ERESTARTNOHAND || regs->regs[2] == ERESTARTSYS || regs->regs[2] == ERESTARTNOINTR) { - regs->regs[2] = regs->regs[0]; regs->regs[7] = regs->regs[26]; - regs->cp0_epc -= 4; + regs->cp0_epc -= 8; } if (regs->regs[2] == ERESTART_RESTARTBLOCK) { regs->regs[2] = current->thread.abi->restart; diff --git a/trunk/arch/mips/kernel/signal_n32.c b/trunk/arch/mips/kernel/signal_n32.c index ee24d814d5b9..2c5df818c65a 100644 --- a/trunk/arch/mips/kernel/signal_n32.c +++ b/trunk/arch/mips/kernel/signal_n32.c @@ -109,7 +109,6 @@ asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) { struct rt_sigframe_n32 __user *frame; - mm_segment_t old_fs; sigset_t set; stack_t st; s32 sp; @@ -144,11 +143,7 @@ asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - old_fs = get_fs(); - set_fs(KERNEL_DS); do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]); - set_fs(old_fs); - /* * Don't let your children do this ... diff --git a/trunk/arch/mips/kernel/unaligned.c b/trunk/arch/mips/kernel/unaligned.c index 33d5a5ce4a29..69b039ca8d83 100644 --- a/trunk/arch/mips/kernel/unaligned.c +++ b/trunk/arch/mips/kernel/unaligned.c @@ -109,6 +109,8 @@ static void emulate_load_store_insn(struct pt_regs *regs, unsigned long value; unsigned int res; + regs->regs[0] = 0; + /* * This load never faults. */ diff --git a/trunk/arch/um/drivers/hostaudio_kern.c b/trunk/arch/um/drivers/hostaudio_kern.c index 63c740a85b4c..0c46e398cd8f 100644 --- a/trunk/arch/um/drivers/hostaudio_kern.c +++ b/trunk/arch/um/drivers/hostaudio_kern.c @@ -40,11 +40,6 @@ static char *mixer = HOSTAUDIO_DEV_MIXER; " This is used to specify the host mixer device to the hostaudio driver.\n"\ " The default is \"" HOSTAUDIO_DEV_MIXER "\".\n\n" -module_param(dsp, charp, 0644); -MODULE_PARM_DESC(dsp, DSP_HELP); -module_param(mixer, charp, 0644); -MODULE_PARM_DESC(mixer, MIXER_HELP); - #ifndef MODULE static int set_dsp(char *name, int *add) { @@ -61,6 +56,15 @@ static int set_mixer(char *name, int *add) } __uml_setup("mixer=", set_mixer, "mixer=\n" MIXER_HELP); + +#else /*MODULE*/ + +module_param(dsp, charp, 0644); +MODULE_PARM_DESC(dsp, DSP_HELP); + +module_param(mixer, charp, 0644); +MODULE_PARM_DESC(mixer, MIXER_HELP); + #endif /* /dev/dsp file operations */ diff --git a/trunk/arch/um/drivers/ubd_kern.c b/trunk/arch/um/drivers/ubd_kern.c index 9734994cba1e..1bcd208c459f 100644 --- a/trunk/arch/um/drivers/ubd_kern.c +++ b/trunk/arch/um/drivers/ubd_kern.c @@ -163,7 +163,6 @@ struct ubd { struct scatterlist sg[MAX_SG]; struct request *request; int start_sg, end_sg; - sector_t rq_pos; }; #define DEFAULT_COW { \ @@ -188,7 +187,6 @@ struct ubd { .request = NULL, \ .start_sg = 0, \ .end_sg = 0, \ - .rq_pos = 0, \ } /* Protected by ubd_lock */ @@ -1230,6 +1228,7 @@ static void do_ubd_request(struct request_queue *q) { struct io_thread_req *io_req; struct request *req; + sector_t sector; int n; while(1){ @@ -1240,12 +1239,12 @@ static void do_ubd_request(struct request_queue *q) return; dev->request = req; - dev->rq_pos = blk_rq_pos(req); dev->start_sg = 0; dev->end_sg = blk_rq_map_sg(q, req, dev->sg); } req = dev->request; + sector = blk_rq_pos(req); while(dev->start_sg < dev->end_sg){ struct scatterlist *sg = &dev->sg[dev->start_sg]; @@ -1257,9 +1256,10 @@ static void do_ubd_request(struct request_queue *q) return; } prepare_request(req, io_req, - (unsigned long long)dev->rq_pos << 9, + (unsigned long long)sector << 9, sg->offset, sg->length, sg_page(sg)); + sector += sg->length >> 9; n = os_write_file(thread_fd, &io_req, sizeof(struct io_thread_req *)); if(n != sizeof(struct io_thread_req *)){ @@ -1272,7 +1272,6 @@ static void do_ubd_request(struct request_queue *q) return; } - dev->rq_pos += sg->length >> 9; dev->start_sg++; } dev->end_sg = 0; diff --git a/trunk/arch/x86/include/asm/kvm_host.h b/trunk/arch/x86/include/asm/kvm_host.h index c52e2eb40a1e..502e53f999cf 100644 --- a/trunk/arch/x86/include/asm/kvm_host.h +++ b/trunk/arch/x86/include/asm/kvm_host.h @@ -652,6 +652,20 @@ static inline struct kvm_mmu_page *page_header(hpa_t shadow_page) return (struct kvm_mmu_page *)page_private(page); } +static inline u16 kvm_read_fs(void) +{ + u16 seg; + asm("mov %%fs, %0" : "=g"(seg)); + return seg; +} + +static inline u16 kvm_read_gs(void) +{ + u16 seg; + asm("mov %%gs, %0" : "=g"(seg)); + return seg; +} + static inline u16 kvm_read_ldt(void) { u16 ldt; @@ -659,6 +673,16 @@ static inline u16 kvm_read_ldt(void) return ldt; } +static inline void kvm_load_fs(u16 sel) +{ + asm("mov %0, %%fs" : : "rm"(sel)); +} + +static inline void kvm_load_gs(u16 sel) +{ + asm("mov %0, %%gs" : : "rm"(sel)); +} + static inline void kvm_load_ldt(u16 sel) { asm("lldt %0" : : "rm"(sel)); diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/trunk/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index a2baafb2fe6d..cd8da247dda1 100644 --- a/trunk/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/trunk/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -701,7 +701,6 @@ static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy) per_cpu(acfreq_data, policy->cpu) = NULL; acpi_processor_unregister_performance(data->acpi_data, policy->cpu); - kfree(data->freq_table); kfree(data); } diff --git a/trunk/arch/x86/kvm/svm.c b/trunk/arch/x86/kvm/svm.c index 8a3f9f64f86f..81ed28cb36e6 100644 --- a/trunk/arch/x86/kvm/svm.c +++ b/trunk/arch/x86/kvm/svm.c @@ -3163,8 +3163,8 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu) sync_lapic_to_cr8(vcpu); save_host_msrs(vcpu); - savesegment(fs, fs_selector); - savesegment(gs, gs_selector); + fs_selector = kvm_read_fs(); + gs_selector = kvm_read_gs(); ldt_selector = kvm_read_ldt(); svm->vmcb->save.cr2 = vcpu->arch.cr2; /* required for live migration with NPT */ @@ -3251,15 +3251,10 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu) vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp; vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip; - load_host_msrs(vcpu); - loadsegment(fs, fs_selector); -#ifdef CONFIG_X86_64 - load_gs_index(gs_selector); - wrmsrl(MSR_KERNEL_GS_BASE, current->thread.gs); -#else - loadsegment(gs, gs_selector); -#endif + kvm_load_fs(fs_selector); + kvm_load_gs(gs_selector); kvm_load_ldt(ldt_selector); + load_host_msrs(vcpu); reload_tss(vcpu); diff --git a/trunk/arch/x86/kvm/vmx.c b/trunk/arch/x86/kvm/vmx.c index 7bddfab12013..49b25eee25ac 100644 --- a/trunk/arch/x86/kvm/vmx.c +++ b/trunk/arch/x86/kvm/vmx.c @@ -803,7 +803,7 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu) */ vmx->host_state.ldt_sel = kvm_read_ldt(); vmx->host_state.gs_ldt_reload_needed = vmx->host_state.ldt_sel; - savesegment(fs, vmx->host_state.fs_sel); + vmx->host_state.fs_sel = kvm_read_fs(); if (!(vmx->host_state.fs_sel & 7)) { vmcs_write16(HOST_FS_SELECTOR, vmx->host_state.fs_sel); vmx->host_state.fs_reload_needed = 0; @@ -811,7 +811,7 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu) vmcs_write16(HOST_FS_SELECTOR, 0); vmx->host_state.fs_reload_needed = 1; } - savesegment(gs, vmx->host_state.gs_sel); + vmx->host_state.gs_sel = kvm_read_gs(); if (!(vmx->host_state.gs_sel & 7)) vmcs_write16(HOST_GS_SELECTOR, vmx->host_state.gs_sel); else { @@ -841,21 +841,27 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu) static void __vmx_load_host_state(struct vcpu_vmx *vmx) { + unsigned long flags; + if (!vmx->host_state.loaded) return; ++vmx->vcpu.stat.host_state_reload; vmx->host_state.loaded = 0; if (vmx->host_state.fs_reload_needed) - loadsegment(fs, vmx->host_state.fs_sel); + kvm_load_fs(vmx->host_state.fs_sel); if (vmx->host_state.gs_ldt_reload_needed) { kvm_load_ldt(vmx->host_state.ldt_sel); + /* + * If we have to reload gs, we must take care to + * preserve our gs base. + */ + local_irq_save(flags); + kvm_load_gs(vmx->host_state.gs_sel); #ifdef CONFIG_X86_64 - load_gs_index(vmx->host_state.gs_sel); - wrmsrl(MSR_KERNEL_GS_BASE, current->thread.gs); -#else - loadsegment(gs, vmx->host_state.gs_sel); + wrmsrl(MSR_GS_BASE, vmcs_readl(HOST_GS_BASE)); #endif + local_irq_restore(flags); } reload_tss(); #ifdef CONFIG_X86_64 @@ -2583,8 +2589,8 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) vmcs_write16(HOST_CS_SELECTOR, __KERNEL_CS); /* 22.2.4 */ vmcs_write16(HOST_DS_SELECTOR, __KERNEL_DS); /* 22.2.4 */ vmcs_write16(HOST_ES_SELECTOR, __KERNEL_DS); /* 22.2.4 */ - vmcs_write16(HOST_FS_SELECTOR, 0); /* 22.2.4 */ - vmcs_write16(HOST_GS_SELECTOR, 0); /* 22.2.4 */ + vmcs_write16(HOST_FS_SELECTOR, kvm_read_fs()); /* 22.2.4 */ + vmcs_write16(HOST_GS_SELECTOR, kvm_read_gs()); /* 22.2.4 */ vmcs_write16(HOST_SS_SELECTOR, __KERNEL_DS); /* 22.2.4 */ #ifdef CONFIG_X86_64 rdmsrl(MSR_FS_BASE, a); diff --git a/trunk/block/bsg.c b/trunk/block/bsg.c index 0c00870553a3..82d58829ba59 100644 --- a/trunk/block/bsg.c +++ b/trunk/block/bsg.c @@ -426,7 +426,7 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr, /* * fill in all the output members */ - hdr->device_status = rq->errors & 0xff; + hdr->device_status = status_byte(rq->errors); hdr->transport_status = host_byte(rq->errors); hdr->driver_status = driver_byte(rq->errors); hdr->info = 0; diff --git a/trunk/drivers/acpi/Kconfig b/trunk/drivers/acpi/Kconfig index 0f9de2b44c0c..79f4178c4719 100644 --- a/trunk/drivers/acpi/Kconfig +++ b/trunk/drivers/acpi/Kconfig @@ -9,7 +9,6 @@ menuconfig ACPI depends on PCI depends on PM select PNP - select CPU_IDLE default y help Advanced Configuration and Power Interface (ACPI) support for @@ -66,6 +65,7 @@ config ACPI_PROCFS config ACPI_PROCFS_POWER bool "Deprecated power /proc/acpi directories" depends on PROC_FS + default y help For backwards compatibility, this option allows deprecated power /proc/acpi/ directories to exist, even when @@ -89,6 +89,13 @@ config ACPI_POWER_METER To compile this driver as a module, choose M here: the module will be called power-meter. +config ACPI_SYSFS_POWER + bool "Future power /sys interface" + select POWER_SUPPLY + default y + help + Say N to disable power /sys interface + config ACPI_EC_DEBUGFS tristate "EC read/write access through /sys/kernel/debug/ec" default n @@ -128,7 +135,6 @@ config ACPI_PROC_EVENT config ACPI_AC tristate "AC Adapter" depends on X86 - select POWER_SUPPLY default y help This driver supports the AC Adapter object, which indicates @@ -141,7 +147,6 @@ config ACPI_AC config ACPI_BATTERY tristate "Battery" depends on X86 - select POWER_SUPPLY default y help This driver adds support for battery information through @@ -200,6 +205,7 @@ config ACPI_DOCK config ACPI_PROCESSOR tristate "Processor" select THERMAL + select CPU_IDLE default y help This driver installs ACPI as the idle handler for Linux and uses @@ -358,7 +364,6 @@ config ACPI_HOTPLUG_MEMORY config ACPI_SBS tristate "Smart Battery System" depends on X86 - select POWER_SUPPLY help This driver supports the Smart Battery System, another type of access to battery information, found on some laptops. diff --git a/trunk/drivers/acpi/ac.c b/trunk/drivers/acpi/ac.c index ba9afeaa23ac..56205a0b85df 100644 --- a/trunk/drivers/acpi/ac.c +++ b/trunk/drivers/acpi/ac.c @@ -32,7 +32,9 @@ #include #include #endif +#ifdef CONFIG_ACPI_SYSFS_POWER #include +#endif #include #include @@ -84,7 +86,9 @@ static struct acpi_driver acpi_ac_driver = { }; struct acpi_ac { +#ifdef CONFIG_ACPI_SYSFS_POWER struct power_supply charger; +#endif struct acpi_device * device; unsigned long long state; }; @@ -100,6 +104,7 @@ static const struct file_operations acpi_ac_fops = { .release = single_release, }; #endif +#ifdef CONFIG_ACPI_SYSFS_POWER static int get_ac_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) @@ -118,6 +123,7 @@ static int get_ac_property(struct power_supply *psy, static enum power_supply_property ac_props[] = { POWER_SUPPLY_PROP_ONLINE, }; +#endif /* -------------------------------------------------------------------------- AC Adapter Management -------------------------------------------------------------------------- */ @@ -241,7 +247,9 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event) dev_name(&device->dev), event, (u32) ac->state); acpi_notifier_call_chain(device, event, (u32) ac->state); +#ifdef CONFIG_ACPI_SYSFS_POWER kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); +#endif } return; @@ -274,12 +282,14 @@ static int acpi_ac_add(struct acpi_device *device) #endif if (result) goto end; +#ifdef CONFIG_ACPI_SYSFS_POWER ac->charger.name = acpi_device_bid(device); ac->charger.type = POWER_SUPPLY_TYPE_MAINS; ac->charger.properties = ac_props; ac->charger.num_properties = ARRAY_SIZE(ac_props); ac->charger.get_property = get_ac_property; power_supply_register(&ac->device->dev, &ac->charger); +#endif printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device), acpi_device_bid(device), @@ -306,8 +316,10 @@ static int acpi_ac_resume(struct acpi_device *device) old_state = ac->state; if (acpi_ac_get_state(ac)) return 0; +#ifdef CONFIG_ACPI_SYSFS_POWER if (old_state != ac->state) kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); +#endif return 0; } @@ -321,8 +333,10 @@ static int acpi_ac_remove(struct acpi_device *device, int type) ac = acpi_driver_data(device); +#ifdef CONFIG_ACPI_SYSFS_POWER if (ac->charger.dev) power_supply_unregister(&ac->charger); +#endif #ifdef CONFIG_ACPI_PROCFS_POWER acpi_ac_remove_fs(device); #endif diff --git a/trunk/drivers/acpi/acpica/Makefile b/trunk/drivers/acpi/acpica/Makefile index a7e1d1aa4107..d93cc06f4bf8 100644 --- a/trunk/drivers/acpi/acpica/Makefile +++ b/trunk/drivers/acpi/acpica/Makefile @@ -21,7 +21,7 @@ acpi-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\ excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \ exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o exdebug.o -acpi-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o hwpci.o +acpi-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o @@ -44,5 +44,4 @@ acpi-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ - utstate.o utmutex.o utobject.o utresrc.o utlock.o utids.o \ - utosi.o utxferror.o + utstate.o utmutex.o utobject.o utresrc.o utlock.o utids.o diff --git a/trunk/drivers/acpi/acpica/acdebug.h b/trunk/drivers/acpi/acpica/acdebug.h index 72e9d5eb083c..48faf3eba9fb 100644 --- a/trunk/drivers/acpi/acpica/acdebug.h +++ b/trunk/drivers/acpi/acpica/acdebug.h @@ -105,8 +105,6 @@ void acpi_db_set_method_data(char *type_arg, char *index_arg, char *value_arg); acpi_status acpi_db_display_objects(char *obj_type_arg, char *display_count_arg); -void acpi_db_display_interfaces(char *action_arg, char *interface_name_arg); - acpi_status acpi_db_find_name_in_namespace(char *name_arg); void acpi_db_set_scope(char *name); diff --git a/trunk/drivers/acpi/acpica/acevents.h b/trunk/drivers/acpi/acpica/acevents.h index a6f99cc37a19..36867cd70eac 100644 --- a/trunk/drivers/acpi/acpica/acevents.h +++ b/trunk/drivers/acpi/acpica/acevents.h @@ -105,9 +105,8 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, struct acpi_gpe_block_info **return_gpe_block); acpi_status -acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, - struct acpi_gpe_block_info *gpe_block, - void *ignored); +acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, + struct acpi_gpe_block_info *gpe_block); acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block); diff --git a/trunk/drivers/acpi/acpica/acglobal.h b/trunk/drivers/acpi/acpica/acglobal.h index ad88fcae4eb9..1d192142c691 100644 --- a/trunk/drivers/acpi/acpica/acglobal.h +++ b/trunk/drivers/acpi/acpica/acglobal.h @@ -132,7 +132,6 @@ struct acpi_table_fadt acpi_gbl_FADT; u32 acpi_current_gpe_count; u32 acpi_gbl_trace_flags; acpi_name acpi_gbl_trace_method_name; -u8 acpi_gbl_system_awake_and_running; #endif @@ -188,10 +187,6 @@ ACPI_EXTERN u8 acpi_gbl_integer_bit_width; ACPI_EXTERN u8 acpi_gbl_integer_byte_width; ACPI_EXTERN u8 acpi_gbl_integer_nybble_width; -/* Mutex for _OSI support */ - -ACPI_EXTERN acpi_mutex acpi_gbl_osi_mutex; - /* Reader/Writer lock is used for namespace walk and dynamic table unload */ ACPI_EXTERN struct acpi_rw_lock acpi_gbl_namespace_rw_lock; @@ -260,7 +255,6 @@ ACPI_EXTERN acpi_init_handler acpi_gbl_init_handler; ACPI_EXTERN acpi_tbl_handler acpi_gbl_table_handler; ACPI_EXTERN void *acpi_gbl_table_handler_context; ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk; -ACPI_EXTERN acpi_interface_handler acpi_gbl_interface_handler; /* Owner ID support */ @@ -279,8 +273,8 @@ ACPI_EXTERN u8 acpi_gbl_debugger_configuration; ACPI_EXTERN u8 acpi_gbl_step_to_next_call; ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present; ACPI_EXTERN u8 acpi_gbl_events_initialized; +ACPI_EXTERN u8 acpi_gbl_system_awake_and_running; ACPI_EXTERN u8 acpi_gbl_osi_data; -ACPI_EXTERN struct acpi_interface_info *acpi_gbl_supported_interfaces; #ifndef DEFINE_ACPI_GLOBALS @@ -370,7 +364,6 @@ ACPI_EXTERN struct acpi_fixed_event_handler ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head; ACPI_EXTERN struct acpi_gpe_block_info *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS]; -ACPI_EXTERN u8 acpi_all_gpes_initialized; /***************************************************************************** * diff --git a/trunk/drivers/acpi/acpica/achware.h b/trunk/drivers/acpi/acpica/achware.h index 167470ad2d21..120b3af56596 100644 --- a/trunk/drivers/acpi/acpica/achware.h +++ b/trunk/drivers/acpi/acpica/achware.h @@ -121,13 +121,6 @@ acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, struct acpi_gpe_block_info *gpe_block, void *context); -/* - * hwpci - PCI configuration support - */ -acpi_status -acpi_hw_derive_pci_id(struct acpi_pci_id *pci_id, - acpi_handle root_pci_device, acpi_handle pci_region); - #ifdef ACPI_FUTURE_USAGE /* * hwtimer - ACPI Timer prototypes diff --git a/trunk/drivers/acpi/acpica/aclocal.h b/trunk/drivers/acpi/acpica/aclocal.h index 2ceb0c05b2d7..7dad9160f209 100644 --- a/trunk/drivers/acpi/acpica/aclocal.h +++ b/trunk/drivers/acpi/acpica/aclocal.h @@ -413,7 +413,6 @@ struct acpi_handler_info { void *context; /* Context to be passed to handler */ struct acpi_namespace_node *method_node; /* Method node for this GPE level (saved) */ u8 orig_flags; /* Original misc info about this GPE */ - u8 orig_enabled; /* Set if the GPE was originally enabled */ }; union acpi_gpe_dispatch_info { @@ -458,7 +457,6 @@ struct acpi_gpe_block_info { u32 register_count; /* Number of register pairs in block */ u16 gpe_count; /* Number of individual GPEs in block */ u8 block_base_number; /* Base GPE number for this block */ - u8 initialized; /* If set, the GPE block has been initialized */ }; /* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */ @@ -475,6 +473,7 @@ struct acpi_gpe_walk_info { struct acpi_gpe_block_info *gpe_block; u16 count; acpi_owner_id owner_id; + u8 enable_this_gpe; u8 execute_by_owner_id; }; @@ -855,7 +854,7 @@ struct acpi_bit_register_info { ACPI_BITMASK_POWER_BUTTON_STATUS | \ ACPI_BITMASK_SLEEP_BUTTON_STATUS | \ ACPI_BITMASK_RT_CLOCK_STATUS | \ - ACPI_BITMASK_PCIEXP_WAKE_STATUS | \ + ACPI_BITMASK_PCIEXP_WAKE_DISABLE | \ ACPI_BITMASK_WAKE_STATUS) #define ACPI_BITMASK_TIMER_ENABLE 0x0001 @@ -910,21 +909,15 @@ struct acpi_bit_register_info { #define ACPI_OSI_WIN_VISTA 0x07 #define ACPI_OSI_WINSRV_2008 0x08 #define ACPI_OSI_WIN_VISTA_SP1 0x09 -#define ACPI_OSI_WIN_VISTA_SP2 0x0A -#define ACPI_OSI_WIN_7 0x0B +#define ACPI_OSI_WIN_7 0x0A #define ACPI_ALWAYS_ILLEGAL 0x00 struct acpi_interface_info { char *name; - struct acpi_interface_info *next; - u8 flags; u8 value; }; -#define ACPI_OSI_INVALID 0x01 -#define ACPI_OSI_DYNAMIC 0x02 - struct acpi_port_info { char *name; u16 start; @@ -1004,7 +997,7 @@ struct acpi_port_info { struct acpi_db_method_info { acpi_handle main_thread_gate; acpi_handle thread_complete_gate; - acpi_thread_id *threads; + u32 *threads; u32 num_threads; u32 num_created; u32 num_completed; diff --git a/trunk/drivers/acpi/acpica/acmacros.h b/trunk/drivers/acpi/acpica/acmacros.h index 8d5c9e0a495f..9894929a2abb 100644 --- a/trunk/drivers/acpi/acpica/acmacros.h +++ b/trunk/drivers/acpi/acpica/acmacros.h @@ -338,8 +338,8 @@ * the plist contains a set of parens to allow variable-length lists. * These macros are used for both the debug and non-debug versions of the code. */ -#define ACPI_ERROR_NAMESPACE(s, e) acpi_ut_namespace_error (AE_INFO, s, e); -#define ACPI_ERROR_METHOD(s, n, p, e) acpi_ut_method_error (AE_INFO, s, n, p, e); +#define ACPI_ERROR_NAMESPACE(s, e) acpi_ns_report_error (AE_INFO, s, e); +#define ACPI_ERROR_METHOD(s, n, p, e) acpi_ns_report_method_error (AE_INFO, s, n, p, e); #define ACPI_WARN_PREDEFINED(plist) acpi_ut_predefined_warning plist #define ACPI_INFO_PREDEFINED(plist) acpi_ut_predefined_info plist diff --git a/trunk/drivers/acpi/acpica/acnamesp.h b/trunk/drivers/acpi/acpica/acnamesp.h index d44d3bc5b847..9f60ff002203 100644 --- a/trunk/drivers/acpi/acpica/acnamesp.h +++ b/trunk/drivers/acpi/acpica/acnamesp.h @@ -338,6 +338,18 @@ acpi_object_type acpi_ns_get_type(struct acpi_namespace_node *node); u32 acpi_ns_local(acpi_object_type type); +void +acpi_ns_report_error(const char *module_name, + u32 line_number, + const char *internal_name, acpi_status lookup_status); + +void +acpi_ns_report_method_error(const char *module_name, + u32 line_number, + const char *message, + struct acpi_namespace_node *node, + const char *path, acpi_status lookup_status); + void acpi_ns_print_node_pathname(struct acpi_namespace_node *node, const char *msg); diff --git a/trunk/drivers/acpi/acpica/acobject.h b/trunk/drivers/acpi/acpica/acobject.h index bdbfaf22bd14..54857fa87aaf 100644 --- a/trunk/drivers/acpi/acpica/acobject.h +++ b/trunk/drivers/acpi/acpica/acobject.h @@ -248,7 +248,7 @@ ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_NOTIFY_INFO}; u32 base_byte_offset; /* Byte offset within containing object */\ u32 value; /* Value to store into the Bank or Index register */\ u8 start_field_bit_offset;/* Bit offset within first field datum (0-63) */\ - + u8 access_bit_width; /* Read/Write size in bits (8-64) */ struct acpi_object_field_common { /* COMMON FIELD (for BUFFER, REGION, BANK, and INDEX fields) */ ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO union acpi_operand_object *region_obj; /* Parent Operation Region object (REGION/BANK fields only) */ diff --git a/trunk/drivers/acpi/acpica/acutils.h b/trunk/drivers/acpi/acpica/acutils.h index 72e4183c1937..35df755251ce 100644 --- a/trunk/drivers/acpi/acpica/acutils.h +++ b/trunk/drivers/acpi/acpica/acutils.h @@ -312,6 +312,8 @@ void acpi_ut_delete_internal_object_list(union acpi_operand_object **obj_list); /* * uteval - object evaluation */ +acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state); + acpi_status acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, char *path, @@ -392,21 +394,6 @@ union acpi_operand_object *acpi_ut_create_string_object(acpi_size string_size); acpi_status acpi_ut_get_object_size(union acpi_operand_object *obj, acpi_size * obj_length); -/* - * utosi - Support for the _OSI predefined control method - */ -acpi_status acpi_ut_initialize_interfaces(void); - -void acpi_ut_interface_terminate(void); - -acpi_status acpi_ut_install_interface(acpi_string interface_name); - -acpi_status acpi_ut_remove_interface(acpi_string interface_name); - -struct acpi_interface_info *acpi_ut_get_interface(acpi_string interface_name); - -acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state); - /* * utstate - Generic state creation/cache routines */ @@ -486,6 +473,17 @@ u8 acpi_ut_valid_acpi_char(char character, u32 position); acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 * ret_integer); +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_predefined_warning(const char *module_name, + u32 line_number, + char *pathname, + u8 node_flags, const char *format, ...); + +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_predefined_info(const char *module_name, + u32 line_number, + char *pathname, u8 node_flags, const char *format, ...); + /* Values for Base above (16=Hex, 10=Decimal) */ #define ACPI_ANY_BASE 0 @@ -576,32 +574,6 @@ acpi_status acpi_ut_create_list(char *list_name, u16 object_size, struct acpi_memory_list **return_cache); -#endif /* ACPI_DBG_TRACK_ALLOCATIONS */ - -/* - * utxferror - various error/warning output functions - */ -void ACPI_INTERNAL_VAR_XFACE -acpi_ut_predefined_warning(const char *module_name, - u32 line_number, - char *pathname, - u8 node_flags, const char *format, ...); - -void ACPI_INTERNAL_VAR_XFACE -acpi_ut_predefined_info(const char *module_name, - u32 line_number, - char *pathname, u8 node_flags, const char *format, ...); - -void -acpi_ut_namespace_error(const char *module_name, - u32 line_number, - const char *internal_name, acpi_status lookup_status); - -void -acpi_ut_method_error(const char *module_name, - u32 line_number, - const char *message, - struct acpi_namespace_node *node, - const char *path, acpi_status lookup_status); +#endif #endif /* _ACUTILS_H */ diff --git a/trunk/drivers/acpi/acpica/dsmethod.c b/trunk/drivers/acpi/acpica/dsmethod.c index d94dd8974b55..64750ee96e20 100644 --- a/trunk/drivers/acpi/acpica/dsmethod.c +++ b/trunk/drivers/acpi/acpica/dsmethod.c @@ -573,7 +573,7 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, acpi_os_release_mutex(method_desc->method. mutex->mutex.os_mutex); - method_desc->method.mutex->mutex.thread_id = 0; + method_desc->method.mutex->mutex.thread_id = NULL; } } diff --git a/trunk/drivers/acpi/acpica/dswexec.c b/trunk/drivers/acpi/acpica/dswexec.c index 6b0b5d08d97a..d555b374e314 100644 --- a/trunk/drivers/acpi/acpica/dswexec.c +++ b/trunk/drivers/acpi/acpica/dswexec.c @@ -300,25 +300,10 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, * we must enter this object into the namespace. The created * object is temporary and will be deleted upon completion of * the execution of this method. - * - * Note 10/2010: Except for the Scope() op. This opcode does - * not actually create a new object, it refers to an existing - * object. However, for Scope(), we want to indeed open a - * new scope. */ - if (op->common.aml_opcode != AML_SCOPE_OP) { - status = - acpi_ds_load2_begin_op(walk_state, NULL); - } else { - status = - acpi_ds_scope_stack_push(op->named.node, - op->named.node-> - type, walk_state); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - } + status = acpi_ds_load2_begin_op(walk_state, NULL); } + break; case AML_CLASS_EXECUTE: diff --git a/trunk/drivers/acpi/acpica/evevent.c b/trunk/drivers/acpi/acpica/evevent.c index c61c3039c31a..303618889da0 100644 --- a/trunk/drivers/acpi/acpica/evevent.c +++ b/trunk/drivers/acpi/acpica/evevent.c @@ -93,6 +93,47 @@ acpi_status acpi_ev_initialize_events(void) return_ACPI_STATUS(status); } +/******************************************************************************* + * + * FUNCTION: acpi_ev_install_fadt_gpes + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Completes initialization of the FADT-defined GPE blocks + * (0 and 1). The HW must be fully initialized at this point, + * including global lock support. + * + ******************************************************************************/ + +acpi_status acpi_ev_install_fadt_gpes(void) +{ + acpi_status status; + + ACPI_FUNCTION_TRACE(ev_install_fadt_gpes); + + /* Namespace must be locked */ + + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + return (status); + } + + /* FADT GPE Block 0 */ + + (void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device, + acpi_gbl_gpe_fadt_blocks[0]); + + /* FADT GPE Block 1 */ + + (void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device, + acpi_gbl_gpe_fadt_blocks[1]); + + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + return_ACPI_STATUS(AE_OK); +} + /******************************************************************************* * * FUNCTION: acpi_ev_install_xrupt_handlers diff --git a/trunk/drivers/acpi/acpica/evgpeblk.c b/trunk/drivers/acpi/acpica/evgpeblk.c index 020add3eee1c..85445fb5844e 100644 --- a/trunk/drivers/acpi/acpica/evgpeblk.c +++ b/trunk/drivers/acpi/acpica/evgpeblk.c @@ -363,7 +363,6 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH); gpe_block->register_count = register_count; gpe_block->block_base_number = gpe_block_base_number; - gpe_block->initialized = FALSE; ACPI_MEMCPY(&gpe_block->block_address, gpe_block_address, sizeof(struct acpi_generic_address)); @@ -386,12 +385,11 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, return_ACPI_STATUS(status); } - acpi_all_gpes_initialized = FALSE; - /* Find all GPE methods (_Lxx or_Exx) for this block */ walk_info.gpe_block = gpe_block; walk_info.gpe_device = gpe_device; + walk_info.enable_this_gpe = FALSE; walk_info.execute_by_owner_id = FALSE; status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device, @@ -436,34 +434,35 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, ******************************************************************************/ acpi_status -acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, - struct acpi_gpe_block_info *gpe_block, - void *ignored) +acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, + struct acpi_gpe_block_info *gpe_block) { acpi_status status; struct acpi_gpe_event_info *gpe_event_info; u32 gpe_enabled_count; u32 gpe_index; + u32 gpe_number; u32 i; u32 j; ACPI_FUNCTION_TRACE(ev_initialize_gpe_block); - /* - * Ignore a null GPE block (e.g., if no GPE block 1 exists) and - * GPE blocks that have been initialized already. - */ - if (!gpe_block || gpe_block->initialized) { + /* Ignore a null GPE block (e.g., if no GPE block 1 exists) */ + + if (!gpe_block) { return_ACPI_STATUS(AE_OK); } /* - * Enable all GPEs that have a corresponding method and have the - * ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block must - * be enabled via the acpi_enable_gpe() interface. + * Enable all GPEs that have a corresponding method. Any other GPEs + * within this block must be enabled via the acpi_enable_gpe interface. */ gpe_enabled_count = 0; + if (gpe_device == acpi_gbl_fadt_gpe_device) { + gpe_device = NULL; + } + for (i = 0; i < gpe_block->register_count; i++) { for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { @@ -471,19 +470,27 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j; gpe_event_info = &gpe_block->event_info[gpe_index]; + gpe_number = gpe_index + gpe_block->block_base_number; /* Ignore GPEs that have no corresponding _Lxx/_Exx method */ - if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD) - || (gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { + if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)) { continue; } - status = acpi_raw_enable_gpe(gpe_event_info); + /* + * If the GPE has already been enabled for runtime + * signaling, make sure it remains enabled, but do not + * increment its reference counter. + */ + status = gpe_event_info->runtime_count ? + acpi_ev_enable_gpe(gpe_event_info) : + acpi_enable_gpe(gpe_device, gpe_number); + if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, - "Could not enable GPE 0x%02X", - gpe_index + gpe_block->block_base_number)); + "Could not enable GPE 0x%02X", + gpe_number)); continue; } @@ -497,7 +504,5 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, gpe_enabled_count)); } - gpe_block->initialized = TRUE; - return_ACPI_STATUS(AE_OK); } diff --git a/trunk/drivers/acpi/acpica/evgpeinit.c b/trunk/drivers/acpi/acpica/evgpeinit.c index 2c7def95f721..3084c5de1bba 100644 --- a/trunk/drivers/acpi/acpica/evgpeinit.c +++ b/trunk/drivers/acpi/acpica/evgpeinit.c @@ -210,7 +210,8 @@ acpi_status acpi_ev_gpe_initialize(void) * * DESCRIPTION: Check for new GPE methods (_Lxx/_Exx) made available as a * result of a Load() or load_table() operation. If new GPE - * methods have been installed, register the new methods. + * methods have been installed, register the new methods and + * enable and runtime GPEs that are associated with them. * ******************************************************************************/ @@ -238,6 +239,7 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id) walk_info.owner_id = table_owner_id; walk_info.execute_by_owner_id = TRUE; walk_info.count = 0; + walk_info.enable_this_gpe = TRUE; /* Walk the interrupt level descriptor list */ @@ -299,6 +301,8 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id) * * If walk_info->execute_by_owner_id is TRUE, we only execute examine GPE methods * with that owner. + * If walk_info->enable_this_gpe is TRUE, the GPE that is referred to by a GPE + * method is immediately enabled (Used for Load/load_table operators) * ******************************************************************************/ @@ -311,6 +315,8 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, struct acpi_gpe_walk_info *walk_info = ACPI_CAST_PTR(struct acpi_gpe_walk_info, context); struct acpi_gpe_event_info *gpe_event_info; + struct acpi_namespace_node *gpe_device; + acpi_status status; u32 gpe_number; char name[ACPI_NAME_SIZE + 1]; u8 type; @@ -415,6 +421,29 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, gpe_event_info->flags |= (u8)(type | ACPI_GPE_DISPATCH_METHOD); gpe_event_info->dispatch.method_node = method_node; + /* + * Enable this GPE if requested. This only happens when during the + * execution of a Load or load_table operator. We have found a new + * GPE method and want to immediately enable the GPE if it is a + * runtime GPE. + */ + if (walk_info->enable_this_gpe) { + + walk_info->count++; + gpe_device = walk_info->gpe_device; + + if (gpe_device == acpi_gbl_fadt_gpe_device) { + gpe_device = NULL; + } + + status = acpi_enable_gpe(gpe_device, gpe_number); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "Could not enable GPE 0x%02X", + gpe_number)); + } + } + ACPI_DEBUG_PRINT((ACPI_DB_LOAD, "Registered GPE method %s as GPE number 0x%.2X\n", name, gpe_number)); diff --git a/trunk/drivers/acpi/acpica/evmisc.c b/trunk/drivers/acpi/acpica/evmisc.c index fcaed9fb44ff..df0aea9a8cfd 100644 --- a/trunk/drivers/acpi/acpica/evmisc.c +++ b/trunk/drivers/acpi/acpica/evmisc.c @@ -553,7 +553,7 @@ acpi_status acpi_ev_release_global_lock(void) acpi_gbl_global_lock_acquired = FALSE; /* Release the local GL mutex */ - acpi_ev_global_lock_thread_id = 0; + acpi_ev_global_lock_thread_id = NULL; acpi_ev_global_lock_acquired = 0; acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex); return_ACPI_STATUS(status); diff --git a/trunk/drivers/acpi/acpica/evrgnini.c b/trunk/drivers/acpi/acpica/evrgnini.c index 0b47a6dc9290..f40d271bf568 100644 --- a/trunk/drivers/acpi/acpica/evrgnini.c +++ b/trunk/drivers/acpi/acpica/evrgnini.c @@ -289,8 +289,8 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, } /* - * Get the PCI device and function numbers from the _ADR object - * contained in the parent's scope. + * Get the PCI device and function numbers from the _ADR object contained + * in the parent's scope. */ status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, pci_device_node, &pci_value); @@ -320,15 +320,9 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, pci_id->bus = ACPI_LOWORD(pci_value); } - /* Complete/update the PCI ID for this device */ + /* Complete this device's pci_id */ - status = - acpi_hw_derive_pci_id(pci_id, pci_root_node, - region_obj->region.node); - if (ACPI_FAILURE(status)) { - ACPI_FREE(pci_id); - return_ACPI_STATUS(status); - } + acpi_os_derive_pci_id(pci_root_node, region_obj->region.node, &pci_id); *region_context = pci_id; return_ACPI_STATUS(AE_OK); diff --git a/trunk/drivers/acpi/acpica/evxface.c b/trunk/drivers/acpi/acpica/evxface.c index 36af222cac65..14e48add32fa 100644 --- a/trunk/drivers/acpi/acpica/evxface.c +++ b/trunk/drivers/acpi/acpica/evxface.c @@ -726,16 +726,15 @@ acpi_install_gpe_handler(acpi_handle gpe_device, (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); /* - * If the GPE is associated with a method, it might have been enabled - * automatically during initialization, in which case it has to be - * disabled now to avoid spurious execution of the handler. + * If the GPE is associated with a method and it cannot wake up the + * system from sleep states, it was enabled automatically during + * initialization, so it has to be disabled now to avoid spurious + * execution of the handler. */ if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD) - && gpe_event_info->runtime_count) { - handler->orig_enabled = 1; + && !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) (void)acpi_raw_disable_gpe(gpe_event_info); - } /* Install the handler */ @@ -838,13 +837,13 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, gpe_event_info->flags |= handler->orig_flags; /* - * If the GPE was previously associated with a method and it was - * enabled, it should be enabled at this point to restore the - * post-initialization configuration. + * If the GPE was previously associated with a method and it cannot wake + * up the system from sleep states, it should be enabled at this point + * to restore the post-initialization configuration. */ if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD) - && handler->orig_enabled) + && !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) (void)acpi_raw_enable_gpe(gpe_event_info); /* Now we can free the handler object */ diff --git a/trunk/drivers/acpi/acpica/evxfevnt.c b/trunk/drivers/acpi/acpica/evxfevnt.c index a1dabe3fd8ae..304825528d48 100644 --- a/trunk/drivers/acpi/acpica/evxfevnt.c +++ b/trunk/drivers/acpi/acpica/evxfevnt.c @@ -379,12 +379,21 @@ acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number) /* Ensure that we have a valid GPE number */ gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); - if (gpe_event_info) { - gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; - } else { + if (!gpe_event_info) { status = AE_BAD_PARAMETER; + goto unlock_and_exit; + } + + if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) { + goto unlock_and_exit; } + gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; + if (gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD) { + (void)acpi_raw_disable_gpe(gpe_event_info); + } + +unlock_and_exit: acpi_os_release_lock(acpi_gbl_gpe_lock, flags); return_ACPI_STATUS(status); } @@ -642,7 +651,7 @@ acpi_install_gpe_block(acpi_handle gpe_device, struct acpi_generic_address *gpe_block_address, u32 register_count, u32 interrupt_number) { - acpi_status status = AE_OK; + acpi_status status; union acpi_operand_object *obj_desc; struct acpi_namespace_node *node; struct acpi_gpe_block_info *gpe_block; @@ -706,6 +715,10 @@ acpi_install_gpe_block(acpi_handle gpe_device, obj_desc->device.gpe_block = gpe_block; + /* Enable the runtime GPEs in the new block */ + + status = acpi_ev_initialize_gpe_block(node, gpe_block); + unlock_and_exit: (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); return_ACPI_STATUS(status); @@ -911,43 +924,3 @@ acpi_status acpi_enable_all_runtime_gpes(void) return_ACPI_STATUS(status); } - -/****************************************************************************** - * - * FUNCTION: acpi_update_gpes - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Enable all GPEs that have associated _Lxx or _Exx methods and - * are not pointed to by any device _PRW methods indicating that - * these GPEs are generally intended for system or device wakeup - * (such GPEs have to be enabled directly when the devices whose - * _PRW methods point to them are set up for wakeup signaling). - * - ******************************************************************************/ - -acpi_status acpi_update_gpes(void) -{ - acpi_status status; - - ACPI_FUNCTION_TRACE(acpi_update_gpes); - - status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } else if (acpi_all_gpes_initialized) { - goto unlock; - } - - status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block, NULL); - if (ACPI_SUCCESS(status)) { - acpi_all_gpes_initialized = TRUE; - } - -unlock: - (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); - - return_ACPI_STATUS(status); -} diff --git a/trunk/drivers/acpi/acpica/evxfregn.c b/trunk/drivers/acpi/acpica/evxfregn.c index ce9314f79451..541cbc1544d5 100644 --- a/trunk/drivers/acpi/acpica/evxfregn.c +++ b/trunk/drivers/acpi/acpica/evxfregn.c @@ -64,12 +64,6 @@ ACPI_MODULE_NAME("evxfregn") * * DESCRIPTION: Install a handler for all op_regions of a given space_id. * - * NOTE: This function should only be called after acpi_enable_subsystem has - * been called. This is because any _REG methods associated with the Space ID - * are executed here, and these methods can only be safely executed after - * the default handlers have been installed and the hardware has been - * initialized (via acpi_enable_subsystem.) - * ******************************************************************************/ acpi_status acpi_install_address_space_handler(acpi_handle device, diff --git a/trunk/drivers/acpi/acpica/exfldio.c b/trunk/drivers/acpi/acpica/exfldio.c index 38293fd3e088..047217303a4b 100644 --- a/trunk/drivers/acpi/acpica/exfldio.c +++ b/trunk/drivers/acpi/acpica/exfldio.c @@ -119,8 +119,8 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, } /* - * Exit now for SMBus or IPMI address space, it has a non-linear - * address space and the request cannot be directly validated + * Exit now for SMBus or IPMI address space, it has a non-linear address space + * and the request cannot be directly validated */ if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS || rgn_desc->region.space_id == ACPI_ADR_SPACE_IPMI) { @@ -147,7 +147,8 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, * (Region length is specified in bytes) */ if (rgn_desc->region.length < - (obj_desc->common_field.base_byte_offset + field_datum_byte_offset + + (obj_desc->common_field.base_byte_offset + + field_datum_byte_offset + obj_desc->common_field.access_byte_width)) { if (acpi_gbl_enable_interpreter_slack) { /* @@ -679,7 +680,6 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, u32 buffer_tail_bits; u32 datum_count; u32 field_datum_count; - u32 access_bit_width; u32 i; ACPI_FUNCTION_TRACE(ex_extract_from_field); @@ -694,36 +694,16 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, return_ACPI_STATUS(AE_BUFFER_OVERFLOW); } - ACPI_MEMSET(buffer, 0, buffer_length); - access_bit_width = ACPI_MUL_8(obj_desc->common_field.access_byte_width); - - /* Handle the simple case here */ - - if ((obj_desc->common_field.start_field_bit_offset == 0) && - (obj_desc->common_field.bit_length == access_bit_width)) { - status = acpi_ex_field_datum_io(obj_desc, 0, buffer, ACPI_READ); - return_ACPI_STATUS(status); - } - -/* TBD: Move to common setup code */ - - /* Field algorithm is limited to sizeof(u64), truncate if needed */ - - if (obj_desc->common_field.access_byte_width > sizeof(u64)) { - obj_desc->common_field.access_byte_width = sizeof(u64); - access_bit_width = sizeof(u64) * 8; - } /* Compute the number of datums (access width data items) */ - datum_count = - ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, - access_bit_width); - + datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, + obj_desc->common_field.access_bit_width); field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length + obj_desc->common_field. start_field_bit_offset, + obj_desc->common_field. access_bit_width); /* Priming read from the field */ @@ -758,11 +738,12 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, * This avoids the differences in behavior between different compilers * concerning shift values larger than the target data width. */ - if (access_bit_width - - obj_desc->common_field.start_field_bit_offset < + if ((obj_desc->common_field.access_bit_width - + obj_desc->common_field.start_field_bit_offset) < ACPI_INTEGER_BIT_SIZE) { merged_datum |= - raw_datum << (access_bit_width - + raw_datum << (obj_desc->common_field. + access_bit_width - obj_desc->common_field. start_field_bit_offset); } @@ -784,7 +765,8 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, /* Mask off any extra bits in the last datum */ - buffer_tail_bits = obj_desc->common_field.bit_length % access_bit_width; + buffer_tail_bits = obj_desc->common_field.bit_length % + obj_desc->common_field.access_bit_width; if (buffer_tail_bits) { merged_datum &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits); } @@ -816,7 +798,6 @@ acpi_status acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, void *buffer, u32 buffer_length) { - void *new_buffer; acpi_status status; u64 mask; u64 width_mask; @@ -827,9 +808,9 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, u32 buffer_tail_bits; u32 datum_count; u32 field_datum_count; - u32 access_bit_width; - u32 required_length; u32 i; + u32 required_length; + void *new_buffer; ACPI_FUNCTION_TRACE(ex_insert_into_field); @@ -863,24 +844,17 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, buffer_length = required_length; } -/* TBD: Move to common setup code */ - - /* Algo is limited to sizeof(u64), so cut the access_byte_width */ - if (obj_desc->common_field.access_byte_width > sizeof(u64)) { - obj_desc->common_field.access_byte_width = sizeof(u64); - } - - access_bit_width = ACPI_MUL_8(obj_desc->common_field.access_byte_width); - /* * Create the bitmasks used for bit insertion. * Note: This if/else is used to bypass compiler differences with the * shift operator */ - if (access_bit_width == ACPI_INTEGER_BIT_SIZE) { + if (obj_desc->common_field.access_bit_width == ACPI_INTEGER_BIT_SIZE) { width_mask = ACPI_UINT64_MAX; } else { - width_mask = ACPI_MASK_BITS_ABOVE(access_bit_width); + width_mask = + ACPI_MASK_BITS_ABOVE(obj_desc->common_field. + access_bit_width); } mask = width_mask & @@ -889,11 +863,12 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, /* Compute the number of datums (access width data items) */ datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, - access_bit_width); + obj_desc->common_field.access_bit_width); field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length + obj_desc->common_field. start_field_bit_offset, + obj_desc->common_field. access_bit_width); /* Get initial Datum from the input buffer */ @@ -930,11 +905,12 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, * This avoids the differences in behavior between different compilers * concerning shift values larger than the target data width. */ - if ((access_bit_width - + if ((obj_desc->common_field.access_bit_width - obj_desc->common_field.start_field_bit_offset) < ACPI_INTEGER_BIT_SIZE) { merged_datum = - raw_datum >> (access_bit_width - + raw_datum >> (obj_desc->common_field. + access_bit_width - obj_desc->common_field. start_field_bit_offset); } else { @@ -953,7 +929,6 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, ACPI_MEMCPY(&raw_datum, ((char *)buffer) + buffer_offset, ACPI_MIN(obj_desc->common_field.access_byte_width, buffer_length - buffer_offset)); - merged_datum |= raw_datum << obj_desc->common_field.start_field_bit_offset; } @@ -962,7 +937,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, buffer_tail_bits = (obj_desc->common_field.bit_length + obj_desc->common_field.start_field_bit_offset) % - access_bit_width; + obj_desc->common_field.access_bit_width; if (buffer_tail_bits) { mask &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits); } diff --git a/trunk/drivers/acpi/acpica/exmutex.c b/trunk/drivers/acpi/acpica/exmutex.c index 6af14e43f839..f73be97043c0 100644 --- a/trunk/drivers/acpi/acpica/exmutex.c +++ b/trunk/drivers/acpi/acpica/exmutex.c @@ -336,7 +336,7 @@ acpi_status acpi_ex_release_mutex_object(union acpi_operand_object *obj_desc) /* Clear mutex info */ - obj_desc->mutex.thread_id = 0; + obj_desc->mutex.thread_id = NULL; return_ACPI_STATUS(status); } @@ -393,10 +393,10 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, if ((owner_thread->thread_id != walk_state->thread->thread_id) && (obj_desc != acpi_gbl_global_lock_mutex)) { ACPI_ERROR((AE_INFO, - "Thread %u cannot release Mutex [%4.4s] acquired by thread %u", - (u32)walk_state->thread->thread_id, + "Thread %p cannot release Mutex [%4.4s] acquired by thread %p", + ACPI_CAST_PTR(void, walk_state->thread->thread_id), acpi_ut_get_node_name(obj_desc->mutex.node), - (u32)owner_thread->thread_id)); + ACPI_CAST_PTR(void, owner_thread->thread_id))); return_ACPI_STATUS(AE_AML_NOT_OWNER); } @@ -488,7 +488,7 @@ void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread) /* Mark mutex unowned */ obj_desc->mutex.owner_thread = NULL; - obj_desc->mutex.thread_id = 0; + obj_desc->mutex.thread_id = NULL; /* Update Thread sync_level (Last mutex is the important one) */ diff --git a/trunk/drivers/acpi/acpica/exprep.c b/trunk/drivers/acpi/acpica/exprep.c index 7aae29f73d3f..98a331d2249b 100644 --- a/trunk/drivers/acpi/acpica/exprep.c +++ b/trunk/drivers/acpi/acpica/exprep.c @@ -355,10 +355,12 @@ acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc, return_ACPI_STATUS(AE_AML_OPERAND_VALUE); } - /* Setup width (access granularity) fields (values are: 1, 2, 4, 8) */ + /* Setup width (access granularity) fields */ obj_desc->common_field.access_byte_width = (u8) - ACPI_DIV_8(access_bit_width); + ACPI_DIV_8(access_bit_width); /* 1, 2, 4, 8 */ + + obj_desc->common_field.access_bit_width = (u8) access_bit_width; /* * base_byte_offset is the address of the start of the field within the @@ -403,9 +405,8 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) { union acpi_operand_object *obj_desc; union acpi_operand_object *second_desc = NULL; - acpi_status status; - u32 access_byte_width; u32 type; + acpi_status status; ACPI_FUNCTION_TRACE(ex_prep_field_value); @@ -420,8 +421,8 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) type = acpi_ns_get_type(info->region_node); if (type != ACPI_TYPE_REGION) { ACPI_ERROR((AE_INFO, - "Needed Region, found type 0x%X (%s)", type, - acpi_ut_get_type_name(type))); + "Needed Region, found type 0x%X (%s)", + type, acpi_ut_get_type_name(type))); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -437,8 +438,7 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) /* Initialize areas of the object that are common to all fields */ obj_desc->common_field.node = info->field_node; - status = acpi_ex_prep_common_field_object(obj_desc, - info->field_flags, + status = acpi_ex_prep_common_field_object(obj_desc, info->field_flags, info->attribute, info->field_bit_position, info->field_bit_length); @@ -455,25 +455,26 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) obj_desc->field.region_obj = acpi_ns_get_attached_object(info->region_node); - /* Allow full data read from EC address space */ - - if ((obj_desc->field.region_obj->region.space_id == - ACPI_ADR_SPACE_EC) - && (obj_desc->common_field.bit_length > 8)) { - access_byte_width = - ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field. - bit_length); + /* An additional reference for the container */ - /* Maximum byte width supported is 255 */ + acpi_ut_add_reference(obj_desc->field.region_obj); - if (access_byte_width < 256) { + /* allow full data read from EC address space */ + if (obj_desc->field.region_obj->region.space_id == + ACPI_ADR_SPACE_EC) { + if (obj_desc->common_field.bit_length > 8) { + unsigned width = + ACPI_ROUND_BITS_UP_TO_BYTES( + obj_desc->common_field.bit_length); + // access_bit_width is u8, don't overflow it + if (width > 8) + width = 8; obj_desc->common_field.access_byte_width = - (u8)access_byte_width; + width; + obj_desc->common_field.access_bit_width = + 8 * width; } } - /* An additional reference for the container */ - - acpi_ut_add_reference(obj_desc->field.region_obj); ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n", diff --git a/trunk/drivers/acpi/acpica/exregion.c b/trunk/drivers/acpi/acpica/exregion.c index de17e10da0ed..8819d2ac5aee 100644 --- a/trunk/drivers/acpi/acpica/exregion.c +++ b/trunk/drivers/acpi/acpica/exregion.c @@ -353,6 +353,7 @@ acpi_ex_pci_config_space_handler(u32 function, acpi_status status = AE_OK; struct acpi_pci_id *pci_id; u16 pci_register; + u32 value32; ACPI_FUNCTION_TRACE(ex_pci_config_space_handler); @@ -380,7 +381,8 @@ acpi_ex_pci_config_space_handler(u32 function, case ACPI_READ: status = acpi_os_read_pci_configuration(pci_id, pci_register, - value, bit_width); + &value32, bit_width); + *value = value32; break; case ACPI_WRITE: diff --git a/trunk/drivers/acpi/acpica/hwpci.c b/trunk/drivers/acpi/acpica/hwpci.c deleted file mode 100644 index ad21c7d8bf4f..000000000000 --- a/trunk/drivers/acpi/acpica/hwpci.c +++ /dev/null @@ -1,412 +0,0 @@ -/******************************************************************************* - * - * Module Name: hwpci - Obtain PCI bus, device, and function numbers - * - ******************************************************************************/ - -/* - * Copyright (C) 2000 - 2010, Intel Corp. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - */ - -#include -#include "accommon.h" - -#define _COMPONENT ACPI_NAMESPACE -ACPI_MODULE_NAME("hwpci") - -/* PCI configuration space values */ -#define PCI_CFG_HEADER_TYPE_REG 0x0E -#define PCI_CFG_PRIMARY_BUS_NUMBER_REG 0x18 -#define PCI_CFG_SECONDARY_BUS_NUMBER_REG 0x19 -/* PCI header values */ -#define PCI_HEADER_TYPE_MASK 0x7F -#define PCI_TYPE_BRIDGE 0x01 -#define PCI_TYPE_CARDBUS_BRIDGE 0x02 -typedef struct acpi_pci_device { - acpi_handle device; - struct acpi_pci_device *next; - -} acpi_pci_device; - -/* Local prototypes */ - -static acpi_status -acpi_hw_build_pci_list(acpi_handle root_pci_device, - acpi_handle pci_region, - struct acpi_pci_device **return_list_head); - -static acpi_status -acpi_hw_process_pci_list(struct acpi_pci_id *pci_id, - struct acpi_pci_device *list_head); - -static void acpi_hw_delete_pci_list(struct acpi_pci_device *list_head); - -static acpi_status -acpi_hw_get_pci_device_info(struct acpi_pci_id *pci_id, - acpi_handle pci_device, - u16 *bus_number, u8 *is_bridge); - -/******************************************************************************* - * - * FUNCTION: acpi_hw_derive_pci_id - * - * PARAMETERS: pci_id - Initial values for the PCI ID. May be - * modified by this function. - * root_pci_device - A handle to a PCI device object. This - * object must be a PCI Root Bridge having a - * _HID value of either PNP0A03 or PNP0A08 - * pci_region - A handle to a PCI configuration space - * Operation Region being initialized - * - * RETURN: Status - * - * DESCRIPTION: This function derives a full PCI ID for a PCI device, - * consisting of a Segment number, Bus number, Device number, - * and function code. - * - * The PCI hardware dynamically configures PCI bus numbers - * depending on the bus topology discovered during system - * initialization. This function is invoked during configuration - * of a PCI_Config Operation Region in order to (possibly) update - * the Bus/Device/Function numbers in the pci_id with the actual - * values as determined by the hardware and operating system - * configuration. - * - * The pci_id parameter is initially populated during the Operation - * Region initialization. This function is then called, and is - * will make any necessary modifications to the Bus, Device, or - * Function number PCI ID subfields as appropriate for the - * current hardware and OS configuration. - * - * NOTE: Created 08/2010. Replaces the previous OSL acpi_os_derive_pci_id - * interface since this feature is OS-independent. This module - * specifically avoids any use of recursion by building a local - * temporary device list. - * - ******************************************************************************/ - -acpi_status -acpi_hw_derive_pci_id(struct acpi_pci_id *pci_id, - acpi_handle root_pci_device, acpi_handle pci_region) -{ - acpi_status status; - struct acpi_pci_device *list_head = NULL; - - ACPI_FUNCTION_TRACE(hw_derive_pci_id); - - if (!pci_id) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - /* Build a list of PCI devices, from pci_region up to root_pci_device */ - - status = - acpi_hw_build_pci_list(root_pci_device, pci_region, &list_head); - if (ACPI_SUCCESS(status)) { - - /* Walk the list, updating the PCI device/function/bus numbers */ - - status = acpi_hw_process_pci_list(pci_id, list_head); - } - - /* Always delete the list */ - - acpi_hw_delete_pci_list(list_head); - return_ACPI_STATUS(status); -} - -/******************************************************************************* - * - * FUNCTION: acpi_hw_build_pci_list - * - * PARAMETERS: root_pci_device - A handle to a PCI device object. This - * object is guaranteed to be a PCI Root - * Bridge having a _HID value of either - * PNP0A03 or PNP0A08 - * pci_region - A handle to the PCI configuration space - * Operation Region - * return_list_head - Where the PCI device list is returned - * - * RETURN: Status - * - * DESCRIPTION: Builds a list of devices from the input PCI region up to the - * Root PCI device for this namespace subtree. - * - ******************************************************************************/ - -static acpi_status -acpi_hw_build_pci_list(acpi_handle root_pci_device, - acpi_handle pci_region, - struct acpi_pci_device **return_list_head) -{ - acpi_handle current_device; - acpi_handle parent_device; - acpi_status status; - struct acpi_pci_device *list_element; - struct acpi_pci_device *list_head = NULL; - - /* - * Ascend namespace branch until the root_pci_device is reached, building - * a list of device nodes. Loop will exit when either the PCI device is - * found, or the root of the namespace is reached. - */ - current_device = pci_region; - while (1) { - status = acpi_get_parent(current_device, &parent_device); - if (ACPI_FAILURE(status)) { - return (status); - } - - /* Finished when we reach the PCI root device (PNP0A03 or PNP0A08) */ - - if (parent_device == root_pci_device) { - *return_list_head = list_head; - return (AE_OK); - } - - list_element = ACPI_ALLOCATE(sizeof(struct acpi_pci_device)); - if (!list_element) { - return (AE_NO_MEMORY); - } - - /* Put new element at the head of the list */ - - list_element->next = list_head; - list_element->device = parent_device; - list_head = list_element; - - current_device = parent_device; - } -} - -/******************************************************************************* - * - * FUNCTION: acpi_hw_process_pci_list - * - * PARAMETERS: pci_id - Initial values for the PCI ID. May be - * modified by this function. - * list_head - Device list created by - * acpi_hw_build_pci_list - * - * RETURN: Status - * - * DESCRIPTION: Walk downward through the PCI device list, getting the device - * info for each, via the PCI configuration space and updating - * the PCI ID as necessary. Deletes the list during traversal. - * - ******************************************************************************/ - -static acpi_status -acpi_hw_process_pci_list(struct acpi_pci_id *pci_id, - struct acpi_pci_device *list_head) -{ - acpi_status status = AE_OK; - struct acpi_pci_device *info; - u16 bus_number; - u8 is_bridge = TRUE; - - ACPI_FUNCTION_NAME(hw_process_pci_list); - - ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, - "Input PciId: Seg %4.4X Bus %4.4X Dev %4.4X Func %4.4X\n", - pci_id->segment, pci_id->bus, pci_id->device, - pci_id->function)); - - bus_number = pci_id->bus; - - /* - * Descend down the namespace tree, collecting PCI device, function, - * and bus numbers. bus_number is only important for PCI bridges. - * Algorithm: As we descend the tree, use the last valid PCI device, - * function, and bus numbers that are discovered, and assign them - * to the PCI ID for the target device. - */ - info = list_head; - while (info) { - status = acpi_hw_get_pci_device_info(pci_id, info->device, - &bus_number, &is_bridge); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - info = info->next; - } - - ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, - "Output PciId: Seg %4.4X Bus %4.4X Dev %4.4X Func %4.4X " - "Status %X BusNumber %X IsBridge %X\n", - pci_id->segment, pci_id->bus, pci_id->device, - pci_id->function, status, bus_number, is_bridge)); - - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_hw_delete_pci_list - * - * PARAMETERS: list_head - Device list created by - * acpi_hw_build_pci_list - * - * RETURN: None - * - * DESCRIPTION: Free the entire PCI list. - * - ******************************************************************************/ - -static void acpi_hw_delete_pci_list(struct acpi_pci_device *list_head) -{ - struct acpi_pci_device *next; - struct acpi_pci_device *previous; - - next = list_head; - while (next) { - previous = next; - next = previous->next; - ACPI_FREE(previous); - } -} - -/******************************************************************************* - * - * FUNCTION: acpi_hw_get_pci_device_info - * - * PARAMETERS: pci_id - Initial values for the PCI ID. May be - * modified by this function. - * pci_device - Handle for the PCI device object - * bus_number - Where a PCI bridge bus number is returned - * is_bridge - Return value, indicates if this PCI - * device is a PCI bridge - * - * RETURN: Status - * - * DESCRIPTION: Get the device info for a single PCI device object. Get the - * _ADR (contains PCI device and function numbers), and for PCI - * bridge devices, get the bus number from PCI configuration - * space. - * - ******************************************************************************/ - -static acpi_status -acpi_hw_get_pci_device_info(struct acpi_pci_id *pci_id, - acpi_handle pci_device, - u16 *bus_number, u8 *is_bridge) -{ - acpi_status status; - acpi_object_type object_type; - u64 return_value; - u64 pci_value; - - /* We only care about objects of type Device */ - - status = acpi_get_type(pci_device, &object_type); - if (ACPI_FAILURE(status)) { - return (status); - } - - if (object_type != ACPI_TYPE_DEVICE) { - return (AE_OK); - } - - /* We need an _ADR. Ignore device if not present */ - - status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, - pci_device, &return_value); - if (ACPI_FAILURE(status)) { - return (AE_OK); - } - - /* - * From _ADR, get the PCI Device and Function and - * update the PCI ID. - */ - pci_id->device = ACPI_HIWORD(ACPI_LODWORD(return_value)); - pci_id->function = ACPI_LOWORD(ACPI_LODWORD(return_value)); - - /* - * If the previous device was a bridge, use the previous - * device bus number - */ - if (*is_bridge) { - pci_id->bus = *bus_number; - } - - /* - * Get the bus numbers from PCI Config space: - * - * First, get the PCI header_type - */ - *is_bridge = FALSE; - status = acpi_os_read_pci_configuration(pci_id, - PCI_CFG_HEADER_TYPE_REG, - &pci_value, 8); - if (ACPI_FAILURE(status)) { - return (status); - } - - /* We only care about bridges (1=pci_bridge, 2=card_bus_bridge) */ - - pci_value &= PCI_HEADER_TYPE_MASK; - - if ((pci_value != PCI_TYPE_BRIDGE) && - (pci_value != PCI_TYPE_CARDBUS_BRIDGE)) { - return (AE_OK); - } - - /* Bridge: Get the Primary bus_number */ - - status = acpi_os_read_pci_configuration(pci_id, - PCI_CFG_PRIMARY_BUS_NUMBER_REG, - &pci_value, 8); - if (ACPI_FAILURE(status)) { - return (status); - } - - *is_bridge = TRUE; - pci_id->bus = (u16)pci_value; - - /* Bridge: Get the Secondary bus_number */ - - status = acpi_os_read_pci_configuration(pci_id, - PCI_CFG_SECONDARY_BUS_NUMBER_REG, - &pci_value, 8); - if (ACPI_FAILURE(status)) { - return (status); - } - - *bus_number = (u16)pci_value; - return (AE_OK); -} diff --git a/trunk/drivers/acpi/acpica/nsrepair2.c b/trunk/drivers/acpi/acpica/nsrepair2.c index 4ef9f43ea926..4009498fbabd 100644 --- a/trunk/drivers/acpi/acpica/nsrepair2.c +++ b/trunk/drivers/acpi/acpica/nsrepair2.c @@ -73,18 +73,10 @@ static acpi_status acpi_ns_repair_ALR(struct acpi_predefined_data *data, union acpi_operand_object **return_object_ptr); -static acpi_status -acpi_ns_repair_CID(struct acpi_predefined_data *data, - union acpi_operand_object **return_object_ptr); - static acpi_status acpi_ns_repair_FDE(struct acpi_predefined_data *data, union acpi_operand_object **return_object_ptr); -static acpi_status -acpi_ns_repair_HID(struct acpi_predefined_data *data, - union acpi_operand_object **return_object_ptr); - static acpi_status acpi_ns_repair_PSS(struct acpi_predefined_data *data, union acpi_operand_object **return_object_ptr); @@ -116,10 +108,8 @@ acpi_ns_sort_list(union acpi_operand_object **elements, * As necessary: * * _ALR: Sort the list ascending by ambient_illuminance - * _CID: Strings: uppercase all, remove any leading asterisk * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs - * _HID: Strings: uppercase all, remove any leading asterisk * _PSS: Sort the list descending by Power * _TSS: Sort the list descending by Power * @@ -132,10 +122,8 @@ acpi_ns_sort_list(union acpi_operand_object **elements, */ static const struct acpi_repair_info acpi_ns_repairable_names[] = { {"_ALR", acpi_ns_repair_ALR}, - {"_CID", acpi_ns_repair_CID}, {"_FDE", acpi_ns_repair_FDE}, {"_GTM", acpi_ns_repair_FDE}, /* _GTM has same repair as _FDE */ - {"_HID", acpi_ns_repair_HID}, {"_PSS", acpi_ns_repair_PSS}, {"_TSS", acpi_ns_repair_TSS}, {{0, 0, 0, 0}, NULL} /* Table terminator */ @@ -331,157 +319,6 @@ acpi_ns_repair_FDE(struct acpi_predefined_data *data, return (AE_OK); } -/****************************************************************************** - * - * FUNCTION: acpi_ns_repair_CID - * - * PARAMETERS: Data - Pointer to validation data structure - * return_object_ptr - Pointer to the object returned from the - * evaluation of a method or object - * - * RETURN: Status. AE_OK if object is OK or was repaired successfully - * - * DESCRIPTION: Repair for the _CID object. If a string, ensure that all - * letters are uppercase and that there is no leading asterisk. - * If a Package, ensure same for all string elements. - * - *****************************************************************************/ - -static acpi_status -acpi_ns_repair_CID(struct acpi_predefined_data *data, - union acpi_operand_object **return_object_ptr) -{ - acpi_status status; - union acpi_operand_object *return_object = *return_object_ptr; - union acpi_operand_object **element_ptr; - union acpi_operand_object *original_element; - u16 original_ref_count; - u32 i; - - /* Check for _CID as a simple string */ - - if (return_object->common.type == ACPI_TYPE_STRING) { - status = acpi_ns_repair_HID(data, return_object_ptr); - return (status); - } - - /* Exit if not a Package */ - - if (return_object->common.type != ACPI_TYPE_PACKAGE) { - return (AE_OK); - } - - /* Examine each element of the _CID package */ - - element_ptr = return_object->package.elements; - for (i = 0; i < return_object->package.count; i++) { - original_element = *element_ptr; - original_ref_count = original_element->common.reference_count; - - status = acpi_ns_repair_HID(data, element_ptr); - if (ACPI_FAILURE(status)) { - return (status); - } - - /* Take care with reference counts */ - - if (original_element != *element_ptr) { - - /* Element was replaced */ - - (*element_ptr)->common.reference_count = - original_ref_count; - - acpi_ut_remove_reference(original_element); - } - - element_ptr++; - } - - return (AE_OK); -} - -/****************************************************************************** - * - * FUNCTION: acpi_ns_repair_HID - * - * PARAMETERS: Data - Pointer to validation data structure - * return_object_ptr - Pointer to the object returned from the - * evaluation of a method or object - * - * RETURN: Status. AE_OK if object is OK or was repaired successfully - * - * DESCRIPTION: Repair for the _HID object. If a string, ensure that all - * letters are uppercase and that there is no leading asterisk. - * - *****************************************************************************/ - -static acpi_status -acpi_ns_repair_HID(struct acpi_predefined_data *data, - union acpi_operand_object **return_object_ptr) -{ - union acpi_operand_object *return_object = *return_object_ptr; - union acpi_operand_object *new_string; - char *source; - char *dest; - - ACPI_FUNCTION_NAME(ns_repair_HID); - - /* We only care about string _HID objects (not integers) */ - - if (return_object->common.type != ACPI_TYPE_STRING) { - return (AE_OK); - } - - if (return_object->string.length == 0) { - ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, - "Invalid zero-length _HID or _CID string")); - - /* Return AE_OK anyway, let driver handle it */ - - data->flags |= ACPI_OBJECT_REPAIRED; - return (AE_OK); - } - - /* It is simplest to always create a new string object */ - - new_string = acpi_ut_create_string_object(return_object->string.length); - if (!new_string) { - return (AE_NO_MEMORY); - } - - /* - * Remove a leading asterisk if present. For some unknown reason, there - * are many machines in the field that contains IDs like this. - * - * Examples: "*PNP0C03", "*ACPI0003" - */ - source = return_object->string.pointer; - if (*source == '*') { - source++; - new_string->string.length--; - - ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, - "%s: Removed invalid leading asterisk\n", - data->pathname)); - } - - /* - * Copy and uppercase the string. From the ACPI specification: - * - * A valid PNP ID must be of the form "AAA####" where A is an uppercase - * letter and # is a hex digit. A valid ACPI ID must be of the form - * "ACPI####" where # is a hex digit. - */ - for (dest = new_string->string.pointer; *source; dest++, source++) { - *dest = (char)ACPI_TOUPPER(*source); - } - - acpi_ut_remove_reference(return_object); - *return_object_ptr = new_string; - return (AE_OK); -} - /****************************************************************************** * * FUNCTION: acpi_ns_repair_TSS diff --git a/trunk/drivers/acpi/acpica/nsutils.c b/trunk/drivers/acpi/acpica/nsutils.c index a7d6ad9c111b..e1add3491b04 100644 --- a/trunk/drivers/acpi/acpica/nsutils.c +++ b/trunk/drivers/acpi/acpica/nsutils.c @@ -58,6 +58,104 @@ static u8 acpi_ns_valid_path_separator(char sep); acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node *node_to_search); #endif +/******************************************************************************* + * + * FUNCTION: acpi_ns_report_error + * + * PARAMETERS: module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * internal_name - Name or path of the namespace node + * lookup_status - Exception code from NS lookup + * + * RETURN: None + * + * DESCRIPTION: Print warning message with full pathname + * + ******************************************************************************/ + +void +acpi_ns_report_error(const char *module_name, + u32 line_number, + const char *internal_name, acpi_status lookup_status) +{ + acpi_status status; + u32 bad_name; + char *name = NULL; + + acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); + + if (lookup_status == AE_BAD_CHARACTER) { + + /* There is a non-ascii character in the name */ + + ACPI_MOVE_32_TO_32(&bad_name, + ACPI_CAST_PTR(u32, internal_name)); + acpi_os_printf("[0x%4.4X] (NON-ASCII)", bad_name); + } else { + /* Convert path to external format */ + + status = acpi_ns_externalize_name(ACPI_UINT32_MAX, + internal_name, NULL, &name); + + /* Print target name */ + + if (ACPI_SUCCESS(status)) { + acpi_os_printf("[%s]", name); + } else { + acpi_os_printf("[COULD NOT EXTERNALIZE NAME]"); + } + + if (name) { + ACPI_FREE(name); + } + } + + acpi_os_printf(" Namespace lookup failure, %s\n", + acpi_format_exception(lookup_status)); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ns_report_method_error + * + * PARAMETERS: module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * Message - Error message to use on failure + * prefix_node - Prefix relative to the path + * Path - Path to the node (optional) + * method_status - Execution status + * + * RETURN: None + * + * DESCRIPTION: Print warning message with full pathname + * + ******************************************************************************/ + +void +acpi_ns_report_method_error(const char *module_name, + u32 line_number, + const char *message, + struct acpi_namespace_node *prefix_node, + const char *path, acpi_status method_status) +{ + acpi_status status; + struct acpi_namespace_node *node = prefix_node; + + acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); + + if (path) { + status = + acpi_ns_get_node(prefix_node, path, ACPI_NS_NO_UPSEARCH, + &node); + if (ACPI_FAILURE(status)) { + acpi_os_printf("[Could not get node by pathname]"); + } + } + + acpi_ns_print_node_pathname(node, message); + acpi_os_printf(", %s\n", acpi_format_exception(method_status)); +} + /******************************************************************************* * * FUNCTION: acpi_ns_print_node_pathname diff --git a/trunk/drivers/acpi/acpica/tbfadt.c b/trunk/drivers/acpi/acpica/tbfadt.c index d2ff4325c427..1728cb9bf600 100644 --- a/trunk/drivers/acpi/acpica/tbfadt.c +++ b/trunk/drivers/acpi/acpica/tbfadt.c @@ -49,7 +49,7 @@ ACPI_MODULE_NAME("tbfadt") /* Local prototypes */ -static ACPI_INLINE void +static inline void acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, u8 space_id, u8 byte_width, u64 address); @@ -181,7 +181,7 @@ static struct acpi_fadt_pm_info fadt_pm_info_table[] = { * ******************************************************************************/ -static ACPI_INLINE void +static inline void acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, u8 space_id, u8 byte_width, u64 address) { diff --git a/trunk/drivers/acpi/acpica/utdebug.c b/trunk/drivers/acpi/acpica/utdebug.c index f21c486929a5..983510640059 100644 --- a/trunk/drivers/acpi/acpica/utdebug.c +++ b/trunk/drivers/acpi/acpica/utdebug.c @@ -179,8 +179,9 @@ acpi_debug_print(u32 requested_debug_level, if (thread_id != acpi_gbl_prev_thread_id) { if (ACPI_LV_THREADS & acpi_dbg_level) { acpi_os_printf - ("\n**** Context Switch from TID %u to TID %u ****\n\n", - (u32)acpi_gbl_prev_thread_id, (u32)thread_id); + ("\n**** Context Switch from TID %p to TID %p ****\n\n", + ACPI_CAST_PTR(void, acpi_gbl_prev_thread_id), + ACPI_CAST_PTR(void, thread_id)); } acpi_gbl_prev_thread_id = thread_id; @@ -193,7 +194,7 @@ acpi_debug_print(u32 requested_debug_level, acpi_os_printf("%8s-%04ld ", module_name, line_number); if (ACPI_LV_THREADS & acpi_dbg_level) { - acpi_os_printf("[%u] ", (u32)thread_id); + acpi_os_printf("[%p] ", ACPI_CAST_PTR(void, thread_id)); } acpi_os_printf("[%02ld] %-22.22s: ", diff --git a/trunk/drivers/acpi/acpica/uteval.c b/trunk/drivers/acpi/acpica/uteval.c index 22f59ef604e0..6dfdeb653490 100644 --- a/trunk/drivers/acpi/acpica/uteval.c +++ b/trunk/drivers/acpi/acpica/uteval.c @@ -48,6 +48,153 @@ #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("uteval") +/* + * Strings supported by the _OSI predefined (internal) method. + * + * March 2009: Removed "Linux" as this host no longer wants to respond true + * for this string. Basically, the only safe OS strings are windows-related + * and in many or most cases represent the only test path within the + * BIOS-provided ASL code. + * + * The second element of each entry is used to track the newest version of + * Windows that the BIOS has requested. + */ +static struct acpi_interface_info acpi_interfaces_supported[] = { + /* Operating System Vendor Strings */ + + {"Windows 2000", ACPI_OSI_WIN_2000}, /* Windows 2000 */ + {"Windows 2001", ACPI_OSI_WIN_XP}, /* Windows XP */ + {"Windows 2001 SP1", ACPI_OSI_WIN_XP_SP1}, /* Windows XP SP1 */ + {"Windows 2001.1", ACPI_OSI_WINSRV_2003}, /* Windows Server 2003 */ + {"Windows 2001 SP2", ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */ + {"Windows 2001.1 SP1", ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */ + {"Windows 2006", ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */ + {"Windows 2006.1", ACPI_OSI_WINSRV_2008}, /* Windows Server 2008 - Added 09/2009 */ + {"Windows 2006 SP1", ACPI_OSI_WIN_VISTA_SP1}, /* Windows Vista SP1 - Added 09/2009 */ + {"Windows 2009", ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */ + + /* Feature Group Strings */ + + {"Extended Address Space Descriptor", 0} + + /* + * All "optional" feature group strings (features that are implemented + * by the host) should be implemented in the host version of + * acpi_os_validate_interface and should not be added here. + */ +}; + +/******************************************************************************* + * + * FUNCTION: acpi_ut_osi_implementation + * + * PARAMETERS: walk_state - Current walk state + * + * RETURN: Status + * + * DESCRIPTION: Implementation of the _OSI predefined control method + * + ******************************************************************************/ + +acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) +{ + acpi_status status; + union acpi_operand_object *string_desc; + union acpi_operand_object *return_desc; + u32 return_value; + u32 i; + + ACPI_FUNCTION_TRACE(ut_osi_implementation); + + /* Validate the string input argument */ + + string_desc = walk_state->arguments[0].object; + if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) { + return_ACPI_STATUS(AE_TYPE); + } + + /* Create a return object */ + + return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); + if (!return_desc) { + return_ACPI_STATUS(AE_NO_MEMORY); + } + + /* Default return value is 0, NOT SUPPORTED */ + + return_value = 0; + + /* Compare input string to static table of supported interfaces */ + + for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) { + if (!ACPI_STRCMP(string_desc->string.pointer, + acpi_interfaces_supported[i].name)) { + /* + * The interface is supported. + * Update the osi_data if necessary. We keep track of the latest + * version of Windows that has been requested by the BIOS. + */ + if (acpi_interfaces_supported[i].value > + acpi_gbl_osi_data) { + acpi_gbl_osi_data = + acpi_interfaces_supported[i].value; + } + + return_value = ACPI_UINT32_MAX; + goto exit; + } + } + + /* + * Did not match the string in the static table, call the host OSL to + * check for a match with one of the optional strings (such as + * "Module Device", "3.0 Thermal Model", etc.) + */ + status = acpi_os_validate_interface(string_desc->string.pointer); + if (ACPI_SUCCESS(status)) { + + /* The interface is supported */ + + return_value = ACPI_UINT32_MAX; + } + +exit: + ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, + "ACPI: BIOS _OSI(%s) is %ssupported\n", + string_desc->string.pointer, return_value == 0 ? "not " : "")); + + /* Complete the return value */ + + return_desc->integer.value = return_value; + walk_state->return_desc = return_desc; + return_ACPI_STATUS (AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_osi_invalidate + * + * PARAMETERS: interface_string + * + * RETURN: Status + * + * DESCRIPTION: invalidate string in pre-defiend _OSI string list + * + ******************************************************************************/ + +acpi_status acpi_osi_invalidate(char *interface) +{ + int i; + + for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) { + if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i].name)) { + *acpi_interfaces_supported[i].name = '\0'; + return AE_OK; + } + } + return AE_NOT_FOUND; +} + /******************************************************************************* * * FUNCTION: acpi_ut_evaluate_object diff --git a/trunk/drivers/acpi/acpica/utglobal.c b/trunk/drivers/acpi/acpica/utglobal.c index e87bc6760be6..0558747579ef 100644 --- a/trunk/drivers/acpi/acpica/utglobal.c +++ b/trunk/drivers/acpi/acpica/utglobal.c @@ -154,16 +154,14 @@ ACPI_EXPORT_SYMBOL(acpi_format_exception) * 1) _SB_ is defined to be a device to allow \_SB_._INI to be run * during the initialization sequence. * 2) _TZ_ is defined to be a thermal zone in order to allow ASL code to - * perform a Notify() operation on it. 09/2010: Changed to type Device. - * This still allows notifies, but does not confuse host code that - * searches for valid thermal_zone objects. + * perform a Notify() operation on it. */ const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = { {"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL}, {"_PR_", ACPI_TYPE_LOCAL_SCOPE, NULL}, {"_SB_", ACPI_TYPE_DEVICE, NULL}, {"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL}, - {"_TZ_", ACPI_TYPE_DEVICE, NULL}, + {"_TZ_", ACPI_TYPE_THERMAL, NULL}, {"_REV", ACPI_TYPE_INTEGER, (char *)ACPI_CA_SUPPORT_LEVEL}, {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME}, {"_GL_", ACPI_TYPE_MUTEX, (char *)1}, @@ -768,7 +766,6 @@ acpi_status acpi_ut_init_globals(void) acpi_gbl_gpe_fadt_blocks[0] = NULL; acpi_gbl_gpe_fadt_blocks[1] = NULL; acpi_current_gpe_count = 0; - acpi_all_gpes_initialized = FALSE; /* Global handlers */ @@ -777,7 +774,6 @@ acpi_status acpi_ut_init_globals(void) acpi_gbl_exception_handler = NULL; acpi_gbl_init_handler = NULL; acpi_gbl_table_handler = NULL; - acpi_gbl_interface_handler = NULL; /* Global Lock support */ @@ -804,7 +800,6 @@ acpi_status acpi_ut_init_globals(void) acpi_gbl_debugger_configuration = DEBUGGER_THREADING; acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT; acpi_gbl_osi_data = 0; - acpi_gbl_osi_mutex = NULL; /* Hardware oriented */ diff --git a/trunk/drivers/acpi/acpica/utids.c b/trunk/drivers/acpi/acpica/utids.c index d2906328535d..1397fadd0d4b 100644 --- a/trunk/drivers/acpi/acpica/utids.c +++ b/trunk/drivers/acpi/acpica/utids.c @@ -48,6 +48,42 @@ #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utids") +/* Local prototypes */ +static void acpi_ut_copy_id_string(char *destination, char *source); + +/******************************************************************************* + * + * FUNCTION: acpi_ut_copy_id_string + * + * PARAMETERS: Destination - Where to copy the string + * Source - Source string + * + * RETURN: None + * + * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods. + * Performs removal of a leading asterisk if present -- workaround + * for a known issue on a bunch of machines. + * + ******************************************************************************/ + +static void acpi_ut_copy_id_string(char *destination, char *source) +{ + + /* + * Workaround for ID strings that have a leading asterisk. This construct + * is not allowed by the ACPI specification (ID strings must be + * alphanumeric), but enough existing machines have this embedded in their + * ID strings that the following code is useful. + */ + if (*source == '*') { + source++; + } + + /* Do the actual copy */ + + ACPI_STRCPY(destination, source); +} + /******************************************************************************* * * FUNCTION: acpi_ut_execute_HID @@ -65,6 +101,7 @@ ACPI_MODULE_NAME("utids") * NOTE: Internal function, no parameter validation * ******************************************************************************/ + acpi_status acpi_ut_execute_HID(struct acpi_namespace_node *device_node, struct acpica_device_id **return_id) @@ -110,7 +147,7 @@ acpi_ut_execute_HID(struct acpi_namespace_node *device_node, if (obj_desc->common.type == ACPI_TYPE_INTEGER) { acpi_ex_eisa_id_to_string(hid->string, obj_desc->integer.value); } else { - ACPI_STRCPY(hid->string, obj_desc->string.pointer); + acpi_ut_copy_id_string(hid->string, obj_desc->string.pointer); } hid->length = length; @@ -187,7 +224,7 @@ acpi_ut_execute_UID(struct acpi_namespace_node *device_node, if (obj_desc->common.type == ACPI_TYPE_INTEGER) { acpi_ex_integer_to_string(uid->string, obj_desc->integer.value); } else { - ACPI_STRCPY(uid->string, obj_desc->string.pointer); + acpi_ut_copy_id_string(uid->string, obj_desc->string.pointer); } uid->length = length; @@ -320,8 +357,8 @@ acpi_ut_execute_CID(struct acpi_namespace_node *device_node, /* Copy the String CID from the returned object */ - ACPI_STRCPY(next_id_string, - cid_objects[i]->string.pointer); + acpi_ut_copy_id_string(next_id_string, + cid_objects[i]->string.pointer); length = cid_objects[i]->string.length + 1; } diff --git a/trunk/drivers/acpi/acpica/utinit.c b/trunk/drivers/acpi/acpica/utinit.c index c1b1c803ea9b..a39c93dac719 100644 --- a/trunk/drivers/acpi/acpica/utinit.c +++ b/trunk/drivers/acpi/acpica/utinit.c @@ -117,10 +117,6 @@ void acpi_ut_subsystem_shutdown(void) /* Close the acpi_event Handling */ acpi_ev_terminate(); - - /* Delete any dynamic _OSI interfaces */ - - acpi_ut_interface_terminate(); #endif /* Close the Namespace */ diff --git a/trunk/drivers/acpi/acpica/utmath.c b/trunk/drivers/acpi/acpica/utmath.c index 49cf7b7fd816..35059a14eb72 100644 --- a/trunk/drivers/acpi/acpica/utmath.c +++ b/trunk/drivers/acpi/acpica/utmath.c @@ -48,27 +48,11 @@ ACPI_MODULE_NAME("utmath") /* - * Optional support for 64-bit double-precision integer divide. This code - * is configurable and is implemented in order to support 32-bit kernel - * environments where a 64-bit double-precision math library is not available. - * - * Support for a more normal 64-bit divide/modulo (with check for a divide- - * by-zero) appears after this optional section of code. + * Support for double-precision integer divide. This code is included here + * in order to support kernel environments where the double-precision math + * library is not available. */ #ifndef ACPI_USE_NATIVE_DIVIDE -/* Structures used only for 64-bit divide */ -typedef struct uint64_struct { - u32 lo; - u32 hi; - -} uint64_struct; - -typedef union uint64_overlay { - u64 full; - struct uint64_struct part; - -} uint64_overlay; - /******************************************************************************* * * FUNCTION: acpi_ut_short_divide @@ -85,7 +69,6 @@ typedef union uint64_overlay { * 32-bit remainder. * ******************************************************************************/ - acpi_status acpi_ut_short_divide(u64 dividend, u32 divisor, u64 *out_quotient, u32 *out_remainder) diff --git a/trunk/drivers/acpi/acpica/utmisc.c b/trunk/drivers/acpi/acpica/utmisc.c index c7d0e05ef5a4..e8d0724ee403 100644 --- a/trunk/drivers/acpi/acpica/utmisc.c +++ b/trunk/drivers/acpi/acpica/utmisc.c @@ -50,6 +50,11 @@ #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utmisc") +/* + * Common suffix for messages + */ +#define ACPI_COMMON_MSG_SUFFIX \ + acpi_os_printf(" (%8.8X/%s-%u)\n", ACPI_CA_VERSION, module_name, line_number) /******************************************************************************* * * FUNCTION: acpi_ut_validate_exception @@ -1039,3 +1044,160 @@ acpi_ut_walk_package_tree(union acpi_operand_object * source_object, return_ACPI_STATUS(AE_AML_INTERNAL); } + +/******************************************************************************* + * + * FUNCTION: acpi_error, acpi_exception, acpi_warning, acpi_info + * + * PARAMETERS: module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * Format - Printf format string + additional args + * + * RETURN: None + * + * DESCRIPTION: Print message with module/line/version info + * + ******************************************************************************/ + +void ACPI_INTERNAL_VAR_XFACE +acpi_error(const char *module_name, u32 line_number, const char *format, ...) +{ + va_list args; + + acpi_os_printf("ACPI Error: "); + + va_start(args, format); + acpi_os_vprintf(format, args); + ACPI_COMMON_MSG_SUFFIX; + va_end(args); +} + +void ACPI_INTERNAL_VAR_XFACE +acpi_exception(const char *module_name, + u32 line_number, acpi_status status, const char *format, ...) +{ + va_list args; + + acpi_os_printf("ACPI Exception: %s, ", acpi_format_exception(status)); + + va_start(args, format); + acpi_os_vprintf(format, args); + ACPI_COMMON_MSG_SUFFIX; + va_end(args); +} + +void ACPI_INTERNAL_VAR_XFACE +acpi_warning(const char *module_name, u32 line_number, const char *format, ...) +{ + va_list args; + + acpi_os_printf("ACPI Warning: "); + + va_start(args, format); + acpi_os_vprintf(format, args); + ACPI_COMMON_MSG_SUFFIX; + va_end(args); +} + +void ACPI_INTERNAL_VAR_XFACE +acpi_info(const char *module_name, u32 line_number, const char *format, ...) +{ + va_list args; + + acpi_os_printf("ACPI: "); + + va_start(args, format); + acpi_os_vprintf(format, args); + acpi_os_printf("\n"); + va_end(args); +} + +ACPI_EXPORT_SYMBOL(acpi_error) +ACPI_EXPORT_SYMBOL(acpi_exception) +ACPI_EXPORT_SYMBOL(acpi_warning) +ACPI_EXPORT_SYMBOL(acpi_info) + +/******************************************************************************* + * + * FUNCTION: acpi_ut_predefined_warning + * + * PARAMETERS: module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * Pathname - Full pathname to the node + * node_flags - From Namespace node for the method/object + * Format - Printf format string + additional args + * + * RETURN: None + * + * DESCRIPTION: Warnings for the predefined validation module. Messages are + * only emitted the first time a problem with a particular + * method/object is detected. This prevents a flood of error + * messages for methods that are repeatedly evaluated. + * +******************************************************************************/ + +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_predefined_warning(const char *module_name, + u32 line_number, + char *pathname, + u8 node_flags, const char *format, ...) +{ + va_list args; + + /* + * Warning messages for this method/object will be disabled after the + * first time a validation fails or an object is successfully repaired. + */ + if (node_flags & ANOBJ_EVALUATED) { + return; + } + + acpi_os_printf("ACPI Warning for %s: ", pathname); + + va_start(args, format); + acpi_os_vprintf(format, args); + ACPI_COMMON_MSG_SUFFIX; + va_end(args); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_predefined_info + * + * PARAMETERS: module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * Pathname - Full pathname to the node + * node_flags - From Namespace node for the method/object + * Format - Printf format string + additional args + * + * RETURN: None + * + * DESCRIPTION: Info messages for the predefined validation module. Messages + * are only emitted the first time a problem with a particular + * method/object is detected. This prevents a flood of + * messages for methods that are repeatedly evaluated. + * + ******************************************************************************/ + +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_predefined_info(const char *module_name, + u32 line_number, + char *pathname, u8 node_flags, const char *format, ...) +{ + va_list args; + + /* + * Warning messages for this method/object will be disabled after the + * first time a validation fails or an object is successfully repaired. + */ + if (node_flags & ANOBJ_EVALUATED) { + return; + } + + acpi_os_printf("ACPI Info for %s: ", pathname); + + va_start(args, format); + acpi_os_vprintf(format, args); + ACPI_COMMON_MSG_SUFFIX; + va_end(args); +} diff --git a/trunk/drivers/acpi/acpica/utmutex.c b/trunk/drivers/acpi/acpica/utmutex.c index d9efa495b433..f5cca3a1300c 100644 --- a/trunk/drivers/acpi/acpica/utmutex.c +++ b/trunk/drivers/acpi/acpica/utmutex.c @@ -86,12 +86,6 @@ acpi_status acpi_ut_mutex_initialize(void) spin_lock_init(acpi_gbl_gpe_lock); spin_lock_init(acpi_gbl_hardware_lock); - /* Mutex for _OSI support */ - status = acpi_os_create_mutex(&acpi_gbl_osi_mutex); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - /* Create the reader/writer lock for namespace access */ status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock); @@ -123,8 +117,6 @@ void acpi_ut_mutex_terminate(void) acpi_ut_delete_mutex(i); } - acpi_os_delete_mutex(acpi_gbl_osi_mutex); - /* Delete the spinlocks */ acpi_os_delete_lock(acpi_gbl_gpe_lock); @@ -228,17 +220,18 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) { if (i == mutex_id) { ACPI_ERROR((AE_INFO, - "Mutex [%s] already acquired by this thread [%u]", + "Mutex [%s] already acquired by this thread [%p]", acpi_ut_get_mutex_name (mutex_id), - (u32)this_thread_id)); + ACPI_CAST_PTR(void, + this_thread_id))); return (AE_ALREADY_ACQUIRED); } ACPI_ERROR((AE_INFO, - "Invalid acquire order: Thread %u owns [%s], wants [%s]", - (u32)this_thread_id, + "Invalid acquire order: Thread %p owns [%s], wants [%s]", + ACPI_CAST_PTR(void, this_thread_id), acpi_ut_get_mutex_name(i), acpi_ut_get_mutex_name(mutex_id))); @@ -249,24 +242,24 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) #endif ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, - "Thread %u attempting to acquire Mutex [%s]\n", - (u32)this_thread_id, + "Thread %p attempting to acquire Mutex [%s]\n", + ACPI_CAST_PTR(void, this_thread_id), acpi_ut_get_mutex_name(mutex_id))); status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex, ACPI_WAIT_FOREVER); if (ACPI_SUCCESS(status)) { ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, - "Thread %u acquired Mutex [%s]\n", - (u32)this_thread_id, + "Thread %p acquired Mutex [%s]\n", + ACPI_CAST_PTR(void, this_thread_id), acpi_ut_get_mutex_name(mutex_id))); acpi_gbl_mutex_info[mutex_id].use_count++; acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id; } else { ACPI_EXCEPTION((AE_INFO, status, - "Thread %u could not acquire Mutex [0x%X]", - (u32)this_thread_id, mutex_id)); + "Thread %p could not acquire Mutex [0x%X]", + ACPI_CAST_PTR(void, this_thread_id), mutex_id)); } return (status); @@ -286,14 +279,10 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) { - acpi_thread_id this_thread_id; - ACPI_FUNCTION_NAME(ut_release_mutex); - this_thread_id = acpi_os_get_thread_id(); - - ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %u releasing Mutex [%s]\n", - (u32)this_thread_id, + ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %p releasing Mutex [%s]\n", + ACPI_CAST_PTR(void, acpi_os_get_thread_id()), acpi_ut_get_mutex_name(mutex_id))); if (mutex_id > ACPI_MAX_MUTEX) { diff --git a/trunk/drivers/acpi/acpica/utosi.c b/trunk/drivers/acpi/acpica/utosi.c deleted file mode 100644 index 18c59a85fdca..000000000000 --- a/trunk/drivers/acpi/acpica/utosi.c +++ /dev/null @@ -1,380 +0,0 @@ -/****************************************************************************** - * - * Module Name: utosi - Support for the _OSI predefined control method - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2010, Intel Corp. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - */ - -#include -#include "accommon.h" - -#define _COMPONENT ACPI_UTILITIES -ACPI_MODULE_NAME("utosi") - -/* - * Strings supported by the _OSI predefined control method (which is - * implemented internally within this module.) - * - * March 2009: Removed "Linux" as this host no longer wants to respond true - * for this string. Basically, the only safe OS strings are windows-related - * and in many or most cases represent the only test path within the - * BIOS-provided ASL code. - * - * The last element of each entry is used to track the newest version of - * Windows that the BIOS has requested. - */ -static struct acpi_interface_info acpi_default_supported_interfaces[] = { - /* Operating System Vendor Strings */ - - {"Windows 2000", NULL, 0, ACPI_OSI_WIN_2000}, /* Windows 2000 */ - {"Windows 2001", NULL, 0, ACPI_OSI_WIN_XP}, /* Windows XP */ - {"Windows 2001 SP1", NULL, 0, ACPI_OSI_WIN_XP_SP1}, /* Windows XP SP1 */ - {"Windows 2001.1", NULL, 0, ACPI_OSI_WINSRV_2003}, /* Windows Server 2003 */ - {"Windows 2001 SP2", NULL, 0, ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */ - {"Windows 2001.1 SP1", NULL, 0, ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */ - {"Windows 2006", NULL, 0, ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */ - {"Windows 2006.1", NULL, 0, ACPI_OSI_WINSRV_2008}, /* Windows Server 2008 - Added 09/2009 */ - {"Windows 2006 SP1", NULL, 0, ACPI_OSI_WIN_VISTA_SP1}, /* Windows Vista SP1 - Added 09/2009 */ - {"Windows 2006 SP2", NULL, 0, ACPI_OSI_WIN_VISTA_SP2}, /* Windows Vista SP2 - Added 09/2010 */ - {"Windows 2009", NULL, 0, ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */ - - /* Feature Group Strings */ - - {"Extended Address Space Descriptor", NULL, 0, 0} - - /* - * All "optional" feature group strings (features that are implemented - * by the host) should be dynamically added by the host via - * acpi_install_interface and should not be manually added here. - * - * Examples of optional feature group strings: - * - * "Module Device" - * "Processor Device" - * "3.0 Thermal Model" - * "3.0 _SCP Extensions" - * "Processor Aggregator Device" - */ -}; - -/******************************************************************************* - * - * FUNCTION: acpi_ut_initialize_interfaces - * - * PARAMETERS: None - * - * RETURN: Status - * - * DESCRIPTION: Initialize the global _OSI supported interfaces list - * - ******************************************************************************/ - -acpi_status acpi_ut_initialize_interfaces(void) -{ - u32 i; - - (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); - acpi_gbl_supported_interfaces = acpi_default_supported_interfaces; - - /* Link the static list of supported interfaces */ - - for (i = 0; - i < (ACPI_ARRAY_LENGTH(acpi_default_supported_interfaces) - 1); - i++) { - acpi_default_supported_interfaces[i].next = - &acpi_default_supported_interfaces[(acpi_size) i + 1]; - } - - acpi_os_release_mutex(acpi_gbl_osi_mutex); - return (AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ut_interface_terminate - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Delete all interfaces in the global list. Sets - * acpi_gbl_supported_interfaces to NULL. - * - ******************************************************************************/ - -void acpi_ut_interface_terminate(void) -{ - struct acpi_interface_info *next_interface; - - (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); - next_interface = acpi_gbl_supported_interfaces; - - while (next_interface) { - acpi_gbl_supported_interfaces = next_interface->next; - - /* Only interfaces added at runtime can be freed */ - - if (next_interface->flags & ACPI_OSI_DYNAMIC) { - ACPI_FREE(next_interface->name); - ACPI_FREE(next_interface); - } - - next_interface = acpi_gbl_supported_interfaces; - } - - acpi_os_release_mutex(acpi_gbl_osi_mutex); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ut_install_interface - * - * PARAMETERS: interface_name - The interface to install - * - * RETURN: Status - * - * DESCRIPTION: Install the interface into the global interface list. - * Caller MUST hold acpi_gbl_osi_mutex - * - ******************************************************************************/ - -acpi_status acpi_ut_install_interface(acpi_string interface_name) -{ - struct acpi_interface_info *interface_info; - - /* Allocate info block and space for the name string */ - - interface_info = - ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_interface_info)); - if (!interface_info) { - return (AE_NO_MEMORY); - } - - interface_info->name = - ACPI_ALLOCATE_ZEROED(ACPI_STRLEN(interface_name) + 1); - if (!interface_info->name) { - ACPI_FREE(interface_info); - return (AE_NO_MEMORY); - } - - /* Initialize new info and insert at the head of the global list */ - - ACPI_STRCPY(interface_info->name, interface_name); - interface_info->flags = ACPI_OSI_DYNAMIC; - interface_info->next = acpi_gbl_supported_interfaces; - - acpi_gbl_supported_interfaces = interface_info; - return (AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ut_remove_interface - * - * PARAMETERS: interface_name - The interface to remove - * - * RETURN: Status - * - * DESCRIPTION: Remove the interface from the global interface list. - * Caller MUST hold acpi_gbl_osi_mutex - * - ******************************************************************************/ - -acpi_status acpi_ut_remove_interface(acpi_string interface_name) -{ - struct acpi_interface_info *previous_interface; - struct acpi_interface_info *next_interface; - - previous_interface = next_interface = acpi_gbl_supported_interfaces; - while (next_interface) { - if (!ACPI_STRCMP(interface_name, next_interface->name)) { - - /* Found: name is in either the static list or was added at runtime */ - - if (next_interface->flags & ACPI_OSI_DYNAMIC) { - - /* Interface was added dynamically, remove and free it */ - - if (previous_interface == next_interface) { - acpi_gbl_supported_interfaces = - next_interface->next; - } else { - previous_interface->next = - next_interface->next; - } - - ACPI_FREE(next_interface->name); - ACPI_FREE(next_interface); - } else { - /* - * Interface is in static list. If marked invalid, then it - * does not actually exist. Else, mark it invalid. - */ - if (next_interface->flags & ACPI_OSI_INVALID) { - return (AE_NOT_EXIST); - } - - next_interface->flags |= ACPI_OSI_INVALID; - } - - return (AE_OK); - } - - previous_interface = next_interface; - next_interface = next_interface->next; - } - - /* Interface was not found */ - - return (AE_NOT_EXIST); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ut_get_interface - * - * PARAMETERS: interface_name - The interface to find - * - * RETURN: struct acpi_interface_info if found. NULL if not found. - * - * DESCRIPTION: Search for the specified interface name in the global list. - * Caller MUST hold acpi_gbl_osi_mutex - * - ******************************************************************************/ - -struct acpi_interface_info *acpi_ut_get_interface(acpi_string interface_name) -{ - struct acpi_interface_info *next_interface; - - next_interface = acpi_gbl_supported_interfaces; - while (next_interface) { - if (!ACPI_STRCMP(interface_name, next_interface->name)) { - return (next_interface); - } - - next_interface = next_interface->next; - } - - return (NULL); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ut_osi_implementation - * - * PARAMETERS: walk_state - Current walk state - * - * RETURN: Status - * - * DESCRIPTION: Implementation of the _OSI predefined control method. When - * an invocation of _OSI is encountered in the system AML, - * control is transferred to this function. - * - ******************************************************************************/ - -acpi_status acpi_ut_osi_implementation(struct acpi_walk_state * walk_state) -{ - union acpi_operand_object *string_desc; - union acpi_operand_object *return_desc; - struct acpi_interface_info *interface_info; - acpi_interface_handler interface_handler; - u32 return_value; - - ACPI_FUNCTION_TRACE(ut_osi_implementation); - - /* Validate the string input argument (from the AML caller) */ - - string_desc = walk_state->arguments[0].object; - if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) { - return_ACPI_STATUS(AE_TYPE); - } - - /* Create a return object */ - - return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); - if (!return_desc) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - /* Default return value is 0, NOT SUPPORTED */ - - return_value = 0; - (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); - - /* Lookup the interface in the global _OSI list */ - - interface_info = acpi_ut_get_interface(string_desc->string.pointer); - if (interface_info && !(interface_info->flags & ACPI_OSI_INVALID)) { - /* - * The interface is supported. - * Update the osi_data if necessary. We keep track of the latest - * version of Windows that has been requested by the BIOS. - */ - if (interface_info->value > acpi_gbl_osi_data) { - acpi_gbl_osi_data = interface_info->value; - } - - return_value = ACPI_UINT32_MAX; - } - - acpi_os_release_mutex(acpi_gbl_osi_mutex); - - /* - * Invoke an optional _OSI interface handler. The host OS may wish - * to do some interface-specific handling. For example, warn about - * certain interfaces or override the true/false support value. - */ - interface_handler = acpi_gbl_interface_handler; - if (interface_handler) { - return_value = - interface_handler(string_desc->string.pointer, - return_value); - } - - ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, - "ACPI: BIOS _OSI(\"%s\") is %ssupported\n", - string_desc->string.pointer, - return_value == 0 ? "not " : "")); - - /* Complete the return object */ - - return_desc->integer.value = return_value; - walk_state->return_desc = return_desc; - return_ACPI_STATUS(AE_OK); -} diff --git a/trunk/drivers/acpi/acpica/utxface.c b/trunk/drivers/acpi/acpica/utxface.c index 1f484c9a6888..7f8cefcb2b32 100644 --- a/trunk/drivers/acpi/acpica/utxface.c +++ b/trunk/drivers/acpi/acpica/utxface.c @@ -110,15 +110,6 @@ acpi_status __init acpi_initialize_subsystem(void) return_ACPI_STATUS(status); } - /* Initialize the global OSI interfaces list with the static names */ - - status = acpi_ut_initialize_interfaces(); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, - "During OSI interfaces initialization")); - return_ACPI_STATUS(status); - } - /* If configured, initialize the AML debugger */ ACPI_DEBUGGER_EXEC(status = acpi_db_initialize()); @@ -298,6 +289,19 @@ acpi_status acpi_initialize_objects(u32 flags) } } + /* + * Complete the GPE initialization for the GPE blocks defined in the FADT + * (GPE block 0 and 1). + * + * NOTE: Currently, there seems to be no need to run the _REG methods + * before enabling the GPEs. + */ + if (!(flags & ACPI_NO_EVENT_INIT)) { + status = acpi_ev_install_fadt_gpes(); + if (ACPI_FAILURE(status)) + return (status); + } + /* * Empty the caches (delete the cached objects) on the assumption that * the table load filled them up more than they will be at runtime -- @@ -502,7 +506,6 @@ acpi_install_initialization_handler(acpi_init_handler handler, u32 function) ACPI_EXPORT_SYMBOL(acpi_install_initialization_handler) #endif /* ACPI_FUTURE_USAGE */ - /***************************************************************************** * * FUNCTION: acpi_purge_cached_objects @@ -526,117 +529,4 @@ acpi_status acpi_purge_cached_objects(void) } ACPI_EXPORT_SYMBOL(acpi_purge_cached_objects) - -/***************************************************************************** - * - * FUNCTION: acpi_install_interface - * - * PARAMETERS: interface_name - The interface to install - * - * RETURN: Status - * - * DESCRIPTION: Install an _OSI interface to the global list - * - ****************************************************************************/ -acpi_status acpi_install_interface(acpi_string interface_name) -{ - acpi_status status; - struct acpi_interface_info *interface_info; - - /* Parameter validation */ - - if (!interface_name || (ACPI_STRLEN(interface_name) == 0)) { - return (AE_BAD_PARAMETER); - } - - (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); - - /* Check if the interface name is already in the global list */ - - interface_info = acpi_ut_get_interface(interface_name); - if (interface_info) { - /* - * The interface already exists in the list. This is OK if the - * interface has been marked invalid -- just clear the bit. - */ - if (interface_info->flags & ACPI_OSI_INVALID) { - interface_info->flags &= ~ACPI_OSI_INVALID; - status = AE_OK; - } else { - status = AE_ALREADY_EXISTS; - } - } else { - /* New interface name, install into the global list */ - - status = acpi_ut_install_interface(interface_name); - } - - acpi_os_release_mutex(acpi_gbl_osi_mutex); - return (status); -} - -ACPI_EXPORT_SYMBOL(acpi_install_interface) - -/***************************************************************************** - * - * FUNCTION: acpi_remove_interface - * - * PARAMETERS: interface_name - The interface to remove - * - * RETURN: Status - * - * DESCRIPTION: Remove an _OSI interface from the global list - * - ****************************************************************************/ -acpi_status acpi_remove_interface(acpi_string interface_name) -{ - acpi_status status; - - /* Parameter validation */ - - if (!interface_name || (ACPI_STRLEN(interface_name) == 0)) { - return (AE_BAD_PARAMETER); - } - - (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); - - status = acpi_ut_remove_interface(interface_name); - - acpi_os_release_mutex(acpi_gbl_osi_mutex); - return (status); -} - -ACPI_EXPORT_SYMBOL(acpi_remove_interface) - -/***************************************************************************** - * - * FUNCTION: acpi_install_interface_handler - * - * PARAMETERS: Handler - The _OSI interface handler to install - * NULL means "remove existing handler" - * - * RETURN: Status - * - * DESCRIPTION: Install a handler for the predefined _OSI ACPI method. - * invoked during execution of the internal implementation of - * _OSI. A NULL handler simply removes any existing handler. - * - ****************************************************************************/ -acpi_status acpi_install_interface_handler(acpi_interface_handler handler) -{ - acpi_status status = AE_OK; - - (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); - - if (handler && acpi_gbl_interface_handler) { - status = AE_ALREADY_EXISTS; - } else { - acpi_gbl_interface_handler = handler; - } - - acpi_os_release_mutex(acpi_gbl_osi_mutex); - return (status); -} - -ACPI_EXPORT_SYMBOL(acpi_install_interface_handler) -#endif /* !ACPI_ASL_COMPILER */ +#endif diff --git a/trunk/drivers/acpi/acpica/utxferror.c b/trunk/drivers/acpi/acpica/utxferror.c deleted file mode 100644 index 6f12e314fbae..000000000000 --- a/trunk/drivers/acpi/acpica/utxferror.c +++ /dev/null @@ -1,415 +0,0 @@ -/******************************************************************************* - * - * Module Name: utxferror - Various error/warning output functions - * - ******************************************************************************/ - -/* - * Copyright (C) 2000 - 2010, Intel Corp. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - */ - -#include -#include "accommon.h" -#include "acnamesp.h" - -#define _COMPONENT ACPI_UTILITIES -ACPI_MODULE_NAME("utxferror") - -/* - * This module is used for the in-kernel ACPICA as well as the ACPICA - * tools/applications. - * - * For the i_aSL compiler case, the output is redirected to stderr so that - * any of the various ACPI errors and warnings do not appear in the output - * files, for either the compiler or disassembler portions of the tool. - */ -#ifdef ACPI_ASL_COMPILER -#include -extern FILE *acpi_gbl_output_file; - -#define ACPI_MSG_REDIRECT_BEGIN \ - FILE *output_file = acpi_gbl_output_file; \ - acpi_os_redirect_output (stderr); - -#define ACPI_MSG_REDIRECT_END \ - acpi_os_redirect_output (output_file); - -#else -/* - * non-i_aSL case - no redirection, nothing to do - */ -#define ACPI_MSG_REDIRECT_BEGIN -#define ACPI_MSG_REDIRECT_END -#endif -/* - * Common message prefixes - */ -#define ACPI_MSG_ERROR "ACPI Error: " -#define ACPI_MSG_EXCEPTION "ACPI Exception: " -#define ACPI_MSG_WARNING "ACPI Warning: " -#define ACPI_MSG_INFO "ACPI: " -/* - * Common message suffix - */ -#define ACPI_MSG_SUFFIX \ - acpi_os_printf (" (%8.8X/%s-%u)\n", ACPI_CA_VERSION, module_name, line_number) -/******************************************************************************* - * - * FUNCTION: acpi_error - * - * PARAMETERS: module_name - Caller's module name (for error output) - * line_number - Caller's line number (for error output) - * Format - Printf format string + additional args - * - * RETURN: None - * - * DESCRIPTION: Print "ACPI Error" message with module/line/version info - * - ******************************************************************************/ -void ACPI_INTERNAL_VAR_XFACE -acpi_error(const char *module_name, u32 line_number, const char *format, ...) -{ - va_list arg_list; - - ACPI_MSG_REDIRECT_BEGIN; - acpi_os_printf(ACPI_MSG_ERROR); - - va_start(arg_list, format); - acpi_os_vprintf(format, arg_list); - ACPI_MSG_SUFFIX; - va_end(arg_list); - - ACPI_MSG_REDIRECT_END; -} - -ACPI_EXPORT_SYMBOL(acpi_error) - -/******************************************************************************* - * - * FUNCTION: acpi_exception - * - * PARAMETERS: module_name - Caller's module name (for error output) - * line_number - Caller's line number (for error output) - * Status - Status to be formatted - * Format - Printf format string + additional args - * - * RETURN: None - * - * DESCRIPTION: Print "ACPI Exception" message with module/line/version info - * and decoded acpi_status. - * - ******************************************************************************/ -void ACPI_INTERNAL_VAR_XFACE -acpi_exception(const char *module_name, - u32 line_number, acpi_status status, const char *format, ...) -{ - va_list arg_list; - - ACPI_MSG_REDIRECT_BEGIN; - acpi_os_printf(ACPI_MSG_EXCEPTION "%s, ", - acpi_format_exception(status)); - - va_start(arg_list, format); - acpi_os_vprintf(format, arg_list); - ACPI_MSG_SUFFIX; - va_end(arg_list); - - ACPI_MSG_REDIRECT_END; -} - -ACPI_EXPORT_SYMBOL(acpi_exception) - -/******************************************************************************* - * - * FUNCTION: acpi_warning - * - * PARAMETERS: module_name - Caller's module name (for error output) - * line_number - Caller's line number (for error output) - * Format - Printf format string + additional args - * - * RETURN: None - * - * DESCRIPTION: Print "ACPI Warning" message with module/line/version info - * - ******************************************************************************/ -void ACPI_INTERNAL_VAR_XFACE -acpi_warning(const char *module_name, u32 line_number, const char *format, ...) -{ - va_list arg_list; - - ACPI_MSG_REDIRECT_BEGIN; - acpi_os_printf(ACPI_MSG_WARNING); - - va_start(arg_list, format); - acpi_os_vprintf(format, arg_list); - ACPI_MSG_SUFFIX; - va_end(arg_list); - - ACPI_MSG_REDIRECT_END; -} - -ACPI_EXPORT_SYMBOL(acpi_warning) - -/******************************************************************************* - * - * FUNCTION: acpi_info - * - * PARAMETERS: module_name - Caller's module name (for error output) - * line_number - Caller's line number (for error output) - * Format - Printf format string + additional args - * - * RETURN: None - * - * DESCRIPTION: Print generic "ACPI:" information message. There is no - * module/line/version info in order to keep the message simple. - * - * TBD: module_name and line_number args are not needed, should be removed. - * - ******************************************************************************/ -void ACPI_INTERNAL_VAR_XFACE -acpi_info(const char *module_name, u32 line_number, const char *format, ...) -{ - va_list arg_list; - - ACPI_MSG_REDIRECT_BEGIN; - acpi_os_printf(ACPI_MSG_INFO); - - va_start(arg_list, format); - acpi_os_vprintf(format, arg_list); - acpi_os_printf("\n"); - va_end(arg_list); - - ACPI_MSG_REDIRECT_END; -} - -ACPI_EXPORT_SYMBOL(acpi_info) - -/* - * The remainder of this module contains internal error functions that may - * be configured out. - */ -#if !defined (ACPI_NO_ERROR_MESSAGES) && !defined (ACPI_BIN_APP) -/******************************************************************************* - * - * FUNCTION: acpi_ut_predefined_warning - * - * PARAMETERS: module_name - Caller's module name (for error output) - * line_number - Caller's line number (for error output) - * Pathname - Full pathname to the node - * node_flags - From Namespace node for the method/object - * Format - Printf format string + additional args - * - * RETURN: None - * - * DESCRIPTION: Warnings for the predefined validation module. Messages are - * only emitted the first time a problem with a particular - * method/object is detected. This prevents a flood of error - * messages for methods that are repeatedly evaluated. - * - ******************************************************************************/ -void ACPI_INTERNAL_VAR_XFACE -acpi_ut_predefined_warning(const char *module_name, - u32 line_number, - char *pathname, - u8 node_flags, const char *format, ...) -{ - va_list arg_list; - - /* - * Warning messages for this method/object will be disabled after the - * first time a validation fails or an object is successfully repaired. - */ - if (node_flags & ANOBJ_EVALUATED) { - return; - } - - acpi_os_printf(ACPI_MSG_WARNING "For %s: ", pathname); - - va_start(arg_list, format); - acpi_os_vprintf(format, arg_list); - ACPI_MSG_SUFFIX; - va_end(arg_list); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ut_predefined_info - * - * PARAMETERS: module_name - Caller's module name (for error output) - * line_number - Caller's line number (for error output) - * Pathname - Full pathname to the node - * node_flags - From Namespace node for the method/object - * Format - Printf format string + additional args - * - * RETURN: None - * - * DESCRIPTION: Info messages for the predefined validation module. Messages - * are only emitted the first time a problem with a particular - * method/object is detected. This prevents a flood of - * messages for methods that are repeatedly evaluated. - * - ******************************************************************************/ - -void ACPI_INTERNAL_VAR_XFACE -acpi_ut_predefined_info(const char *module_name, - u32 line_number, - char *pathname, u8 node_flags, const char *format, ...) -{ - va_list arg_list; - - /* - * Warning messages for this method/object will be disabled after the - * first time a validation fails or an object is successfully repaired. - */ - if (node_flags & ANOBJ_EVALUATED) { - return; - } - - acpi_os_printf(ACPI_MSG_INFO "For %s: ", pathname); - - va_start(arg_list, format); - acpi_os_vprintf(format, arg_list); - ACPI_MSG_SUFFIX; - va_end(arg_list); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ut_namespace_error - * - * PARAMETERS: module_name - Caller's module name (for error output) - * line_number - Caller's line number (for error output) - * internal_name - Name or path of the namespace node - * lookup_status - Exception code from NS lookup - * - * RETURN: None - * - * DESCRIPTION: Print error message with the full pathname for the NS node. - * - ******************************************************************************/ - -void -acpi_ut_namespace_error(const char *module_name, - u32 line_number, - const char *internal_name, acpi_status lookup_status) -{ - acpi_status status; - u32 bad_name; - char *name = NULL; - - ACPI_MSG_REDIRECT_BEGIN; - acpi_os_printf(ACPI_MSG_ERROR); - - if (lookup_status == AE_BAD_CHARACTER) { - - /* There is a non-ascii character in the name */ - - ACPI_MOVE_32_TO_32(&bad_name, - ACPI_CAST_PTR(u32, internal_name)); - acpi_os_printf("[0x%4.4X] (NON-ASCII)", bad_name); - } else { - /* Convert path to external format */ - - status = acpi_ns_externalize_name(ACPI_UINT32_MAX, - internal_name, NULL, &name); - - /* Print target name */ - - if (ACPI_SUCCESS(status)) { - acpi_os_printf("[%s]", name); - } else { - acpi_os_printf("[COULD NOT EXTERNALIZE NAME]"); - } - - if (name) { - ACPI_FREE(name); - } - } - - acpi_os_printf(" Namespace lookup failure, %s", - acpi_format_exception(lookup_status)); - - ACPI_MSG_SUFFIX; - ACPI_MSG_REDIRECT_END; -} - -/******************************************************************************* - * - * FUNCTION: acpi_ut_method_error - * - * PARAMETERS: module_name - Caller's module name (for error output) - * line_number - Caller's line number (for error output) - * Message - Error message to use on failure - * prefix_node - Prefix relative to the path - * Path - Path to the node (optional) - * method_status - Execution status - * - * RETURN: None - * - * DESCRIPTION: Print error message with the full pathname for the method. - * - ******************************************************************************/ - -void -acpi_ut_method_error(const char *module_name, - u32 line_number, - const char *message, - struct acpi_namespace_node *prefix_node, - const char *path, acpi_status method_status) -{ - acpi_status status; - struct acpi_namespace_node *node = prefix_node; - - ACPI_MSG_REDIRECT_BEGIN; - acpi_os_printf(ACPI_MSG_ERROR); - - if (path) { - status = - acpi_ns_get_node(prefix_node, path, ACPI_NS_NO_UPSEARCH, - &node); - if (ACPI_FAILURE(status)) { - acpi_os_printf("[Could not get node by pathname]"); - } - } - - acpi_ns_print_node_pathname(node, message); - acpi_os_printf(", %s", acpi_format_exception(method_status)); - - ACPI_MSG_SUFFIX; - ACPI_MSG_REDIRECT_END; -} - -#endif /* ACPI_NO_ERROR_MESSAGES */ diff --git a/trunk/drivers/acpi/battery.c b/trunk/drivers/acpi/battery.c index 95649d373071..98417201e9ce 100644 --- a/trunk/drivers/acpi/battery.c +++ b/trunk/drivers/acpi/battery.c @@ -42,7 +42,10 @@ #include #include + +#ifdef CONFIG_ACPI_SYSFS_POWER #include +#endif #define PREFIX "ACPI: " @@ -95,12 +98,13 @@ enum { * due to bad math. */ ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, - ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, }; struct acpi_battery { struct mutex lock; +#ifdef CONFIG_ACPI_SYSFS_POWER struct power_supply bat; +#endif struct acpi_device *device; unsigned long update_time; int rate_now; @@ -137,6 +141,7 @@ inline int acpi_battery_present(struct acpi_battery *battery) return battery->device->status.battery_present; } +#ifdef CONFIG_ACPI_SYSFS_POWER static int acpi_battery_technology(struct acpi_battery *battery) { if (!strcasecmp("NiCd", battery->type)) @@ -181,7 +186,6 @@ static int acpi_battery_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) { - int ret = 0; struct acpi_battery *battery = to_acpi_battery(psy); if (acpi_battery_present(battery)) { @@ -210,44 +214,26 @@ static int acpi_battery_get_property(struct power_supply *psy, val->intval = battery->cycle_count; break; case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: - if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN) - ret = -ENODEV; - else - val->intval = battery->design_voltage * 1000; + val->intval = battery->design_voltage * 1000; break; case POWER_SUPPLY_PROP_VOLTAGE_NOW: - if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN) - ret = -ENODEV; - else - val->intval = battery->voltage_now * 1000; + val->intval = battery->voltage_now * 1000; break; case POWER_SUPPLY_PROP_CURRENT_NOW: case POWER_SUPPLY_PROP_POWER_NOW: - if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN) - ret = -ENODEV; - else - val->intval = battery->rate_now * 1000; + val->intval = battery->rate_now * 1000; break; case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: - if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) - ret = -ENODEV; - else - val->intval = battery->design_capacity * 1000; + val->intval = battery->design_capacity * 1000; break; case POWER_SUPPLY_PROP_CHARGE_FULL: case POWER_SUPPLY_PROP_ENERGY_FULL: - if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN) - ret = -ENODEV; - else - val->intval = battery->full_charge_capacity * 1000; + val->intval = battery->full_charge_capacity * 1000; break; case POWER_SUPPLY_PROP_CHARGE_NOW: case POWER_SUPPLY_PROP_ENERGY_NOW: - if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN) - ret = -ENODEV; - else - val->intval = battery->capacity_now * 1000; + val->intval = battery->capacity_now * 1000; break; case POWER_SUPPLY_PROP_MODEL_NAME: val->strval = battery->model_number; @@ -259,9 +245,9 @@ static int acpi_battery_get_property(struct power_supply *psy, val->strval = battery->serial_number; break; default: - ret = -EINVAL; + return -EINVAL; } - return ret; + return 0; } static enum power_supply_property charge_battery_props[] = { @@ -295,6 +281,7 @@ static enum power_supply_property energy_battery_props[] = { POWER_SUPPLY_PROP_MANUFACTURER, POWER_SUPPLY_PROP_SERIAL_NUMBER, }; +#endif #ifdef CONFIG_ACPI_PROCFS_POWER inline char *acpi_battery_units(struct acpi_battery *battery) @@ -425,8 +412,6 @@ static int acpi_battery_get_info(struct acpi_battery *battery) result = extract_package(battery, buffer.pointer, info_offsets, ARRAY_SIZE(info_offsets)); kfree(buffer.pointer); - if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)) - battery->full_charge_capacity = battery->design_capacity; return result; } @@ -463,10 +448,6 @@ static int acpi_battery_get_state(struct acpi_battery *battery) battery->rate_now != -1) battery->rate_now = abs((s16)battery->rate_now); - if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags) - && battery->capacity_now >= 0 && battery->capacity_now <= 100) - battery->capacity_now = (battery->capacity_now * - battery->full_charge_capacity) / 100; return result; } @@ -511,6 +492,7 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery) return acpi_battery_set_alarm(battery); } +#ifdef CONFIG_ACPI_SYSFS_POWER static ssize_t acpi_battery_alarm_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -570,6 +552,7 @@ static void sysfs_remove_battery(struct acpi_battery *battery) power_supply_unregister(&battery->bat); battery->bat.dev = NULL; } +#endif static void acpi_battery_quirks(struct acpi_battery *battery) { @@ -578,33 +561,6 @@ static void acpi_battery_quirks(struct acpi_battery *battery) } } -/* - * According to the ACPI spec, some kinds of primary batteries can - * report percentage battery remaining capacity directly to OS. - * In this case, it reports the Last Full Charged Capacity == 100 - * and BatteryPresentRate == 0xFFFFFFFF. - * - * Now we found some battery reports percentage remaining capacity - * even if it's rechargeable. - * https://bugzilla.kernel.org/show_bug.cgi?id=15979 - * - * Handle this correctly so that they won't break userspace. - */ -static void acpi_battery_quirks2(struct acpi_battery *battery) -{ - if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)) - return ; - - if (battery->full_charge_capacity == 100 && - battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN && - battery->capacity_now >=0 && battery->capacity_now <= 100) { - set_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags); - battery->full_charge_capacity = battery->design_capacity; - battery->capacity_now = (battery->capacity_now * - battery->full_charge_capacity) / 100; - } -} - static int acpi_battery_update(struct acpi_battery *battery) { int result, old_present = acpi_battery_present(battery); @@ -612,7 +568,9 @@ static int acpi_battery_update(struct acpi_battery *battery) if (result) return result; if (!acpi_battery_present(battery)) { +#ifdef CONFIG_ACPI_SYSFS_POWER sysfs_remove_battery(battery); +#endif battery->update_time = 0; return 0; } @@ -624,11 +582,11 @@ static int acpi_battery_update(struct acpi_battery *battery) acpi_battery_quirks(battery); acpi_battery_init_alarm(battery); } +#ifdef CONFIG_ACPI_SYSFS_POWER if (!battery->bat.dev) sysfs_add_battery(battery); - result = acpi_battery_get_state(battery); - acpi_battery_quirks2(battery); - return result; +#endif + return acpi_battery_get_state(battery); } /* -------------------------------------------------------------------------- @@ -909,20 +867,26 @@ static void acpi_battery_remove_fs(struct acpi_device *device) static void acpi_battery_notify(struct acpi_device *device, u32 event) { struct acpi_battery *battery = acpi_driver_data(device); +#ifdef CONFIG_ACPI_SYSFS_POWER struct device *old; +#endif if (!battery) return; +#ifdef CONFIG_ACPI_SYSFS_POWER old = battery->bat.dev; +#endif acpi_battery_update(battery); acpi_bus_generate_proc_event(device, event, acpi_battery_present(battery)); acpi_bus_generate_netlink_event(device->pnp.device_class, dev_name(&device->dev), event, acpi_battery_present(battery)); +#ifdef CONFIG_ACPI_SYSFS_POWER /* acpi_battery_update could remove power_supply object */ if (old && battery->bat.dev) power_supply_changed(&battery->bat); +#endif } static int acpi_battery_add(struct acpi_device *device) @@ -970,7 +934,9 @@ static int acpi_battery_remove(struct acpi_device *device, int type) #ifdef CONFIG_ACPI_PROCFS_POWER acpi_battery_remove_fs(device); #endif +#ifdef CONFIG_ACPI_SYSFS_POWER sysfs_remove_battery(battery); +#endif mutex_destroy(&battery->lock); kfree(battery); return 0; diff --git a/trunk/drivers/acpi/button.c b/trunk/drivers/acpi/button.c index 71ef9cd0735f..1575a9b51f1d 100644 --- a/trunk/drivers/acpi/button.c +++ b/trunk/drivers/acpi/button.c @@ -338,8 +338,7 @@ static int acpi_button_add(struct acpi_device *device) { struct acpi_button *button; struct input_dev *input; - const char *hid = acpi_device_hid(device); - char *name, *class; + char *hid, *name, *class; int error; button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL); @@ -354,6 +353,7 @@ static int acpi_button_add(struct acpi_device *device) goto err_free_button; } + hid = acpi_device_hid(device); name = acpi_device_name(device); class = acpi_device_class(device); diff --git a/trunk/drivers/acpi/dock.c b/trunk/drivers/acpi/dock.c index 44f99bd83741..3fe29e992be8 100644 --- a/trunk/drivers/acpi/dock.c +++ b/trunk/drivers/acpi/dock.c @@ -725,7 +725,6 @@ static void dock_notify(acpi_handle handle, u32 event, void *data) complete_dock(ds); dock_event(ds, event, DOCK_EVENT); dock_lock(ds, 1); - acpi_update_gpes(); break; } if (dock_present(ds) || dock_in_progress(ds)) diff --git a/trunk/drivers/acpi/ec.c b/trunk/drivers/acpi/ec.c index 372ff80b7b0c..f31291ba94d0 100644 --- a/trunk/drivers/acpi/ec.c +++ b/trunk/drivers/acpi/ec.c @@ -83,11 +83,6 @@ enum { EC_FLAGS_BLOCKED, /* Transactions are blocked */ }; -/* ec.c is compiled in acpi namespace so this shows up as acpi.ec_delay param */ -static unsigned int ec_delay __read_mostly = ACPI_EC_DELAY; -module_param(ec_delay, uint, 0644); -MODULE_PARM_DESC(ec_delay, "Timeout(ms) waited until an EC command completes"); - /* If we find an EC via the ECDT, we need to keep a ptr to its context */ /* External interfaces use first EC only, so remember */ typedef int (*acpi_ec_query_func) (void *data); @@ -215,7 +210,7 @@ static int ec_poll(struct acpi_ec *ec) int repeat = 2; /* number of command restarts */ while (repeat--) { unsigned long delay = jiffies + - msecs_to_jiffies(ec_delay); + msecs_to_jiffies(ACPI_EC_DELAY); do { /* don't sleep with disabled interrupts */ if (EC_FLAGS_MSI || irqs_disabled()) { @@ -270,7 +265,7 @@ static int ec_check_ibf0(struct acpi_ec *ec) static int ec_wait_ibf0(struct acpi_ec *ec) { - unsigned long delay = jiffies + msecs_to_jiffies(ec_delay); + unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); /* interrupt wait manually if GPE mode is not active */ while (time_before(jiffies, delay)) if (wait_event_timeout(ec->wait, ec_check_ibf0(ec), diff --git a/trunk/drivers/acpi/fan.c b/trunk/drivers/acpi/fan.c index 60049080c869..d94d2953c974 100644 --- a/trunk/drivers/acpi/fan.c +++ b/trunk/drivers/acpi/fan.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include #include #include @@ -116,6 +118,122 @@ static struct thermal_cooling_device_ops fan_cooling_ops = { .set_cur_state = fan_set_cur_state, }; +/* -------------------------------------------------------------------------- + FS Interface (/proc) + -------------------------------------------------------------------------- */ +#ifdef CONFIG_ACPI_PROCFS + +static struct proc_dir_entry *acpi_fan_dir; + +static int acpi_fan_read_state(struct seq_file *seq, void *offset) +{ + struct acpi_device *device = seq->private; + int state = 0; + + + if (device) { + if (acpi_bus_get_power(device->handle, &state)) + seq_printf(seq, "status: ERROR\n"); + else + seq_printf(seq, "status: %s\n", + !state ? "on" : "off"); + } + return 0; +} + +static int acpi_fan_state_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_fan_read_state, PDE(inode)->data); +} + +static ssize_t +acpi_fan_write_state(struct file *file, const char __user * buffer, + size_t count, loff_t * ppos) +{ + int result = 0; + struct seq_file *m = file->private_data; + struct acpi_device *device = m->private; + char state_string[3] = { '\0' }; + + if (count > sizeof(state_string) - 1) + return -EINVAL; + + if (copy_from_user(state_string, buffer, count)) + return -EFAULT; + + state_string[count] = '\0'; + if ((state_string[0] < '0') || (state_string[0] > '3')) + return -EINVAL; + if (state_string[1] == '\n') + state_string[1] = '\0'; + if (state_string[1] != '\0') + return -EINVAL; + + result = acpi_bus_set_power(device->handle, + simple_strtoul(state_string, NULL, 0)); + if (result) + return result; + + return count; +} + +static const struct file_operations acpi_fan_state_ops = { + .open = acpi_fan_state_open_fs, + .read = seq_read, + .write = acpi_fan_write_state, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static int acpi_fan_add_fs(struct acpi_device *device) +{ + struct proc_dir_entry *entry = NULL; + + + if (!device) + return -EINVAL; + + if (!acpi_device_dir(device)) { + acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), + acpi_fan_dir); + if (!acpi_device_dir(device)) + return -ENODEV; + } + + /* 'status' [R/W] */ + entry = proc_create_data(ACPI_FAN_FILE_STATE, + S_IFREG | S_IRUGO | S_IWUSR, + acpi_device_dir(device), + &acpi_fan_state_ops, + device); + if (!entry) + return -ENODEV; + return 0; +} + +static int acpi_fan_remove_fs(struct acpi_device *device) +{ + + if (acpi_device_dir(device)) { + remove_proc_entry(ACPI_FAN_FILE_STATE, acpi_device_dir(device)); + remove_proc_entry(acpi_device_bid(device), acpi_fan_dir); + acpi_device_dir(device) = NULL; + } + + return 0; +} +#else +static int acpi_fan_add_fs(struct acpi_device *device) +{ + return 0; +} + +static int acpi_fan_remove_fs(struct acpi_device *device) +{ + return 0; +} +#endif /* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */ @@ -166,6 +284,10 @@ static int acpi_fan_add(struct acpi_device *device) dev_err(&device->dev, "Failed to create sysfs link " "'device'\n"); + result = acpi_fan_add_fs(device); + if (result) + goto end; + printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device), acpi_device_bid(device), !device->power.state ? "on" : "off"); @@ -181,6 +303,7 @@ static int acpi_fan_remove(struct acpi_device *device, int type) if (!device || !cdev) return -EINVAL; + acpi_fan_remove_fs(device); sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); sysfs_remove_link(&cdev->device.kobj, "device"); thermal_cooling_device_unregister(cdev); @@ -224,9 +347,19 @@ static int __init acpi_fan_init(void) { int result = 0; +#ifdef CONFIG_ACPI_PROCFS + acpi_fan_dir = proc_mkdir(ACPI_FAN_CLASS, acpi_root_dir); + if (!acpi_fan_dir) + return -ENODEV; +#endif + result = acpi_bus_register_driver(&acpi_fan_driver); - if (result < 0) + if (result < 0) { +#ifdef CONFIG_ACPI_PROCFS + remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir); +#endif return -ENODEV; + } return 0; } @@ -236,6 +369,10 @@ static void __exit acpi_fan_exit(void) acpi_bus_unregister_driver(&acpi_fan_driver); +#ifdef CONFIG_ACPI_PROCFS + remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir); +#endif + return; } diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c index 0c2e445410ab..65b25a303b86 100644 --- a/trunk/drivers/acpi/osl.c +++ b/trunk/drivers/acpi/osl.c @@ -95,25 +95,8 @@ struct acpi_res_list { static LIST_HEAD(resource_list_head); static DEFINE_SPINLOCK(acpi_res_lock); -/* - * This list of permanent mappings is for memory that may be accessed from - * interrupt context, where we can't do the ioremap(). - */ -struct acpi_ioremap { - struct list_head list; - void __iomem *virt; - acpi_physical_address phys; - acpi_size size; - struct kref ref; -}; - -static LIST_HEAD(acpi_ioremaps); -static DEFINE_SPINLOCK(acpi_ioremap_lock); - #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ -static char osi_setup_string[OSI_STRING_LENGTH_MAX]; - -static void __init acpi_osi_setup_late(void); +static char osi_additional_string[OSI_STRING_LENGTH_MAX]; /* * The story of _OSI(Linux) @@ -155,20 +138,6 @@ static struct osi_linux { unsigned int known:1; } osi_linux = { 0, 0, 0, 0}; -static u32 acpi_osi_handler(acpi_string interface, u32 supported) -{ - if (!strcmp("Linux", interface)) { - - printk(KERN_NOTICE FW_BUG PREFIX - "BIOS _OSI(Linux) query %s%s\n", - osi_linux.enable ? "honored" : "ignored", - osi_linux.cmdline ? " via cmdline" : - osi_linux.dmi ? " via DMI" : ""); - } - - return supported; -} - static void __init acpi_request_region (struct acpi_generic_address *addr, unsigned int length, char *desc) { @@ -216,6 +185,36 @@ static int __init acpi_reserve_resources(void) } device_initcall(acpi_reserve_resources); +acpi_status __init acpi_os_initialize(void) +{ + return AE_OK; +} + +acpi_status acpi_os_initialize1(void) +{ + kacpid_wq = create_workqueue("kacpid"); + kacpi_notify_wq = create_workqueue("kacpi_notify"); + kacpi_hotplug_wq = create_workqueue("kacpi_hotplug"); + BUG_ON(!kacpid_wq); + BUG_ON(!kacpi_notify_wq); + BUG_ON(!kacpi_hotplug_wq); + return AE_OK; +} + +acpi_status acpi_os_terminate(void) +{ + if (acpi_irq_handler) { + acpi_os_remove_interrupt_handler(acpi_irq_irq, + acpi_irq_handler); + } + + destroy_workqueue(kacpid_wq); + destroy_workqueue(kacpi_notify_wq); + destroy_workqueue(kacpi_hotplug_wq); + + return AE_OK; +} + void acpi_os_printf(const char *fmt, ...) { va_list args; @@ -261,135 +260,29 @@ acpi_physical_address __init acpi_os_get_root_pointer(void) } } -/* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */ -static struct acpi_ioremap * -acpi_map_lookup(acpi_physical_address phys, acpi_size size) -{ - struct acpi_ioremap *map; - - list_for_each_entry_rcu(map, &acpi_ioremaps, list) - if (map->phys <= phys && - phys + size <= map->phys + map->size) - return map; - - return NULL; -} - -/* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */ -static void __iomem * -acpi_map_vaddr_lookup(acpi_physical_address phys, unsigned int size) -{ - struct acpi_ioremap *map; - - map = acpi_map_lookup(phys, size); - if (map) - return map->virt + (phys - map->phys); - - return NULL; -} - -/* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */ -static struct acpi_ioremap * -acpi_map_lookup_virt(void __iomem *virt, acpi_size size) -{ - struct acpi_ioremap *map; - - list_for_each_entry_rcu(map, &acpi_ioremaps, list) - if (map->virt <= virt && - virt + size <= map->virt + map->size) - return map; - - return NULL; -} - void __iomem *__init_refok acpi_os_map_memory(acpi_physical_address phys, acpi_size size) { - struct acpi_ioremap *map, *tmp_map; - unsigned long flags, pg_sz; - void __iomem *virt; - phys_addr_t pg_off; - if (phys > ULONG_MAX) { printk(KERN_ERR PREFIX "Cannot map memory that high\n"); return NULL; } - - if (!acpi_gbl_permanent_mmap) + if (acpi_gbl_permanent_mmap) + /* + * ioremap checks to ensure this is in reserved space + */ + return ioremap((unsigned long)phys, size); + else return __acpi_map_table((unsigned long)phys, size); - - map = kzalloc(sizeof(*map), GFP_KERNEL); - if (!map) - return NULL; - - pg_off = round_down(phys, PAGE_SIZE); - pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off; - virt = ioremap(pg_off, pg_sz); - if (!virt) { - kfree(map); - return NULL; - } - - INIT_LIST_HEAD(&map->list); - map->virt = virt; - map->phys = pg_off; - map->size = pg_sz; - kref_init(&map->ref); - - spin_lock_irqsave(&acpi_ioremap_lock, flags); - /* Check if page has already been mapped. */ - tmp_map = acpi_map_lookup(phys, size); - if (tmp_map) { - kref_get(&tmp_map->ref); - spin_unlock_irqrestore(&acpi_ioremap_lock, flags); - iounmap(map->virt); - kfree(map); - return tmp_map->virt + (phys - tmp_map->phys); - } - list_add_tail_rcu(&map->list, &acpi_ioremaps); - spin_unlock_irqrestore(&acpi_ioremap_lock, flags); - - return map->virt + (phys - map->phys); } EXPORT_SYMBOL_GPL(acpi_os_map_memory); -static void acpi_kref_del_iomap(struct kref *ref) -{ - struct acpi_ioremap *map; - - map = container_of(ref, struct acpi_ioremap, ref); - list_del_rcu(&map->list); -} - void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size) { - struct acpi_ioremap *map; - unsigned long flags; - int del; - - if (!acpi_gbl_permanent_mmap) { + if (acpi_gbl_permanent_mmap) + iounmap(virt); + else __acpi_unmap_table(virt, size); - return; - } - - spin_lock_irqsave(&acpi_ioremap_lock, flags); - map = acpi_map_lookup_virt(virt, size); - if (!map) { - spin_unlock_irqrestore(&acpi_ioremap_lock, flags); - printk(KERN_ERR PREFIX "%s: bad address %p\n", __func__, virt); - dump_stack(); - return; - } - - del = kref_put(&map->ref, acpi_kref_del_iomap); - spin_unlock_irqrestore(&acpi_ioremap_lock, flags); - - if (!del) - return; - - synchronize_rcu(); - iounmap(map->virt); - kfree(map); } EXPORT_SYMBOL_GPL(acpi_os_unmap_memory); @@ -399,44 +292,6 @@ void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size) __acpi_unmap_table(virt, size); } -int acpi_os_map_generic_address(struct acpi_generic_address *addr) -{ - void __iomem *virt; - - if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) - return 0; - - if (!addr->address || !addr->bit_width) - return -EINVAL; - - virt = acpi_os_map_memory(addr->address, addr->bit_width / 8); - if (!virt) - return -EIO; - - return 0; -} -EXPORT_SYMBOL_GPL(acpi_os_map_generic_address); - -void acpi_os_unmap_generic_address(struct acpi_generic_address *addr) -{ - void __iomem *virt; - unsigned long flags; - acpi_size size = addr->bit_width / 8; - - if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) - return; - - if (!addr->address || !addr->bit_width) - return; - - spin_lock_irqsave(&acpi_ioremap_lock, flags); - virt = acpi_map_vaddr_lookup(addr->address, size); - spin_unlock_irqrestore(&acpi_ioremap_lock, flags); - - acpi_os_unmap_memory(virt, size); -} -EXPORT_SYMBOL_GPL(acpi_os_unmap_generic_address); - #ifdef ACPI_FUTURE_USAGE acpi_status acpi_os_get_physical_address(void *virt, acpi_physical_address * phys) @@ -640,15 +495,8 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width) { u32 dummy; void __iomem *virt_addr; - int size = width / 8, unmap = 0; - - rcu_read_lock(); - virt_addr = acpi_map_vaddr_lookup(phys_addr, size); - rcu_read_unlock(); - if (!virt_addr) { - virt_addr = ioremap(phys_addr, size); - unmap = 1; - } + + virt_addr = ioremap(phys_addr, width); if (!value) value = &dummy; @@ -666,8 +514,7 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width) BUG(); } - if (unmap) - iounmap(virt_addr); + iounmap(virt_addr); return AE_OK; } @@ -676,15 +523,8 @@ acpi_status acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) { void __iomem *virt_addr; - int size = width / 8, unmap = 0; - - rcu_read_lock(); - virt_addr = acpi_map_vaddr_lookup(phys_addr, size); - rcu_read_unlock(); - if (!virt_addr) { - virt_addr = ioremap(phys_addr, size); - unmap = 1; - } + + virt_addr = ioremap(phys_addr, width); switch (width) { case 8: @@ -700,18 +540,16 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) BUG(); } - if (unmap) - iounmap(virt_addr); + iounmap(virt_addr); return AE_OK; } acpi_status acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, - u64 *value, u32 width) + u32 *value, u32 width) { int result, size; - u32 value32; if (!value) return AE_BAD_PARAMETER; @@ -732,8 +570,7 @@ acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, result = raw_pci_read(pci_id->segment, pci_id->bus, PCI_DEVFN(pci_id->device, pci_id->function), - reg, size, &value32); - *value = value32; + reg, size, value); return (result ? AE_ERROR : AE_OK); } @@ -765,6 +602,74 @@ acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, return (result ? AE_ERROR : AE_OK); } +/* TODO: Change code to take advantage of driver model more */ +static void acpi_os_derive_pci_id_2(acpi_handle rhandle, /* upper bound */ + acpi_handle chandle, /* current node */ + struct acpi_pci_id **id, + int *is_bridge, u8 * bus_number) +{ + acpi_handle handle; + struct acpi_pci_id *pci_id = *id; + acpi_status status; + unsigned long long temp; + acpi_object_type type; + + acpi_get_parent(chandle, &handle); + if (handle != rhandle) { + acpi_os_derive_pci_id_2(rhandle, handle, &pci_id, is_bridge, + bus_number); + + status = acpi_get_type(handle, &type); + if ((ACPI_FAILURE(status)) || (type != ACPI_TYPE_DEVICE)) + return; + + status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, + &temp); + if (ACPI_SUCCESS(status)) { + u32 val; + pci_id->device = ACPI_HIWORD(ACPI_LODWORD(temp)); + pci_id->function = ACPI_LOWORD(ACPI_LODWORD(temp)); + + if (*is_bridge) + pci_id->bus = *bus_number; + + /* any nicer way to get bus number of bridge ? */ + status = + acpi_os_read_pci_configuration(pci_id, 0x0e, &val, + 8); + if (ACPI_SUCCESS(status) + && ((val & 0x7f) == 1 || (val & 0x7f) == 2)) { + status = + acpi_os_read_pci_configuration(pci_id, 0x18, + &val, 8); + if (!ACPI_SUCCESS(status)) { + /* Certainly broken... FIX ME */ + return; + } + *is_bridge = 1; + pci_id->bus = val; + status = + acpi_os_read_pci_configuration(pci_id, 0x19, + &val, 8); + if (ACPI_SUCCESS(status)) { + *bus_number = val; + } + } else + *is_bridge = 0; + } + } +} + +void acpi_os_derive_pci_id(acpi_handle rhandle, /* upper bound */ + acpi_handle chandle, /* current node */ + struct acpi_pci_id **id) +{ + int is_bridge = 1; + u8 bus_number = (*id)->bus; + + acpi_os_derive_pci_id_2(rhandle, chandle, id, &is_bridge, &bus_number); +} + static void acpi_os_execute_deferred(struct work_struct *work) { struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work); @@ -1072,12 +977,6 @@ static void __init set_osi_linux(unsigned int enable) printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n", enable ? "Add": "Delet"); } - - if (osi_linux.enable) - acpi_osi_setup("Linux"); - else - acpi_osi_setup("!Linux"); - return; } @@ -1112,33 +1011,21 @@ void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) * string starting with '!' disables that string * otherwise string is added to list, augmenting built-in strings */ -static void __init acpi_osi_setup_late(void) +int __init acpi_osi_setup(char *str) { - char *str = osi_setup_string; - - if (*str == '\0') - return; - - if (!strcmp("!Linux", str)) { + if (str == NULL || *str == '\0') { + printk(KERN_INFO PREFIX "_OSI method disabled\n"); + acpi_gbl_create_osi_method = FALSE; + } else if (!strcmp("!Linux", str)) { acpi_cmdline_osi_linux(0); /* !enable */ } else if (*str == '!') { - if (acpi_remove_interface(++str) == AE_OK) + if (acpi_osi_invalidate(++str) == AE_OK) printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); } else if (!strcmp("Linux", str)) { acpi_cmdline_osi_linux(1); /* enable */ - } else { - if (acpi_install_interface(str) == AE_OK) - printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); - } -} - -int __init acpi_osi_setup(char *str) -{ - if (str == NULL || *str == '\0') { - printk(KERN_INFO PREFIX "_OSI method disabled\n"); - acpi_gbl_create_osi_method = FALSE; - } else { - strncpy(osi_setup_string, str, OSI_STRING_LENGTH_MAX); + } else if (*osi_additional_string == '\0') { + strncpy(osi_additional_string, str, OSI_STRING_LENGTH_MAX); + printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); } return 1; @@ -1395,6 +1282,38 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object) return (AE_OK); } +/****************************************************************************** + * + * FUNCTION: acpi_os_validate_interface + * + * PARAMETERS: interface - Requested interface to be validated + * + * RETURN: AE_OK if interface is supported, AE_SUPPORT otherwise + * + * DESCRIPTION: Match an interface string to the interfaces supported by the + * host. Strings originate from an AML call to the _OSI method. + * + *****************************************************************************/ + +acpi_status +acpi_os_validate_interface (char *interface) +{ + if (!strncmp(osi_additional_string, interface, OSI_STRING_LENGTH_MAX)) + return AE_OK; + if (!strcmp("Linux", interface)) { + + printk(KERN_NOTICE PREFIX + "BIOS _OSI(Linux) query %s%s\n", + osi_linux.enable ? "honored" : "ignored", + osi_linux.cmdline ? " via cmdline" : + osi_linux.dmi ? " via DMI" : ""); + + if (osi_linux.enable) + return AE_OK; + } + return AE_SUPPORT; +} + static inline int acpi_res_list_add(struct acpi_res_list *res) { struct acpi_res_list *res_list_elem; @@ -1543,46 +1462,5 @@ acpi_os_validate_address ( } return AE_OK; } -#endif - -acpi_status __init acpi_os_initialize(void) -{ - acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1a_event_block); - acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1b_event_block); - acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe0_block); - acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe1_block); - - return AE_OK; -} - -acpi_status acpi_os_initialize1(void) -{ - kacpid_wq = create_workqueue("kacpid"); - kacpi_notify_wq = create_workqueue("kacpi_notify"); - kacpi_hotplug_wq = create_workqueue("kacpi_hotplug"); - BUG_ON(!kacpid_wq); - BUG_ON(!kacpi_notify_wq); - BUG_ON(!kacpi_hotplug_wq); - acpi_install_interface_handler(acpi_osi_handler); - acpi_osi_setup_late(); - return AE_OK; -} -acpi_status acpi_os_terminate(void) -{ - if (acpi_irq_handler) { - acpi_os_remove_interrupt_handler(acpi_irq_irq, - acpi_irq_handler); - } - - acpi_os_unmap_generic_address(&acpi_gbl_FADT.xgpe1_block); - acpi_os_unmap_generic_address(&acpi_gbl_FADT.xgpe0_block); - acpi_os_unmap_generic_address(&acpi_gbl_FADT.xpm1b_event_block); - acpi_os_unmap_generic_address(&acpi_gbl_FADT.xpm1a_event_block); - - destroy_workqueue(kacpid_wq); - destroy_workqueue(kacpi_notify_wq); - destroy_workqueue(kacpi_hotplug_wq); - - return AE_OK; -} +#endif diff --git a/trunk/drivers/acpi/pci_irq.c b/trunk/drivers/acpi/pci_irq.c index f907cfbfa13c..e4804fb05e23 100644 --- a/trunk/drivers/acpi/pci_irq.c +++ b/trunk/drivers/acpi/pci_irq.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/acpi/pci_link.c b/trunk/drivers/acpi/pci_link.c index 9ff80a7e9f6a..8d47a5846aeb 100644 --- a/trunk/drivers/acpi/pci_link.c +++ b/trunk/drivers/acpi/pci_link.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/acpi/pci_root.c b/trunk/drivers/acpi/pci_root.c index 96668ad09622..3ba8d1f44a73 100644 --- a/trunk/drivers/acpi/pci_root.c +++ b/trunk/drivers/acpi/pci_root.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/acpi/power.c b/trunk/drivers/acpi/power.c index 67dedeed144c..844c155aeb0f 100644 --- a/trunk/drivers/acpi/power.c +++ b/trunk/drivers/acpi/power.c @@ -80,13 +80,18 @@ static struct acpi_driver acpi_power_driver = { }, }; +struct acpi_power_reference { + struct list_head node; + struct acpi_device *device; +}; + struct acpi_power_resource { struct acpi_device * device; acpi_bus_id name; u32 system_level; u32 order; - unsigned int ref_count; struct mutex resource_lock; + struct list_head reference; }; static struct list_head acpi_power_resource_list; @@ -179,89 +184,101 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state) return result; } -static int __acpi_power_on(struct acpi_power_resource *resource) -{ - acpi_status status = AE_OK; - - status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL); - if (ACPI_FAILURE(status)) - return -ENODEV; - - /* Update the power resource's _device_ power state */ - resource->device->power.state = ACPI_STATE_D0; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n", - resource->name)); - - return 0; -} - -static int acpi_power_on(acpi_handle handle) +static int acpi_power_on(acpi_handle handle, struct acpi_device *dev) { int result = 0; + int found = 0; + acpi_status status = AE_OK; struct acpi_power_resource *resource = NULL; + struct list_head *node, *next; + struct acpi_power_reference *ref; + result = acpi_power_get_context(handle, &resource); if (result) return result; mutex_lock(&resource->resource_lock); - - if (resource->ref_count++) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Power resource [%s] already on", - resource->name)); - } else { - result = __acpi_power_on(resource); + list_for_each_safe(node, next, &resource->reference) { + ref = container_of(node, struct acpi_power_reference, node); + if (dev->handle == ref->device->handle) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] already referenced by resource [%s]\n", + dev->pnp.bus_id, resource->name)); + found = 1; + break; + } } + if (!found) { + ref = kmalloc(sizeof (struct acpi_power_reference), + irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL); + if (!ref) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "kmalloc() failed\n")); + mutex_unlock(&resource->resource_lock); + return -ENOMEM; + } + list_add_tail(&ref->node, &resource->reference); + ref->device = dev; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] added to resource [%s] references\n", + dev->pnp.bus_id, resource->name)); + } mutex_unlock(&resource->resource_lock); + status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL); + if (ACPI_FAILURE(status)) + return -ENODEV; + + /* Update the power resource's _device_ power state */ + resource->device->power.state = ACPI_STATE_D0; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned on\n", + resource->name)); return 0; } -static int acpi_power_off_device(acpi_handle handle) +static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev) { int result = 0; acpi_status status = AE_OK; struct acpi_power_resource *resource = NULL; + struct list_head *node, *next; + struct acpi_power_reference *ref; result = acpi_power_get_context(handle, &resource); if (result) return result; mutex_lock(&resource->resource_lock); - - if (!resource->ref_count) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Power resource [%s] already off", - resource->name)); - goto unlock; + list_for_each_safe(node, next, &resource->reference) { + ref = container_of(node, struct acpi_power_reference, node); + if (dev->handle == ref->device->handle) { + list_del(&ref->node); + kfree(ref); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] removed from resource [%s] references\n", + dev->pnp.bus_id, resource->name)); + break; + } } - if (--resource->ref_count) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Power resource [%s] still in use\n", - resource->name)); - goto unlock; + if (!list_empty(&resource->reference)) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cannot turn resource [%s] off - resource is in use\n", + resource->name)); + mutex_unlock(&resource->resource_lock); + return 0; } + mutex_unlock(&resource->resource_lock); status = acpi_evaluate_object(resource->device->handle, "_OFF", NULL, NULL); - if (ACPI_FAILURE(status)) { - result = -ENODEV; - } else { - /* Update the power resource's _device_ power state */ - resource->device->power.state = ACPI_STATE_D3; + if (ACPI_FAILURE(status)) + return -ENODEV; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Power resource [%s] turned off\n", - resource->name)); - } + /* Update the power resource's _device_ power state */ + resource->device->power.state = ACPI_STATE_D3; - unlock: - mutex_unlock(&resource->resource_lock); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned off\n", + resource->name)); - return result; + return 0; } /** @@ -347,7 +364,7 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state) /* Open power resource */ for (i = 0; i < dev->wakeup.resources.count; i++) { - int ret = acpi_power_on(dev->wakeup.resources.handles[i]); + int ret = acpi_power_on(dev->wakeup.resources.handles[i], dev); if (ret) { printk(KERN_ERR PREFIX "Transition power state\n"); dev->wakeup.flags.valid = 0; @@ -403,7 +420,7 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev) /* Close power resource */ for (i = 0; i < dev->wakeup.resources.count; i++) { int ret = acpi_power_off_device( - dev->wakeup.resources.handles[i]); + dev->wakeup.resources.handles[i], dev); if (ret) { printk(KERN_ERR PREFIX "Transition power state\n"); dev->wakeup.flags.valid = 0; @@ -483,7 +500,7 @@ int acpi_power_transition(struct acpi_device *device, int state) * (e.g. so the device doesn't lose power while transitioning). */ for (i = 0; i < tl->count; i++) { - result = acpi_power_on(tl->handles[i]); + result = acpi_power_on(tl->handles[i], device); if (result) goto end; } @@ -496,7 +513,7 @@ int acpi_power_transition(struct acpi_device *device, int state) * Then we dereference all power resources used in the current list. */ for (i = 0; i < cl->count; i++) { - result = acpi_power_off_device(cl->handles[i]); + result = acpi_power_off_device(cl->handles[i], device); if (result) goto end; } @@ -534,6 +551,7 @@ static int acpi_power_add(struct acpi_device *device) resource->device = device; mutex_init(&resource->resource_lock); + INIT_LIST_HEAD(&resource->reference); strcpy(resource->name, device->pnp.bus_id); strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_POWER_CLASS); @@ -576,14 +594,22 @@ static int acpi_power_add(struct acpi_device *device) static int acpi_power_remove(struct acpi_device *device, int type) { - struct acpi_power_resource *resource; + struct acpi_power_resource *resource = NULL; + struct list_head *node, *next; - if (!device) + + if (!device || !acpi_driver_data(device)) return -EINVAL; resource = acpi_driver_data(device); - if (!resource) - return -EINVAL; + + mutex_lock(&resource->resource_lock); + list_for_each_safe(node, next, &resource->reference) { + struct acpi_power_reference *ref = container_of(node, struct acpi_power_reference, node); + list_del(&ref->node); + kfree(ref); + } + mutex_unlock(&resource->resource_lock); kfree(resource); @@ -593,28 +619,29 @@ static int acpi_power_remove(struct acpi_device *device, int type) static int acpi_power_resume(struct acpi_device *device) { int result = 0, state; - struct acpi_power_resource *resource; + struct acpi_power_resource *resource = NULL; + struct acpi_power_reference *ref; - if (!device) + if (!device || !acpi_driver_data(device)) return -EINVAL; resource = acpi_driver_data(device); - if (!resource) - return -EINVAL; - - mutex_lock(&resource->resource_lock); result = acpi_power_get_state(device->handle, &state); if (result) - goto unlock; + return result; - if (state == ACPI_POWER_RESOURCE_STATE_OFF && resource->ref_count) - result = __acpi_power_on(resource); + mutex_lock(&resource->resource_lock); + if (state == ACPI_POWER_RESOURCE_STATE_OFF && + !list_empty(&resource->reference)) { + ref = container_of(resource->reference.next, struct acpi_power_reference, node); + mutex_unlock(&resource->resource_lock); + result = acpi_power_on(device->handle, ref->device); + return result; + } - unlock: mutex_unlock(&resource->resource_lock); - - return result; + return 0; } int __init acpi_power_init(void) diff --git a/trunk/drivers/acpi/processor_driver.c b/trunk/drivers/acpi/processor_driver.c index 356c320bdd08..347eb21b2353 100644 --- a/trunk/drivers/acpi/processor_driver.c +++ b/trunk/drivers/acpi/processor_driver.c @@ -40,10 +40,8 @@ #include #include #include -#ifdef CONFIG_ACPI_PROCFS #include #include -#endif #include #include #include @@ -246,7 +244,6 @@ static int acpi_processor_errata(struct acpi_processor *pr) return result; } -#ifdef CONFIG_ACPI_PROCFS static struct proc_dir_entry *acpi_processor_dir = NULL; static int __cpuinit acpi_processor_add_fs(struct acpi_device *device) @@ -283,16 +280,7 @@ static int acpi_processor_remove_fs(struct acpi_device *device) return 0; } -#else -static inline int acpi_processor_add_fs(struct acpi_device *device) -{ - return 0; -} -static inline int acpi_processor_remove_fs(struct acpi_device *device) -{ - return 0; -} -#endif + /* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */ @@ -854,11 +842,9 @@ static int __init acpi_processor_init(void) memset(&errata, 0, sizeof(errata)); -#ifdef CONFIG_ACPI_PROCFS acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); if (!acpi_processor_dir) return -ENOMEM; -#endif if (!cpuidle_register_driver(&acpi_idle_driver)) { printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", @@ -885,9 +871,7 @@ static int __init acpi_processor_init(void) out_cpuidle: cpuidle_unregister_driver(&acpi_idle_driver); -#ifdef CONFIG_ACPI_PROCFS remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); -#endif return result; } @@ -907,9 +891,7 @@ static void __exit acpi_processor_exit(void) cpuidle_unregister_driver(&acpi_idle_driver); -#ifdef CONFIG_ACPI_PROCFS remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); -#endif return; } diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index 175c89a5ca90..f4428e82b352 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -64,6 +64,7 @@ #define ACPI_PROCESSOR_CLASS "processor" #define _COMPONENT ACPI_PROCESSOR_COMPONENT ACPI_MODULE_NAME("processor_idle"); +#define ACPI_PROCESSOR_FILE_POWER "power" #define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY) #define C2_OVERHEAD 1 /* 1us */ #define C3_OVERHEAD 1 /* 1us */ diff --git a/trunk/drivers/acpi/processor_throttling.c b/trunk/drivers/acpi/processor_throttling.c index ff3632717c51..730863855ed5 100644 --- a/trunk/drivers/acpi/processor_throttling.c +++ b/trunk/drivers/acpi/processor_throttling.c @@ -32,10 +32,8 @@ #include #include #include -#ifdef CONFIG_ACPI_PROCFS #include #include -#endif #include #include @@ -1216,7 +1214,6 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr) return result; } -#ifdef CONFIG_ACPI_PROCFS /* proc interface */ static int acpi_processor_throttling_seq_show(struct seq_file *seq, void *offset) @@ -1325,4 +1322,3 @@ const struct file_operations acpi_processor_throttling_fops = { .llseek = seq_lseek, .release = single_release, }; -#endif diff --git a/trunk/drivers/acpi/sbs.c b/trunk/drivers/acpi/sbs.c index e5dbedb16bbf..4ff76e8174eb 100644 --- a/trunk/drivers/acpi/sbs.c +++ b/trunk/drivers/acpi/sbs.c @@ -40,7 +40,10 @@ #include #include #include + +#ifdef CONFIG_ACPI_SYSFS_POWER #include +#endif #include "sbshc.h" @@ -82,7 +85,9 @@ static const struct acpi_device_id sbs_device_ids[] = { MODULE_DEVICE_TABLE(acpi, sbs_device_ids); struct acpi_battery { +#ifdef CONFIG_ACPI_SYSFS_POWER struct power_supply bat; +#endif struct acpi_sbs *sbs; #ifdef CONFIG_ACPI_PROCFS_POWER struct proc_dir_entry *proc_entry; @@ -115,7 +120,9 @@ struct acpi_battery { #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); struct acpi_sbs { +#ifdef CONFIG_ACPI_SYSFS_POWER struct power_supply charger; +#endif struct acpi_device *device; struct acpi_smb_hc *hc; struct mutex lock; @@ -159,6 +166,7 @@ static inline int acpi_battery_scale(struct acpi_battery *battery) acpi_battery_ipscale(battery); } +#ifdef CONFIG_ACPI_SYSFS_POWER static int sbs_get_ac_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) @@ -305,6 +313,7 @@ static enum power_supply_property sbs_energy_battery_props[] = { POWER_SUPPLY_PROP_MANUFACTURER, }; +#endif /* -------------------------------------------------------------------------- Smart Battery System Management @@ -440,6 +449,7 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs) return result; } +#ifdef CONFIG_ACPI_SYSFS_POWER static ssize_t acpi_battery_alarm_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -469,6 +479,7 @@ static struct device_attribute alarm_attr = { .show = acpi_battery_alarm_show, .store = acpi_battery_alarm_store, }; +#endif /* -------------------------------------------------------------------------- FS Interface (/proc/acpi) @@ -787,6 +798,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) &acpi_battery_state_fops, &acpi_battery_alarm_fops, battery); #endif +#ifdef CONFIG_ACPI_SYSFS_POWER battery->bat.name = battery->name; battery->bat.type = POWER_SUPPLY_TYPE_BATTERY; if (!acpi_battery_mode(battery)) { @@ -807,6 +819,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) goto end; battery->have_sysfs_alarm = 1; end: +#endif printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n", ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), battery->name, battery->present ? "present" : "absent"); @@ -815,13 +828,17 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) static void acpi_battery_remove(struct acpi_sbs *sbs, int id) { +#if defined(CONFIG_ACPI_SYSFS_POWER) || defined(CONFIG_ACPI_PROCFS_POWER) struct acpi_battery *battery = &sbs->battery[id]; +#endif +#ifdef CONFIG_ACPI_SYSFS_POWER if (battery->bat.dev) { if (battery->have_sysfs_alarm) device_remove_file(battery->bat.dev, &alarm_attr); power_supply_unregister(&battery->bat); } +#endif #ifdef CONFIG_ACPI_PROCFS_POWER if (battery->proc_entry) acpi_sbs_remove_fs(&battery->proc_entry, acpi_battery_dir); @@ -842,12 +859,14 @@ static int acpi_charger_add(struct acpi_sbs *sbs) if (result) goto end; #endif +#ifdef CONFIG_ACPI_SYSFS_POWER sbs->charger.name = "sbs-charger"; sbs->charger.type = POWER_SUPPLY_TYPE_MAINS; sbs->charger.properties = sbs_ac_props; sbs->charger.num_properties = ARRAY_SIZE(sbs_ac_props); sbs->charger.get_property = sbs_get_ac_property; power_supply_register(&sbs->device->dev, &sbs->charger); +#endif printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n", ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line"); @@ -857,8 +876,10 @@ static int acpi_charger_add(struct acpi_sbs *sbs) static void acpi_charger_remove(struct acpi_sbs *sbs) { +#ifdef CONFIG_ACPI_SYSFS_POWER if (sbs->charger.dev) power_supply_unregister(&sbs->charger); +#endif #ifdef CONFIG_ACPI_PROCFS_POWER if (sbs->charger_entry) acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir); @@ -879,7 +900,9 @@ static void acpi_sbs_callback(void *context) ACPI_SBS_NOTIFY_STATUS, sbs->charger_present); #endif +#ifdef CONFIG_ACPI_SYSFS_POWER kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE); +#endif } if (sbs->manager_present) { for (id = 0; id < MAX_SBS_BAT; ++id) { @@ -896,7 +919,9 @@ static void acpi_sbs_callback(void *context) ACPI_SBS_NOTIFY_STATUS, bat->present); #endif +#ifdef CONFIG_ACPI_SYSFS_POWER kobject_uevent(&bat->bat.dev->kobj, KOBJ_CHANGE); +#endif } } } diff --git a/trunk/drivers/acpi/scan.c b/trunk/drivers/acpi/scan.c index 2b6c21d86b98..b23825ecfa37 100644 --- a/trunk/drivers/acpi/scan.c +++ b/trunk/drivers/acpi/scan.c @@ -26,8 +26,6 @@ extern struct acpi_device *acpi_root; #define ACPI_IS_ROOT_DEVICE(device) (!(device)->parent) -static const char *dummy_hid = "device"; - static LIST_HEAD(acpi_device_list); static LIST_HEAD(acpi_bus_id_list); DEFINE_MUTEX(acpi_device_lock); @@ -51,9 +49,6 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias, int count; struct acpi_hardware_id *id; - if (list_empty(&acpi_dev->pnp.ids)) - return 0; - len = snprintf(modalias, size, "acpi:"); size -= len; @@ -207,15 +202,13 @@ static int acpi_device_setup_files(struct acpi_device *dev) goto end; } - if (!list_empty(&dev->pnp.ids)) { - result = device_create_file(&dev->dev, &dev_attr_hid); - if (result) - goto end; + result = device_create_file(&dev->dev, &dev_attr_hid); + if (result) + goto end; - result = device_create_file(&dev->dev, &dev_attr_modalias); - if (result) - goto end; - } + result = device_create_file(&dev->dev, &dev_attr_modalias); + if (result) + goto end; /* * If device has _EJ0, 'eject' file is created that is used to trigger @@ -323,9 +316,6 @@ static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env) struct acpi_device *acpi_dev = to_acpi_device(dev); int len; - if (list_empty(&acpi_dev->pnp.ids)) - return 0; - if (add_uevent_var(env, "MODALIAS=")) return -ENOMEM; len = create_modalias(acpi_dev, &env->buf[env->buflen - 1], @@ -1020,13 +1010,10 @@ static int acpi_dock_match(struct acpi_device *device) return acpi_get_handle(device->handle, "_DCK", &tmp); } -const char *acpi_device_hid(struct acpi_device *device) +char *acpi_device_hid(struct acpi_device *device) { struct acpi_hardware_id *hid; - if (list_empty(&device->pnp.ids)) - return dummy_hid; - hid = list_first_entry(&device->pnp.ids, struct acpi_hardware_id, list); return hid->id; } @@ -1155,6 +1142,16 @@ static void acpi_device_set_id(struct acpi_device *device) acpi_add_id(device, ACPI_BUTTON_HID_SLEEPF); break; } + + /* + * We build acpi_devices for some objects that don't have _HID or _CID, + * e.g., PCI bridges and slots. Drivers can't bind to these objects, + * but we do use them indirectly by traversing the acpi_device tree. + * This generic ID isn't useful for driver binding, but it provides + * the useful property that "every acpi_device has an ID." + */ + if (list_empty(&device->pnp.ids)) + acpi_add_id(device, "device"); } static int acpi_device_set_context(struct acpi_device *device) @@ -1434,7 +1431,6 @@ EXPORT_SYMBOL(acpi_bus_add); int acpi_bus_start(struct acpi_device *device) { struct acpi_bus_ops ops; - int result; if (!device) return -EINVAL; @@ -1442,11 +1438,7 @@ int acpi_bus_start(struct acpi_device *device) memset(&ops, 0, sizeof(ops)); ops.acpi_op_start = 1; - result = acpi_bus_scan(device->handle, &ops, NULL); - - acpi_update_gpes(); - - return result; + return acpi_bus_scan(device->handle, &ops, NULL); } EXPORT_SYMBOL(acpi_bus_start); @@ -1560,8 +1552,6 @@ int __init acpi_scan_init(void) if (result) acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); - else - acpi_update_gpes(); return result; } diff --git a/trunk/drivers/acpi/sleep.c b/trunk/drivers/acpi/sleep.c index e807f4196f89..4754ff6e70e6 100644 --- a/trunk/drivers/acpi/sleep.c +++ b/trunk/drivers/acpi/sleep.c @@ -27,8 +27,6 @@ u8 sleep_states[ACPI_S_STATE_COUNT]; -static u32 acpi_target_sleep_state = ACPI_STATE_S0; - static void acpi_sleep_tts_switch(u32 acpi_state) { union acpi_object in_arg = { ACPI_TYPE_INTEGER }; @@ -81,6 +79,8 @@ static int acpi_sleep_prepare(u32 acpi_state) } #ifdef CONFIG_ACPI_SLEEP +static u32 acpi_target_sleep_state = ACPI_STATE_S0; + /* * The ACPI specification wants us to save NVS memory regions during hibernation * and to restore them during the subsequent resume. Windows does that also for @@ -562,7 +562,7 @@ int acpi_suspend(u32 acpi_state) return -EINVAL; } -#ifdef CONFIG_PM_OPS +#ifdef CONFIG_PM_SLEEP /** * acpi_pm_device_sleep_state - return preferred power state of ACPI device * in the system sleep state given by %acpi_target_sleep_state @@ -624,7 +624,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p) * can wake the system. _S0W may be valid, too. */ if (acpi_target_sleep_state == ACPI_STATE_S0 || - (device_may_wakeup(dev) && + (device_may_wakeup(dev) && adev->wakeup.state.enabled && adev->wakeup.sleep_state <= acpi_target_sleep_state)) { acpi_status status; @@ -632,9 +632,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p) status = acpi_evaluate_integer(handle, acpi_method, NULL, &d_max); if (ACPI_FAILURE(status)) { - if (acpi_target_sleep_state != ACPI_STATE_S0 || - status != AE_NOT_FOUND) - d_max = d_min; + d_max = d_min; } else if (d_max < d_min) { /* Warn the user of the broken DSDT */ printk(KERN_WARNING "ACPI: Wrong value from %s\n", @@ -648,9 +646,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p) *d_min_p = d_min; return d_max; } -#endif /* CONFIG_PM_OPS */ -#ifdef CONFIG_PM_SLEEP /** * acpi_pm_device_sleep_wake - enable or disable the system wake-up * capability of given device @@ -681,7 +677,7 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable) return error; } -#endif /* CONFIG_PM_SLEEP */ +#endif static void acpi_power_off_prepare(void) { diff --git a/trunk/drivers/acpi/thermal.c b/trunk/drivers/acpi/thermal.c index 5a27b0a31315..2f8f17131d9f 100644 --- a/trunk/drivers/acpi/thermal.c +++ b/trunk/drivers/acpi/thermal.c @@ -37,6 +37,12 @@ #include #include #include + +#ifdef CONFIG_ACPI_PROCFS +#include +#include +#endif + #include #include #include @@ -189,6 +195,61 @@ struct acpi_thermal { struct mutex lock; }; +#ifdef CONFIG_ACPI_PROCFS +static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file); +static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file); +static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file); +static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file); +static ssize_t acpi_thermal_write_cooling_mode(struct file *, + const char __user *, size_t, + loff_t *); +static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file); +static ssize_t acpi_thermal_write_polling(struct file *, const char __user *, + size_t, loff_t *); + +static const struct file_operations acpi_thermal_state_fops = { + .owner = THIS_MODULE, + .open = acpi_thermal_state_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static const struct file_operations acpi_thermal_temp_fops = { + .owner = THIS_MODULE, + .open = acpi_thermal_temp_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static const struct file_operations acpi_thermal_trip_fops = { + .owner = THIS_MODULE, + .open = acpi_thermal_trip_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static const struct file_operations acpi_thermal_cooling_fops = { + .owner = THIS_MODULE, + .open = acpi_thermal_cooling_open_fs, + .read = seq_read, + .write = acpi_thermal_write_cooling_mode, + .llseek = seq_lseek, + .release = single_release, +}; + +static const struct file_operations acpi_thermal_polling_fops = { + .owner = THIS_MODULE, + .open = acpi_thermal_polling_open_fs, + .read = seq_read, + .write = acpi_thermal_write_polling, + .llseek = seq_lseek, + .release = single_release, +}; +#endif /* CONFIG_ACPI_PROCFS*/ + /* -------------------------------------------------------------------------- Thermal Zone Management -------------------------------------------------------------------------- */ @@ -896,6 +957,358 @@ static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz) } +/* -------------------------------------------------------------------------- + FS Interface (/proc) + -------------------------------------------------------------------------- */ +#ifdef CONFIG_ACPI_PROCFS +static struct proc_dir_entry *acpi_thermal_dir; + +static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset) +{ + struct acpi_thermal *tz = seq->private; + + + if (!tz) + goto end; + + seq_puts(seq, "state: "); + + if (!tz->state.critical && !tz->state.hot && !tz->state.passive + && !tz->state.active) + seq_puts(seq, "ok\n"); + else { + if (tz->state.critical) + seq_puts(seq, "critical "); + if (tz->state.hot) + seq_puts(seq, "hot "); + if (tz->state.passive) + seq_puts(seq, "passive "); + if (tz->state.active) + seq_printf(seq, "active[%d]", tz->state.active_index); + seq_puts(seq, "\n"); + } + + end: + return 0; +} + +static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_thermal_state_seq_show, PDE(inode)->data); +} + +static int acpi_thermal_temp_seq_show(struct seq_file *seq, void *offset) +{ + int result = 0; + struct acpi_thermal *tz = seq->private; + + + if (!tz) + goto end; + + result = acpi_thermal_get_temperature(tz); + if (result) + goto end; + + seq_printf(seq, "temperature: %ld C\n", + KELVIN_TO_CELSIUS(tz->temperature)); + + end: + return 0; +} + +static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_thermal_temp_seq_show, PDE(inode)->data); +} + +static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset) +{ + struct acpi_thermal *tz = seq->private; + struct acpi_device *device; + acpi_status status; + + int i = 0; + int j = 0; + + + if (!tz) + goto end; + + if (tz->trips.critical.flags.valid) + seq_printf(seq, "critical (S5): %ld C%s", + KELVIN_TO_CELSIUS(tz->trips.critical.temperature), + nocrt ? " \n" : "\n"); + + if (tz->trips.hot.flags.valid) + seq_printf(seq, "hot (S4): %ld C%s", + KELVIN_TO_CELSIUS(tz->trips.hot.temperature), + nocrt ? " \n" : "\n"); + + if (tz->trips.passive.flags.valid) { + seq_printf(seq, + "passive: %ld C: tc1=%lu tc2=%lu tsp=%lu devices=", + KELVIN_TO_CELSIUS(tz->trips.passive.temperature), + tz->trips.passive.tc1, tz->trips.passive.tc2, + tz->trips.passive.tsp); + for (j = 0; j < tz->trips.passive.devices.count; j++) { + status = acpi_bus_get_device(tz->trips.passive.devices. + handles[j], &device); + seq_printf(seq, "%4.4s ", status ? "" : + acpi_device_bid(device)); + } + seq_puts(seq, "\n"); + } else { + seq_printf(seq, "passive (forced):"); + if (tz->thermal_zone->forced_passive) + seq_printf(seq, " %i C\n", + tz->thermal_zone->forced_passive / 1000); + else + seq_printf(seq, "\n"); + } + + for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { + if (!(tz->trips.active[i].flags.valid)) + break; + seq_printf(seq, "active[%d]: %ld C: devices=", + i, + KELVIN_TO_CELSIUS(tz->trips.active[i].temperature)); + for (j = 0; j < tz->trips.active[i].devices.count; j++){ + status = acpi_bus_get_device(tz->trips.active[i]. + devices.handles[j], + &device); + seq_printf(seq, "%4.4s ", status ? "" : + acpi_device_bid(device)); + } + seq_puts(seq, "\n"); + } + + end: + return 0; +} + +static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_thermal_trip_seq_show, PDE(inode)->data); +} + +static int acpi_thermal_cooling_seq_show(struct seq_file *seq, void *offset) +{ + struct acpi_thermal *tz = seq->private; + + + if (!tz) + goto end; + + if (!tz->flags.cooling_mode) + seq_puts(seq, "\n"); + else + seq_puts(seq, "0 - Active; 1 - Passive\n"); + + end: + return 0; +} + +static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_thermal_cooling_seq_show, + PDE(inode)->data); +} + +static ssize_t +acpi_thermal_write_cooling_mode(struct file *file, + const char __user * buffer, + size_t count, loff_t * ppos) +{ + struct seq_file *m = file->private_data; + struct acpi_thermal *tz = m->private; + int result = 0; + char mode_string[12] = { '\0' }; + + + if (!tz || (count > sizeof(mode_string) - 1)) + return -EINVAL; + + if (!tz->flags.cooling_mode) + return -ENODEV; + + if (copy_from_user(mode_string, buffer, count)) + return -EFAULT; + + mode_string[count] = '\0'; + + result = acpi_thermal_set_cooling_mode(tz, + simple_strtoul(mode_string, NULL, + 0)); + if (result) + return result; + + acpi_thermal_check(tz); + + return count; +} + +static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset) +{ + struct acpi_thermal *tz = seq->private; + + + if (!tz) + goto end; + + if (!tz->thermal_zone->polling_delay) { + seq_puts(seq, "\n"); + goto end; + } + + seq_printf(seq, "polling frequency: %d seconds\n", + (tz->thermal_zone->polling_delay / 1000)); + + end: + return 0; +} + +static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_thermal_polling_seq_show, + PDE(inode)->data); +} + +static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds) +{ + if (!tz) + return -EINVAL; + + /* Convert value to deci-seconds */ + tz->polling_frequency = seconds * 10; + + tz->thermal_zone->polling_delay = seconds * 1000; + + if (tz->tz_enabled) + thermal_zone_device_update(tz->thermal_zone); + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Polling frequency set to %lu seconds\n", + tz->polling_frequency/10)); + + return 0; +} + +static ssize_t +acpi_thermal_write_polling(struct file *file, + const char __user * buffer, + size_t count, loff_t * ppos) +{ + struct seq_file *m = file->private_data; + struct acpi_thermal *tz = m->private; + int result = 0; + char polling_string[12] = { '\0' }; + int seconds = 0; + + + if (!tz || (count > sizeof(polling_string) - 1)) + return -EINVAL; + + if (copy_from_user(polling_string, buffer, count)) + return -EFAULT; + + polling_string[count] = '\0'; + + seconds = simple_strtoul(polling_string, NULL, 0); + + result = acpi_thermal_set_polling(tz, seconds); + if (result) + return result; + + acpi_thermal_check(tz); + + return count; +} + +static int acpi_thermal_add_fs(struct acpi_device *device) +{ + struct proc_dir_entry *entry = NULL; + + + if (!acpi_device_dir(device)) { + acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), + acpi_thermal_dir); + if (!acpi_device_dir(device)) + return -ENODEV; + } + + /* 'state' [R] */ + entry = proc_create_data(ACPI_THERMAL_FILE_STATE, + S_IRUGO, acpi_device_dir(device), + &acpi_thermal_state_fops, + acpi_driver_data(device)); + if (!entry) + return -ENODEV; + + /* 'temperature' [R] */ + entry = proc_create_data(ACPI_THERMAL_FILE_TEMPERATURE, + S_IRUGO, acpi_device_dir(device), + &acpi_thermal_temp_fops, + acpi_driver_data(device)); + if (!entry) + return -ENODEV; + + /* 'trip_points' [R] */ + entry = proc_create_data(ACPI_THERMAL_FILE_TRIP_POINTS, + S_IRUGO, + acpi_device_dir(device), + &acpi_thermal_trip_fops, + acpi_driver_data(device)); + if (!entry) + return -ENODEV; + + /* 'cooling_mode' [R/W] */ + entry = proc_create_data(ACPI_THERMAL_FILE_COOLING_MODE, + S_IFREG | S_IRUGO | S_IWUSR, + acpi_device_dir(device), + &acpi_thermal_cooling_fops, + acpi_driver_data(device)); + if (!entry) + return -ENODEV; + + /* 'polling_frequency' [R/W] */ + entry = proc_create_data(ACPI_THERMAL_FILE_POLLING_FREQ, + S_IFREG | S_IRUGO | S_IWUSR, + acpi_device_dir(device), + &acpi_thermal_polling_fops, + acpi_driver_data(device)); + if (!entry) + return -ENODEV; + return 0; +} + +static int acpi_thermal_remove_fs(struct acpi_device *device) +{ + + if (acpi_device_dir(device)) { + remove_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ, + acpi_device_dir(device)); + remove_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE, + acpi_device_dir(device)); + remove_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS, + acpi_device_dir(device)); + remove_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE, + acpi_device_dir(device)); + remove_proc_entry(ACPI_THERMAL_FILE_STATE, + acpi_device_dir(device)); + remove_proc_entry(acpi_device_bid(device), acpi_thermal_dir); + acpi_device_dir(device) = NULL; + } + + return 0; +} +#else +static inline int acpi_thermal_add_fs(struct acpi_device *device) { return 0; } +static inline int acpi_thermal_remove_fs(struct acpi_device *device) +{ + return 0; +} +#endif /* CONFIG_ACPI_PROCFS */ /* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */ @@ -1015,11 +1428,17 @@ static int acpi_thermal_add(struct acpi_device *device) if (result) goto free_memory; + result = acpi_thermal_add_fs(device); + if (result) + goto unregister_thermal_zone; + printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n", acpi_device_name(device), acpi_device_bid(device), KELVIN_TO_CELSIUS(tz->temperature)); goto end; +unregister_thermal_zone: + thermal_zone_device_unregister(tz->thermal_zone); free_memory: kfree(tz); end: @@ -1035,6 +1454,7 @@ static int acpi_thermal_remove(struct acpi_device *device, int type) tz = acpi_driver_data(device); + acpi_thermal_remove_fs(device); acpi_thermal_unregister_thermal_zone(tz); mutex_destroy(&tz->lock); kfree(tz); @@ -1160,9 +1580,19 @@ static int __init acpi_thermal_init(void) return -ENODEV; } +#ifdef CONFIG_ACPI_PROCFS + acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir); + if (!acpi_thermal_dir) + return -ENODEV; +#endif + result = acpi_bus_register_driver(&acpi_thermal_driver); - if (result < 0) + if (result < 0) { +#ifdef CONFIG_ACPI_PROCFS + remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); +#endif return -ENODEV; + } return 0; } @@ -1172,6 +1602,10 @@ static void __exit acpi_thermal_exit(void) acpi_bus_unregister_driver(&acpi_thermal_driver); +#ifdef CONFIG_ACPI_PROCFS + remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); +#endif + return; } diff --git a/trunk/drivers/acpi/video.c b/trunk/drivers/acpi/video.c index 5cd0228d2daa..67dec0c675aa 100644 --- a/trunk/drivers/acpi/video.c +++ b/trunk/drivers/acpi/video.c @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include #include #include @@ -150,6 +152,9 @@ struct acpi_video_bus { struct acpi_video_bus_flags flags; struct list_head video_device_list; struct mutex device_list_lock; /* protects video_device_list */ +#ifdef CONFIG_ACPI_PROCFS + struct proc_dir_entry *dir; +#endif struct input_dev *input; char phys[32]; /* for input device */ struct notifier_block pm_nb; @@ -205,6 +210,108 @@ struct acpi_video_device { struct output_device *output_dev; }; +#ifdef CONFIG_ACPI_PROCFS +/* bus */ +static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file); +static const struct file_operations acpi_video_bus_info_fops = { + .owner = THIS_MODULE, + .open = acpi_video_bus_info_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file); +static const struct file_operations acpi_video_bus_ROM_fops = { + .owner = THIS_MODULE, + .open = acpi_video_bus_ROM_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int acpi_video_bus_POST_info_open_fs(struct inode *inode, + struct file *file); +static const struct file_operations acpi_video_bus_POST_info_fops = { + .owner = THIS_MODULE, + .open = acpi_video_bus_POST_info_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file); +static ssize_t acpi_video_bus_write_POST(struct file *file, + const char __user *buffer, size_t count, loff_t *data); +static const struct file_operations acpi_video_bus_POST_fops = { + .owner = THIS_MODULE, + .open = acpi_video_bus_POST_open_fs, + .read = seq_read, + .write = acpi_video_bus_write_POST, + .llseek = seq_lseek, + .release = single_release, +}; + +static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file); +static ssize_t acpi_video_bus_write_DOS(struct file *file, + const char __user *buffer, size_t count, loff_t *data); +static const struct file_operations acpi_video_bus_DOS_fops = { + .owner = THIS_MODULE, + .open = acpi_video_bus_DOS_open_fs, + .read = seq_read, + .write = acpi_video_bus_write_DOS, + .llseek = seq_lseek, + .release = single_release, +}; + +/* device */ +static int acpi_video_device_info_open_fs(struct inode *inode, + struct file *file); +static const struct file_operations acpi_video_device_info_fops = { + .owner = THIS_MODULE, + .open = acpi_video_device_info_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int acpi_video_device_state_open_fs(struct inode *inode, + struct file *file); +static ssize_t acpi_video_device_write_state(struct file *file, + const char __user *buffer, size_t count, loff_t *data); +static const struct file_operations acpi_video_device_state_fops = { + .owner = THIS_MODULE, + .open = acpi_video_device_state_open_fs, + .read = seq_read, + .write = acpi_video_device_write_state, + .llseek = seq_lseek, + .release = single_release, +}; + +static int acpi_video_device_brightness_open_fs(struct inode *inode, + struct file *file); +static ssize_t acpi_video_device_write_brightness(struct file *file, + const char __user *buffer, size_t count, loff_t *data); +static const struct file_operations acpi_video_device_brightness_fops = { + .owner = THIS_MODULE, + .open = acpi_video_device_brightness_open_fs, + .read = seq_read, + .write = acpi_video_device_write_brightness, + .llseek = seq_lseek, + .release = single_release, +}; + +static int acpi_video_device_EDID_open_fs(struct inode *inode, + struct file *file); +static const struct file_operations acpi_video_device_EDID_fops = { + .owner = THIS_MODULE, + .open = acpi_video_device_EDID_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; +#endif /* CONFIG_ACPI_PROCFS */ + static const char device_decode[][30] = { "motherboard VGA device", "PCI VGA device", @@ -1003,6 +1110,646 @@ static int acpi_video_bus_check(struct acpi_video_bus *video) return status; } +/* -------------------------------------------------------------------------- + FS Interface (/proc) + -------------------------------------------------------------------------- */ +#ifdef CONFIG_ACPI_PROCFS + +static struct proc_dir_entry *acpi_video_dir; + +/* video devices */ + +static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset) +{ + struct acpi_video_device *dev = seq->private; + + + if (!dev) + goto end; + + seq_printf(seq, "device_id: 0x%04x\n", (u32) dev->device_id); + seq_printf(seq, "type: "); + if (dev->flags.crt) + seq_printf(seq, "CRT\n"); + else if (dev->flags.lcd) + seq_printf(seq, "LCD\n"); + else if (dev->flags.tvout) + seq_printf(seq, "TVOUT\n"); + else if (dev->flags.dvi) + seq_printf(seq, "DVI\n"); + else + seq_printf(seq, "UNKNOWN\n"); + + seq_printf(seq, "known by bios: %s\n", dev->flags.bios ? "yes" : "no"); + + end: + return 0; +} + +static int +acpi_video_device_info_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_video_device_info_seq_show, + PDE(inode)->data); +} + +static int +acpi_video_device_query(struct acpi_video_device *device, + unsigned long long *state) +{ + int status; + + status = acpi_evaluate_integer(device->dev->handle, "_DGS", + NULL, state); + + return status; +} + +static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset) +{ + int status; + struct acpi_video_device *dev = seq->private; + unsigned long long state; + + + if (!dev) + goto end; + + status = acpi_video_device_get_state(dev, &state); + seq_printf(seq, "state: "); + if (ACPI_SUCCESS(status)) + seq_printf(seq, "0x%02llx\n", state); + else + seq_printf(seq, "\n"); + + status = acpi_video_device_query(dev, &state); + seq_printf(seq, "query: "); + if (ACPI_SUCCESS(status)) + seq_printf(seq, "0x%02llx\n", state); + else + seq_printf(seq, "\n"); + + end: + return 0; +} + +static int +acpi_video_device_state_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_video_device_state_seq_show, + PDE(inode)->data); +} + +static ssize_t +acpi_video_device_write_state(struct file *file, + const char __user * buffer, + size_t count, loff_t * data) +{ + int status; + struct seq_file *m = file->private_data; + struct acpi_video_device *dev = m->private; + char str[12] = { 0 }; + u32 state = 0; + + + if (!dev || count >= sizeof(str)) + return -EINVAL; + + if (copy_from_user(str, buffer, count)) + return -EFAULT; + + str[count] = 0; + state = simple_strtoul(str, NULL, 0); + state &= ((1ul << 31) | (1ul << 30) | (1ul << 0)); + + status = acpi_video_device_set_state(dev, state); + + if (status) + return -EFAULT; + + return count; +} + +static int +acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset) +{ + struct acpi_video_device *dev = seq->private; + int i; + + + if (!dev || !dev->brightness) { + seq_printf(seq, "\n"); + return 0; + } + + seq_printf(seq, "levels: "); + for (i = 2; i < dev->brightness->count; i++) + seq_printf(seq, " %d", dev->brightness->levels[i]); + seq_printf(seq, "\ncurrent: %d\n", dev->brightness->curr); + + return 0; +} + +static int +acpi_video_device_brightness_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_video_device_brightness_seq_show, + PDE(inode)->data); +} + +static ssize_t +acpi_video_device_write_brightness(struct file *file, + const char __user * buffer, + size_t count, loff_t * data) +{ + struct seq_file *m = file->private_data; + struct acpi_video_device *dev = m->private; + char str[5] = { 0 }; + unsigned int level = 0; + int i; + + + if (!dev || !dev->brightness || count >= sizeof(str)) + return -EINVAL; + + if (copy_from_user(str, buffer, count)) + return -EFAULT; + + str[count] = 0; + level = simple_strtoul(str, NULL, 0); + + if (level > 100) + return -EFAULT; + + /* validate through the list of available levels */ + for (i = 2; i < dev->brightness->count; i++) + if (level == dev->brightness->levels[i]) { + if (!acpi_video_device_lcd_set_level(dev, level)) + return count; + break; + } + + return -EINVAL; +} + +static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset) +{ + struct acpi_video_device *dev = seq->private; + int status; + int i; + union acpi_object *edid = NULL; + + + if (!dev) + goto out; + + status = acpi_video_device_EDID(dev, &edid, 128); + if (ACPI_FAILURE(status)) { + status = acpi_video_device_EDID(dev, &edid, 256); + } + + if (ACPI_FAILURE(status)) { + goto out; + } + + if (edid && edid->type == ACPI_TYPE_BUFFER) { + for (i = 0; i < edid->buffer.length; i++) + seq_putc(seq, edid->buffer.pointer[i]); + } + + out: + if (!edid) + seq_printf(seq, "\n"); + else + kfree(edid); + + return 0; +} + +static int +acpi_video_device_EDID_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_video_device_EDID_seq_show, + PDE(inode)->data); +} + +static int acpi_video_device_add_fs(struct acpi_device *device) +{ + struct proc_dir_entry *entry, *device_dir; + struct acpi_video_device *vid_dev; + + vid_dev = acpi_driver_data(device); + if (!vid_dev) + return -ENODEV; + + device_dir = proc_mkdir(acpi_device_bid(device), + vid_dev->video->dir); + if (!device_dir) + return -ENOMEM; + + /* 'info' [R] */ + entry = proc_create_data("info", S_IRUGO, device_dir, + &acpi_video_device_info_fops, acpi_driver_data(device)); + if (!entry) + goto err_remove_dir; + + /* 'state' [R/W] */ + entry = proc_create_data("state", S_IFREG | S_IRUGO | S_IWUSR, + device_dir, + &acpi_video_device_state_fops, + acpi_driver_data(device)); + if (!entry) + goto err_remove_info; + + /* 'brightness' [R/W] */ + entry = proc_create_data("brightness", S_IFREG | S_IRUGO | S_IWUSR, + device_dir, + &acpi_video_device_brightness_fops, + acpi_driver_data(device)); + if (!entry) + goto err_remove_state; + + /* 'EDID' [R] */ + entry = proc_create_data("EDID", S_IRUGO, device_dir, + &acpi_video_device_EDID_fops, + acpi_driver_data(device)); + if (!entry) + goto err_remove_brightness; + + acpi_device_dir(device) = device_dir; + + return 0; + + err_remove_brightness: + remove_proc_entry("brightness", device_dir); + err_remove_state: + remove_proc_entry("state", device_dir); + err_remove_info: + remove_proc_entry("info", device_dir); + err_remove_dir: + remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir); + return -ENOMEM; +} + +static int acpi_video_device_remove_fs(struct acpi_device *device) +{ + struct acpi_video_device *vid_dev; + struct proc_dir_entry *device_dir; + + vid_dev = acpi_driver_data(device); + if (!vid_dev || !vid_dev->video || !vid_dev->video->dir) + return -ENODEV; + + device_dir = acpi_device_dir(device); + if (device_dir) { + remove_proc_entry("info", device_dir); + remove_proc_entry("state", device_dir); + remove_proc_entry("brightness", device_dir); + remove_proc_entry("EDID", device_dir); + remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir); + acpi_device_dir(device) = NULL; + } + + return 0; +} + +/* video bus */ +static int acpi_video_bus_info_seq_show(struct seq_file *seq, void *offset) +{ + struct acpi_video_bus *video = seq->private; + + + if (!video) + goto end; + + seq_printf(seq, "Switching heads: %s\n", + video->flags.multihead ? "yes" : "no"); + seq_printf(seq, "Video ROM: %s\n", + video->flags.rom ? "yes" : "no"); + seq_printf(seq, "Device to be POSTed on boot: %s\n", + video->flags.post ? "yes" : "no"); + + end: + return 0; +} + +static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_video_bus_info_seq_show, + PDE(inode)->data); +} + +static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset) +{ + struct acpi_video_bus *video = seq->private; + + + if (!video) + goto end; + + printk(KERN_INFO PREFIX "Please implement %s\n", __func__); + seq_printf(seq, "\n"); + + end: + return 0; +} + +static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_video_bus_ROM_seq_show, PDE(inode)->data); +} + +static int +acpi_video_bus_POST_options(struct acpi_video_bus *video, + unsigned long long *options) +{ + int status; + + status = acpi_evaluate_integer(video->device->handle, "_VPO", + NULL, options); + *options &= 3; + + return status; +} + +static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset) +{ + struct acpi_video_bus *video = seq->private; + unsigned long long options; + int status; + + + if (!video) + goto end; + + status = acpi_video_bus_POST_options(video, &options); + if (ACPI_SUCCESS(status)) { + if (!(options & 1)) { + printk(KERN_WARNING PREFIX + "The motherboard VGA device is not listed as a possible POST device.\n"); + printk(KERN_WARNING PREFIX + "This indicates a BIOS bug. Please contact the manufacturer.\n"); + } + printk(KERN_WARNING "%llx\n", options); + seq_printf(seq, "can POST: "); + if (options & 2) + seq_printf(seq, " "); + if (options & 4) + seq_printf(seq, " "); + seq_putc(seq, '\n'); + } else + seq_printf(seq, "\n"); + end: + return 0; +} + +static int +acpi_video_bus_POST_info_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_video_bus_POST_info_seq_show, + PDE(inode)->data); +} + +static int +acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long long *id) +{ + int status; + + status = acpi_evaluate_integer(video->device->handle, "_GPD", NULL, id); + + return status; +} + +static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset) +{ + struct acpi_video_bus *video = seq->private; + int status; + unsigned long long id; + + + if (!video) + goto end; + + status = acpi_video_bus_get_POST(video, &id); + if (!ACPI_SUCCESS(status)) { + seq_printf(seq, "\n"); + goto end; + } + seq_printf(seq, "device POSTed is <%s>\n", device_decode[id & 3]); + + end: + return 0; +} + +static int acpi_video_bus_DOS_seq_show(struct seq_file *seq, void *offset) +{ + struct acpi_video_bus *video = seq->private; + + + seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting); + + return 0; +} + +static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_video_bus_POST_seq_show, + PDE(inode)->data); +} + +static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_video_bus_DOS_seq_show, PDE(inode)->data); +} + +static int +acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option) +{ + int status; + unsigned long long tmp; + union acpi_object arg0 = { ACPI_TYPE_INTEGER }; + struct acpi_object_list args = { 1, &arg0 }; + + + arg0.integer.value = option; + + status = acpi_evaluate_integer(video->device->handle, "_SPD", + &args, &tmp); + if (ACPI_SUCCESS(status)) + status = tmp ? (-EINVAL) : (AE_OK); + + return status; +} + +static ssize_t +acpi_video_bus_write_POST(struct file *file, + const char __user * buffer, + size_t count, loff_t * data) +{ + int status; + struct seq_file *m = file->private_data; + struct acpi_video_bus *video = m->private; + char str[12] = { 0 }; + unsigned long long opt, options; + + + if (!video || count >= sizeof(str)) + return -EINVAL; + + status = acpi_video_bus_POST_options(video, &options); + if (!ACPI_SUCCESS(status)) + return -EINVAL; + + if (copy_from_user(str, buffer, count)) + return -EFAULT; + + str[count] = 0; + opt = strtoul(str, NULL, 0); + if (opt > 3) + return -EFAULT; + + /* just in case an OEM 'forgot' the motherboard... */ + options |= 1; + + if (options & (1ul << opt)) { + status = acpi_video_bus_set_POST(video, opt); + if (!ACPI_SUCCESS(status)) + return -EFAULT; + + } + + return count; +} + +static ssize_t +acpi_video_bus_write_DOS(struct file *file, + const char __user * buffer, + size_t count, loff_t * data) +{ + int status; + struct seq_file *m = file->private_data; + struct acpi_video_bus *video = m->private; + char str[12] = { 0 }; + unsigned long opt; + + + if (!video || count >= sizeof(str)) + return -EINVAL; + + if (copy_from_user(str, buffer, count)) + return -EFAULT; + + str[count] = 0; + opt = strtoul(str, NULL, 0); + if (opt > 7) + return -EFAULT; + + status = acpi_video_bus_DOS(video, opt & 0x3, (opt & 0x4) >> 2); + + if (!ACPI_SUCCESS(status)) + return -EFAULT; + + return count; +} + +static int acpi_video_bus_add_fs(struct acpi_device *device) +{ + struct acpi_video_bus *video = acpi_driver_data(device); + struct proc_dir_entry *device_dir; + struct proc_dir_entry *entry; + + device_dir = proc_mkdir(acpi_device_bid(device), acpi_video_dir); + if (!device_dir) + return -ENOMEM; + + /* 'info' [R] */ + entry = proc_create_data("info", S_IRUGO, device_dir, + &acpi_video_bus_info_fops, + acpi_driver_data(device)); + if (!entry) + goto err_remove_dir; + + /* 'ROM' [R] */ + entry = proc_create_data("ROM", S_IRUGO, device_dir, + &acpi_video_bus_ROM_fops, + acpi_driver_data(device)); + if (!entry) + goto err_remove_info; + + /* 'POST_info' [R] */ + entry = proc_create_data("POST_info", S_IRUGO, device_dir, + &acpi_video_bus_POST_info_fops, + acpi_driver_data(device)); + if (!entry) + goto err_remove_rom; + + /* 'POST' [R/W] */ + entry = proc_create_data("POST", S_IFREG | S_IRUGO | S_IWUSR, + device_dir, + &acpi_video_bus_POST_fops, + acpi_driver_data(device)); + if (!entry) + goto err_remove_post_info; + + /* 'DOS' [R/W] */ + entry = proc_create_data("DOS", S_IFREG | S_IRUGO | S_IWUSR, + device_dir, + &acpi_video_bus_DOS_fops, + acpi_driver_data(device)); + if (!entry) + goto err_remove_post; + + video->dir = acpi_device_dir(device) = device_dir; + return 0; + + err_remove_post: + remove_proc_entry("POST", device_dir); + err_remove_post_info: + remove_proc_entry("POST_info", device_dir); + err_remove_rom: + remove_proc_entry("ROM", device_dir); + err_remove_info: + remove_proc_entry("info", device_dir); + err_remove_dir: + remove_proc_entry(acpi_device_bid(device), acpi_video_dir); + return -ENOMEM; +} + +static int acpi_video_bus_remove_fs(struct acpi_device *device) +{ + struct proc_dir_entry *device_dir = acpi_device_dir(device); + + if (device_dir) { + remove_proc_entry("info", device_dir); + remove_proc_entry("ROM", device_dir); + remove_proc_entry("POST_info", device_dir); + remove_proc_entry("POST", device_dir); + remove_proc_entry("DOS", device_dir); + remove_proc_entry(acpi_device_bid(device), acpi_video_dir); + acpi_device_dir(device) = NULL; + } + + return 0; +} +#else +static inline int acpi_video_device_add_fs(struct acpi_device *device) +{ + return 0; +} +static inline int acpi_video_device_remove_fs(struct acpi_device *device) +{ + return 0; +} +static inline int acpi_video_bus_add_fs(struct acpi_device *device) +{ + return 0; +} +static inline int acpi_video_bus_remove_fs(struct acpi_device *device) +{ + return 0; +} +#endif /* CONFIG_ACPI_PROCFS */ + /* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */ @@ -1130,6 +1877,8 @@ acpi_video_bus_get_one_device(struct acpi_device *device, list_add_tail(&data->entry, &video->video_device_list); mutex_unlock(&video->device_list_lock); + acpi_video_device_add_fs(device); + return 0; } @@ -1432,6 +2181,8 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) if (!device || !device->video) return -ENOENT; + acpi_video_device_remove_fs(device->dev); + status = acpi_remove_notify_handler(device->dev->handle, ACPI_DEVICE_NOTIFY, acpi_video_device_notify); @@ -1715,6 +2466,10 @@ static int acpi_video_bus_add(struct acpi_device *device) if (error) goto err_free_video; + error = acpi_video_bus_add_fs(device); + if (error) + goto err_free_video; + mutex_init(&video->device_list_lock); INIT_LIST_HEAD(&video->video_device_list); @@ -1767,6 +2522,7 @@ static int acpi_video_bus_add(struct acpi_device *device) acpi_video_bus_stop_devices(video); acpi_video_bus_put_devices(video); kfree(video->attached_array); + acpi_video_bus_remove_fs(device); err_free_video: kfree(video); device->driver_data = NULL; @@ -1788,6 +2544,7 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type) acpi_video_bus_stop_devices(video); acpi_video_bus_put_devices(video); + acpi_video_bus_remove_fs(device); input_unregister_device(video->input); kfree(video->attached_array); @@ -1827,9 +2584,17 @@ int acpi_video_register(void) return 0; } +#ifdef CONFIG_ACPI_PROCFS + acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir); + if (!acpi_video_dir) + return -ENODEV; +#endif + result = acpi_bus_register_driver(&acpi_video_bus); - if (result < 0) + if (result < 0) { + remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir); return -ENODEV; + } /* * When the acpi_video_bus is loaded successfully, increase @@ -1852,6 +2617,10 @@ void acpi_video_unregister(void) } acpi_bus_unregister_driver(&acpi_video_bus); +#ifdef CONFIG_ACPI_PROCFS + remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir); +#endif + register_count = 0; return; diff --git a/trunk/drivers/block/ps3disk.c b/trunk/drivers/block/ps3disk.c index 03688c2da319..e9da874d0419 100644 --- a/trunk/drivers/block/ps3disk.c +++ b/trunk/drivers/block/ps3disk.c @@ -113,7 +113,7 @@ static void ps3disk_scatter_gather(struct ps3_storage_device *dev, memcpy(buf, dev->bounce_buf+offset, size); offset += size; flush_kernel_dcache_page(bvec->bv_page); - bvec_kunmap_irq(buf, &flags); + bvec_kunmap_irq(bvec, &flags); i++; } } diff --git a/trunk/drivers/char/virtio_console.c b/trunk/drivers/char/virtio_console.c index 0f69c5ec0ecd..c810481a5bc2 100644 --- a/trunk/drivers/char/virtio_console.c +++ b/trunk/drivers/char/virtio_console.c @@ -459,12 +459,9 @@ static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count, /* * Wait till the host acknowledges it pushed out the data we - * sent. This is done for data from the hvc_console; the tty - * operations are performed with spinlocks held so we can't - * sleep here. An alternative would be to copy the data to a - * buffer and relax the spinning requirement. The downside is - * we need to kmalloc a GFP_ATOMIC buffer each time the - * console driver writes something out. + * sent. This is done for ports in blocking mode or for data + * from the hvc_console; the tty operations are performed with + * spinlocks held so we can't sleep here. */ while (!virtqueue_get_buf(out_vq, &len)) cpu_relax(); @@ -629,14 +626,6 @@ static ssize_t port_fops_write(struct file *filp, const char __user *ubuf, goto free_buf; } - /* - * We now ask send_buf() to not spin for generic ports -- we - * can re-use the same code path that non-blocking file - * descriptors take for blocking file descriptors since the - * wait is already done and we're certain the write will go - * through to the host. - */ - nonblock = true; ret = send_buf(port, buf, count, nonblock); if (nonblock && ret > 0) diff --git a/trunk/drivers/firewire/ohci.c b/trunk/drivers/firewire/ohci.c index 9dcb17d51aee..1b05896648bc 100644 --- a/trunk/drivers/firewire/ohci.c +++ b/trunk/drivers/firewire/ohci.c @@ -2840,7 +2840,7 @@ static int __devinit pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { struct fw_ohci *ohci; - u32 bus_options, max_receive, link_speed, version; + u32 bus_options, max_receive, link_speed, version, link_enh; u64 guid; int i, err, n_ir, n_it; size_t size; @@ -2894,6 +2894,23 @@ static int __devinit pci_probe(struct pci_dev *dev, if (param_quirks) ohci->quirks = param_quirks; + /* TI OHCI-Lynx and compatible: set recommended configuration bits. */ + if (dev->vendor == PCI_VENDOR_ID_TI) { + pci_read_config_dword(dev, PCI_CFG_TI_LinkEnh, &link_enh); + + /* adjust latency of ATx FIFO: use 1.7 KB threshold */ + link_enh &= ~TI_LinkEnh_atx_thresh_mask; + link_enh |= TI_LinkEnh_atx_thresh_1_7K; + + /* use priority arbitration for asynchronous responses */ + link_enh |= TI_LinkEnh_enab_unfair; + + /* required for aPhyEnhanceEnable to work */ + link_enh |= TI_LinkEnh_enab_accel; + + pci_write_config_dword(dev, PCI_CFG_TI_LinkEnh, link_enh); + } + ar_context_init(&ohci->ar_request_ctx, ohci, OHCI1394_AsReqRcvContextControlSet); diff --git a/trunk/drivers/firewire/ohci.h b/trunk/drivers/firewire/ohci.h index ef5e7336da68..0e6c5a466908 100644 --- a/trunk/drivers/firewire/ohci.h +++ b/trunk/drivers/firewire/ohci.h @@ -155,4 +155,12 @@ #define OHCI1394_phy_tcode 0xe +/* TI extensions */ + +#define PCI_CFG_TI_LinkEnh 0xf4 +#define TI_LinkEnh_enab_accel 0x00000002 +#define TI_LinkEnh_enab_unfair 0x00000080 +#define TI_LinkEnh_atx_thresh_mask 0x00003000 +#define TI_LinkEnh_atx_thresh_1_7K 0x00001000 + #endif /* _FIREWIRE_OHCI_H */ diff --git a/trunk/drivers/gpu/drm/radeon/radeon_cursor.c b/trunk/drivers/gpu/drm/radeon/radeon_cursor.c index 3eef567b0421..5731fc9b1ae3 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_cursor.c @@ -203,7 +203,6 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct radeon_device *rdev = crtc->dev->dev_private; int xorigin = 0, yorigin = 0; - int w = radeon_crtc->cursor_width; if (x < 0) xorigin = -x + 1; @@ -214,7 +213,22 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, if (yorigin >= CURSOR_HEIGHT) yorigin = CURSOR_HEIGHT - 1; - if (ASIC_IS_AVIVO(rdev)) { + radeon_lock_cursor(crtc, true); + if (ASIC_IS_DCE4(rdev)) { + /* cursors are offset into the total surface */ + x += crtc->x; + y += crtc->y; + DRM_DEBUG("x %d y %d c->x %d c->y %d\n", x, y, crtc->x, crtc->y); + + /* XXX: check if evergreen has the same issues as avivo chips */ + WREG32(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset, + ((xorigin ? 0 : x) << 16) | + (yorigin ? 0 : y)); + WREG32(EVERGREEN_CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin); + WREG32(EVERGREEN_CUR_SIZE + radeon_crtc->crtc_offset, + ((radeon_crtc->cursor_width - 1) << 16) | (radeon_crtc->cursor_height - 1)); + } else if (ASIC_IS_AVIVO(rdev)) { + int w = radeon_crtc->cursor_width; int i = 0; struct drm_crtc *crtc_p; @@ -246,17 +260,7 @@ int radeon_crtc_cursor_move(struct drm_crtc *crtc, if (w <= 0) w = 1; } - } - radeon_lock_cursor(crtc, true); - if (ASIC_IS_DCE4(rdev)) { - WREG32(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset, - ((xorigin ? 0 : x) << 16) | - (yorigin ? 0 : y)); - WREG32(EVERGREEN_CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin); - WREG32(EVERGREEN_CUR_SIZE + radeon_crtc->crtc_offset, - ((w - 1) << 16) | (radeon_crtc->cursor_height - 1)); - } else if (ASIC_IS_AVIVO(rdev)) { WREG32(AVIVO_D1CUR_POSITION + radeon_crtc->crtc_offset, ((xorigin ? 0 : x) << 16) | (yorigin ? 0 : y)); diff --git a/trunk/drivers/hid/hid-cando.c b/trunk/drivers/hid/hid-cando.c index 5925bdcd417d..4267a6fdc277 100644 --- a/trunk/drivers/hid/hid-cando.c +++ b/trunk/drivers/hid/hid-cando.c @@ -237,8 +237,6 @@ static const struct hid_device_id cando_devices[] = { USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, - { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, - USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, { } }; MODULE_DEVICE_TABLE(hid, cando_devices); diff --git a/trunk/drivers/hid/hid-core.c b/trunk/drivers/hid/hid-core.c index a0dea3d1296e..3f7292486024 100644 --- a/trunk/drivers/hid/hid-core.c +++ b/trunk/drivers/hid/hid-core.c @@ -1292,7 +1292,6 @@ static const struct hid_device_id hid_blacklist[] = { { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) }, { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, - { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, diff --git a/trunk/drivers/hid/hid-ids.h b/trunk/drivers/hid/hid-ids.h index c5ae5f1545bd..765a4f53eb5c 100644 --- a/trunk/drivers/hid/hid-ids.h +++ b/trunk/drivers/hid/hid-ids.h @@ -134,7 +134,6 @@ #define USB_VENDOR_ID_CANDO 0x2087 #define USB_DEVICE_ID_CANDO_MULTI_TOUCH 0x0a01 #define USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6 0x0b03 -#define USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6 0x0f01 #define USB_VENDOR_ID_CH 0x068e #define USB_DEVICE_ID_CH_PRO_PEDALS 0x00f2 @@ -504,7 +503,6 @@ #define USB_VENDOR_ID_TURBOX 0x062a #define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201 -#define USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART 0x7100 #define USB_VENDOR_ID_TWINHAN 0x6253 #define USB_DEVICE_ID_TWINHAN_IR_REMOTE 0x0100 diff --git a/trunk/drivers/hid/hidraw.c b/trunk/drivers/hid/hidraw.c index a3866b5c0c43..47d70c523d93 100644 --- a/trunk/drivers/hid/hidraw.c +++ b/trunk/drivers/hid/hidraw.c @@ -109,12 +109,6 @@ static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t int ret = 0; mutex_lock(&minors_lock); - - if (!hidraw_table[minor]) { - ret = -ENODEV; - goto out; - } - dev = hidraw_table[minor]->hid; if (!dev->hid_output_raw_report) { @@ -250,10 +244,6 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd, mutex_lock(&minors_lock); dev = hidraw_table[minor]; - if (!dev) { - ret = -ENODEV; - goto out; - } switch (cmd) { case HIDIOCGRDESCSIZE: @@ -327,7 +317,6 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd, ret = -ENOTTY; } -out: mutex_unlock(&minors_lock); return ret; } diff --git a/trunk/drivers/hid/usbhid/hid-quirks.c b/trunk/drivers/hid/usbhid/hid-quirks.c index f0260c699adb..70da3181c8a0 100644 --- a/trunk/drivers/hid/usbhid/hid-quirks.c +++ b/trunk/drivers/hid/usbhid/hid-quirks.c @@ -36,7 +36,6 @@ static const struct hid_blacklist { { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER, HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET }, { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER, HID_QUIRK_MULTI_INPUT }, - { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, diff --git a/trunk/drivers/i2c/busses/i2c-davinci.c b/trunk/drivers/i2c/busses/i2c-davinci.c index 5795c8398c7c..b8feac5f2ef4 100644 --- a/trunk/drivers/i2c/busses/i2c-davinci.c +++ b/trunk/drivers/i2c/busses/i2c-davinci.c @@ -331,16 +331,21 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) INIT_COMPLETION(dev->cmd_complete); dev->cmd_err = 0; - /* Take I2C out of reset and configure it as master */ - flag = DAVINCI_I2C_MDR_IRS | DAVINCI_I2C_MDR_MST; + /* Take I2C out of reset, configure it as master and set the + * start bit */ + flag = DAVINCI_I2C_MDR_IRS | DAVINCI_I2C_MDR_MST | DAVINCI_I2C_MDR_STT; /* if the slave address is ten bit address, enable XA bit */ if (msg->flags & I2C_M_TEN) flag |= DAVINCI_I2C_MDR_XA; if (!(msg->flags & I2C_M_RD)) flag |= DAVINCI_I2C_MDR_TRX; - if (msg->len == 0) + if (stop) + flag |= DAVINCI_I2C_MDR_STP; + if (msg->len == 0) { flag |= DAVINCI_I2C_MDR_RM; + flag &= ~DAVINCI_I2C_MDR_STP; + } /* Enable receive or transmit interrupts */ w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG); @@ -352,29 +357,18 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) dev->terminate = 0; - /* - * Write mode register first as needed for correct behaviour - * on OMAP-L138, but don't set STT yet to avoid a race with XRDY - * occuring before we have loaded DXR - */ - davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); - /* * First byte should be set here, not after interrupt, * because transmit-data-ready interrupt can come before * NACK-interrupt during sending of previous message and * ICDXR may have wrong data - * It also saves us one interrupt, slightly faster */ if ((!(msg->flags & I2C_M_RD)) && dev->buf_len) { davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev->buf++); dev->buf_len--; } - /* Set STT to begin transmit now DXR is loaded */ - flag |= DAVINCI_I2C_MDR_STT; - if (stop && msg->len != 0) - flag |= DAVINCI_I2C_MDR_STP; + /* write the data into mode register; start transmitting */ davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); r = wait_for_completion_interruptible_timeout(&dev->cmd_complete, diff --git a/trunk/drivers/i2c/busses/i2c-imx.c b/trunk/drivers/i2c/busses/i2c-imx.c index 4c2a62b75b5c..d1ff9408dc1f 100644 --- a/trunk/drivers/i2c/busses/i2c-imx.c +++ b/trunk/drivers/i2c/busses/i2c-imx.c @@ -159,9 +159,15 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy) static int i2c_imx_trx_complete(struct imx_i2c_struct *i2c_imx) { - wait_event_timeout(i2c_imx->queue, i2c_imx->i2csr & I2SR_IIF, HZ / 10); + int result; + + result = wait_event_interruptible_timeout(i2c_imx->queue, + i2c_imx->i2csr & I2SR_IIF, HZ / 10); - if (unlikely(!(i2c_imx->i2csr & I2SR_IIF))) { + if (unlikely(result < 0)) { + dev_dbg(&i2c_imx->adapter.dev, "<%s> result < 0\n", __func__); + return result; + } else if (unlikely(!(i2c_imx->i2csr & I2SR_IIF))) { dev_dbg(&i2c_imx->adapter.dev, "<%s> Timeout\n", __func__); return -ETIMEDOUT; } @@ -289,7 +295,7 @@ static irqreturn_t i2c_imx_isr(int irq, void *dev_id) i2c_imx->i2csr = temp; temp &= ~I2SR_IIF; writeb(temp, i2c_imx->base + IMX_I2C_I2SR); - wake_up(&i2c_imx->queue); + wake_up_interruptible(&i2c_imx->queue); return IRQ_HANDLED; } diff --git a/trunk/drivers/input/evdev.c b/trunk/drivers/input/evdev.c index 9ddafc30f432..c908c5f83645 100644 --- a/trunk/drivers/input/evdev.c +++ b/trunk/drivers/input/evdev.c @@ -669,9 +669,6 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) { - if (!dev->absinfo) - return -EINVAL; - t = _IOC_NR(cmd) & ABS_MAX; abs = dev->absinfo[t]; @@ -683,13 +680,10 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, } } - if (_IOC_DIR(cmd) == _IOC_WRITE) { + if (_IOC_DIR(cmd) == _IOC_READ) { if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) { - if (!dev->absinfo) - return -EINVAL; - t = _IOC_NR(cmd) & ABS_MAX; if (copy_from_user(&abs, p, min_t(size_t, diff --git a/trunk/drivers/media/video/v4l2-compat-ioctl32.c b/trunk/drivers/media/video/v4l2-compat-ioctl32.c index 86294ed35c9b..073f01390cdd 100644 --- a/trunk/drivers/media/video/v4l2-compat-ioctl32.c +++ b/trunk/drivers/media/video/v4l2-compat-ioctl32.c @@ -193,24 +193,17 @@ static int put_video_window32(struct video_window *kp, struct video_window32 __u struct video_code32 { char loadwhat[16]; /* name or tag of file being passed */ compat_int_t datasize; - compat_uptr_t data; + unsigned char *data; }; -static struct video_code __user *get_microcode32(struct video_code32 *kp) +static int get_microcode32(struct video_code *kp, struct video_code32 __user *up) { - struct video_code __user *up; - - up = compat_alloc_user_space(sizeof(*up)); - - /* - * NOTE! We don't actually care if these fail. If the - * user address is invalid, the native ioctl will do - * the error handling for us - */ - (void) copy_to_user(up->loadwhat, kp->loadwhat, sizeof(up->loadwhat)); - (void) put_user(kp->datasize, &up->datasize); - (void) put_user(compat_ptr(kp->data), &up->data); - return up; + if (!access_ok(VERIFY_READ, up, sizeof(struct video_code32)) || + copy_from_user(kp->loadwhat, up->loadwhat, sizeof(up->loadwhat)) || + get_user(kp->datasize, &up->datasize) || + copy_from_user(kp->data, up->data, up->datasize)) + return -EFAULT; + return 0; } #define VIDIOCGTUNER32 _IOWR('v', 4, struct video_tuner32) @@ -746,7 +739,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar struct video_tuner vt; struct video_buffer vb; struct video_window vw; - struct video_code32 vc; + struct video_code vc; struct video_audio va; #endif struct v4l2_format v2f; @@ -825,11 +818,8 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar break; case VIDIOCSMICROCODE: - /* Copy the 32-bit "video_code32" to kernel space */ - if (copy_from_user(&karg.vc, up, sizeof(karg.vc))) - return -EFAULT; - /* Convert the 32-bit version to a 64-bit version in user space */ - up = get_microcode32(&karg.vc); + err = get_microcode32(&karg.vc, up); + compatible_arg = 0; break; case VIDIOCSFREQ: diff --git a/trunk/drivers/mmc/core/core.c b/trunk/drivers/mmc/core/core.c index 09eee6df0653..5db49b124ffa 100644 --- a/trunk/drivers/mmc/core/core.c +++ b/trunk/drivers/mmc/core/core.c @@ -1631,19 +1631,6 @@ int mmc_suspend_host(struct mmc_host *host) if (host->bus_ops && !host->bus_dead) { if (host->bus_ops->suspend) err = host->bus_ops->suspend(host); - if (err == -ENOSYS || !host->bus_ops->resume) { - /* - * We simply "remove" the card in this case. - * It will be redetected on resume. - */ - if (host->bus_ops->remove) - host->bus_ops->remove(host); - mmc_claim_host(host); - mmc_detach_bus(host); - mmc_release_host(host); - host->pm_flags = 0; - err = 0; - } } mmc_bus_put(host); diff --git a/trunk/drivers/mtd/nand/mxc_nand.c b/trunk/drivers/mtd/nand/mxc_nand.c index 214b03afdd48..b2828e84d243 100644 --- a/trunk/drivers/mtd/nand/mxc_nand.c +++ b/trunk/drivers/mtd/nand/mxc_nand.c @@ -30,8 +30,6 @@ #include #include #include -#include -#include #include #include @@ -153,7 +151,7 @@ struct mxc_nand_host { int irq; int eccsize; - struct completion op_completion; + wait_queue_head_t irq_waitq; uint8_t *data_buf; unsigned int buf_start; @@ -166,7 +164,6 @@ struct mxc_nand_host { void (*send_read_id)(struct mxc_nand_host *); uint16_t (*get_dev_status)(struct mxc_nand_host *); int (*check_int)(struct mxc_nand_host *); - void (*irq_control)(struct mxc_nand_host *, int); }; /* OOB placement block for use with hardware ecc generation */ @@ -219,12 +216,9 @@ static irqreturn_t mxc_nfc_irq(int irq, void *dev_id) { struct mxc_nand_host *host = dev_id; - if (!host->check_int(host)) - return IRQ_NONE; + disable_irq_nosync(irq); - host->irq_control(host, 0); - - complete(&host->op_completion); + wake_up(&host->irq_waitq); return IRQ_HANDLED; } @@ -251,54 +245,11 @@ static int check_int_v1_v2(struct mxc_nand_host *host) if (!(tmp & NFC_V1_V2_CONFIG2_INT)) return 0; - if (!cpu_is_mx21()) - writew(tmp & ~NFC_V1_V2_CONFIG2_INT, NFC_V1_V2_CONFIG2); + writew(tmp & ~NFC_V1_V2_CONFIG2_INT, NFC_V1_V2_CONFIG2); return 1; } -/* - * It has been observed that the i.MX21 cannot read the CONFIG2:INT bit - * if interrupts are masked (CONFIG1:INT_MSK is set). To handle this, the - * driver can enable/disable the irq line rather than simply masking the - * interrupts. - */ -static void irq_control_mx21(struct mxc_nand_host *host, int activate) -{ - if (activate) - enable_irq(host->irq); - else - disable_irq_nosync(host->irq); -} - -static void irq_control_v1_v2(struct mxc_nand_host *host, int activate) -{ - uint16_t tmp; - - tmp = readw(NFC_V1_V2_CONFIG1); - - if (activate) - tmp &= ~NFC_V1_V2_CONFIG1_INT_MSK; - else - tmp |= NFC_V1_V2_CONFIG1_INT_MSK; - - writew(tmp, NFC_V1_V2_CONFIG1); -} - -static void irq_control_v3(struct mxc_nand_host *host, int activate) -{ - uint32_t tmp; - - tmp = readl(NFC_V3_CONFIG2); - - if (activate) - tmp &= ~NFC_V3_CONFIG2_INT_MSK; - else - tmp |= NFC_V3_CONFIG2_INT_MSK; - - writel(tmp, NFC_V3_CONFIG2); -} - /* This function polls the NANDFC to wait for the basic operation to * complete by checking the INT bit of config2 register. */ @@ -308,9 +259,10 @@ static void wait_op_done(struct mxc_nand_host *host, int useirq) if (useirq) { if (!host->check_int(host)) { - INIT_COMPLETION(host->op_completion); - host->irq_control(host, 1); - wait_for_completion(&host->op_completion); + + enable_irq(host->irq); + + wait_event(host->irq_waitq, host->check_int(host)); } } else { while (max_retries-- > 0) { @@ -847,7 +799,6 @@ static void preset_v3(struct mtd_info *mtd) NFC_V3_CONFIG2_2CMD_PHASES | NFC_V3_CONFIG2_SPAS(mtd->oobsize >> 1) | NFC_V3_CONFIG2_ST_CMD(0x70) | - NFC_V3_CONFIG2_INT_MSK | NFC_V3_CONFIG2_NUM_ADDR_PHASE0; if (chip->ecc.mode == NAND_ECC_HW) @@ -1073,10 +1024,6 @@ static int __init mxcnd_probe(struct platform_device *pdev) host->send_read_id = send_read_id_v1_v2; host->get_dev_status = get_dev_status_v1_v2; host->check_int = check_int_v1_v2; - if (cpu_is_mx21()) - host->irq_control = irq_control_mx21; - else - host->irq_control = irq_control_v1_v2; } if (nfc_is_v21()) { @@ -1115,7 +1062,6 @@ static int __init mxcnd_probe(struct platform_device *pdev) host->send_read_id = send_read_id_v3; host->check_int = check_int_v3; host->get_dev_status = get_dev_status_v3; - host->irq_control = irq_control_v3; oob_smallpage = &nandv2_hw_eccoob_smallpage; oob_largepage = &nandv2_hw_eccoob_largepage; } else @@ -1147,34 +1093,14 @@ static int __init mxcnd_probe(struct platform_device *pdev) this->options |= NAND_USE_FLASH_BBT; } - init_completion(&host->op_completion); + init_waitqueue_head(&host->irq_waitq); host->irq = platform_get_irq(pdev, 0); - /* - * mask the interrupt. For i.MX21 explicitely call - * irq_control_v1_v2 to use the mask bit. We can't call - * disable_irq_nosync() for an interrupt we do not own yet. - */ - if (cpu_is_mx21()) - irq_control_v1_v2(host, 0); - else - host->irq_control(host, 0); - err = request_irq(host->irq, mxc_nfc_irq, IRQF_DISABLED, DRIVER_NAME, host); if (err) goto eirq; - host->irq_control(host, 0); - - /* - * Now that the interrupt is disabled make sure the interrupt - * mask bit is cleared on i.MX21. Otherwise we can't read - * the interrupt status bit on this machine. - */ - if (cpu_is_mx21()) - irq_control_v1_v2(host, 1); - /* first scan to find the device and get the page size */ if (nand_scan_ident(mtd, 1, NULL)) { err = -ENXIO; diff --git a/trunk/drivers/pnp/base.h b/trunk/drivers/pnp/base.h index 19bc73695475..0bab84ebb15d 100644 --- a/trunk/drivers/pnp/base.h +++ b/trunk/drivers/pnp/base.h @@ -12,12 +12,11 @@ void pnp_unregister_protocol(struct pnp_protocol *protocol); #define PNP_EISA_ID_MASK 0x7fffffff void pnp_eisa_id_to_string(u32 id, char *str); -struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *, int id, - const char *pnpid); +struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *, int id, char *pnpid); struct pnp_card *pnp_alloc_card(struct pnp_protocol *, int id, char *pnpid); int pnp_add_device(struct pnp_dev *dev); -struct pnp_id *pnp_add_id(struct pnp_dev *dev, const char *id); +struct pnp_id *pnp_add_id(struct pnp_dev *dev, char *id); int pnp_add_card(struct pnp_card *card); void pnp_remove_card(struct pnp_card *card); diff --git a/trunk/drivers/pnp/core.c b/trunk/drivers/pnp/core.c index 0f34d962fd3c..88b3cde52596 100644 --- a/trunk/drivers/pnp/core.c +++ b/trunk/drivers/pnp/core.c @@ -124,8 +124,7 @@ static void pnp_release_device(struct device *dmdev) kfree(dev); } -struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, - const char *pnpid) +struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, char *pnpid) { struct pnp_dev *dev; struct pnp_id *dev_id; @@ -195,9 +194,8 @@ int pnp_add_device(struct pnp_dev *dev) for (id = dev->id; id; id = id->next) len += scnprintf(buf + len, sizeof(buf) - len, " %s", id->id); - dev_printk(KERN_DEBUG, &dev->dev, "%s device, IDs%s (%s)\n", - dev->protocol->name, buf, - dev->active ? "active" : "disabled"); + pnp_dbg(&dev->dev, "%s device, IDs%s (%s)\n", + dev->protocol->name, buf, dev->active ? "active" : "disabled"); return 0; } diff --git a/trunk/drivers/pnp/driver.c b/trunk/drivers/pnp/driver.c index d1dbb9df53fa..cd11b113494f 100644 --- a/trunk/drivers/pnp/driver.c +++ b/trunk/drivers/pnp/driver.c @@ -236,7 +236,7 @@ void pnp_unregister_driver(struct pnp_driver *drv) * @dev: pointer to the desired device * @id: pointer to an EISA id string */ -struct pnp_id *pnp_add_id(struct pnp_dev *dev, const char *id) +struct pnp_id *pnp_add_id(struct pnp_dev *dev, char *id) { struct pnp_id *dev_id, *ptr; diff --git a/trunk/drivers/pnp/pnpacpi/core.c b/trunk/drivers/pnp/pnpacpi/core.c index 2d73dfcecdbb..dc4e32e031e9 100644 --- a/trunk/drivers/pnp/pnpacpi/core.c +++ b/trunk/drivers/pnp/pnpacpi/core.c @@ -28,7 +28,7 @@ #include "../base.h" #include "pnpacpi.h" -static int num; +static int num = 0; /* We need only to blacklist devices that have already an acpi driver that * can't use pnp layer. We don't need to blacklist device that are directly @@ -59,7 +59,7 @@ static inline int __init is_exclusive_device(struct acpi_device *dev) #define TEST_ALPHA(c) \ if (!('@' <= (c) || (c) <= 'Z')) \ return 0 -static int __init ispnpidacpi(const char *id) +static int __init ispnpidacpi(char *id) { TEST_ALPHA(id[0]); TEST_ALPHA(id[1]); @@ -180,24 +180,11 @@ struct pnp_protocol pnpacpi_protocol = { }; EXPORT_SYMBOL(pnpacpi_protocol); -static char *pnpacpi_get_id(struct acpi_device *device) -{ - struct acpi_hardware_id *id; - - list_for_each_entry(id, &device->pnp.ids, list) { - if (ispnpidacpi(id->id)) - return id->id; - } - - return NULL; -} - static int __init pnpacpi_add_device(struct acpi_device *device) { acpi_handle temp = NULL; acpi_status status; struct pnp_dev *dev; - char *pnpid; struct acpi_hardware_id *id; /* @@ -205,17 +192,11 @@ static int __init pnpacpi_add_device(struct acpi_device *device) * driver should not be loaded. */ status = acpi_get_handle(device->handle, "_CRS", &temp); - if (ACPI_FAILURE(status)) - return 0; - - pnpid = pnpacpi_get_id(device); - if (!pnpid) - return 0; - - if (is_exclusive_device(device) || !device->status.present) + if (ACPI_FAILURE(status) || !ispnpidacpi(acpi_device_hid(device)) || + is_exclusive_device(device) || (!device->status.present)) return 0; - dev = pnp_alloc_dev(&pnpacpi_protocol, num, pnpid); + dev = pnp_alloc_dev(&pnpacpi_protocol, num, acpi_device_hid(device)); if (!dev) return -ENOMEM; @@ -246,7 +227,7 @@ static int __init pnpacpi_add_device(struct acpi_device *device) pnpacpi_parse_resource_option_data(dev); list_for_each_entry(id, &device->pnp.ids, list) { - if (!strcmp(id->id, pnpid)) + if (!strcmp(id->id, acpi_device_hid(device))) continue; if (!ispnpidacpi(id->id)) continue; diff --git a/trunk/drivers/pnp/resource.c b/trunk/drivers/pnp/resource.c index a925e6b63d72..e3446ab8b563 100644 --- a/trunk/drivers/pnp/resource.c +++ b/trunk/drivers/pnp/resource.c @@ -523,7 +523,7 @@ struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, res->start = irq; res->end = irq; - dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); + pnp_dbg(&dev->dev, " add %pr\n", res); return pnp_res; } @@ -544,7 +544,7 @@ struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma, res->start = dma; res->end = dma; - dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); + pnp_dbg(&dev->dev, " add %pr\n", res); return pnp_res; } @@ -568,7 +568,7 @@ struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev, res->start = start; res->end = end; - dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); + pnp_dbg(&dev->dev, " add %pr\n", res); return pnp_res; } @@ -592,7 +592,7 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, res->start = start; res->end = end; - dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); + pnp_dbg(&dev->dev, " add %pr\n", res); return pnp_res; } @@ -616,7 +616,7 @@ struct pnp_resource *pnp_add_bus_resource(struct pnp_dev *dev, res->start = start; res->end = end; - dev_printk(KERN_DEBUG, &dev->dev, "%pR\n", res); + pnp_dbg(&dev->dev, " add %pr\n", res); return pnp_res; } diff --git a/trunk/drivers/scsi/scsi.c b/trunk/drivers/scsi/scsi.c index 348fba0a8976..ad0ed212db4a 100644 --- a/trunk/drivers/scsi/scsi.c +++ b/trunk/drivers/scsi/scsi.c @@ -1046,13 +1046,13 @@ int scsi_get_vpd_page(struct scsi_device *sdev, u8 page, unsigned char *buf, /* If the user actually wanted this page, we can skip the rest */ if (page == 0) - return 0; + return -EINVAL; for (i = 0; i < min((int)buf[3], buf_len - 4); i++) if (buf[i + 4] == page) goto found; - if (i < buf[3] && i >= buf_len - 4) + if (i < buf[3] && i > buf_len) /* ran off the end of the buffer, give us benefit of doubt */ goto found; /* The device claims it doesn't support the requested page */ diff --git a/trunk/drivers/serial/ioc3_serial.c b/trunk/drivers/serial/ioc3_serial.c index 800c54602339..93de907b1208 100644 --- a/trunk/drivers/serial/ioc3_serial.c +++ b/trunk/drivers/serial/ioc3_serial.c @@ -2044,7 +2044,6 @@ ioc3uart_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd) if (!port) { printk(KERN_WARNING "IOC3 serial memory not available for port\n"); - ret = -ENOMEM; goto out4; } spin_lock_init(&port->ip_lock); diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index 6d2b6f936858..03278c984ba0 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -2024,7 +2024,6 @@ int dump_write(struct file *file, const void *addr, int nr) { return access_ok(VERIFY_READ, addr, nr) && file->f_op->write(file, addr, nr, &file->f_pos) == nr; } -EXPORT_SYMBOL(dump_write); int dump_seek(struct file *file, loff_t off) { @@ -2053,4 +2052,3 @@ int dump_seek(struct file *file, loff_t off) } return ret; } -EXPORT_SYMBOL(dump_seek); diff --git a/trunk/include/acpi/acpi_bus.h b/trunk/include/acpi/acpi_bus.h index 359ef11725a6..4de84ce3a927 100644 --- a/trunk/include/acpi/acpi_bus.h +++ b/trunk/include/acpi/acpi_bus.h @@ -184,7 +184,7 @@ struct acpi_device_pnp { #define acpi_device_bid(d) ((d)->pnp.bus_id) #define acpi_device_adr(d) ((d)->pnp.bus_address) -const char *acpi_device_hid(struct acpi_device *device); +char *acpi_device_hid(struct acpi_device *device); #define acpi_device_name(d) ((d)->pnp.device_name) #define acpi_device_class(d) ((d)->pnp.device_class) @@ -389,25 +389,21 @@ struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle); int acpi_enable_wakeup_device_power(struct acpi_device *dev, int state); int acpi_disable_wakeup_device_power(struct acpi_device *dev); -#ifdef CONFIG_PM_OPS +#ifdef CONFIG_PM_SLEEP int acpi_pm_device_sleep_state(struct device *, int *); -#else +int acpi_pm_device_sleep_wake(struct device *, bool); +#else /* !CONFIG_PM_SLEEP */ static inline int acpi_pm_device_sleep_state(struct device *d, int *p) { if (p) *p = ACPI_STATE_D0; return ACPI_STATE_D3; } -#endif - -#ifdef CONFIG_PM_SLEEP -int acpi_pm_device_sleep_wake(struct device *, bool); -#else static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable) { return -ENODEV; } -#endif +#endif /* !CONFIG_PM_SLEEP */ #endif /* CONFIG_ACPI */ diff --git a/trunk/include/acpi/acpiosxf.h b/trunk/include/acpi/acpiosxf.h index 43027432a055..29bf945143e8 100644 --- a/trunk/include/acpi/acpiosxf.h +++ b/trunk/include/acpi/acpiosxf.h @@ -223,15 +223,25 @@ acpi_os_write_memory(acpi_physical_address address, u32 value, u32 width); */ acpi_status acpi_os_read_pci_configuration(struct acpi_pci_id *pci_id, - u32 reg, u64 *value, u32 width); + u32 reg, u32 *value, u32 width); acpi_status acpi_os_write_pci_configuration(struct acpi_pci_id *pci_id, u32 reg, u64 value, u32 width); +/* + * Interim function needed for PCI IRQ routing + */ +void +acpi_os_derive_pci_id(acpi_handle device, + acpi_handle region, struct acpi_pci_id **pci_id); + /* * Miscellaneous */ +acpi_status acpi_os_validate_interface(char *interface); +acpi_status acpi_osi_invalidate(char* interface); + acpi_status acpi_os_validate_address(u8 space_id, acpi_physical_address address, acpi_size length, char *name); diff --git a/trunk/include/acpi/acpixf.h b/trunk/include/acpi/acpixf.h index 53b7cfd924a3..984cdc62e30b 100644 --- a/trunk/include/acpi/acpixf.h +++ b/trunk/include/acpi/acpixf.h @@ -47,7 +47,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20101013 +#define ACPI_CA_VERSION 0x20100702 #include "actypes.h" #include "actbl.h" @@ -72,7 +72,6 @@ extern u8 acpi_gbl_truncate_io_addresses; extern u32 acpi_current_gpe_count; extern struct acpi_table_fadt acpi_gbl_FADT; -extern u8 acpi_gbl_system_awake_and_running; extern u32 acpi_rsdt_forced; /* @@ -106,10 +105,6 @@ const char *acpi_format_exception(acpi_status exception); acpi_status acpi_purge_cached_objects(void); -acpi_status acpi_install_interface(acpi_string interface_name); - -acpi_status acpi_remove_interface(acpi_string interface_name); - /* * ACPI Memory management */ @@ -268,8 +263,6 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, acpi_status acpi_install_exception_handler(acpi_exception_handler handler); #endif -acpi_status acpi_install_interface_handler(acpi_interface_handler handler); - /* * Event interfaces */ @@ -315,8 +308,6 @@ acpi_install_gpe_block(acpi_handle gpe_device, acpi_status acpi_remove_gpe_block(acpi_handle gpe_device); -acpi_status acpi_update_gpes(void); - /* * Resource interfaces */ diff --git a/trunk/include/acpi/actypes.h b/trunk/include/acpi/actypes.h index 2b134b691e34..5db8f472fec9 100644 --- a/trunk/include/acpi/actypes.h +++ b/trunk/include/acpi/actypes.h @@ -115,6 +115,7 @@ * * ACPI_SIZE 16/32/64-bit unsigned value * ACPI_NATIVE_INT 16/32/64-bit signed value + * */ /******************************************************************************* @@ -131,16 +132,6 @@ typedef COMPILER_DEPENDENT_INT64 INT64; /*! [End] no source code translation !*/ -/* - * Value returned by acpi_os_get_thread_id. There is no standard "thread_id" - * across operating systems or even the various UNIX systems. Since ACPICA - * only needs the thread ID as a unique thread identifier, we use a u64 - * as the only common data type - it will accommodate any type of pointer or - * any type of integer. It is up to the host-dependent OSL to cast the - * native thread ID type to a u64 (in acpi_os_get_thread_id). - */ -#define acpi_thread_id u64 - /******************************************************************************* * * Types specific to 64-bit targets @@ -220,6 +211,12 @@ typedef u32 acpi_physical_address; * ******************************************************************************/ +/* Value returned by acpi_os_get_thread_id */ + +#ifndef acpi_thread_id +#define acpi_thread_id acpi_size +#endif + /* Flags for acpi_os_acquire_lock/acpi_os_release_lock */ #ifndef acpi_cpu_flags @@ -378,6 +375,16 @@ typedef void *acpi_handle; /* Actually a ptr to a NS Node */ typedef u8 acpi_owner_id; #define ACPI_OWNER_ID_MAX 0xFF +struct uint64_struct { + u32 lo; + u32 hi; +}; + +union uint64_overlay { + u64 full; + struct uint64_struct part; +}; + #define ACPI_INTEGER_BIT_SIZE 64 #define ACPI_MAX_DECIMAL_DIGITS 20 /* 2^64 = 18,446,744,073,709,551,616 */ @@ -943,9 +950,6 @@ acpi_status(*acpi_walk_callback) (acpi_handle object, u32 nesting_level, void *context, void **return_value); -typedef -u32 (*acpi_interface_handler) (acpi_string interface_name, u32 supported); - /* Interrupt handler return values */ #define ACPI_INTERRUPT_NOT_HANDLED 0x00 diff --git a/trunk/include/acpi/platform/acenv.h b/trunk/include/acpi/platform/acenv.h index a3e334ab1119..c05aeba9e8f0 100644 --- a/trunk/include/acpi/platform/acenv.h +++ b/trunk/include/acpi/platform/acenv.h @@ -193,12 +193,6 @@ #define ACPI_MUTEX_TYPE ACPI_BINARY_SEMAPHORE #endif -/* "inline" keywords - configurable since inline is not standardized */ - -#ifndef ACPI_INLINE -#define ACPI_INLINE -#endif - /* * Debugger threading model * Use single threaded if the entire subsystem is contained in an application diff --git a/trunk/include/acpi/platform/acgcc.h b/trunk/include/acpi/platform/acgcc.h index 5dcb9537343c..0cd53e3cd1a3 100644 --- a/trunk/include/acpi/platform/acgcc.h +++ b/trunk/include/acpi/platform/acgcc.h @@ -44,8 +44,6 @@ #ifndef __ACGCC_H__ #define __ACGCC_H__ -#define ACPI_INLINE __inline__ - /* Function name is used for debug output. Non-ANSI, compiler-dependent */ #define ACPI_GET_FUNCTION_NAME __func__ diff --git a/trunk/include/acpi/platform/aclinux.h b/trunk/include/acpi/platform/aclinux.h index 572189e37133..103f08aca764 100644 --- a/trunk/include/acpi/platform/aclinux.h +++ b/trunk/include/acpi/platform/aclinux.h @@ -75,6 +75,7 @@ #define acpi_cache_t struct kmem_cache #define acpi_spinlock spinlock_t * #define acpi_cpu_flags unsigned long +#define acpi_thread_id struct task_struct * #else /* !__KERNEL__ */ @@ -87,7 +88,7 @@ /* Host-dependent types and defines for user-space ACPICA */ #define ACPI_FLUSH_CPU_CACHE() -#define ACPI_CAST_PTHREAD_T(pthread) ((acpi_thread_id) (pthread)) +#define acpi_thread_id pthread_t #if defined(__ia64__) || defined(__x86_64__) #define ACPI_MACHINE_WIDTH 64 @@ -112,13 +113,12 @@ #ifdef __KERNEL__ -#include /* * Overrides for in-kernel ACPICA */ static inline acpi_thread_id acpi_os_get_thread_id(void) { - return (acpi_thread_id)(unsigned long)current; + return current; } /* @@ -127,6 +127,7 @@ static inline acpi_thread_id acpi_os_get_thread_id(void) * However, boot has (system_state != SYSTEM_RUNNING) * to quiet __might_sleep() in kmalloc() and resume does not. */ +#include static inline void *acpi_os_allocate(acpi_size size) { return kmalloc(size, irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL); diff --git a/trunk/include/linux/acpi.h b/trunk/include/linux/acpi.h index 7774e6d8fddd..c227757feb06 100644 --- a/trunk/include/linux/acpi.h +++ b/trunk/include/linux/acpi.h @@ -308,9 +308,6 @@ extern acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req); extern void acpi_early_init(void); -int acpi_os_map_generic_address(struct acpi_generic_address *addr); -void acpi_os_unmap_generic_address(struct acpi_generic_address *addr); - #else /* !CONFIG_ACPI */ #define acpi_disabled 1 diff --git a/trunk/include/linux/types.h b/trunk/include/linux/types.h index 357dbc19606f..01a082f56ef4 100644 --- a/trunk/include/linux/types.h +++ b/trunk/include/linux/types.h @@ -121,15 +121,7 @@ typedef __u64 u_int64_t; typedef __s64 int64_t; #endif -/* - * aligned_u64 should be used in defining kernel<->userspace ABIs to avoid - * common 32/64-bit compat problems. - * 64-bit values align to 4-byte boundaries on x86_32 (and possibly other - * architectures) and to 8-byte boundaries on 64-bit architetures. The new - * aligned_64 type enforces 8-byte alignment so that structs containing - * aligned_64 values have the same alignment on 32-bit and 64-bit architectures. - * No conversions are necessary between 32-bit user-space and a 64-bit kernel. - */ +/* this is a special 64bit data type that is 8-byte aligned */ #define aligned_u64 __u64 __attribute__((aligned(8))) #define aligned_be64 __be64 __attribute__((aligned(8))) #define aligned_le64 __le64 __attribute__((aligned(8))) @@ -186,11 +178,6 @@ typedef __u64 __bitwise __be64; typedef __u16 __bitwise __sum16; typedef __u32 __bitwise __wsum; -/* this is a special 64bit data type that is 8-byte aligned */ -#define __aligned_u64 __u64 __attribute__((aligned(8))) -#define __aligned_be64 __be64 __attribute__((aligned(8))) -#define __aligned_le64 __le64 __attribute__((aligned(8))) - #ifdef __KERNEL__ typedef unsigned __bitwise__ gfp_t; typedef unsigned __bitwise__ fmode_t; diff --git a/trunk/kernel/hrtimer.c b/trunk/kernel/hrtimer.c index 72206cf5c6cf..1decafbb6b1a 100644 --- a/trunk/kernel/hrtimer.c +++ b/trunk/kernel/hrtimer.c @@ -931,7 +931,6 @@ static inline int remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base) { if (hrtimer_is_queued(timer)) { - unsigned long state; int reprogram; /* @@ -945,13 +944,8 @@ remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base) debug_deactivate(timer); timer_stats_hrtimer_clear_start_info(timer); reprogram = base->cpu_base == &__get_cpu_var(hrtimer_bases); - /* - * We must preserve the CALLBACK state flag here, - * otherwise we could move the timer base in - * switch_hrtimer_base. - */ - state = timer->state & HRTIMER_STATE_CALLBACK; - __remove_hrtimer(timer, base, state, reprogram); + __remove_hrtimer(timer, base, HRTIMER_STATE_INACTIVE, + reprogram); return 1; } return 0; @@ -1237,9 +1231,6 @@ static void __run_hrtimer(struct hrtimer *timer, ktime_t *now) BUG_ON(timer->state != HRTIMER_STATE_CALLBACK); enqueue_hrtimer(timer, base); } - - WARN_ON_ONCE(!(timer->state & HRTIMER_STATE_CALLBACK)); - timer->state &= ~HRTIMER_STATE_CALLBACK; } diff --git a/trunk/kernel/sysctl_check.c b/trunk/kernel/sysctl_check.c index 10b90d8a03c4..04cdcf72c827 100644 --- a/trunk/kernel/sysctl_check.c +++ b/trunk/kernel/sysctl_check.c @@ -143,6 +143,15 @@ int sysctl_check_table(struct nsproxy *namespaces, struct ctl_table *table) if (!table->maxlen) set_fail(&fail, table, "No maxlen"); } + if ((table->proc_handler == proc_doulongvec_minmax) || + (table->proc_handler == proc_doulongvec_ms_jiffies_minmax)) { + if (table->maxlen > sizeof (unsigned long)) { + if (!table->extra1) + set_fail(&fail, table, "No min"); + if (!table->extra2) + set_fail(&fail, table, "No max"); + } + } #ifdef CONFIG_PROC_SYSCTL if (table->procname && !table->proc_handler) set_fail(&fail, table, "No proc_handler"); diff --git a/trunk/net/rds/page.c b/trunk/net/rds/page.c index 1dfbfea12e9b..595a952d4b17 100644 --- a/trunk/net/rds/page.c +++ b/trunk/net/rds/page.c @@ -57,17 +57,30 @@ int rds_page_copy_user(struct page *page, unsigned long offset, unsigned long ret; void *addr; - addr = kmap(page); - if (to_user) { + if (to_user) rds_stats_add(s_copy_to_user, bytes); - ret = copy_to_user(ptr, addr + offset, bytes); - } else { + else rds_stats_add(s_copy_from_user, bytes); - ret = copy_from_user(addr + offset, ptr, bytes); + + addr = kmap_atomic(page, KM_USER0); + if (to_user) + ret = __copy_to_user_inatomic(ptr, addr + offset, bytes); + else + ret = __copy_from_user_inatomic(addr + offset, ptr, bytes); + kunmap_atomic(addr, KM_USER0); + + if (ret) { + addr = kmap(page); + if (to_user) + ret = copy_to_user(ptr, addr + offset, bytes); + else + ret = copy_from_user(addr + offset, ptr, bytes); + kunmap(page); + if (ret) + return -EFAULT; } - kunmap(page); - return ret ? -EFAULT : 0; + return 0; } EXPORT_SYMBOL_GPL(rds_page_copy_user); diff --git a/trunk/sound/core/rawmidi.c b/trunk/sound/core/rawmidi.c index cbbed0db9e56..a7868ad4d530 100644 --- a/trunk/sound/core/rawmidi.c +++ b/trunk/sound/core/rawmidi.c @@ -535,15 +535,13 @@ static int snd_rawmidi_release(struct inode *inode, struct file *file) { struct snd_rawmidi_file *rfile; struct snd_rawmidi *rmidi; - struct module *module; rfile = file->private_data; rmidi = rfile->rmidi; rawmidi_release_priv(rfile); kfree(rfile); - module = rmidi->card->module; snd_card_file_remove(rmidi->card, file); - module_put(module); + module_put(rmidi->card->module); return 0; }