diff options
52 files changed, 1450 insertions, 748 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index a5cb7839a679..c175eedadb5f 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -180,24 +180,11 @@ Who: Adrian Bunk <bunk@stusta.de> | |||
180 | 180 | ||
181 | --------------------------- | 181 | --------------------------- |
182 | 182 | ||
183 | What: /sys/firmware/acpi/namespace | ||
184 | When: 2.6.21 | ||
185 | Why: The ACPI namespace is effectively the symbol list for | ||
186 | the BIOS. The device names are completely arbitrary | ||
187 | and have no place being exposed to user-space. | ||
188 | |||
189 | For those interested in the BIOS ACPI namespace, | ||
190 | the BIOS can be extracted and disassembled with acpidump | ||
191 | and iasl as documented in the pmtools package here: | ||
192 | http://ftp.kernel.org/pub/linux/kernel/people/lenb/acpi/utils | ||
193 | Who: Len Brown <len.brown@intel.com> | ||
194 | |||
195 | --------------------------- | ||
196 | |||
197 | What: ACPI procfs interface | 183 | What: ACPI procfs interface |
198 | When: July 2007 | 184 | When: July 2008 |
199 | Why: After ACPI sysfs conversion, ACPI attributes will be duplicated | 185 | Why: ACPI sysfs conversion should be finished by January 2008. |
200 | in sysfs and the ACPI procfs interface should be removed. | 186 | ACPI procfs interface will be removed in July 2008 so that |
187 | there is enough time for the user space to catch up. | ||
201 | Who: Zhang Rui <rui.zhang@intel.com> | 188 | Who: Zhang Rui <rui.zhang@intel.com> |
202 | 189 | ||
203 | --------------------------- | 190 | --------------------------- |
diff --git a/MAINTAINERS b/MAINTAINERS index 773c732b4177..a9b9ef614ae7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -225,15 +225,15 @@ T: git kernel.org:/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git | |||
225 | S: Supported | 225 | S: Supported |
226 | 226 | ||
227 | ACPI BATTERY DRIVERS | 227 | ACPI BATTERY DRIVERS |
228 | P: Vladimir P. Lebedev | 228 | P: Alexey Starikovskiy |
229 | M: vladimir.p.lebedev@intel.com | 229 | M: astarikovskiy@suse.de |
230 | L: linux-acpi@vger.kernel.org | 230 | L: linux-acpi@vger.kernel.org |
231 | W: http://acpi.sourceforge.net/ | 231 | W: http://acpi.sourceforge.net/ |
232 | S: Supported | 232 | S: Supported |
233 | 233 | ||
234 | ACPI EC DRIVER | 234 | ACPI EC DRIVER |
235 | P: Alexey Starikovskiy | 235 | P: Alexey Starikovskiy |
236 | M: alexey.y.starikovskiy@linux.intel.com | 236 | M: astarikovskiy@suse.de |
237 | L: linux-acpi@vger.kernel.org | 237 | L: linux-acpi@vger.kernel.org |
238 | W: http://acpi.sourceforge.net/ | 238 | W: http://acpi.sourceforge.net/ |
239 | S: Supported | 239 | S: Supported |
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index b87cedeaf59b..cacdd883bf2b 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c | |||
@@ -986,14 +986,6 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = { | |||
986 | }, | 986 | }, |
987 | { | 987 | { |
988 | .callback = force_acpi_ht, | 988 | .callback = force_acpi_ht, |
989 | .ident = "DELL GX240", | ||
990 | .matches = { | ||
991 | DMI_MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"), | ||
992 | DMI_MATCH(DMI_BOARD_NAME, "OptiPlex GX240"), | ||
993 | }, | ||
994 | }, | ||
995 | { | ||
996 | .callback = force_acpi_ht, | ||
997 | .ident = "HP VISUALIZE NT Workstation", | 989 | .ident = "HP VISUALIZE NT Workstation", |
998 | .matches = { | 990 | .matches = { |
999 | DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), | 991 | DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), |
diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index 18c8b67ea3a7..6f846bee2103 100644 --- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c | |||
@@ -665,8 +665,8 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
665 | data->max_freq = perf->states[0].core_frequency * 1000; | 665 | data->max_freq = perf->states[0].core_frequency * 1000; |
666 | /* table init */ | 666 | /* table init */ |
667 | for (i=0; i<perf->state_count; i++) { | 667 | for (i=0; i<perf->state_count; i++) { |
668 | if (i>0 && perf->states[i].core_frequency == | 668 | if (i>0 && perf->states[i].core_frequency >= |
669 | perf->states[i-1].core_frequency) | 669 | data->freq_table[valid_states-1].frequency / 1000) |
670 | continue; | 670 | continue; |
671 | 671 | ||
672 | data->freq_table[valid_states].index = i; | 672 | data->freq_table[valid_states].index = i; |
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index 831f540251f8..eac38388f5fd 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S | |||
@@ -1749,8 +1749,8 @@ fpload: | |||
1749 | __ndelay: | 1749 | __ndelay: |
1750 | save %sp, -STACKFRAME_SZ, %sp | 1750 | save %sp, -STACKFRAME_SZ, %sp |
1751 | mov %i0, %o0 | 1751 | mov %i0, %o0 |
1752 | call .umul | 1752 | call .umul ! round multiplier up so large ns ok |
1753 | mov 0x1ad, %o1 ! 2**32 / (1 000 000 000 / HZ) | 1753 | mov 0x1ae, %o1 ! 2**32 / (1 000 000 000 / HZ) |
1754 | call .umul | 1754 | call .umul |
1755 | mov %i1, %o1 ! udelay_val | 1755 | mov %i1, %o1 ! udelay_val |
1756 | ba delay_continue | 1756 | ba delay_continue |
@@ -1760,11 +1760,17 @@ __ndelay: | |||
1760 | __udelay: | 1760 | __udelay: |
1761 | save %sp, -STACKFRAME_SZ, %sp | 1761 | save %sp, -STACKFRAME_SZ, %sp |
1762 | mov %i0, %o0 | 1762 | mov %i0, %o0 |
1763 | sethi %hi(0x10c6), %o1 | 1763 | sethi %hi(0x10c7), %o1 ! round multiplier up so large us ok |
1764 | call .umul | 1764 | call .umul |
1765 | or %o1, %lo(0x10c6), %o1 ! 2**32 / 1 000 000 | 1765 | or %o1, %lo(0x10c7), %o1 ! 2**32 / 1 000 000 |
1766 | call .umul | 1766 | call .umul |
1767 | mov %i1, %o1 ! udelay_val | 1767 | mov %i1, %o1 ! udelay_val |
1768 | sethi %hi(0x028f4b62), %l0 ! Add in rounding constant * 2**32, | ||
1769 | or %g0, %lo(0x028f4b62), %l0 | ||
1770 | addcc %o0, %l0, %o0 ! 2**32 * 0.009 999 | ||
1771 | bcs,a 3f | ||
1772 | add %o1, 0x01, %o1 | ||
1773 | 3: | ||
1768 | call .umul | 1774 | call .umul |
1769 | mov HZ, %o0 ! >>32 earlier for wider range | 1775 | mov HZ, %o0 ! >>32 earlier for wider range |
1770 | 1776 | ||
diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c index f257a67bcf93..75b2240ad0f9 100644 --- a/arch/sparc/kernel/irq.c +++ b/arch/sparc/kernel/irq.c | |||
@@ -47,6 +47,8 @@ | |||
47 | #include <asm/cacheflush.h> | 47 | #include <asm/cacheflush.h> |
48 | #include <asm/irq_regs.h> | 48 | #include <asm/irq_regs.h> |
49 | 49 | ||
50 | #include "irq.h" | ||
51 | |||
50 | #ifdef CONFIG_SMP | 52 | #ifdef CONFIG_SMP |
51 | #define SMP_NOP2 "nop; nop;\n\t" | 53 | #define SMP_NOP2 "nop; nop;\n\t" |
52 | #define SMP_NOP3 "nop; nop; nop;\n\t" | 54 | #define SMP_NOP3 "nop; nop; nop;\n\t" |
@@ -268,7 +270,7 @@ void free_irq(unsigned int irq, void *dev_id) | |||
268 | kfree(action); | 270 | kfree(action); |
269 | 271 | ||
270 | if (!sparc_irq[cpu_irq].action) | 272 | if (!sparc_irq[cpu_irq].action) |
271 | disable_irq(irq); | 273 | __disable_irq(irq); |
272 | 274 | ||
273 | out_unlock: | 275 | out_unlock: |
274 | spin_unlock_irqrestore(&irq_action_lock, flags); | 276 | spin_unlock_irqrestore(&irq_action_lock, flags); |
@@ -464,7 +466,7 @@ int request_fast_irq(unsigned int irq, | |||
464 | 466 | ||
465 | sparc_irq[cpu_irq].action = action; | 467 | sparc_irq[cpu_irq].action = action; |
466 | 468 | ||
467 | enable_irq(irq); | 469 | __enable_irq(irq); |
468 | 470 | ||
469 | ret = 0; | 471 | ret = 0; |
470 | out_unlock: | 472 | out_unlock: |
@@ -544,7 +546,7 @@ int request_irq(unsigned int irq, | |||
544 | 546 | ||
545 | *actionp = action; | 547 | *actionp = action; |
546 | 548 | ||
547 | enable_irq(irq); | 549 | __enable_irq(irq); |
548 | 550 | ||
549 | ret = 0; | 551 | ret = 0; |
550 | out_unlock: | 552 | out_unlock: |
@@ -555,6 +557,25 @@ out: | |||
555 | 557 | ||
556 | EXPORT_SYMBOL(request_irq); | 558 | EXPORT_SYMBOL(request_irq); |
557 | 559 | ||
560 | void disable_irq_nosync(unsigned int irq) | ||
561 | { | ||
562 | return __disable_irq(irq); | ||
563 | } | ||
564 | EXPORT_SYMBOL(disable_irq_nosync); | ||
565 | |||
566 | void disable_irq(unsigned int irq) | ||
567 | { | ||
568 | return __disable_irq(irq); | ||
569 | } | ||
570 | EXPORT_SYMBOL(disable_irq); | ||
571 | |||
572 | void enable_irq(unsigned int irq) | ||
573 | { | ||
574 | return __enable_irq(irq); | ||
575 | } | ||
576 | |||
577 | EXPORT_SYMBOL(enable_irq); | ||
578 | |||
558 | /* We really don't need these at all on the Sparc. We only have | 579 | /* We really don't need these at all on the Sparc. We only have |
559 | * stubs here because they are exported to modules. | 580 | * stubs here because they are exported to modules. |
560 | */ | 581 | */ |
diff --git a/arch/sparc/kernel/irq.h b/arch/sparc/kernel/irq.h new file mode 100644 index 000000000000..32ef3ebd0a88 --- /dev/null +++ b/arch/sparc/kernel/irq.h | |||
@@ -0,0 +1,68 @@ | |||
1 | #include <asm/btfixup.h> | ||
2 | |||
3 | /* Dave Redman (djhr@tadpole.co.uk) | ||
4 | * changed these to function pointers.. it saves cycles and will allow | ||
5 | * the irq dependencies to be split into different files at a later date | ||
6 | * sun4c_irq.c, sun4m_irq.c etc so we could reduce the kernel size. | ||
7 | * Jakub Jelinek (jj@sunsite.mff.cuni.cz) | ||
8 | * Changed these to btfixup entities... It saves cycles :) | ||
9 | */ | ||
10 | |||
11 | BTFIXUPDEF_CALL(void, disable_irq, unsigned int) | ||
12 | BTFIXUPDEF_CALL(void, enable_irq, unsigned int) | ||
13 | BTFIXUPDEF_CALL(void, disable_pil_irq, unsigned int) | ||
14 | BTFIXUPDEF_CALL(void, enable_pil_irq, unsigned int) | ||
15 | BTFIXUPDEF_CALL(void, clear_clock_irq, void) | ||
16 | BTFIXUPDEF_CALL(void, clear_profile_irq, int) | ||
17 | BTFIXUPDEF_CALL(void, load_profile_irq, int, unsigned int) | ||
18 | |||
19 | static inline void __disable_irq(unsigned int irq) | ||
20 | { | ||
21 | BTFIXUP_CALL(disable_irq)(irq); | ||
22 | } | ||
23 | |||
24 | static inline void __enable_irq(unsigned int irq) | ||
25 | { | ||
26 | BTFIXUP_CALL(enable_irq)(irq); | ||
27 | } | ||
28 | |||
29 | static inline void disable_pil_irq(unsigned int irq) | ||
30 | { | ||
31 | BTFIXUP_CALL(disable_pil_irq)(irq); | ||
32 | } | ||
33 | |||
34 | static inline void enable_pil_irq(unsigned int irq) | ||
35 | { | ||
36 | BTFIXUP_CALL(enable_pil_irq)(irq); | ||
37 | } | ||
38 | |||
39 | static inline void clear_clock_irq(void) | ||
40 | { | ||
41 | BTFIXUP_CALL(clear_clock_irq)(); | ||
42 | } | ||
43 | |||
44 | static inline void clear_profile_irq(int irq) | ||
45 | { | ||
46 | BTFIXUP_CALL(clear_profile_irq)(irq); | ||
47 | } | ||
48 | |||
49 | static inline void load_profile_irq(int cpu, int limit) | ||
50 | { | ||
51 | BTFIXUP_CALL(load_profile_irq)(cpu, limit); | ||
52 | } | ||
53 | |||
54 | extern void (*sparc_init_timers)(irq_handler_t lvl10_irq); | ||
55 | |||
56 | extern void claim_ticker14(irq_handler_t irq_handler, | ||
57 | int irq, | ||
58 | unsigned int timeout); | ||
59 | |||
60 | #ifdef CONFIG_SMP | ||
61 | BTFIXUPDEF_CALL(void, set_cpu_int, int, int) | ||
62 | BTFIXUPDEF_CALL(void, clear_cpu_int, int, int) | ||
63 | BTFIXUPDEF_CALL(void, set_irq_udt, int) | ||
64 | |||
65 | #define set_cpu_int(cpu,level) BTFIXUP_CALL(set_cpu_int)(cpu,level) | ||
66 | #define clear_cpu_int(cpu,level) BTFIXUP_CALL(clear_cpu_int)(cpu,level) | ||
67 | #define set_irq_udt(cpu) BTFIXUP_CALL(set_irq_udt)(cpu) | ||
68 | #endif | ||
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index 791771196905..f2eae457fc9a 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
37 | #include <asm/irq_regs.h> | 37 | #include <asm/irq_regs.h> |
38 | 38 | ||
39 | #include "irq.h" | ||
39 | 40 | ||
40 | /* | 41 | /* |
41 | * I studied different documents and many live PROMs both from 2.30 | 42 | * I studied different documents and many live PROMs both from 2.30 |
diff --git a/arch/sparc/kernel/smp.c b/arch/sparc/kernel/smp.c index 4fea3ac7bff0..6724ab90f82b 100644 --- a/arch/sparc/kernel/smp.c +++ b/arch/sparc/kernel/smp.c | |||
@@ -33,6 +33,8 @@ | |||
33 | #include <asm/tlbflush.h> | 33 | #include <asm/tlbflush.h> |
34 | #include <asm/cpudata.h> | 34 | #include <asm/cpudata.h> |
35 | 35 | ||
36 | #include "irq.h" | ||
37 | |||
36 | int smp_num_cpus = 1; | 38 | int smp_num_cpus = 1; |
37 | volatile unsigned long cpu_callin_map[NR_CPUS] __initdata = {0,}; | 39 | volatile unsigned long cpu_callin_map[NR_CPUS] __initdata = {0,}; |
38 | unsigned char boot_cpu_id = 0; | 40 | unsigned char boot_cpu_id = 0; |
diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c index d8e008a04e2b..55bac516dfe2 100644 --- a/arch/sparc/kernel/sparc_ksyms.c +++ b/arch/sparc/kernel/sparc_ksyms.c | |||
@@ -154,8 +154,6 @@ EXPORT_SYMBOL(BTFIXUP_CALL(___xchg32)); | |||
154 | #else | 154 | #else |
155 | EXPORT_SYMBOL(BTFIXUP_CALL(__hard_smp_processor_id)); | 155 | EXPORT_SYMBOL(BTFIXUP_CALL(__hard_smp_processor_id)); |
156 | #endif | 156 | #endif |
157 | EXPORT_SYMBOL(BTFIXUP_CALL(enable_irq)); | ||
158 | EXPORT_SYMBOL(BTFIXUP_CALL(disable_irq)); | ||
159 | EXPORT_SYMBOL(BTFIXUP_CALL(mmu_unlockarea)); | 157 | EXPORT_SYMBOL(BTFIXUP_CALL(mmu_unlockarea)); |
160 | EXPORT_SYMBOL(BTFIXUP_CALL(mmu_lockarea)); | 158 | EXPORT_SYMBOL(BTFIXUP_CALL(mmu_lockarea)); |
161 | EXPORT_SYMBOL(BTFIXUP_CALL(mmu_get_scsi_sgl)); | 159 | EXPORT_SYMBOL(BTFIXUP_CALL(mmu_get_scsi_sgl)); |
diff --git a/arch/sparc/kernel/sun4c_irq.c b/arch/sparc/kernel/sun4c_irq.c index 009e891a4329..c6ac9fc52563 100644 --- a/arch/sparc/kernel/sun4c_irq.c +++ b/arch/sparc/kernel/sun4c_irq.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include "irq.h" | ||
21 | 22 | ||
22 | #include <asm/ptrace.h> | 23 | #include <asm/ptrace.h> |
23 | #include <asm/processor.h> | 24 | #include <asm/processor.h> |
@@ -40,6 +41,20 @@ static struct resource sun4c_timer_eb = { "sun4c_timer" }; | |||
40 | static struct resource sun4c_intr_eb = { "sun4c_intr" }; | 41 | static struct resource sun4c_intr_eb = { "sun4c_intr" }; |
41 | #endif | 42 | #endif |
42 | 43 | ||
44 | /* | ||
45 | * Bit field defines for the interrupt registers on various | ||
46 | * Sparc machines. | ||
47 | */ | ||
48 | |||
49 | /* The sun4c interrupt register. */ | ||
50 | #define SUN4C_INT_ENABLE 0x01 /* Allow interrupts. */ | ||
51 | #define SUN4C_INT_E14 0x80 /* Enable level 14 IRQ. */ | ||
52 | #define SUN4C_INT_E10 0x20 /* Enable level 10 IRQ. */ | ||
53 | #define SUN4C_INT_E8 0x10 /* Enable level 8 IRQ. */ | ||
54 | #define SUN4C_INT_E6 0x08 /* Enable level 6 IRQ. */ | ||
55 | #define SUN4C_INT_E4 0x04 /* Enable level 4 IRQ. */ | ||
56 | #define SUN4C_INT_E1 0x02 /* Enable level 1 IRQ. */ | ||
57 | |||
43 | /* Pointer to the interrupt enable byte | 58 | /* Pointer to the interrupt enable byte |
44 | * | 59 | * |
45 | * Dave Redman (djhr@tadpole.co.uk) | 60 | * Dave Redman (djhr@tadpole.co.uk) |
diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c index 396797e20c39..e0efab2a6bef 100644 --- a/arch/sparc/kernel/sun4d_irq.c +++ b/arch/sparc/kernel/sun4d_irq.c | |||
@@ -39,6 +39,8 @@ | |||
39 | #include <asm/cacheflush.h> | 39 | #include <asm/cacheflush.h> |
40 | #include <asm/irq_regs.h> | 40 | #include <asm/irq_regs.h> |
41 | 41 | ||
42 | #include "irq.h" | ||
43 | |||
42 | /* If you trust current SCSI layer to handle different SCSI IRQs, enable this. I don't trust it... -jj */ | 44 | /* If you trust current SCSI layer to handle different SCSI IRQs, enable this. I don't trust it... -jj */ |
43 | /* #define DISTRIBUTE_IRQS */ | 45 | /* #define DISTRIBUTE_IRQS */ |
44 | 46 | ||
@@ -188,7 +190,7 @@ void sun4d_free_irq(unsigned int irq, void *dev_id) | |||
188 | kfree(action); | 190 | kfree(action); |
189 | 191 | ||
190 | if (!(*actionp)) | 192 | if (!(*actionp)) |
191 | disable_irq(irq); | 193 | __disable_irq(irq); |
192 | 194 | ||
193 | out_unlock: | 195 | out_unlock: |
194 | spin_unlock_irqrestore(&irq_action_lock, flags); | 196 | spin_unlock_irqrestore(&irq_action_lock, flags); |
@@ -346,7 +348,7 @@ int sun4d_request_irq(unsigned int irq, | |||
346 | else | 348 | else |
347 | *actionp = action; | 349 | *actionp = action; |
348 | 350 | ||
349 | enable_irq(irq); | 351 | __enable_irq(irq); |
350 | 352 | ||
351 | ret = 0; | 353 | ret = 0; |
352 | out_unlock: | 354 | out_unlock: |
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index 098c94f1a322..89a6de95070c 100644 --- a/arch/sparc/kernel/sun4d_smp.c +++ b/arch/sparc/kernel/sun4d_smp.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <asm/cacheflush.h> | 36 | #include <asm/cacheflush.h> |
37 | #include <asm/cpudata.h> | 37 | #include <asm/cpudata.h> |
38 | 38 | ||
39 | #include "irq.h" | ||
39 | #define IRQ_CROSS_CALL 15 | 40 | #define IRQ_CROSS_CALL 15 |
40 | 41 | ||
41 | extern ctxd_t *srmmu_ctx_table_phys; | 42 | extern ctxd_t *srmmu_ctx_table_phys; |
diff --git a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c index 91a803ea88be..b92d6d2d5b04 100644 --- a/arch/sparc/kernel/sun4m_irq.c +++ b/arch/sparc/kernel/sun4m_irq.c | |||
@@ -38,11 +38,85 @@ | |||
38 | #include <asm/sbus.h> | 38 | #include <asm/sbus.h> |
39 | #include <asm/cacheflush.h> | 39 | #include <asm/cacheflush.h> |
40 | 40 | ||
41 | #include "irq.h" | ||
42 | |||
43 | /* On the sun4m, just like the timers, we have both per-cpu and master | ||
44 | * interrupt registers. | ||
45 | */ | ||
46 | |||
47 | /* These registers are used for sending/receiving irqs from/to | ||
48 | * different cpu's. | ||
49 | */ | ||
50 | struct sun4m_intreg_percpu { | ||
51 | unsigned int tbt; /* Interrupts still pending for this cpu. */ | ||
52 | |||
53 | /* These next two registers are WRITE-ONLY and are only | ||
54 | * "on bit" sensitive, "off bits" written have NO affect. | ||
55 | */ | ||
56 | unsigned int clear; /* Clear this cpus irqs here. */ | ||
57 | unsigned int set; /* Set this cpus irqs here. */ | ||
58 | unsigned char space[PAGE_SIZE - 12]; | ||
59 | }; | ||
60 | |||
61 | /* | ||
62 | * djhr | ||
63 | * Actually the clear and set fields in this struct are misleading.. | ||
64 | * according to the SLAVIO manual (and the same applies for the SEC) | ||
65 | * the clear field clears bits in the mask which will ENABLE that IRQ | ||
66 | * the set field sets bits in the mask to DISABLE the IRQ. | ||
67 | * | ||
68 | * Also the undirected_xx address in the SLAVIO is defined as | ||
69 | * RESERVED and write only.. | ||
70 | * | ||
71 | * DAVEM_NOTE: The SLAVIO only specifies behavior on uniprocessor | ||
72 | * sun4m machines, for MP the layout makes more sense. | ||
73 | */ | ||
74 | struct sun4m_intregs { | ||
75 | struct sun4m_intreg_percpu cpu_intregs[SUN4M_NCPUS]; | ||
76 | unsigned int tbt; /* IRQ's that are still pending. */ | ||
77 | unsigned int irqs; /* Master IRQ bits. */ | ||
78 | |||
79 | /* Again, like the above, two these registers are WRITE-ONLY. */ | ||
80 | unsigned int clear; /* Clear master IRQ's by setting bits here. */ | ||
81 | unsigned int set; /* Set master IRQ's by setting bits here. */ | ||
82 | |||
83 | /* This register is both READ and WRITE. */ | ||
84 | unsigned int undirected_target; /* Which cpu gets undirected irqs. */ | ||
85 | }; | ||
86 | |||
41 | static unsigned long dummy; | 87 | static unsigned long dummy; |
42 | 88 | ||
43 | struct sun4m_intregs *sun4m_interrupts; | 89 | struct sun4m_intregs *sun4m_interrupts; |
44 | unsigned long *irq_rcvreg = &dummy; | 90 | unsigned long *irq_rcvreg = &dummy; |
45 | 91 | ||
92 | /* Dave Redman (djhr@tadpole.co.uk) | ||
93 | * The sun4m interrupt registers. | ||
94 | */ | ||
95 | #define SUN4M_INT_ENABLE 0x80000000 | ||
96 | #define SUN4M_INT_E14 0x00000080 | ||
97 | #define SUN4M_INT_E10 0x00080000 | ||
98 | |||
99 | #define SUN4M_HARD_INT(x) (0x000000001 << (x)) | ||
100 | #define SUN4M_SOFT_INT(x) (0x000010000 << (x)) | ||
101 | |||
102 | #define SUN4M_INT_MASKALL 0x80000000 /* mask all interrupts */ | ||
103 | #define SUN4M_INT_MODULE_ERR 0x40000000 /* module error */ | ||
104 | #define SUN4M_INT_M2S_WRITE 0x20000000 /* write buffer error */ | ||
105 | #define SUN4M_INT_ECC 0x10000000 /* ecc memory error */ | ||
106 | #define SUN4M_INT_FLOPPY 0x00400000 /* floppy disk */ | ||
107 | #define SUN4M_INT_MODULE 0x00200000 /* module interrupt */ | ||
108 | #define SUN4M_INT_VIDEO 0x00100000 /* onboard video */ | ||
109 | #define SUN4M_INT_REALTIME 0x00080000 /* system timer */ | ||
110 | #define SUN4M_INT_SCSI 0x00040000 /* onboard scsi */ | ||
111 | #define SUN4M_INT_AUDIO 0x00020000 /* audio/isdn */ | ||
112 | #define SUN4M_INT_ETHERNET 0x00010000 /* onboard ethernet */ | ||
113 | #define SUN4M_INT_SERIAL 0x00008000 /* serial ports */ | ||
114 | #define SUN4M_INT_KBDMS 0x00004000 /* keyboard/mouse */ | ||
115 | #define SUN4M_INT_SBUSBITS 0x00003F80 /* sbus int bits */ | ||
116 | |||
117 | #define SUN4M_INT_SBUS(x) (1 << (x+7)) | ||
118 | #define SUN4M_INT_VME(x) (1 << (x)) | ||
119 | |||
46 | /* These tables only apply for interrupts greater than 15.. | 120 | /* These tables only apply for interrupts greater than 15.. |
47 | * | 121 | * |
48 | * any intr value below 0x10 is considered to be a soft-int | 122 | * any intr value below 0x10 is considered to be a soft-int |
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c index 63ed19bfd028..730eb5796f8e 100644 --- a/arch/sparc/kernel/sun4m_smp.c +++ b/arch/sparc/kernel/sun4m_smp.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #include <asm/oplib.h> | 31 | #include <asm/oplib.h> |
32 | #include <asm/cpudata.h> | 32 | #include <asm/cpudata.h> |
33 | 33 | ||
34 | #include "irq.h" | ||
35 | |||
34 | #define IRQ_RESCHEDULE 13 | 36 | #define IRQ_RESCHEDULE 13 |
35 | #define IRQ_STOP_CPU 14 | 37 | #define IRQ_STOP_CPU 14 |
36 | #define IRQ_CROSS_CALL 15 | 38 | #define IRQ_CROSS_CALL 15 |
diff --git a/arch/sparc/kernel/tick14.c b/arch/sparc/kernel/tick14.c index f1a7bd19e04f..707bfda86570 100644 --- a/arch/sparc/kernel/tick14.c +++ b/arch/sparc/kernel/tick14.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #include <asm/irq.h> | 25 | #include <asm/irq.h> |
26 | #include <asm/io.h> | 26 | #include <asm/io.h> |
27 | 27 | ||
28 | #include "irq.h" | ||
29 | |||
28 | extern unsigned long lvl14_save[5]; | 30 | extern unsigned long lvl14_save[5]; |
29 | static unsigned long *linux_lvl14 = NULL; | 31 | static unsigned long *linux_lvl14 = NULL; |
30 | static unsigned long obp_lvl14[4]; | 32 | static unsigned long obp_lvl14[4]; |
@@ -62,7 +64,7 @@ void claim_ticker14(irq_handler_t handler, | |||
62 | 64 | ||
63 | /* first we copy the obp handler instructions | 65 | /* first we copy the obp handler instructions |
64 | */ | 66 | */ |
65 | disable_irq(irq_nr); | 67 | __disable_irq(irq_nr); |
66 | if (!handler) | 68 | if (!handler) |
67 | return; | 69 | return; |
68 | 70 | ||
@@ -79,6 +81,6 @@ void claim_ticker14(irq_handler_t handler, | |||
79 | NULL)) { | 81 | NULL)) { |
80 | install_linux_ticker(); | 82 | install_linux_ticker(); |
81 | load_profile_irq(cpu, timeout); | 83 | load_profile_irq(cpu, timeout); |
82 | enable_irq(irq_nr); | 84 | __enable_irq(irq_nr); |
83 | } | 85 | } |
84 | } | 86 | } |
diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c index f2fdbb3664d3..6a2513321620 100644 --- a/arch/sparc/kernel/time.c +++ b/arch/sparc/kernel/time.c | |||
@@ -44,6 +44,8 @@ | |||
44 | #include <asm/of_device.h> | 44 | #include <asm/of_device.h> |
45 | #include <asm/irq_regs.h> | 45 | #include <asm/irq_regs.h> |
46 | 46 | ||
47 | #include "irq.h" | ||
48 | |||
47 | DEFINE_SPINLOCK(rtc_lock); | 49 | DEFINE_SPINLOCK(rtc_lock); |
48 | enum sparc_clock_type sp_clock_typ; | 50 | enum sparc_clock_type sp_clock_typ; |
49 | DEFINE_SPINLOCK(mostek_lock); | 51 | DEFINE_SPINLOCK(mostek_lock); |
diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c index a532922e2e35..a1bef07755a9 100644 --- a/arch/sparc/mm/init.c +++ b/arch/sparc/mm/init.c | |||
@@ -308,6 +308,9 @@ extern void sun4c_paging_init(void); | |||
308 | extern void srmmu_paging_init(void); | 308 | extern void srmmu_paging_init(void); |
309 | extern void device_scan(void); | 309 | extern void device_scan(void); |
310 | 310 | ||
311 | pgprot_t PAGE_SHARED __read_mostly; | ||
312 | EXPORT_SYMBOL(PAGE_SHARED); | ||
313 | |||
311 | void __init paging_init(void) | 314 | void __init paging_init(void) |
312 | { | 315 | { |
313 | switch(sparc_cpu_model) { | 316 | switch(sparc_cpu_model) { |
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index ca26232da7ab..17b485f2825c 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c | |||
@@ -2154,7 +2154,7 @@ void __init ld_mmu_srmmu(void) | |||
2154 | BTFIXUPSET_SIMM13(ptrs_per_pgd, SRMMU_PTRS_PER_PGD); | 2154 | BTFIXUPSET_SIMM13(ptrs_per_pgd, SRMMU_PTRS_PER_PGD); |
2155 | 2155 | ||
2156 | BTFIXUPSET_INT(page_none, pgprot_val(SRMMU_PAGE_NONE)); | 2156 | BTFIXUPSET_INT(page_none, pgprot_val(SRMMU_PAGE_NONE)); |
2157 | BTFIXUPSET_INT(page_shared, pgprot_val(SRMMU_PAGE_SHARED)); | 2157 | PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED); |
2158 | BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY)); | 2158 | BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY)); |
2159 | BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY)); | 2159 | BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY)); |
2160 | BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL)); | 2160 | BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL)); |
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c index bdd835fba02e..a57a366e339a 100644 --- a/arch/sparc/mm/sun4c.c +++ b/arch/sparc/mm/sun4c.c | |||
@@ -2155,7 +2155,7 @@ void __init ld_mmu_sun4c(void) | |||
2155 | BTFIXUPSET_SIMM13(user_ptrs_per_pgd, KERNBASE / SUN4C_PGDIR_SIZE); | 2155 | BTFIXUPSET_SIMM13(user_ptrs_per_pgd, KERNBASE / SUN4C_PGDIR_SIZE); |
2156 | 2156 | ||
2157 | BTFIXUPSET_INT(page_none, pgprot_val(SUN4C_PAGE_NONE)); | 2157 | BTFIXUPSET_INT(page_none, pgprot_val(SUN4C_PAGE_NONE)); |
2158 | BTFIXUPSET_INT(page_shared, pgprot_val(SUN4C_PAGE_SHARED)); | 2158 | PAGE_SHARED = pgprot_val(SUN4C_PAGE_SHARED); |
2159 | BTFIXUPSET_INT(page_copy, pgprot_val(SUN4C_PAGE_COPY)); | 2159 | BTFIXUPSET_INT(page_copy, pgprot_val(SUN4C_PAGE_COPY)); |
2160 | BTFIXUPSET_INT(page_readonly, pgprot_val(SUN4C_PAGE_READONLY)); | 2160 | BTFIXUPSET_INT(page_readonly, pgprot_val(SUN4C_PAGE_READONLY)); |
2161 | BTFIXUPSET_INT(page_kernel, pgprot_val(SUN4C_PAGE_KERNEL)); | 2161 | BTFIXUPSET_INT(page_kernel, pgprot_val(SUN4C_PAGE_KERNEL)); |
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 7d36531aa5b9..d270c2f0be0f 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c | |||
@@ -280,6 +280,7 @@ EXPORT_SYMBOL(sys_getgid); | |||
280 | EXPORT_SYMBOL(svr4_getcontext); | 280 | EXPORT_SYMBOL(svr4_getcontext); |
281 | EXPORT_SYMBOL(svr4_setcontext); | 281 | EXPORT_SYMBOL(svr4_setcontext); |
282 | EXPORT_SYMBOL(compat_sys_ioctl); | 282 | EXPORT_SYMBOL(compat_sys_ioctl); |
283 | EXPORT_SYMBOL(sys_ioctl); | ||
283 | EXPORT_SYMBOL(sparc32_open); | 284 | EXPORT_SYMBOL(sparc32_open); |
284 | #endif | 285 | #endif |
285 | 286 | ||
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 139f41f033d8..501ed6ffa40f 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -2,16 +2,12 @@ | |||
2 | # ACPI Configuration | 2 | # ACPI Configuration |
3 | # | 3 | # |
4 | 4 | ||
5 | menu "ACPI (Advanced Configuration and Power Interface) Support" | 5 | menuconfig ACPI |
6 | bool "ACPI Support (Advanced Configuration and Power Interface) Support" | ||
6 | depends on !X86_NUMAQ | 7 | depends on !X86_NUMAQ |
7 | depends on !X86_VISWS | 8 | depends on !X86_VISWS |
8 | depends on !IA64_HP_SIM | 9 | depends on !IA64_HP_SIM |
9 | depends on IA64 || X86 | 10 | depends on IA64 || X86 |
10 | depends on PM | ||
11 | |||
12 | config ACPI | ||
13 | bool "ACPI Support" | ||
14 | depends on IA64 || X86 | ||
15 | depends on PCI | 11 | depends on PCI |
16 | depends on PM | 12 | depends on PM |
17 | select PNP | 13 | select PNP |
@@ -49,7 +45,6 @@ if ACPI | |||
49 | config ACPI_SLEEP | 45 | config ACPI_SLEEP |
50 | bool "Sleep States" | 46 | bool "Sleep States" |
51 | depends on X86 && (!SMP || SUSPEND_SMP) | 47 | depends on X86 && (!SMP || SUSPEND_SMP) |
52 | depends on PM | ||
53 | default y | 48 | default y |
54 | ---help--- | 49 | ---help--- |
55 | This option adds support for ACPI suspend states. | 50 | This option adds support for ACPI suspend states. |
@@ -82,7 +77,6 @@ config ACPI_SLEEP_PROC_SLEEP | |||
82 | 77 | ||
83 | config ACPI_PROCFS | 78 | config ACPI_PROCFS |
84 | bool "Procfs interface (deprecated)" | 79 | bool "Procfs interface (deprecated)" |
85 | depends on ACPI | ||
86 | default y | 80 | default y |
87 | ---help--- | 81 | ---help--- |
88 | The Procfs interface for ACPI is made optional for backward compatibility. | 82 | The Procfs interface for ACPI is made optional for backward compatibility. |
@@ -280,6 +274,14 @@ config ACPI_DEBUG | |||
280 | of verbosity. Saying Y enables these statements. This will increase | 274 | of verbosity. Saying Y enables these statements. This will increase |
281 | your kernel size by around 50K. | 275 | your kernel size by around 50K. |
282 | 276 | ||
277 | config ACPI_DEBUG_FUNC_TRACE | ||
278 | bool "Additionally enable ACPI function tracing" | ||
279 | default n | ||
280 | depends on ACPI_DEBUG | ||
281 | help | ||
282 | ACPI Debug Statements slow down ACPI processing. Function trace | ||
283 | is about half of the penalty and is rarely useful. | ||
284 | |||
283 | config ACPI_EC | 285 | config ACPI_EC |
284 | bool | 286 | bool |
285 | default y | 287 | default y |
@@ -330,7 +332,6 @@ config ACPI_CONTAINER | |||
330 | 332 | ||
331 | config ACPI_HOTPLUG_MEMORY | 333 | config ACPI_HOTPLUG_MEMORY |
332 | tristate "Memory Hotplug" | 334 | tristate "Memory Hotplug" |
333 | depends on ACPI | ||
334 | depends on MEMORY_HOTPLUG | 335 | depends on MEMORY_HOTPLUG |
335 | default n | 336 | default n |
336 | help | 337 | help |
@@ -359,5 +360,3 @@ config ACPI_SBS | |||
359 | to today's ACPI "Control Method" battery. | 360 | to today's ACPI "Control Method" battery. |
360 | 361 | ||
361 | endif # ACPI | 362 | endif # ACPI |
362 | |||
363 | endmenu | ||
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index e64c76c8b726..cad932de383d 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -43,21 +43,30 @@ | |||
43 | #define ACPI_BATTERY_CLASS "battery" | 43 | #define ACPI_BATTERY_CLASS "battery" |
44 | #define ACPI_BATTERY_HID "PNP0C0A" | 44 | #define ACPI_BATTERY_HID "PNP0C0A" |
45 | #define ACPI_BATTERY_DEVICE_NAME "Battery" | 45 | #define ACPI_BATTERY_DEVICE_NAME "Battery" |
46 | #define ACPI_BATTERY_FILE_INFO "info" | ||
47 | #define ACPI_BATTERY_FILE_STATUS "state" | ||
48 | #define ACPI_BATTERY_FILE_ALARM "alarm" | ||
49 | #define ACPI_BATTERY_NOTIFY_STATUS 0x80 | 46 | #define ACPI_BATTERY_NOTIFY_STATUS 0x80 |
50 | #define ACPI_BATTERY_NOTIFY_INFO 0x81 | 47 | #define ACPI_BATTERY_NOTIFY_INFO 0x81 |
51 | #define ACPI_BATTERY_UNITS_WATTS "mW" | 48 | #define ACPI_BATTERY_UNITS_WATTS "mW" |
52 | #define ACPI_BATTERY_UNITS_AMPS "mA" | 49 | #define ACPI_BATTERY_UNITS_AMPS "mA" |
53 | 50 | ||
54 | #define _COMPONENT ACPI_BATTERY_COMPONENT | 51 | #define _COMPONENT ACPI_BATTERY_COMPONENT |
52 | |||
53 | #define ACPI_BATTERY_UPDATE_TIME 0 | ||
54 | |||
55 | #define ACPI_BATTERY_NONE_UPDATE 0 | ||
56 | #define ACPI_BATTERY_EASY_UPDATE 1 | ||
57 | #define ACPI_BATTERY_INIT_UPDATE 2 | ||
58 | |||
55 | ACPI_MODULE_NAME("battery"); | 59 | ACPI_MODULE_NAME("battery"); |
56 | 60 | ||
57 | MODULE_AUTHOR("Paul Diefenbaugh"); | 61 | MODULE_AUTHOR("Paul Diefenbaugh"); |
58 | MODULE_DESCRIPTION("ACPI Battery Driver"); | 62 | MODULE_DESCRIPTION("ACPI Battery Driver"); |
59 | MODULE_LICENSE("GPL"); | 63 | MODULE_LICENSE("GPL"); |
60 | 64 | ||
65 | static unsigned int update_time = ACPI_BATTERY_UPDATE_TIME; | ||
66 | |||
67 | /* 0 - every time, > 0 - by update_time */ | ||
68 | module_param(update_time, uint, 0644); | ||
69 | |||
61 | extern struct proc_dir_entry *acpi_lock_battery_dir(void); | 70 | extern struct proc_dir_entry *acpi_lock_battery_dir(void); |
62 | extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); | 71 | extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); |
63 | 72 | ||
@@ -76,7 +85,7 @@ static struct acpi_driver acpi_battery_driver = { | |||
76 | }, | 85 | }, |
77 | }; | 86 | }; |
78 | 87 | ||
79 | struct acpi_battery_status { | 88 | struct acpi_battery_state { |
80 | acpi_integer state; | 89 | acpi_integer state; |
81 | acpi_integer present_rate; | 90 | acpi_integer present_rate; |
82 | acpi_integer remaining_capacity; | 91 | acpi_integer remaining_capacity; |
@@ -99,33 +108,111 @@ struct acpi_battery_info { | |||
99 | acpi_string oem_info; | 108 | acpi_string oem_info; |
100 | }; | 109 | }; |
101 | 110 | ||
102 | struct acpi_battery_flags { | 111 | enum acpi_battery_files{ |
103 | u8 present:1; /* Bay occupied? */ | 112 | ACPI_BATTERY_INFO = 0, |
104 | u8 power_unit:1; /* 0=watts, 1=apms */ | 113 | ACPI_BATTERY_STATE, |
105 | u8 alarm:1; /* _BTP present? */ | 114 | ACPI_BATTERY_ALARM, |
106 | u8 reserved:5; | 115 | ACPI_BATTERY_NUMFILES, |
107 | }; | 116 | }; |
108 | 117 | ||
109 | struct acpi_battery_trips { | 118 | struct acpi_battery_flags { |
110 | unsigned long warning; | 119 | u8 battery_present_prev; |
111 | unsigned long low; | 120 | u8 alarm_present; |
121 | u8 init_update; | ||
122 | u8 update[ACPI_BATTERY_NUMFILES]; | ||
123 | u8 power_unit; | ||
112 | }; | 124 | }; |
113 | 125 | ||
114 | struct acpi_battery { | 126 | struct acpi_battery { |
115 | struct acpi_device * device; | 127 | struct mutex mutex; |
128 | struct acpi_device *device; | ||
116 | struct acpi_battery_flags flags; | 129 | struct acpi_battery_flags flags; |
117 | struct acpi_battery_trips trips; | 130 | struct acpi_buffer bif_data; |
131 | struct acpi_buffer bst_data; | ||
118 | unsigned long alarm; | 132 | unsigned long alarm; |
119 | struct acpi_battery_info *info; | 133 | unsigned long update_time[ACPI_BATTERY_NUMFILES]; |
120 | }; | 134 | }; |
121 | 135 | ||
136 | inline int acpi_battery_present(struct acpi_battery *battery) | ||
137 | { | ||
138 | return battery->device->status.battery_present; | ||
139 | } | ||
140 | inline char *acpi_battery_power_units(struct acpi_battery *battery) | ||
141 | { | ||
142 | if (battery->flags.power_unit) | ||
143 | return ACPI_BATTERY_UNITS_AMPS; | ||
144 | else | ||
145 | return ACPI_BATTERY_UNITS_WATTS; | ||
146 | } | ||
147 | |||
148 | inline acpi_handle acpi_battery_handle(struct acpi_battery *battery) | ||
149 | { | ||
150 | return battery->device->handle; | ||
151 | } | ||
152 | |||
122 | /* -------------------------------------------------------------------------- | 153 | /* -------------------------------------------------------------------------- |
123 | Battery Management | 154 | Battery Management |
124 | -------------------------------------------------------------------------- */ | 155 | -------------------------------------------------------------------------- */ |
125 | 156 | ||
126 | static int | 157 | static void acpi_battery_check_result(struct acpi_battery *battery, int result) |
127 | acpi_battery_get_info(struct acpi_battery *battery, | 158 | { |
128 | struct acpi_battery_info **bif) | 159 | if (!battery) |
160 | return; | ||
161 | |||
162 | if (result) { | ||
163 | battery->flags.init_update = 1; | ||
164 | } | ||
165 | } | ||
166 | |||
167 | static int acpi_battery_extract_package(struct acpi_battery *battery, | ||
168 | union acpi_object *package, | ||
169 | struct acpi_buffer *format, | ||
170 | struct acpi_buffer *data, | ||
171 | char *package_name) | ||
172 | { | ||
173 | acpi_status status = AE_OK; | ||
174 | struct acpi_buffer data_null = { 0, NULL }; | ||
175 | |||
176 | status = acpi_extract_package(package, format, &data_null); | ||
177 | if (status != AE_BUFFER_OVERFLOW) { | ||
178 | ACPI_EXCEPTION((AE_INFO, status, "Extracting size %s", | ||
179 | package_name)); | ||
180 | return -ENODEV; | ||
181 | } | ||
182 | |||
183 | if (data_null.length != data->length) { | ||
184 | kfree(data->pointer); | ||
185 | data->pointer = kzalloc(data_null.length, GFP_KERNEL); | ||
186 | if (!data->pointer) { | ||
187 | ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "kzalloc()")); | ||
188 | return -ENOMEM; | ||
189 | } | ||
190 | data->length = data_null.length; | ||
191 | } | ||
192 | |||
193 | status = acpi_extract_package(package, format, data); | ||
194 | if (ACPI_FAILURE(status)) { | ||
195 | ACPI_EXCEPTION((AE_INFO, status, "Extracting %s", | ||
196 | package_name)); | ||
197 | return -ENODEV; | ||
198 | } | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | static int acpi_battery_get_status(struct acpi_battery *battery) | ||
204 | { | ||
205 | int result = 0; | ||
206 | |||
207 | result = acpi_bus_get_status(battery->device); | ||
208 | if (result) { | ||
209 | ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA")); | ||
210 | return -ENODEV; | ||
211 | } | ||
212 | return result; | ||
213 | } | ||
214 | |||
215 | static int acpi_battery_get_info(struct acpi_battery *battery) | ||
129 | { | 216 | { |
130 | int result = 0; | 217 | int result = 0; |
131 | acpi_status status = 0; | 218 | acpi_status status = 0; |
@@ -133,16 +220,20 @@ acpi_battery_get_info(struct acpi_battery *battery, | |||
133 | struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BIF), | 220 | struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BIF), |
134 | ACPI_BATTERY_FORMAT_BIF | 221 | ACPI_BATTERY_FORMAT_BIF |
135 | }; | 222 | }; |
136 | struct acpi_buffer data = { 0, NULL }; | ||
137 | union acpi_object *package = NULL; | 223 | union acpi_object *package = NULL; |
224 | struct acpi_buffer *data = NULL; | ||
225 | struct acpi_battery_info *bif = NULL; | ||
138 | 226 | ||
227 | battery->update_time[ACPI_BATTERY_INFO] = get_seconds(); | ||
139 | 228 | ||
140 | if (!battery || !bif) | 229 | if (!acpi_battery_present(battery)) |
141 | return -EINVAL; | 230 | return 0; |
142 | 231 | ||
143 | /* Evalute _BIF */ | 232 | /* Evaluate _BIF */ |
144 | 233 | ||
145 | status = acpi_evaluate_object(battery->device->handle, "_BIF", NULL, &buffer); | 234 | status = |
235 | acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", NULL, | ||
236 | &buffer); | ||
146 | if (ACPI_FAILURE(status)) { | 237 | if (ACPI_FAILURE(status)) { |
147 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); | 238 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); |
148 | return -ENODEV; | 239 | return -ENODEV; |
@@ -150,41 +241,29 @@ acpi_battery_get_info(struct acpi_battery *battery, | |||
150 | 241 | ||
151 | package = buffer.pointer; | 242 | package = buffer.pointer; |
152 | 243 | ||
153 | /* Extract Package Data */ | 244 | data = &battery->bif_data; |
154 | |||
155 | status = acpi_extract_package(package, &format, &data); | ||
156 | if (status != AE_BUFFER_OVERFLOW) { | ||
157 | ACPI_EXCEPTION((AE_INFO, status, "Extracting _BIF")); | ||
158 | result = -ENODEV; | ||
159 | goto end; | ||
160 | } | ||
161 | 245 | ||
162 | data.pointer = kzalloc(data.length, GFP_KERNEL); | 246 | /* Extract Package Data */ |
163 | if (!data.pointer) { | ||
164 | result = -ENOMEM; | ||
165 | goto end; | ||
166 | } | ||
167 | 247 | ||
168 | status = acpi_extract_package(package, &format, &data); | 248 | result = |
169 | if (ACPI_FAILURE(status)) { | 249 | acpi_battery_extract_package(battery, package, &format, data, |
170 | ACPI_EXCEPTION((AE_INFO, status, "Extracting _BIF")); | 250 | "_BIF"); |
171 | kfree(data.pointer); | 251 | if (result) |
172 | result = -ENODEV; | ||
173 | goto end; | 252 | goto end; |
174 | } | ||
175 | 253 | ||
176 | end: | 254 | end: |
255 | |||
177 | kfree(buffer.pointer); | 256 | kfree(buffer.pointer); |
178 | 257 | ||
179 | if (!result) | 258 | if (!result) { |
180 | (*bif) = data.pointer; | 259 | bif = data->pointer; |
260 | battery->flags.power_unit = bif->power_unit; | ||
261 | } | ||
181 | 262 | ||
182 | return result; | 263 | return result; |
183 | } | 264 | } |
184 | 265 | ||
185 | static int | 266 | static int acpi_battery_get_state(struct acpi_battery *battery) |
186 | acpi_battery_get_status(struct acpi_battery *battery, | ||
187 | struct acpi_battery_status **bst) | ||
188 | { | 267 | { |
189 | int result = 0; | 268 | int result = 0; |
190 | acpi_status status = 0; | 269 | acpi_status status = 0; |
@@ -192,16 +271,19 @@ acpi_battery_get_status(struct acpi_battery *battery, | |||
192 | struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BST), | 271 | struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BST), |
193 | ACPI_BATTERY_FORMAT_BST | 272 | ACPI_BATTERY_FORMAT_BST |
194 | }; | 273 | }; |
195 | struct acpi_buffer data = { 0, NULL }; | ||
196 | union acpi_object *package = NULL; | 274 | union acpi_object *package = NULL; |
275 | struct acpi_buffer *data = NULL; | ||
197 | 276 | ||
277 | battery->update_time[ACPI_BATTERY_STATE] = get_seconds(); | ||
198 | 278 | ||
199 | if (!battery || !bst) | 279 | if (!acpi_battery_present(battery)) |
200 | return -EINVAL; | 280 | return 0; |
201 | 281 | ||
202 | /* Evalute _BST */ | 282 | /* Evaluate _BST */ |
203 | 283 | ||
204 | status = acpi_evaluate_object(battery->device->handle, "_BST", NULL, &buffer); | 284 | status = |
285 | acpi_evaluate_object(acpi_battery_handle(battery), "_BST", NULL, | ||
286 | &buffer); | ||
205 | if (ACPI_FAILURE(status)) { | 287 | if (ACPI_FAILURE(status)) { |
206 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); | 288 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); |
207 | return -ENODEV; | 289 | return -ENODEV; |
@@ -209,55 +291,49 @@ acpi_battery_get_status(struct acpi_battery *battery, | |||
209 | 291 | ||
210 | package = buffer.pointer; | 292 | package = buffer.pointer; |
211 | 293 | ||
212 | /* Extract Package Data */ | 294 | data = &battery->bst_data; |
213 | |||
214 | status = acpi_extract_package(package, &format, &data); | ||
215 | if (status != AE_BUFFER_OVERFLOW) { | ||
216 | ACPI_EXCEPTION((AE_INFO, status, "Extracting _BST")); | ||
217 | result = -ENODEV; | ||
218 | goto end; | ||
219 | } | ||
220 | 295 | ||
221 | data.pointer = kzalloc(data.length, GFP_KERNEL); | 296 | /* Extract Package Data */ |
222 | if (!data.pointer) { | ||
223 | result = -ENOMEM; | ||
224 | goto end; | ||
225 | } | ||
226 | 297 | ||
227 | status = acpi_extract_package(package, &format, &data); | 298 | result = |
228 | if (ACPI_FAILURE(status)) { | 299 | acpi_battery_extract_package(battery, package, &format, data, |
229 | ACPI_EXCEPTION((AE_INFO, status, "Extracting _BST")); | 300 | "_BST"); |
230 | kfree(data.pointer); | 301 | if (result) |
231 | result = -ENODEV; | ||
232 | goto end; | 302 | goto end; |
233 | } | ||
234 | 303 | ||
235 | end: | 304 | end: |
236 | kfree(buffer.pointer); | 305 | kfree(buffer.pointer); |
237 | 306 | ||
238 | if (!result) | ||
239 | (*bst) = data.pointer; | ||
240 | |||
241 | return result; | 307 | return result; |
242 | } | 308 | } |
243 | 309 | ||
244 | static int | 310 | static int acpi_battery_get_alarm(struct acpi_battery *battery) |
245 | acpi_battery_set_alarm(struct acpi_battery *battery, unsigned long alarm) | 311 | { |
312 | battery->update_time[ACPI_BATTERY_ALARM] = get_seconds(); | ||
313 | |||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | static int acpi_battery_set_alarm(struct acpi_battery *battery, | ||
318 | unsigned long alarm) | ||
246 | { | 319 | { |
247 | acpi_status status = 0; | 320 | acpi_status status = 0; |
248 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; | 321 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; |
249 | struct acpi_object_list arg_list = { 1, &arg0 }; | 322 | struct acpi_object_list arg_list = { 1, &arg0 }; |
250 | 323 | ||
324 | battery->update_time[ACPI_BATTERY_ALARM] = get_seconds(); | ||
251 | 325 | ||
252 | if (!battery) | 326 | if (!acpi_battery_present(battery)) |
253 | return -EINVAL; | 327 | return -ENODEV; |
254 | 328 | ||
255 | if (!battery->flags.alarm) | 329 | if (!battery->flags.alarm_present) |
256 | return -ENODEV; | 330 | return -ENODEV; |
257 | 331 | ||
258 | arg0.integer.value = alarm; | 332 | arg0.integer.value = alarm; |
259 | 333 | ||
260 | status = acpi_evaluate_object(battery->device->handle, "_BTP", &arg_list, NULL); | 334 | status = |
335 | acpi_evaluate_object(acpi_battery_handle(battery), "_BTP", | ||
336 | &arg_list, NULL); | ||
261 | if (ACPI_FAILURE(status)) | 337 | if (ACPI_FAILURE(status)) |
262 | return -ENODEV; | 338 | return -ENODEV; |
263 | 339 | ||
@@ -268,65 +344,114 @@ acpi_battery_set_alarm(struct acpi_battery *battery, unsigned long alarm) | |||
268 | return 0; | 344 | return 0; |
269 | } | 345 | } |
270 | 346 | ||
271 | static int acpi_battery_check(struct acpi_battery *battery) | 347 | static int acpi_battery_init_alarm(struct acpi_battery *battery) |
272 | { | 348 | { |
273 | int result = 0; | 349 | int result = 0; |
274 | acpi_status status = AE_OK; | 350 | acpi_status status = AE_OK; |
275 | acpi_handle handle = NULL; | 351 | acpi_handle handle = NULL; |
276 | struct acpi_device *device = NULL; | 352 | struct acpi_battery_info *bif = battery->bif_data.pointer; |
277 | struct acpi_battery_info *bif = NULL; | 353 | unsigned long alarm = battery->alarm; |
278 | 354 | ||
355 | /* See if alarms are supported, and if so, set default */ | ||
279 | 356 | ||
280 | if (!battery) | 357 | status = acpi_get_handle(acpi_battery_handle(battery), "_BTP", &handle); |
281 | return -EINVAL; | 358 | if (ACPI_SUCCESS(status)) { |
282 | 359 | battery->flags.alarm_present = 1; | |
283 | device = battery->device; | 360 | if (!alarm && bif) { |
361 | alarm = bif->design_capacity_warning; | ||
362 | } | ||
363 | result = acpi_battery_set_alarm(battery, alarm); | ||
364 | if (result) | ||
365 | goto end; | ||
366 | } else { | ||
367 | battery->flags.alarm_present = 0; | ||
368 | } | ||
284 | 369 | ||
285 | result = acpi_bus_get_status(device); | 370 | end: |
286 | if (result) | ||
287 | return result; | ||
288 | 371 | ||
289 | /* Insertion? */ | 372 | return result; |
373 | } | ||
290 | 374 | ||
291 | if (!battery->flags.present && device->status.battery_present) { | 375 | static int acpi_battery_init_update(struct acpi_battery *battery) |
376 | { | ||
377 | int result = 0; | ||
292 | 378 | ||
293 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Battery inserted\n")); | 379 | result = acpi_battery_get_status(battery); |
380 | if (result) | ||
381 | return result; | ||
294 | 382 | ||
295 | /* Evalute _BIF to get certain static information */ | 383 | battery->flags.battery_present_prev = acpi_battery_present(battery); |
296 | 384 | ||
297 | result = acpi_battery_get_info(battery, &bif); | 385 | if (acpi_battery_present(battery)) { |
386 | result = acpi_battery_get_info(battery); | ||
387 | if (result) | ||
388 | return result; | ||
389 | result = acpi_battery_get_state(battery); | ||
298 | if (result) | 390 | if (result) |
299 | return result; | 391 | return result; |
300 | 392 | ||
301 | battery->flags.power_unit = bif->power_unit; | 393 | acpi_battery_init_alarm(battery); |
302 | battery->trips.warning = bif->design_capacity_warning; | 394 | } |
303 | battery->trips.low = bif->design_capacity_low; | 395 | |
304 | kfree(bif); | 396 | return result; |
397 | } | ||
305 | 398 | ||
306 | /* See if alarms are supported, and if so, set default */ | 399 | static int acpi_battery_update(struct acpi_battery *battery, |
400 | int update, int *update_result_ptr) | ||
401 | { | ||
402 | int result = 0; | ||
403 | int update_result = ACPI_BATTERY_NONE_UPDATE; | ||
404 | |||
405 | if (!acpi_battery_present(battery)) { | ||
406 | update = 1; | ||
407 | } | ||
307 | 408 | ||
308 | status = acpi_get_handle(battery->device->handle, "_BTP", &handle); | 409 | if (battery->flags.init_update) { |
309 | if (ACPI_SUCCESS(status)) { | 410 | result = acpi_battery_init_update(battery); |
310 | battery->flags.alarm = 1; | 411 | if (result) |
311 | acpi_battery_set_alarm(battery, battery->trips.warning); | 412 | goto end; |
413 | update_result = ACPI_BATTERY_INIT_UPDATE; | ||
414 | } else if (update) { | ||
415 | result = acpi_battery_get_status(battery); | ||
416 | if (result) | ||
417 | goto end; | ||
418 | if ((!battery->flags.battery_present_prev & acpi_battery_present(battery)) | ||
419 | || (battery->flags.battery_present_prev & !acpi_battery_present(battery))) { | ||
420 | result = acpi_battery_init_update(battery); | ||
421 | if (result) | ||
422 | goto end; | ||
423 | update_result = ACPI_BATTERY_INIT_UPDATE; | ||
424 | } else { | ||
425 | update_result = ACPI_BATTERY_EASY_UPDATE; | ||
312 | } | 426 | } |
313 | } | 427 | } |
314 | 428 | ||
315 | /* Removal? */ | 429 | end: |
316 | 430 | ||
317 | else if (battery->flags.present && !device->status.battery_present) { | 431 | battery->flags.init_update = (result != 0); |
318 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Battery removed\n")); | ||
319 | } | ||
320 | 432 | ||
321 | battery->flags.present = device->status.battery_present; | 433 | *update_result_ptr = update_result; |
322 | 434 | ||
323 | return result; | 435 | return result; |
324 | } | 436 | } |
325 | 437 | ||
326 | static void acpi_battery_check_present(struct acpi_battery *battery) | 438 | static void acpi_battery_notify_update(struct acpi_battery *battery) |
327 | { | 439 | { |
328 | if (!battery->flags.present) { | 440 | acpi_battery_get_status(battery); |
329 | acpi_battery_check(battery); | 441 | |
442 | if (battery->flags.init_update) { | ||
443 | return; | ||
444 | } | ||
445 | |||
446 | if ((!battery->flags.battery_present_prev & | ||
447 | acpi_battery_present(battery)) || | ||
448 | (battery->flags.battery_present_prev & | ||
449 | !acpi_battery_present(battery))) { | ||
450 | battery->flags.init_update = 1; | ||
451 | } else { | ||
452 | battery->flags.update[ACPI_BATTERY_INFO] = 1; | ||
453 | battery->flags.update[ACPI_BATTERY_STATE] = 1; | ||
454 | battery->flags.update[ACPI_BATTERY_ALARM] = 1; | ||
330 | } | 455 | } |
331 | } | 456 | } |
332 | 457 | ||
@@ -335,37 +460,33 @@ static void acpi_battery_check_present(struct acpi_battery *battery) | |||
335 | -------------------------------------------------------------------------- */ | 460 | -------------------------------------------------------------------------- */ |
336 | 461 | ||
337 | static struct proc_dir_entry *acpi_battery_dir; | 462 | static struct proc_dir_entry *acpi_battery_dir; |
338 | static int acpi_battery_read_info(struct seq_file *seq, void *offset) | 463 | |
464 | static int acpi_battery_print_info(struct seq_file *seq, int result) | ||
339 | { | 465 | { |
340 | int result = 0; | ||
341 | struct acpi_battery *battery = seq->private; | 466 | struct acpi_battery *battery = seq->private; |
342 | struct acpi_battery_info *bif = NULL; | 467 | struct acpi_battery_info *bif = NULL; |
343 | char *units = "?"; | 468 | char *units = "?"; |
344 | 469 | ||
345 | 470 | if (result) | |
346 | if (!battery) | ||
347 | goto end; | 471 | goto end; |
348 | 472 | ||
349 | acpi_battery_check_present(battery); | 473 | if (acpi_battery_present(battery)) |
350 | |||
351 | if (battery->flags.present) | ||
352 | seq_printf(seq, "present: yes\n"); | 474 | seq_printf(seq, "present: yes\n"); |
353 | else { | 475 | else { |
354 | seq_printf(seq, "present: no\n"); | 476 | seq_printf(seq, "present: no\n"); |
355 | goto end; | 477 | goto end; |
356 | } | 478 | } |
357 | 479 | ||
358 | /* Battery Info (_BIF) */ | 480 | bif = battery->bif_data.pointer; |
359 | 481 | if (!bif) { | |
360 | result = acpi_battery_get_info(battery, &bif); | 482 | ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BIF buffer is NULL")); |
361 | if (result || !bif) { | 483 | result = -ENODEV; |
362 | seq_printf(seq, "ERROR: Unable to read battery information\n"); | ||
363 | goto end; | 484 | goto end; |
364 | } | 485 | } |
365 | 486 | ||
366 | units = | 487 | /* Battery Units */ |
367 | bif-> | 488 | |
368 | power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS; | 489 | units = acpi_battery_power_units(battery); |
369 | 490 | ||
370 | if (bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) | 491 | if (bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) |
371 | seq_printf(seq, "design capacity: unknown\n"); | 492 | seq_printf(seq, "design capacity: unknown\n"); |
@@ -396,7 +517,6 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset) | |||
396 | else | 517 | else |
397 | seq_printf(seq, "design voltage: %d mV\n", | 518 | seq_printf(seq, "design voltage: %d mV\n", |
398 | (u32) bif->design_voltage); | 519 | (u32) bif->design_voltage); |
399 | |||
400 | seq_printf(seq, "design capacity warning: %d %sh\n", | 520 | seq_printf(seq, "design capacity warning: %d %sh\n", |
401 | (u32) bif->design_capacity_warning, units); | 521 | (u32) bif->design_capacity_warning, units); |
402 | seq_printf(seq, "design capacity low: %d %sh\n", | 522 | seq_printf(seq, "design capacity low: %d %sh\n", |
@@ -411,50 +531,40 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset) | |||
411 | seq_printf(seq, "OEM info: %s\n", bif->oem_info); | 531 | seq_printf(seq, "OEM info: %s\n", bif->oem_info); |
412 | 532 | ||
413 | end: | 533 | end: |
414 | kfree(bif); | ||
415 | 534 | ||
416 | return 0; | 535 | if (result) |
417 | } | 536 | seq_printf(seq, "ERROR: Unable to read battery info\n"); |
418 | 537 | ||
419 | static int acpi_battery_info_open_fs(struct inode *inode, struct file *file) | 538 | return result; |
420 | { | ||
421 | return single_open(file, acpi_battery_read_info, PDE(inode)->data); | ||
422 | } | 539 | } |
423 | 540 | ||
424 | static int acpi_battery_read_state(struct seq_file *seq, void *offset) | 541 | static int acpi_battery_print_state(struct seq_file *seq, int result) |
425 | { | 542 | { |
426 | int result = 0; | ||
427 | struct acpi_battery *battery = seq->private; | 543 | struct acpi_battery *battery = seq->private; |
428 | struct acpi_battery_status *bst = NULL; | 544 | struct acpi_battery_state *bst = NULL; |
429 | char *units = "?"; | 545 | char *units = "?"; |
430 | 546 | ||
431 | 547 | if (result) | |
432 | if (!battery) | ||
433 | goto end; | 548 | goto end; |
434 | 549 | ||
435 | acpi_battery_check_present(battery); | 550 | if (acpi_battery_present(battery)) |
436 | |||
437 | if (battery->flags.present) | ||
438 | seq_printf(seq, "present: yes\n"); | 551 | seq_printf(seq, "present: yes\n"); |
439 | else { | 552 | else { |
440 | seq_printf(seq, "present: no\n"); | 553 | seq_printf(seq, "present: no\n"); |
441 | goto end; | 554 | goto end; |
442 | } | 555 | } |
443 | 556 | ||
444 | /* Battery Units */ | 557 | bst = battery->bst_data.pointer; |
445 | 558 | if (!bst) { | |
446 | units = | 559 | ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BST buffer is NULL")); |
447 | battery->flags. | 560 | result = -ENODEV; |
448 | power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS; | ||
449 | |||
450 | /* Battery Status (_BST) */ | ||
451 | |||
452 | result = acpi_battery_get_status(battery, &bst); | ||
453 | if (result || !bst) { | ||
454 | seq_printf(seq, "ERROR: Unable to read battery status\n"); | ||
455 | goto end; | 561 | goto end; |
456 | } | 562 | } |
457 | 563 | ||
564 | /* Battery Units */ | ||
565 | |||
566 | units = acpi_battery_power_units(battery); | ||
567 | |||
458 | if (!(bst->state & 0x04)) | 568 | if (!(bst->state & 0x04)) |
459 | seq_printf(seq, "capacity state: ok\n"); | 569 | seq_printf(seq, "capacity state: ok\n"); |
460 | else | 570 | else |
@@ -490,48 +600,43 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset) | |||
490 | (u32) bst->present_voltage); | 600 | (u32) bst->present_voltage); |
491 | 601 | ||
492 | end: | 602 | end: |
493 | kfree(bst); | ||
494 | 603 | ||
495 | return 0; | 604 | if (result) { |
496 | } | 605 | seq_printf(seq, "ERROR: Unable to read battery state\n"); |
606 | } | ||
497 | 607 | ||
498 | static int acpi_battery_state_open_fs(struct inode *inode, struct file *file) | 608 | return result; |
499 | { | ||
500 | return single_open(file, acpi_battery_read_state, PDE(inode)->data); | ||
501 | } | 609 | } |
502 | 610 | ||
503 | static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) | 611 | static int acpi_battery_print_alarm(struct seq_file *seq, int result) |
504 | { | 612 | { |
505 | struct acpi_battery *battery = seq->private; | 613 | struct acpi_battery *battery = seq->private; |
506 | char *units = "?"; | 614 | char *units = "?"; |
507 | 615 | ||
508 | 616 | if (result) | |
509 | if (!battery) | ||
510 | goto end; | 617 | goto end; |
511 | 618 | ||
512 | acpi_battery_check_present(battery); | 619 | if (!acpi_battery_present(battery)) { |
513 | |||
514 | if (!battery->flags.present) { | ||
515 | seq_printf(seq, "present: no\n"); | 620 | seq_printf(seq, "present: no\n"); |
516 | goto end; | 621 | goto end; |
517 | } | 622 | } |
518 | 623 | ||
519 | /* Battery Units */ | 624 | /* Battery Units */ |
520 | 625 | ||
521 | units = | 626 | units = acpi_battery_power_units(battery); |
522 | battery->flags. | ||
523 | power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS; | ||
524 | |||
525 | /* Battery Alarm */ | ||
526 | 627 | ||
527 | seq_printf(seq, "alarm: "); | 628 | seq_printf(seq, "alarm: "); |
528 | if (!battery->alarm) | 629 | if (!battery->alarm) |
529 | seq_printf(seq, "unsupported\n"); | 630 | seq_printf(seq, "unsupported\n"); |
530 | else | 631 | else |
531 | seq_printf(seq, "%d %sh\n", (u32) battery->alarm, units); | 632 | seq_printf(seq, "%lu %sh\n", battery->alarm, units); |
532 | 633 | ||
533 | end: | 634 | end: |
534 | return 0; | 635 | |
636 | if (result) | ||
637 | seq_printf(seq, "ERROR: Unable to read battery alarm\n"); | ||
638 | |||
639 | return result; | ||
535 | } | 640 | } |
536 | 641 | ||
537 | static ssize_t | 642 | static ssize_t |
@@ -543,27 +648,113 @@ acpi_battery_write_alarm(struct file *file, | |||
543 | char alarm_string[12] = { '\0' }; | 648 | char alarm_string[12] = { '\0' }; |
544 | struct seq_file *m = file->private_data; | 649 | struct seq_file *m = file->private_data; |
545 | struct acpi_battery *battery = m->private; | 650 | struct acpi_battery *battery = m->private; |
546 | 651 | int update_result = ACPI_BATTERY_NONE_UPDATE; | |
547 | 652 | ||
548 | if (!battery || (count > sizeof(alarm_string) - 1)) | 653 | if (!battery || (count > sizeof(alarm_string) - 1)) |
549 | return -EINVAL; | 654 | return -EINVAL; |
550 | 655 | ||
551 | acpi_battery_check_present(battery); | 656 | mutex_lock(&battery->mutex); |
552 | 657 | ||
553 | if (!battery->flags.present) | 658 | result = acpi_battery_update(battery, 1, &update_result); |
554 | return -ENODEV; | 659 | if (result) { |
660 | result = -ENODEV; | ||
661 | goto end; | ||
662 | } | ||
663 | |||
664 | if (!acpi_battery_present(battery)) { | ||
665 | result = -ENODEV; | ||
666 | goto end; | ||
667 | } | ||
555 | 668 | ||
556 | if (copy_from_user(alarm_string, buffer, count)) | 669 | if (copy_from_user(alarm_string, buffer, count)) { |
557 | return -EFAULT; | 670 | result = -EFAULT; |
671 | goto end; | ||
672 | } | ||
558 | 673 | ||
559 | alarm_string[count] = '\0'; | 674 | alarm_string[count] = '\0'; |
560 | 675 | ||
561 | result = acpi_battery_set_alarm(battery, | 676 | result = acpi_battery_set_alarm(battery, |
562 | simple_strtoul(alarm_string, NULL, 0)); | 677 | simple_strtoul(alarm_string, NULL, 0)); |
563 | if (result) | 678 | if (result) |
564 | return result; | 679 | goto end; |
680 | |||
681 | end: | ||
565 | 682 | ||
566 | return count; | 683 | acpi_battery_check_result(battery, result); |
684 | |||
685 | if (!result) | ||
686 | result = count; | ||
687 | |||
688 | mutex_unlock(&battery->mutex); | ||
689 | |||
690 | return result; | ||
691 | } | ||
692 | |||
693 | typedef int(*print_func)(struct seq_file *seq, int result); | ||
694 | typedef int(*get_func)(struct acpi_battery *battery); | ||
695 | |||
696 | static struct acpi_read_mux { | ||
697 | print_func print; | ||
698 | get_func get; | ||
699 | } acpi_read_funcs[ACPI_BATTERY_NUMFILES] = { | ||
700 | {.get = acpi_battery_get_info, .print = acpi_battery_print_info}, | ||
701 | {.get = acpi_battery_get_state, .print = acpi_battery_print_state}, | ||
702 | {.get = acpi_battery_get_alarm, .print = acpi_battery_print_alarm}, | ||
703 | }; | ||
704 | |||
705 | static int acpi_battery_read(int fid, struct seq_file *seq) | ||
706 | { | ||
707 | struct acpi_battery *battery = seq->private; | ||
708 | int result = 0; | ||
709 | int update_result = ACPI_BATTERY_NONE_UPDATE; | ||
710 | int update = 0; | ||
711 | |||
712 | mutex_lock(&battery->mutex); | ||
713 | |||
714 | update = (get_seconds() - battery->update_time[fid] >= update_time); | ||
715 | update = (update | battery->flags.update[fid]); | ||
716 | |||
717 | result = acpi_battery_update(battery, update, &update_result); | ||
718 | if (result) | ||
719 | goto end; | ||
720 | |||
721 | if (update_result == ACPI_BATTERY_EASY_UPDATE) { | ||
722 | result = acpi_read_funcs[fid].get(battery); | ||
723 | if (result) | ||
724 | goto end; | ||
725 | } | ||
726 | |||
727 | end: | ||
728 | result = acpi_read_funcs[fid].print(seq, result); | ||
729 | acpi_battery_check_result(battery, result); | ||
730 | battery->flags.update[fid] = result; | ||
731 | mutex_unlock(&battery->mutex); | ||
732 | return result; | ||
733 | } | ||
734 | |||
735 | static int acpi_battery_read_info(struct seq_file *seq, void *offset) | ||
736 | { | ||
737 | return acpi_battery_read(ACPI_BATTERY_INFO, seq); | ||
738 | } | ||
739 | |||
740 | static int acpi_battery_read_state(struct seq_file *seq, void *offset) | ||
741 | { | ||
742 | return acpi_battery_read(ACPI_BATTERY_STATE, seq); | ||
743 | } | ||
744 | |||
745 | static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) | ||
746 | { | ||
747 | return acpi_battery_read(ACPI_BATTERY_ALARM, seq); | ||
748 | } | ||
749 | |||
750 | static int acpi_battery_info_open_fs(struct inode *inode, struct file *file) | ||
751 | { | ||
752 | return single_open(file, acpi_battery_read_info, PDE(inode)->data); | ||
753 | } | ||
754 | |||
755 | static int acpi_battery_state_open_fs(struct inode *inode, struct file *file) | ||
756 | { | ||
757 | return single_open(file, acpi_battery_read_state, PDE(inode)->data); | ||
567 | } | 758 | } |
568 | 759 | ||
569 | static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file) | 760 | static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file) |
@@ -571,35 +762,51 @@ static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file) | |||
571 | return single_open(file, acpi_battery_read_alarm, PDE(inode)->data); | 762 | return single_open(file, acpi_battery_read_alarm, PDE(inode)->data); |
572 | } | 763 | } |
573 | 764 | ||
574 | static const struct file_operations acpi_battery_info_ops = { | 765 | static struct battery_file { |
766 | struct file_operations ops; | ||
767 | mode_t mode; | ||
768 | char *name; | ||
769 | } acpi_battery_file[] = { | ||
770 | { | ||
771 | .name = "info", | ||
772 | .mode = S_IRUGO, | ||
773 | .ops = { | ||
575 | .open = acpi_battery_info_open_fs, | 774 | .open = acpi_battery_info_open_fs, |
576 | .read = seq_read, | 775 | .read = seq_read, |
577 | .llseek = seq_lseek, | 776 | .llseek = seq_lseek, |
578 | .release = single_release, | 777 | .release = single_release, |
579 | .owner = THIS_MODULE, | 778 | .owner = THIS_MODULE, |
580 | }; | 779 | }, |
581 | 780 | }, | |
582 | static const struct file_operations acpi_battery_state_ops = { | 781 | { |
782 | .name = "state", | ||
783 | .mode = S_IRUGO, | ||
784 | .ops = { | ||
583 | .open = acpi_battery_state_open_fs, | 785 | .open = acpi_battery_state_open_fs, |
584 | .read = seq_read, | 786 | .read = seq_read, |
585 | .llseek = seq_lseek, | 787 | .llseek = seq_lseek, |
586 | .release = single_release, | 788 | .release = single_release, |
587 | .owner = THIS_MODULE, | 789 | .owner = THIS_MODULE, |
588 | }; | 790 | }, |
589 | 791 | }, | |
590 | static const struct file_operations acpi_battery_alarm_ops = { | 792 | { |
793 | .name = "alarm", | ||
794 | .mode = S_IFREG | S_IRUGO | S_IWUSR, | ||
795 | .ops = { | ||
591 | .open = acpi_battery_alarm_open_fs, | 796 | .open = acpi_battery_alarm_open_fs, |
592 | .read = seq_read, | 797 | .read = seq_read, |
593 | .write = acpi_battery_write_alarm, | 798 | .write = acpi_battery_write_alarm, |
594 | .llseek = seq_lseek, | 799 | .llseek = seq_lseek, |
595 | .release = single_release, | 800 | .release = single_release, |
596 | .owner = THIS_MODULE, | 801 | .owner = THIS_MODULE, |
802 | }, | ||
803 | }, | ||
597 | }; | 804 | }; |
598 | 805 | ||
599 | static int acpi_battery_add_fs(struct acpi_device *device) | 806 | static int acpi_battery_add_fs(struct acpi_device *device) |
600 | { | 807 | { |
601 | struct proc_dir_entry *entry = NULL; | 808 | struct proc_dir_entry *entry = NULL; |
602 | 809 | int i; | |
603 | 810 | ||
604 | if (!acpi_device_dir(device)) { | 811 | if (!acpi_device_dir(device)) { |
605 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | 812 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), |
@@ -609,38 +816,16 @@ static int acpi_battery_add_fs(struct acpi_device *device) | |||
609 | acpi_device_dir(device)->owner = THIS_MODULE; | 816 | acpi_device_dir(device)->owner = THIS_MODULE; |
610 | } | 817 | } |
611 | 818 | ||
612 | /* 'info' [R] */ | 819 | for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) { |
613 | entry = create_proc_entry(ACPI_BATTERY_FILE_INFO, | 820 | entry = create_proc_entry(acpi_battery_file[i].name, |
614 | S_IRUGO, acpi_device_dir(device)); | 821 | acpi_battery_file[i].mode, acpi_device_dir(device)); |
615 | if (!entry) | 822 | if (!entry) |
616 | return -ENODEV; | 823 | return -ENODEV; |
617 | else { | 824 | else { |
618 | entry->proc_fops = &acpi_battery_info_ops; | 825 | entry->proc_fops = &acpi_battery_file[i].ops; |
619 | entry->data = acpi_driver_data(device); | 826 | entry->data = acpi_driver_data(device); |
620 | entry->owner = THIS_MODULE; | 827 | entry->owner = THIS_MODULE; |
621 | } | 828 | } |
622 | |||
623 | /* 'status' [R] */ | ||
624 | entry = create_proc_entry(ACPI_BATTERY_FILE_STATUS, | ||
625 | S_IRUGO, acpi_device_dir(device)); | ||
626 | if (!entry) | ||
627 | return -ENODEV; | ||
628 | else { | ||
629 | entry->proc_fops = &acpi_battery_state_ops; | ||
630 | entry->data = acpi_driver_data(device); | ||
631 | entry->owner = THIS_MODULE; | ||
632 | } | ||
633 | |||
634 | /* 'alarm' [R/W] */ | ||
635 | entry = create_proc_entry(ACPI_BATTERY_FILE_ALARM, | ||
636 | S_IFREG | S_IRUGO | S_IWUSR, | ||
637 | acpi_device_dir(device)); | ||
638 | if (!entry) | ||
639 | return -ENODEV; | ||
640 | else { | ||
641 | entry->proc_fops = &acpi_battery_alarm_ops; | ||
642 | entry->data = acpi_driver_data(device); | ||
643 | entry->owner = THIS_MODULE; | ||
644 | } | 829 | } |
645 | 830 | ||
646 | return 0; | 831 | return 0; |
@@ -648,15 +833,12 @@ static int acpi_battery_add_fs(struct acpi_device *device) | |||
648 | 833 | ||
649 | static int acpi_battery_remove_fs(struct acpi_device *device) | 834 | static int acpi_battery_remove_fs(struct acpi_device *device) |
650 | { | 835 | { |
651 | 836 | int i; | |
652 | if (acpi_device_dir(device)) { | 837 | if (acpi_device_dir(device)) { |
653 | remove_proc_entry(ACPI_BATTERY_FILE_ALARM, | 838 | for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) { |
839 | remove_proc_entry(acpi_battery_file[i].name, | ||
654 | acpi_device_dir(device)); | 840 | acpi_device_dir(device)); |
655 | remove_proc_entry(ACPI_BATTERY_FILE_STATUS, | 841 | } |
656 | acpi_device_dir(device)); | ||
657 | remove_proc_entry(ACPI_BATTERY_FILE_INFO, | ||
658 | acpi_device_dir(device)); | ||
659 | |||
660 | remove_proc_entry(acpi_device_bid(device), acpi_battery_dir); | 842 | remove_proc_entry(acpi_device_bid(device), acpi_battery_dir); |
661 | acpi_device_dir(device) = NULL; | 843 | acpi_device_dir(device) = NULL; |
662 | } | 844 | } |
@@ -673,7 +855,6 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) | |||
673 | struct acpi_battery *battery = data; | 855 | struct acpi_battery *battery = data; |
674 | struct acpi_device *device = NULL; | 856 | struct acpi_device *device = NULL; |
675 | 857 | ||
676 | |||
677 | if (!battery) | 858 | if (!battery) |
678 | return; | 859 | return; |
679 | 860 | ||
@@ -684,8 +865,10 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) | |||
684 | case ACPI_BATTERY_NOTIFY_INFO: | 865 | case ACPI_BATTERY_NOTIFY_INFO: |
685 | case ACPI_NOTIFY_BUS_CHECK: | 866 | case ACPI_NOTIFY_BUS_CHECK: |
686 | case ACPI_NOTIFY_DEVICE_CHECK: | 867 | case ACPI_NOTIFY_DEVICE_CHECK: |
687 | acpi_battery_check(battery); | 868 | device = battery->device; |
688 | acpi_bus_generate_event(device, event, battery->flags.present); | 869 | acpi_battery_notify_update(battery); |
870 | acpi_bus_generate_event(device, event, | ||
871 | acpi_battery_present(battery)); | ||
689 | break; | 872 | break; |
690 | default: | 873 | default: |
691 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 874 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
@@ -702,7 +885,6 @@ static int acpi_battery_add(struct acpi_device *device) | |||
702 | acpi_status status = 0; | 885 | acpi_status status = 0; |
703 | struct acpi_battery *battery = NULL; | 886 | struct acpi_battery *battery = NULL; |
704 | 887 | ||
705 | |||
706 | if (!device) | 888 | if (!device) |
707 | return -EINVAL; | 889 | return -EINVAL; |
708 | 890 | ||
@@ -710,15 +892,21 @@ static int acpi_battery_add(struct acpi_device *device) | |||
710 | if (!battery) | 892 | if (!battery) |
711 | return -ENOMEM; | 893 | return -ENOMEM; |
712 | 894 | ||
895 | mutex_init(&battery->mutex); | ||
896 | |||
897 | mutex_lock(&battery->mutex); | ||
898 | |||
713 | battery->device = device; | 899 | battery->device = device; |
714 | strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); | 900 | strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); |
715 | strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); | 901 | strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); |
716 | acpi_driver_data(device) = battery; | 902 | acpi_driver_data(device) = battery; |
717 | 903 | ||
718 | result = acpi_battery_check(battery); | 904 | result = acpi_battery_get_status(battery); |
719 | if (result) | 905 | if (result) |
720 | goto end; | 906 | goto end; |
721 | 907 | ||
908 | battery->flags.init_update = 1; | ||
909 | |||
722 | result = acpi_battery_add_fs(device); | 910 | result = acpi_battery_add_fs(device); |
723 | if (result) | 911 | if (result) |
724 | goto end; | 912 | goto end; |
@@ -727,6 +915,7 @@ static int acpi_battery_add(struct acpi_device *device) | |||
727 | ACPI_ALL_NOTIFY, | 915 | ACPI_ALL_NOTIFY, |
728 | acpi_battery_notify, battery); | 916 | acpi_battery_notify, battery); |
729 | if (ACPI_FAILURE(status)) { | 917 | if (ACPI_FAILURE(status)) { |
918 | ACPI_EXCEPTION((AE_INFO, status, "Installing notify handler")); | ||
730 | result = -ENODEV; | 919 | result = -ENODEV; |
731 | goto end; | 920 | goto end; |
732 | } | 921 | } |
@@ -736,11 +925,14 @@ static int acpi_battery_add(struct acpi_device *device) | |||
736 | device->status.battery_present ? "present" : "absent"); | 925 | device->status.battery_present ? "present" : "absent"); |
737 | 926 | ||
738 | end: | 927 | end: |
928 | |||
739 | if (result) { | 929 | if (result) { |
740 | acpi_battery_remove_fs(device); | 930 | acpi_battery_remove_fs(device); |
741 | kfree(battery); | 931 | kfree(battery); |
742 | } | 932 | } |
743 | 933 | ||
934 | mutex_unlock(&battery->mutex); | ||
935 | |||
744 | return result; | 936 | return result; |
745 | } | 937 | } |
746 | 938 | ||
@@ -749,18 +941,27 @@ static int acpi_battery_remove(struct acpi_device *device, int type) | |||
749 | acpi_status status = 0; | 941 | acpi_status status = 0; |
750 | struct acpi_battery *battery = NULL; | 942 | struct acpi_battery *battery = NULL; |
751 | 943 | ||
752 | |||
753 | if (!device || !acpi_driver_data(device)) | 944 | if (!device || !acpi_driver_data(device)) |
754 | return -EINVAL; | 945 | return -EINVAL; |
755 | 946 | ||
756 | battery = acpi_driver_data(device); | 947 | battery = acpi_driver_data(device); |
757 | 948 | ||
949 | mutex_lock(&battery->mutex); | ||
950 | |||
758 | status = acpi_remove_notify_handler(device->handle, | 951 | status = acpi_remove_notify_handler(device->handle, |
759 | ACPI_ALL_NOTIFY, | 952 | ACPI_ALL_NOTIFY, |
760 | acpi_battery_notify); | 953 | acpi_battery_notify); |
761 | 954 | ||
762 | acpi_battery_remove_fs(device); | 955 | acpi_battery_remove_fs(device); |
763 | 956 | ||
957 | kfree(battery->bif_data.pointer); | ||
958 | |||
959 | kfree(battery->bst_data.pointer); | ||
960 | |||
961 | mutex_unlock(&battery->mutex); | ||
962 | |||
963 | mutex_destroy(&battery->mutex); | ||
964 | |||
764 | kfree(battery); | 965 | kfree(battery); |
765 | 966 | ||
766 | return 0; | 967 | return 0; |
@@ -775,7 +976,10 @@ static int acpi_battery_resume(struct acpi_device *device) | |||
775 | return -EINVAL; | 976 | return -EINVAL; |
776 | 977 | ||
777 | battery = device->driver_data; | 978 | battery = device->driver_data; |
778 | return acpi_battery_check(battery); | 979 | |
980 | battery->flags.init_update = 1; | ||
981 | |||
982 | return 0; | ||
779 | } | 983 | } |
780 | 984 | ||
781 | static int __init acpi_battery_init(void) | 985 | static int __init acpi_battery_init(void) |
@@ -800,7 +1004,6 @@ static int __init acpi_battery_init(void) | |||
800 | 1004 | ||
801 | static void __exit acpi_battery_exit(void) | 1005 | static void __exit acpi_battery_exit(void) |
802 | { | 1006 | { |
803 | |||
804 | acpi_bus_unregister_driver(&acpi_battery_driver); | 1007 | acpi_bus_unregister_driver(&acpi_battery_driver); |
805 | 1008 | ||
806 | acpi_unlock_battery_dir(acpi_battery_dir); | 1009 | acpi_unlock_battery_dir(acpi_battery_dir); |
diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c index fb3f31b5e69f..56a5b3fffeb3 100644 --- a/drivers/acpi/bay.c +++ b/drivers/acpi/bay.c | |||
@@ -288,6 +288,11 @@ static int bay_add(acpi_handle handle, int id) | |||
288 | new_bay->pdev = pdev; | 288 | new_bay->pdev = pdev; |
289 | platform_set_drvdata(pdev, new_bay); | 289 | platform_set_drvdata(pdev, new_bay); |
290 | 290 | ||
291 | /* | ||
292 | * we want the bay driver to be able to send uevents | ||
293 | */ | ||
294 | pdev->dev.uevent_suppress = 0; | ||
295 | |||
291 | if (acpi_bay_add_fs(new_bay)) { | 296 | if (acpi_bay_add_fs(new_bay)) { |
292 | platform_device_unregister(new_bay->pdev); | 297 | platform_device_unregister(new_bay->pdev); |
293 | goto bay_add_err; | 298 | goto bay_add_err; |
@@ -328,18 +333,12 @@ static void bay_notify(acpi_handle handle, u32 event, void *data) | |||
328 | { | 333 | { |
329 | struct bay *bay_dev = (struct bay *)data; | 334 | struct bay *bay_dev = (struct bay *)data; |
330 | struct device *dev = &bay_dev->pdev->dev; | 335 | struct device *dev = &bay_dev->pdev->dev; |
336 | char event_string[12]; | ||
337 | char *envp[] = { event_string, NULL }; | ||
331 | 338 | ||
332 | bay_dprintk(handle, "Bay event"); | 339 | bay_dprintk(handle, "Bay event"); |
333 | 340 | sprintf(event_string, "BAY_EVENT=%d\n", event); | |
334 | switch(event) { | 341 | kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); |
335 | case ACPI_NOTIFY_BUS_CHECK: | ||
336 | case ACPI_NOTIFY_DEVICE_CHECK: | ||
337 | case ACPI_NOTIFY_EJECT_REQUEST: | ||
338 | kobject_uevent(&dev->kobj, KOBJ_CHANGE); | ||
339 | break; | ||
340 | default: | ||
341 | printk(KERN_ERR PREFIX "Bay: unknown event %d\n", event); | ||
342 | } | ||
343 | } | 342 | } |
344 | 343 | ||
345 | static acpi_status | 344 | static acpi_status |
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 4546bf873aea..6192c8be66df 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -40,8 +40,15 @@ MODULE_AUTHOR("Kristen Carlson Accardi"); | |||
40 | MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_DESCRIPTION); | 40 | MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_DESCRIPTION); |
41 | MODULE_LICENSE("GPL"); | 41 | MODULE_LICENSE("GPL"); |
42 | 42 | ||
43 | static int immediate_undock = 1; | ||
44 | module_param(immediate_undock, bool, 0644); | ||
45 | MODULE_PARM_DESC(immediate_undock, "1 (default) will cause the driver to " | ||
46 | "undock immediately when the undock button is pressed, 0 will cause" | ||
47 | " the driver to wait for userspace to write the undock sysfs file " | ||
48 | " before undocking"); | ||
49 | |||
43 | static struct atomic_notifier_head dock_notifier_list; | 50 | static struct atomic_notifier_head dock_notifier_list; |
44 | static struct platform_device dock_device; | 51 | static struct platform_device *dock_device; |
45 | static char dock_device_name[] = "dock"; | 52 | static char dock_device_name[] = "dock"; |
46 | 53 | ||
47 | struct dock_station { | 54 | struct dock_station { |
@@ -63,6 +70,7 @@ struct dock_dependent_device { | |||
63 | }; | 70 | }; |
64 | 71 | ||
65 | #define DOCK_DOCKING 0x00000001 | 72 | #define DOCK_DOCKING 0x00000001 |
73 | #define DOCK_UNDOCKING 0x00000002 | ||
66 | #define DOCK_EVENT 3 | 74 | #define DOCK_EVENT 3 |
67 | #define UNDOCK_EVENT 2 | 75 | #define UNDOCK_EVENT 2 |
68 | 76 | ||
@@ -327,12 +335,20 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event) | |||
327 | 335 | ||
328 | static void dock_event(struct dock_station *ds, u32 event, int num) | 336 | static void dock_event(struct dock_station *ds, u32 event, int num) |
329 | { | 337 | { |
330 | struct device *dev = &dock_device.dev; | 338 | struct device *dev = &dock_device->dev; |
339 | char event_string[7]; | ||
340 | char *envp[] = { event_string, NULL }; | ||
341 | |||
342 | if (num == UNDOCK_EVENT) | ||
343 | sprintf(event_string, "UNDOCK"); | ||
344 | else | ||
345 | sprintf(event_string, "DOCK"); | ||
346 | |||
331 | /* | 347 | /* |
332 | * Indicate that the status of the dock station has | 348 | * Indicate that the status of the dock station has |
333 | * changed. | 349 | * changed. |
334 | */ | 350 | */ |
335 | kobject_uevent(&dev->kobj, KOBJ_CHANGE); | 351 | kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); |
336 | } | 352 | } |
337 | 353 | ||
338 | /** | 354 | /** |
@@ -380,12 +396,11 @@ static void handle_dock(struct dock_station *ds, int dock) | |||
380 | union acpi_object arg; | 396 | union acpi_object arg; |
381 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 397 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
382 | struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 398 | struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
383 | union acpi_object *obj; | ||
384 | 399 | ||
385 | acpi_get_name(ds->handle, ACPI_FULL_PATHNAME, &name_buffer); | 400 | acpi_get_name(ds->handle, ACPI_FULL_PATHNAME, &name_buffer); |
386 | obj = name_buffer.pointer; | ||
387 | 401 | ||
388 | printk(KERN_INFO PREFIX "%s\n", dock ? "docking" : "undocking"); | 402 | printk(KERN_INFO PREFIX "%s - %s\n", |
403 | (char *)name_buffer.pointer, dock ? "docking" : "undocking"); | ||
389 | 404 | ||
390 | /* _DCK method has one argument */ | 405 | /* _DCK method has one argument */ |
391 | arg_list.count = 1; | 406 | arg_list.count = 1; |
@@ -394,7 +409,8 @@ static void handle_dock(struct dock_station *ds, int dock) | |||
394 | arg.integer.value = dock; | 409 | arg.integer.value = dock; |
395 | status = acpi_evaluate_object(ds->handle, "_DCK", &arg_list, &buffer); | 410 | status = acpi_evaluate_object(ds->handle, "_DCK", &arg_list, &buffer); |
396 | if (ACPI_FAILURE(status)) | 411 | if (ACPI_FAILURE(status)) |
397 | pr_debug("%s: failed to execute _DCK\n", obj->string.pointer); | 412 | printk(KERN_ERR PREFIX "%s - failed to execute _DCK\n", |
413 | (char *)name_buffer.pointer); | ||
398 | kfree(buffer.pointer); | 414 | kfree(buffer.pointer); |
399 | kfree(name_buffer.pointer); | 415 | kfree(name_buffer.pointer); |
400 | } | 416 | } |
@@ -420,6 +436,16 @@ static inline void complete_dock(struct dock_station *ds) | |||
420 | ds->last_dock_time = jiffies; | 436 | ds->last_dock_time = jiffies; |
421 | } | 437 | } |
422 | 438 | ||
439 | static inline void begin_undock(struct dock_station *ds) | ||
440 | { | ||
441 | ds->flags |= DOCK_UNDOCKING; | ||
442 | } | ||
443 | |||
444 | static inline void complete_undock(struct dock_station *ds) | ||
445 | { | ||
446 | ds->flags &= ~(DOCK_UNDOCKING); | ||
447 | } | ||
448 | |||
423 | /** | 449 | /** |
424 | * dock_in_progress - see if we are in the middle of handling a dock event | 450 | * dock_in_progress - see if we are in the middle of handling a dock event |
425 | * @ds: the dock station | 451 | * @ds: the dock station |
@@ -550,7 +576,7 @@ static int handle_eject_request(struct dock_station *ds, u32 event) | |||
550 | printk(KERN_ERR PREFIX "Unable to undock!\n"); | 576 | printk(KERN_ERR PREFIX "Unable to undock!\n"); |
551 | return -EBUSY; | 577 | return -EBUSY; |
552 | } | 578 | } |
553 | 579 | complete_undock(ds); | |
554 | return 0; | 580 | return 0; |
555 | } | 581 | } |
556 | 582 | ||
@@ -594,7 +620,11 @@ static void dock_notify(acpi_handle handle, u32 event, void *data) | |||
594 | * to the driver who wish to hotplug. | 620 | * to the driver who wish to hotplug. |
595 | */ | 621 | */ |
596 | case ACPI_NOTIFY_EJECT_REQUEST: | 622 | case ACPI_NOTIFY_EJECT_REQUEST: |
597 | handle_eject_request(ds, event); | 623 | begin_undock(ds); |
624 | if (immediate_undock) | ||
625 | handle_eject_request(ds, event); | ||
626 | else | ||
627 | dock_event(ds, event, UNDOCK_EVENT); | ||
598 | break; | 628 | break; |
599 | default: | 629 | default: |
600 | printk(KERN_ERR PREFIX "Unknown dock event %d\n", event); | 630 | printk(KERN_ERR PREFIX "Unknown dock event %d\n", event); |
@@ -653,6 +683,17 @@ static ssize_t show_docked(struct device *dev, | |||
653 | DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); | 683 | DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); |
654 | 684 | ||
655 | /* | 685 | /* |
686 | * show_flags - read method for flags file in sysfs | ||
687 | */ | ||
688 | static ssize_t show_flags(struct device *dev, | ||
689 | struct device_attribute *attr, char *buf) | ||
690 | { | ||
691 | return snprintf(buf, PAGE_SIZE, "%d\n", dock_station->flags); | ||
692 | |||
693 | } | ||
694 | DEVICE_ATTR(flags, S_IRUGO, show_flags, NULL); | ||
695 | |||
696 | /* | ||
656 | * write_undock - write method for "undock" file in sysfs | 697 | * write_undock - write method for "undock" file in sysfs |
657 | */ | 698 | */ |
658 | static ssize_t write_undock(struct device *dev, struct device_attribute *attr, | 699 | static ssize_t write_undock(struct device *dev, struct device_attribute *attr, |
@@ -675,16 +716,15 @@ static ssize_t show_dock_uid(struct device *dev, | |||
675 | struct device_attribute *attr, char *buf) | 716 | struct device_attribute *attr, char *buf) |
676 | { | 717 | { |
677 | unsigned long lbuf; | 718 | unsigned long lbuf; |
678 | acpi_status status = acpi_evaluate_integer(dock_station->handle, "_UID", NULL, &lbuf); | 719 | acpi_status status = acpi_evaluate_integer(dock_station->handle, |
679 | if(ACPI_FAILURE(status)) { | 720 | "_UID", NULL, &lbuf); |
721 | if (ACPI_FAILURE(status)) | ||
680 | return 0; | 722 | return 0; |
681 | } | 723 | |
682 | return snprintf(buf, PAGE_SIZE, "%lx\n", lbuf); | 724 | return snprintf(buf, PAGE_SIZE, "%lx\n", lbuf); |
683 | } | 725 | } |
684 | DEVICE_ATTR(uid, S_IRUGO, show_dock_uid, NULL); | 726 | DEVICE_ATTR(uid, S_IRUGO, show_dock_uid, NULL); |
685 | 727 | ||
686 | |||
687 | |||
688 | /** | 728 | /** |
689 | * dock_add - add a new dock station | 729 | * dock_add - add a new dock station |
690 | * @handle: the dock station handle | 730 | * @handle: the dock station handle |
@@ -711,33 +751,53 @@ static int dock_add(acpi_handle handle) | |||
711 | ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); | 751 | ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); |
712 | 752 | ||
713 | /* initialize platform device stuff */ | 753 | /* initialize platform device stuff */ |
714 | dock_device.name = dock_device_name; | 754 | dock_device = |
715 | ret = platform_device_register(&dock_device); | 755 | platform_device_register_simple(dock_device_name, 0, NULL, 0); |
756 | if (IS_ERR(dock_device)) { | ||
757 | kfree(dock_station); | ||
758 | dock_station = NULL; | ||
759 | return PTR_ERR(dock_device); | ||
760 | } | ||
761 | |||
762 | /* we want the dock device to send uevents */ | ||
763 | dock_device->dev.uevent_suppress = 0; | ||
764 | |||
765 | ret = device_create_file(&dock_device->dev, &dev_attr_docked); | ||
716 | if (ret) { | 766 | if (ret) { |
717 | printk(KERN_ERR PREFIX "Error %d registering dock device\n", ret); | 767 | printk("Error %d adding sysfs file\n", ret); |
768 | platform_device_unregister(dock_device); | ||
718 | kfree(dock_station); | 769 | kfree(dock_station); |
770 | dock_station = NULL; | ||
719 | return ret; | 771 | return ret; |
720 | } | 772 | } |
721 | ret = device_create_file(&dock_device.dev, &dev_attr_docked); | 773 | ret = device_create_file(&dock_device->dev, &dev_attr_undock); |
722 | if (ret) { | 774 | if (ret) { |
723 | printk("Error %d adding sysfs file\n", ret); | 775 | printk("Error %d adding sysfs file\n", ret); |
724 | platform_device_unregister(&dock_device); | 776 | device_remove_file(&dock_device->dev, &dev_attr_docked); |
777 | platform_device_unregister(dock_device); | ||
725 | kfree(dock_station); | 778 | kfree(dock_station); |
779 | dock_station = NULL; | ||
726 | return ret; | 780 | return ret; |
727 | } | 781 | } |
728 | ret = device_create_file(&dock_device.dev, &dev_attr_undock); | 782 | ret = device_create_file(&dock_device->dev, &dev_attr_uid); |
729 | if (ret) { | 783 | if (ret) { |
730 | printk("Error %d adding sysfs file\n", ret); | 784 | printk("Error %d adding sysfs file\n", ret); |
731 | device_remove_file(&dock_device.dev, &dev_attr_docked); | 785 | device_remove_file(&dock_device->dev, &dev_attr_docked); |
732 | platform_device_unregister(&dock_device); | 786 | device_remove_file(&dock_device->dev, &dev_attr_undock); |
787 | platform_device_unregister(dock_device); | ||
733 | kfree(dock_station); | 788 | kfree(dock_station); |
789 | dock_station = NULL; | ||
734 | return ret; | 790 | return ret; |
735 | } | 791 | } |
736 | ret = device_create_file(&dock_device.dev, &dev_attr_uid); | 792 | ret = device_create_file(&dock_device->dev, &dev_attr_flags); |
737 | if (ret) { | 793 | if (ret) { |
738 | printk("Error %d adding sysfs file\n", ret); | 794 | printk("Error %d adding sysfs file\n", ret); |
739 | platform_device_unregister(&dock_device); | 795 | device_remove_file(&dock_device->dev, &dev_attr_docked); |
796 | device_remove_file(&dock_device->dev, &dev_attr_undock); | ||
797 | device_remove_file(&dock_device->dev, &dev_attr_uid); | ||
798 | platform_device_unregister(dock_device); | ||
740 | kfree(dock_station); | 799 | kfree(dock_station); |
800 | dock_station = NULL; | ||
741 | return ret; | 801 | return ret; |
742 | } | 802 | } |
743 | 803 | ||
@@ -750,6 +810,7 @@ static int dock_add(acpi_handle handle) | |||
750 | dd = alloc_dock_dependent_device(handle); | 810 | dd = alloc_dock_dependent_device(handle); |
751 | if (!dd) { | 811 | if (!dd) { |
752 | kfree(dock_station); | 812 | kfree(dock_station); |
813 | dock_station = NULL; | ||
753 | ret = -ENOMEM; | 814 | ret = -ENOMEM; |
754 | goto dock_add_err_unregister; | 815 | goto dock_add_err_unregister; |
755 | } | 816 | } |
@@ -773,10 +834,13 @@ static int dock_add(acpi_handle handle) | |||
773 | dock_add_err: | 834 | dock_add_err: |
774 | kfree(dd); | 835 | kfree(dd); |
775 | dock_add_err_unregister: | 836 | dock_add_err_unregister: |
776 | device_remove_file(&dock_device.dev, &dev_attr_docked); | 837 | device_remove_file(&dock_device->dev, &dev_attr_docked); |
777 | device_remove_file(&dock_device.dev, &dev_attr_undock); | 838 | device_remove_file(&dock_device->dev, &dev_attr_undock); |
778 | platform_device_unregister(&dock_device); | 839 | device_remove_file(&dock_device->dev, &dev_attr_uid); |
840 | device_remove_file(&dock_device->dev, &dev_attr_flags); | ||
841 | platform_device_unregister(dock_device); | ||
779 | kfree(dock_station); | 842 | kfree(dock_station); |
843 | dock_station = NULL; | ||
780 | return ret; | 844 | return ret; |
781 | } | 845 | } |
782 | 846 | ||
@@ -804,12 +868,15 @@ static int dock_remove(void) | |||
804 | printk(KERN_ERR "Error removing notify handler\n"); | 868 | printk(KERN_ERR "Error removing notify handler\n"); |
805 | 869 | ||
806 | /* cleanup sysfs */ | 870 | /* cleanup sysfs */ |
807 | device_remove_file(&dock_device.dev, &dev_attr_docked); | 871 | device_remove_file(&dock_device->dev, &dev_attr_docked); |
808 | device_remove_file(&dock_device.dev, &dev_attr_undock); | 872 | device_remove_file(&dock_device->dev, &dev_attr_undock); |
809 | platform_device_unregister(&dock_device); | 873 | device_remove_file(&dock_device->dev, &dev_attr_uid); |
874 | device_remove_file(&dock_device->dev, &dev_attr_flags); | ||
875 | platform_device_unregister(dock_device); | ||
810 | 876 | ||
811 | /* free dock station memory */ | 877 | /* free dock station memory */ |
812 | kfree(dock_station); | 878 | kfree(dock_station); |
879 | dock_station = NULL; | ||
813 | return 0; | 880 | return 0; |
814 | } | 881 | } |
815 | 882 | ||
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 82f496c07675..10e851021eca 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -34,25 +34,26 @@ | |||
34 | #include <linux/proc_fs.h> | 34 | #include <linux/proc_fs.h> |
35 | #include <linux/seq_file.h> | 35 | #include <linux/seq_file.h> |
36 | #include <linux/interrupt.h> | 36 | #include <linux/interrupt.h> |
37 | #include <linux/list.h> | ||
37 | #include <asm/io.h> | 38 | #include <asm/io.h> |
38 | #include <acpi/acpi_bus.h> | 39 | #include <acpi/acpi_bus.h> |
39 | #include <acpi/acpi_drivers.h> | 40 | #include <acpi/acpi_drivers.h> |
40 | #include <acpi/actypes.h> | 41 | #include <acpi/actypes.h> |
41 | 42 | ||
42 | #define _COMPONENT ACPI_EC_COMPONENT | ||
43 | ACPI_MODULE_NAME("ec"); | ||
44 | #define ACPI_EC_COMPONENT 0x00100000 | ||
45 | #define ACPI_EC_CLASS "embedded_controller" | 43 | #define ACPI_EC_CLASS "embedded_controller" |
46 | #define ACPI_EC_HID "PNP0C09" | 44 | #define ACPI_EC_HID "PNP0C09" |
47 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" | 45 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" |
48 | #define ACPI_EC_FILE_INFO "info" | 46 | #define ACPI_EC_FILE_INFO "info" |
47 | |||
49 | #undef PREFIX | 48 | #undef PREFIX |
50 | #define PREFIX "ACPI: EC: " | 49 | #define PREFIX "ACPI: EC: " |
50 | |||
51 | /* EC status register */ | 51 | /* EC status register */ |
52 | #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ | 52 | #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ |
53 | #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ | 53 | #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ |
54 | #define ACPI_EC_FLAG_BURST 0x10 /* burst mode */ | 54 | #define ACPI_EC_FLAG_BURST 0x10 /* burst mode */ |
55 | #define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */ | 55 | #define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */ |
56 | |||
56 | /* EC commands */ | 57 | /* EC commands */ |
57 | enum ec_command { | 58 | enum ec_command { |
58 | ACPI_EC_COMMAND_READ = 0x80, | 59 | ACPI_EC_COMMAND_READ = 0x80, |
@@ -61,6 +62,7 @@ enum ec_command { | |||
61 | ACPI_EC_BURST_DISABLE = 0x83, | 62 | ACPI_EC_BURST_DISABLE = 0x83, |
62 | ACPI_EC_COMMAND_QUERY = 0x84, | 63 | ACPI_EC_COMMAND_QUERY = 0x84, |
63 | }; | 64 | }; |
65 | |||
64 | /* EC events */ | 66 | /* EC events */ |
65 | enum ec_event { | 67 | enum ec_event { |
66 | ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */ | 68 | ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */ |
@@ -94,6 +96,16 @@ static struct acpi_driver acpi_ec_driver = { | |||
94 | 96 | ||
95 | /* If we find an EC via the ECDT, we need to keep a ptr to its context */ | 97 | /* If we find an EC via the ECDT, we need to keep a ptr to its context */ |
96 | /* External interfaces use first EC only, so remember */ | 98 | /* External interfaces use first EC only, so remember */ |
99 | typedef int (*acpi_ec_query_func) (void *data); | ||
100 | |||
101 | struct acpi_ec_query_handler { | ||
102 | struct list_head node; | ||
103 | acpi_ec_query_func func; | ||
104 | acpi_handle handle; | ||
105 | void *data; | ||
106 | u8 query_bit; | ||
107 | }; | ||
108 | |||
97 | static struct acpi_ec { | 109 | static struct acpi_ec { |
98 | acpi_handle handle; | 110 | acpi_handle handle; |
99 | unsigned long gpe; | 111 | unsigned long gpe; |
@@ -104,6 +116,7 @@ static struct acpi_ec { | |||
104 | atomic_t query_pending; | 116 | atomic_t query_pending; |
105 | atomic_t event_count; | 117 | atomic_t event_count; |
106 | wait_queue_head_t wait; | 118 | wait_queue_head_t wait; |
119 | struct list_head list; | ||
107 | } *boot_ec, *first_ec; | 120 | } *boot_ec, *first_ec; |
108 | 121 | ||
109 | /* -------------------------------------------------------------------------- | 122 | /* -------------------------------------------------------------------------- |
@@ -245,7 +258,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, | |||
245 | 258 | ||
246 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0, 0); | 259 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0, 0); |
247 | if (status) { | 260 | if (status) { |
248 | printk(KERN_DEBUG PREFIX | 261 | printk(KERN_ERR PREFIX |
249 | "input buffer is not empty, aborting transaction\n"); | 262 | "input buffer is not empty, aborting transaction\n"); |
250 | goto end; | 263 | goto end; |
251 | } | 264 | } |
@@ -394,21 +407,67 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data) | |||
394 | /* -------------------------------------------------------------------------- | 407 | /* -------------------------------------------------------------------------- |
395 | Event Management | 408 | Event Management |
396 | -------------------------------------------------------------------------- */ | 409 | -------------------------------------------------------------------------- */ |
410 | int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, | ||
411 | acpi_handle handle, acpi_ec_query_func func, | ||
412 | void *data) | ||
413 | { | ||
414 | struct acpi_ec_query_handler *handler = | ||
415 | kzalloc(sizeof(struct acpi_ec_query_handler), GFP_KERNEL); | ||
416 | if (!handler) | ||
417 | return -ENOMEM; | ||
418 | |||
419 | handler->query_bit = query_bit; | ||
420 | handler->handle = handle; | ||
421 | handler->func = func; | ||
422 | handler->data = data; | ||
423 | mutex_lock(&ec->lock); | ||
424 | list_add_tail(&handler->node, &ec->list); | ||
425 | mutex_unlock(&ec->lock); | ||
426 | return 0; | ||
427 | } | ||
428 | |||
429 | EXPORT_SYMBOL_GPL(acpi_ec_add_query_handler); | ||
430 | |||
431 | void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) | ||
432 | { | ||
433 | struct acpi_ec_query_handler *handler; | ||
434 | mutex_lock(&ec->lock); | ||
435 | list_for_each_entry(handler, &ec->list, node) { | ||
436 | if (query_bit == handler->query_bit) { | ||
437 | list_del(&handler->node); | ||
438 | kfree(handler); | ||
439 | break; | ||
440 | } | ||
441 | } | ||
442 | mutex_unlock(&ec->lock); | ||
443 | } | ||
444 | |||
445 | EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler); | ||
397 | 446 | ||
398 | static void acpi_ec_gpe_query(void *ec_cxt) | 447 | static void acpi_ec_gpe_query(void *ec_cxt) |
399 | { | 448 | { |
400 | struct acpi_ec *ec = ec_cxt; | 449 | struct acpi_ec *ec = ec_cxt; |
401 | u8 value = 0; | 450 | u8 value = 0; |
402 | char object_name[8]; | 451 | struct acpi_ec_query_handler *handler, copy; |
403 | 452 | ||
404 | if (!ec || acpi_ec_query(ec, &value)) | 453 | if (!ec || acpi_ec_query(ec, &value)) |
405 | return; | 454 | return; |
406 | 455 | mutex_lock(&ec->lock); | |
407 | snprintf(object_name, 8, "_Q%2.2X", value); | 456 | list_for_each_entry(handler, &ec->list, node) { |
408 | 457 | if (value == handler->query_bit) { | |
409 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s", object_name)); | 458 | /* have custom handler for this bit */ |
410 | 459 | memcpy(©, handler, sizeof(copy)); | |
411 | acpi_evaluate_object(ec->handle, object_name, NULL, NULL); | 460 | mutex_unlock(&ec->lock); |
461 | if (copy.func) { | ||
462 | copy.func(copy.data); | ||
463 | } else if (copy.handle) { | ||
464 | acpi_evaluate_object(copy.handle, NULL, NULL, NULL); | ||
465 | } | ||
466 | return; | ||
467 | } | ||
468 | } | ||
469 | mutex_unlock(&ec->lock); | ||
470 | printk(KERN_ERR PREFIX "Handler for query 0x%x is not found!\n", value); | ||
412 | } | 471 | } |
413 | 472 | ||
414 | static u32 acpi_ec_gpe_handler(void *data) | 473 | static u32 acpi_ec_gpe_handler(void *data) |
@@ -427,8 +486,7 @@ static u32 acpi_ec_gpe_handler(void *data) | |||
427 | if ((value & ACPI_EC_FLAG_SCI) && !atomic_read(&ec->query_pending)) { | 486 | if ((value & ACPI_EC_FLAG_SCI) && !atomic_read(&ec->query_pending)) { |
428 | atomic_set(&ec->query_pending, 1); | 487 | atomic_set(&ec->query_pending, 1); |
429 | status = | 488 | status = |
430 | acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, | 489 | acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec); |
431 | ec); | ||
432 | } | 490 | } |
433 | 491 | ||
434 | return status == AE_OK ? | 492 | return status == AE_OK ? |
@@ -454,57 +512,35 @@ acpi_ec_space_setup(acpi_handle region_handle, | |||
454 | } | 512 | } |
455 | 513 | ||
456 | static acpi_status | 514 | static acpi_status |
457 | acpi_ec_space_handler(u32 function, | 515 | acpi_ec_space_handler(u32 function, acpi_physical_address address, |
458 | acpi_physical_address address, | 516 | u32 bits, acpi_integer *value, |
459 | u32 bit_width, | ||
460 | acpi_integer * value, | ||
461 | void *handler_context, void *region_context) | 517 | void *handler_context, void *region_context) |
462 | { | 518 | { |
463 | int result = 0; | ||
464 | struct acpi_ec *ec = handler_context; | 519 | struct acpi_ec *ec = handler_context; |
465 | u64 temp = *value; | 520 | int result = 0, i = 0; |
466 | acpi_integer f_v = 0; | 521 | u8 temp = 0; |
467 | int i = 0; | ||
468 | 522 | ||
469 | if ((address > 0xFF) || !value || !handler_context) | 523 | if ((address > 0xFF) || !value || !handler_context) |
470 | return AE_BAD_PARAMETER; | 524 | return AE_BAD_PARAMETER; |
471 | 525 | ||
472 | if (bit_width != 8 && acpi_strict) { | 526 | if (function != ACPI_READ && function != ACPI_WRITE) |
473 | return AE_BAD_PARAMETER; | 527 | return AE_BAD_PARAMETER; |
474 | } | ||
475 | |||
476 | next_byte: | ||
477 | switch (function) { | ||
478 | case ACPI_READ: | ||
479 | temp = 0; | ||
480 | result = acpi_ec_read(ec, (u8) address, (u8 *) & temp); | ||
481 | break; | ||
482 | case ACPI_WRITE: | ||
483 | result = acpi_ec_write(ec, (u8) address, (u8) temp); | ||
484 | break; | ||
485 | default: | ||
486 | result = -EINVAL; | ||
487 | goto out; | ||
488 | break; | ||
489 | } | ||
490 | 528 | ||
491 | bit_width -= 8; | 529 | if (bits != 8 && acpi_strict) |
492 | if (bit_width) { | 530 | return AE_BAD_PARAMETER; |
493 | if (function == ACPI_READ) | ||
494 | f_v |= temp << 8 * i; | ||
495 | if (function == ACPI_WRITE) | ||
496 | temp >>= 8; | ||
497 | i++; | ||
498 | address++; | ||
499 | goto next_byte; | ||
500 | } | ||
501 | 531 | ||
502 | if (function == ACPI_READ) { | 532 | while (bits - i > 0) { |
503 | f_v |= temp << 8 * i; | 533 | if (function == ACPI_READ) { |
504 | *value = f_v; | 534 | result = acpi_ec_read(ec, address, &temp); |
535 | (*value) |= ((acpi_integer)temp) << i; | ||
536 | } else { | ||
537 | temp = 0xff & ((*value) >> i); | ||
538 | result = acpi_ec_write(ec, address, temp); | ||
539 | } | ||
540 | i += 8; | ||
541 | ++address; | ||
505 | } | 542 | } |
506 | 543 | ||
507 | out: | ||
508 | switch (result) { | 544 | switch (result) { |
509 | case -EINVAL: | 545 | case -EINVAL: |
510 | return AE_BAD_PARAMETER; | 546 | return AE_BAD_PARAMETER; |
@@ -597,9 +633,6 @@ static int acpi_ec_remove_fs(struct acpi_device *device) | |||
597 | static acpi_status | 633 | static acpi_status |
598 | ec_parse_io_ports(struct acpi_resource *resource, void *context); | 634 | ec_parse_io_ports(struct acpi_resource *resource, void *context); |
599 | 635 | ||
600 | static acpi_status | ||
601 | ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval); | ||
602 | |||
603 | static struct acpi_ec *make_acpi_ec(void) | 636 | static struct acpi_ec *make_acpi_ec(void) |
604 | { | 637 | { |
605 | struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL); | 638 | struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL); |
@@ -610,13 +643,52 @@ static struct acpi_ec *make_acpi_ec(void) | |||
610 | atomic_set(&ec->event_count, 1); | 643 | atomic_set(&ec->event_count, 1); |
611 | mutex_init(&ec->lock); | 644 | mutex_init(&ec->lock); |
612 | init_waitqueue_head(&ec->wait); | 645 | init_waitqueue_head(&ec->wait); |
646 | INIT_LIST_HEAD(&ec->list); | ||
613 | 647 | ||
614 | return ec; | 648 | return ec; |
615 | } | 649 | } |
616 | 650 | ||
651 | static acpi_status | ||
652 | acpi_ec_register_query_methods(acpi_handle handle, u32 level, | ||
653 | void *context, void **return_value) | ||
654 | { | ||
655 | struct acpi_namespace_node *node = handle; | ||
656 | struct acpi_ec *ec = context; | ||
657 | int value = 0; | ||
658 | if (sscanf(node->name.ascii, "_Q%x", &value) == 1) { | ||
659 | acpi_ec_add_query_handler(ec, value, handle, NULL, NULL); | ||
660 | } | ||
661 | return AE_OK; | ||
662 | } | ||
663 | |||
664 | static int ec_parse_device(struct acpi_ec *ec, acpi_handle handle) | ||
665 | { | ||
666 | if (ACPI_FAILURE(acpi_walk_resources(handle, METHOD_NAME__CRS, | ||
667 | ec_parse_io_ports, ec))) | ||
668 | return -EINVAL; | ||
669 | |||
670 | /* Get GPE bit assignment (EC events). */ | ||
671 | /* TODO: Add support for _GPE returning a package */ | ||
672 | if (ACPI_FAILURE(acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe))) | ||
673 | return -EINVAL; | ||
674 | |||
675 | /* Use the global lock for all EC transactions? */ | ||
676 | acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock); | ||
677 | |||
678 | /* Find and register all query methods */ | ||
679 | acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1, | ||
680 | acpi_ec_register_query_methods, ec, NULL); | ||
681 | |||
682 | ec->handle = handle; | ||
683 | |||
684 | printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx", | ||
685 | ec->gpe, ec->command_addr, ec->data_addr); | ||
686 | |||
687 | return 0; | ||
688 | } | ||
689 | |||
617 | static int acpi_ec_add(struct acpi_device *device) | 690 | static int acpi_ec_add(struct acpi_device *device) |
618 | { | 691 | { |
619 | acpi_status status = AE_OK; | ||
620 | struct acpi_ec *ec = NULL; | 692 | struct acpi_ec *ec = NULL; |
621 | 693 | ||
622 | if (!device) | 694 | if (!device) |
@@ -629,8 +701,7 @@ static int acpi_ec_add(struct acpi_device *device) | |||
629 | if (!ec) | 701 | if (!ec) |
630 | return -ENOMEM; | 702 | return -ENOMEM; |
631 | 703 | ||
632 | status = ec_parse_device(device->handle, 0, ec, NULL); | 704 | if (ec_parse_device(ec, device->handle)) { |
633 | if (status != AE_CTRL_TERMINATE) { | ||
634 | kfree(ec); | 705 | kfree(ec); |
635 | return -EINVAL; | 706 | return -EINVAL; |
636 | } | 707 | } |
@@ -641,6 +712,8 @@ static int acpi_ec_add(struct acpi_device *device) | |||
641 | /* We might have incorrect info for GL at boot time */ | 712 | /* We might have incorrect info for GL at boot time */ |
642 | mutex_lock(&boot_ec->lock); | 713 | mutex_lock(&boot_ec->lock); |
643 | boot_ec->global_lock = ec->global_lock; | 714 | boot_ec->global_lock = ec->global_lock; |
715 | /* Copy handlers from new ec into boot ec */ | ||
716 | list_splice(&ec->list, &boot_ec->list); | ||
644 | mutex_unlock(&boot_ec->lock); | 717 | mutex_unlock(&boot_ec->lock); |
645 | kfree(ec); | 718 | kfree(ec); |
646 | ec = boot_ec; | 719 | ec = boot_ec; |
@@ -651,22 +724,24 @@ static int acpi_ec_add(struct acpi_device *device) | |||
651 | acpi_driver_data(device) = ec; | 724 | acpi_driver_data(device) = ec; |
652 | 725 | ||
653 | acpi_ec_add_fs(device); | 726 | acpi_ec_add_fs(device); |
654 | |||
655 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s [%s] (gpe %d) interrupt mode.", | ||
656 | acpi_device_name(device), acpi_device_bid(device), | ||
657 | (u32) ec->gpe)); | ||
658 | |||
659 | return 0; | 727 | return 0; |
660 | } | 728 | } |
661 | 729 | ||
662 | static int acpi_ec_remove(struct acpi_device *device, int type) | 730 | static int acpi_ec_remove(struct acpi_device *device, int type) |
663 | { | 731 | { |
664 | struct acpi_ec *ec; | 732 | struct acpi_ec *ec; |
733 | struct acpi_ec_query_handler *handler; | ||
665 | 734 | ||
666 | if (!device) | 735 | if (!device) |
667 | return -EINVAL; | 736 | return -EINVAL; |
668 | 737 | ||
669 | ec = acpi_driver_data(device); | 738 | ec = acpi_driver_data(device); |
739 | mutex_lock(&ec->lock); | ||
740 | list_for_each_entry(handler, &ec->list, node) { | ||
741 | list_del(&handler->node); | ||
742 | kfree(handler); | ||
743 | } | ||
744 | mutex_unlock(&ec->lock); | ||
670 | acpi_ec_remove_fs(device); | 745 | acpi_ec_remove_fs(device); |
671 | acpi_driver_data(device) = NULL; | 746 | acpi_driver_data(device) = NULL; |
672 | if (ec == first_ec) | 747 | if (ec == first_ec) |
@@ -722,15 +797,13 @@ static int ec_install_handlers(struct acpi_ec *ec) | |||
722 | return -ENODEV; | 797 | return -ENODEV; |
723 | } | 798 | } |
724 | 799 | ||
725 | /* EC is fully operational, allow queries */ | ||
726 | atomic_set(&ec->query_pending, 0); | ||
727 | |||
728 | return 0; | 800 | return 0; |
729 | } | 801 | } |
730 | 802 | ||
731 | static int acpi_ec_start(struct acpi_device *device) | 803 | static int acpi_ec_start(struct acpi_device *device) |
732 | { | 804 | { |
733 | struct acpi_ec *ec; | 805 | struct acpi_ec *ec; |
806 | int ret = 0; | ||
734 | 807 | ||
735 | if (!device) | 808 | if (!device) |
736 | return -EINVAL; | 809 | return -EINVAL; |
@@ -740,14 +813,14 @@ static int acpi_ec_start(struct acpi_device *device) | |||
740 | if (!ec) | 813 | if (!ec) |
741 | return -EINVAL; | 814 | return -EINVAL; |
742 | 815 | ||
743 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx", | ||
744 | ec->gpe, ec->command_addr, ec->data_addr)); | ||
745 | |||
746 | /* Boot EC is already working */ | 816 | /* Boot EC is already working */ |
747 | if (ec == boot_ec) | 817 | if (ec != boot_ec) |
748 | return 0; | 818 | ret = ec_install_handlers(ec); |
819 | |||
820 | /* EC is fully operational, allow queries */ | ||
821 | atomic_set(&ec->query_pending, 0); | ||
749 | 822 | ||
750 | return ec_install_handlers(ec); | 823 | return ret; |
751 | } | 824 | } |
752 | 825 | ||
753 | static int acpi_ec_stop(struct acpi_device *device, int type) | 826 | static int acpi_ec_stop(struct acpi_device *device, int type) |
@@ -779,34 +852,6 @@ static int acpi_ec_stop(struct acpi_device *device, int type) | |||
779 | return 0; | 852 | return 0; |
780 | } | 853 | } |
781 | 854 | ||
782 | static acpi_status | ||
783 | ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) | ||
784 | { | ||
785 | acpi_status status; | ||
786 | |||
787 | struct acpi_ec *ec = context; | ||
788 | status = acpi_walk_resources(handle, METHOD_NAME__CRS, | ||
789 | ec_parse_io_ports, ec); | ||
790 | if (ACPI_FAILURE(status)) | ||
791 | return status; | ||
792 | |||
793 | /* Get GPE bit assignment (EC events). */ | ||
794 | /* TODO: Add support for _GPE returning a package */ | ||
795 | status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe); | ||
796 | if (ACPI_FAILURE(status)) | ||
797 | return status; | ||
798 | |||
799 | /* Use the global lock for all EC transactions? */ | ||
800 | acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock); | ||
801 | |||
802 | ec->handle = handle; | ||
803 | |||
804 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx", | ||
805 | ec->gpe, ec->command_addr, ec->data_addr)); | ||
806 | |||
807 | return AE_CTRL_TERMINATE; | ||
808 | } | ||
809 | |||
810 | int __init acpi_ec_ecdt_probe(void) | 855 | int __init acpi_ec_ecdt_probe(void) |
811 | { | 856 | { |
812 | int ret; | 857 | int ret; |
@@ -825,7 +870,7 @@ int __init acpi_ec_ecdt_probe(void) | |||
825 | if (ACPI_FAILURE(status)) | 870 | if (ACPI_FAILURE(status)) |
826 | goto error; | 871 | goto error; |
827 | 872 | ||
828 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found ECDT")); | 873 | printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n"); |
829 | 874 | ||
830 | boot_ec->command_addr = ecdt_ptr->control.address; | 875 | boot_ec->command_addr = ecdt_ptr->control.address; |
831 | boot_ec->data_addr = ecdt_ptr->data.address; | 876 | boot_ec->data_addr = ecdt_ptr->data.address; |
diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c index 902c287b3a4f..361ebe6c4a6f 100644 --- a/drivers/acpi/events/evgpeblk.c +++ b/drivers/acpi/events/evgpeblk.c | |||
@@ -586,6 +586,10 @@ acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt) | |||
586 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | 586 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); |
587 | if (gpe_xrupt->previous) { | 587 | if (gpe_xrupt->previous) { |
588 | gpe_xrupt->previous->next = gpe_xrupt->next; | 588 | gpe_xrupt->previous->next = gpe_xrupt->next; |
589 | } else { | ||
590 | /* No previous, update list head */ | ||
591 | |||
592 | acpi_gbl_gpe_xrupt_list_head = gpe_xrupt->next; | ||
589 | } | 593 | } |
590 | 594 | ||
591 | if (gpe_xrupt->next) { | 595 | if (gpe_xrupt->next) { |
diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c index 400d90fca966..23ee7bc4a705 100644 --- a/drivers/acpi/events/evrgnini.c +++ b/drivers/acpi/events/evrgnini.c | |||
@@ -284,6 +284,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, | |||
284 | } | 284 | } |
285 | 285 | ||
286 | if (!pci_device_node) { | 286 | if (!pci_device_node) { |
287 | ACPI_FREE(pci_id); | ||
287 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | 288 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
288 | } | 289 | } |
289 | 290 | ||
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 41427a41f620..4893e256e399 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #if ACPI_GLUE_DEBUG | 16 | #if ACPI_GLUE_DEBUG |
17 | #define DBG(x...) printk(PREFIX x) | 17 | #define DBG(x...) printk(PREFIX x) |
18 | #else | 18 | #else |
19 | #define DBG(x...) | 19 | #define DBG(x...) do { } while(0) |
20 | #endif | 20 | #endif |
21 | static LIST_HEAD(bus_type_list); | 21 | static LIST_HEAD(bus_type_list); |
22 | static DECLARE_RWSEM(bus_type_sem); | 22 | static DECLARE_RWSEM(bus_type_sem); |
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index acc594771379..3448edd61dc4 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c | |||
@@ -733,7 +733,7 @@ static int acpi_pci_link_add(struct acpi_device *device) | |||
733 | /* query and set link->irq.active */ | 733 | /* query and set link->irq.active */ |
734 | acpi_pci_link_get_current(link); | 734 | acpi_pci_link_get_current(link); |
735 | 735 | ||
736 | printk(PREFIX "%s [%s] (IRQs", acpi_device_name(device), | 736 | printk(KERN_INFO PREFIX "%s [%s] (IRQs", acpi_device_name(device), |
737 | acpi_device_bid(device)); | 737 | acpi_device_bid(device)); |
738 | for (i = 0; i < link->irq.possible_count; i++) { | 738 | for (i = 0; i < link->irq.possible_count; i++) { |
739 | if (link->irq.active == link->irq.possible[i]) { | 739 | if (link->irq.active == link->irq.possible[i]) { |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index bb5d23be4260..a898991f77cb 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -490,7 +490,17 @@ static void acpi_processor_idle(void) | |||
490 | 490 | ||
491 | case ACPI_STATE_C3: | 491 | case ACPI_STATE_C3: |
492 | 492 | ||
493 | if (pr->flags.bm_check) { | 493 | /* |
494 | * disable bus master | ||
495 | * bm_check implies we need ARB_DIS | ||
496 | * !bm_check implies we need cache flush | ||
497 | * bm_control implies whether we can do ARB_DIS | ||
498 | * | ||
499 | * That leaves a case where bm_check is set and bm_control is | ||
500 | * not set. In that case we cannot do much, we enter C3 | ||
501 | * without doing anything. | ||
502 | */ | ||
503 | if (pr->flags.bm_check && pr->flags.bm_control) { | ||
494 | if (atomic_inc_return(&c3_cpu_count) == | 504 | if (atomic_inc_return(&c3_cpu_count) == |
495 | num_online_cpus()) { | 505 | num_online_cpus()) { |
496 | /* | 506 | /* |
@@ -499,7 +509,7 @@ static void acpi_processor_idle(void) | |||
499 | */ | 509 | */ |
500 | acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); | 510 | acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); |
501 | } | 511 | } |
502 | } else { | 512 | } else if (!pr->flags.bm_check) { |
503 | /* SMP with no shared cache... Invalidate cache */ | 513 | /* SMP with no shared cache... Invalidate cache */ |
504 | ACPI_FLUSH_CPU_CACHE(); | 514 | ACPI_FLUSH_CPU_CACHE(); |
505 | } | 515 | } |
@@ -511,7 +521,7 @@ static void acpi_processor_idle(void) | |||
511 | acpi_cstate_enter(cx); | 521 | acpi_cstate_enter(cx); |
512 | /* Get end time (ticks) */ | 522 | /* Get end time (ticks) */ |
513 | t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); | 523 | t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); |
514 | if (pr->flags.bm_check) { | 524 | if (pr->flags.bm_check && pr->flags.bm_control) { |
515 | /* Enable bus master arbitration */ | 525 | /* Enable bus master arbitration */ |
516 | atomic_dec(&c3_cpu_count); | 526 | atomic_dec(&c3_cpu_count); |
517 | acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); | 527 | acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); |
@@ -961,9 +971,9 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr, | |||
961 | if (pr->flags.bm_check) { | 971 | if (pr->flags.bm_check) { |
962 | /* bus mastering control is necessary */ | 972 | /* bus mastering control is necessary */ |
963 | if (!pr->flags.bm_control) { | 973 | if (!pr->flags.bm_control) { |
974 | /* In this case we enter C3 without bus mastering */ | ||
964 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 975 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
965 | "C3 support requires bus mastering control\n")); | 976 | "C3 support without bus mastering control\n")); |
966 | return; | ||
967 | } | 977 | } |
968 | } else { | 978 | } else { |
969 | /* | 979 | /* |
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index c1bae106833c..974d00ccfe84 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c | |||
@@ -127,7 +127,7 @@ static int acpi_sbs_resume(struct acpi_device *device); | |||
127 | static struct acpi_driver acpi_sbs_driver = { | 127 | static struct acpi_driver acpi_sbs_driver = { |
128 | .name = "sbs", | 128 | .name = "sbs", |
129 | .class = ACPI_SBS_CLASS, | 129 | .class = ACPI_SBS_CLASS, |
130 | .ids = ACPI_SBS_HID, | 130 | .ids = "ACPI0001,ACPI0005", |
131 | .ops = { | 131 | .ops = { |
132 | .add = acpi_sbs_add, | 132 | .add = acpi_sbs_add, |
133 | .remove = acpi_sbs_remove, | 133 | .remove = acpi_sbs_remove, |
@@ -176,10 +176,8 @@ struct acpi_battery { | |||
176 | }; | 176 | }; |
177 | 177 | ||
178 | struct acpi_sbs { | 178 | struct acpi_sbs { |
179 | acpi_handle handle; | ||
180 | int base; | 179 | int base; |
181 | struct acpi_device *device; | 180 | struct acpi_device *device; |
182 | struct acpi_ec_smbus *smbus; | ||
183 | struct mutex mutex; | 181 | struct mutex mutex; |
184 | int sbsm_present; | 182 | int sbsm_present; |
185 | int sbsm_batteries_supported; | 183 | int sbsm_batteries_supported; |
@@ -511,7 +509,7 @@ static int acpi_sbsm_get_info(struct acpi_sbs *sbs) | |||
511 | "acpi_sbs_read_word() failed")); | 509 | "acpi_sbs_read_word() failed")); |
512 | goto end; | 510 | goto end; |
513 | } | 511 | } |
514 | 512 | sbs->sbsm_present = 1; | |
515 | sbs->sbsm_batteries_supported = battery_system_info & 0x000f; | 513 | sbs->sbsm_batteries_supported = battery_system_info & 0x000f; |
516 | 514 | ||
517 | end: | 515 | end: |
@@ -1630,13 +1628,12 @@ static int acpi_sbs_add(struct acpi_device *device) | |||
1630 | { | 1628 | { |
1631 | struct acpi_sbs *sbs = NULL; | 1629 | struct acpi_sbs *sbs = NULL; |
1632 | int result = 0, remove_result = 0; | 1630 | int result = 0, remove_result = 0; |
1633 | unsigned long sbs_obj; | ||
1634 | int id; | 1631 | int id; |
1635 | acpi_status status = AE_OK; | 1632 | acpi_status status = AE_OK; |
1636 | unsigned long val; | 1633 | unsigned long val; |
1637 | 1634 | ||
1638 | status = | 1635 | status = |
1639 | acpi_evaluate_integer(device->parent->handle, "_EC", NULL, &val); | 1636 | acpi_evaluate_integer(device->handle, "_EC", NULL, &val); |
1640 | if (ACPI_FAILURE(status)) { | 1637 | if (ACPI_FAILURE(status)) { |
1641 | ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Error obtaining _EC")); | 1638 | ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Error obtaining _EC")); |
1642 | return -EIO; | 1639 | return -EIO; |
@@ -1653,7 +1650,7 @@ static int acpi_sbs_add(struct acpi_device *device) | |||
1653 | 1650 | ||
1654 | sbs_mutex_lock(sbs); | 1651 | sbs_mutex_lock(sbs); |
1655 | 1652 | ||
1656 | sbs->base = (val & 0xff00ull) >> 8; | 1653 | sbs->base = 0xff & (val >> 8); |
1657 | sbs->device = device; | 1654 | sbs->device = device; |
1658 | 1655 | ||
1659 | strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME); | 1656 | strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME); |
@@ -1665,24 +1662,10 @@ static int acpi_sbs_add(struct acpi_device *device) | |||
1665 | ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_ac_add() failed")); | 1662 | ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_ac_add() failed")); |
1666 | goto end; | 1663 | goto end; |
1667 | } | 1664 | } |
1668 | status = acpi_evaluate_integer(device->handle, "_SBS", NULL, &sbs_obj); | ||
1669 | if (status) { | ||
1670 | ACPI_EXCEPTION((AE_INFO, status, | ||
1671 | "acpi_evaluate_integer() failed")); | ||
1672 | result = -EIO; | ||
1673 | goto end; | ||
1674 | } | ||
1675 | if (sbs_obj > 0) { | ||
1676 | result = acpi_sbsm_get_info(sbs); | ||
1677 | if (result) { | ||
1678 | ACPI_EXCEPTION((AE_INFO, AE_ERROR, | ||
1679 | "acpi_sbsm_get_info() failed")); | ||
1680 | goto end; | ||
1681 | } | ||
1682 | sbs->sbsm_present = 1; | ||
1683 | } | ||
1684 | 1665 | ||
1685 | if (sbs->sbsm_present == 0) { | 1666 | acpi_sbsm_get_info(sbs); |
1667 | |||
1668 | if (!sbs->sbsm_present) { | ||
1686 | result = acpi_battery_add(sbs, 0); | 1669 | result = acpi_battery_add(sbs, 0); |
1687 | if (result) { | 1670 | if (result) { |
1688 | ACPI_EXCEPTION((AE_INFO, AE_ERROR, | 1671 | ACPI_EXCEPTION((AE_INFO, AE_ERROR, |
@@ -1702,8 +1685,6 @@ static int acpi_sbs_add(struct acpi_device *device) | |||
1702 | } | 1685 | } |
1703 | } | 1686 | } |
1704 | 1687 | ||
1705 | sbs->handle = device->handle; | ||
1706 | |||
1707 | init_timer(&sbs->update_timer); | 1688 | init_timer(&sbs->update_timer); |
1708 | result = acpi_check_update_proc(sbs); | 1689 | result = acpi_check_update_proc(sbs); |
1709 | if (result) | 1690 | if (result) |
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c index 42127c0d612c..3279e72a94f8 100644 --- a/drivers/acpi/sleep/main.c +++ b/drivers/acpi/sleep/main.c | |||
@@ -210,11 +210,6 @@ static void acpi_hibernation_finish(void) | |||
210 | 210 | ||
211 | /* reset firmware waking vector */ | 211 | /* reset firmware waking vector */ |
212 | acpi_set_firmware_waking_vector((acpi_physical_address) 0); | 212 | acpi_set_firmware_waking_vector((acpi_physical_address) 0); |
213 | |||
214 | if (init_8259A_after_S1) { | ||
215 | printk("Broken toshiba laptop -> kicking interrupts\n"); | ||
216 | init_8259A(0); | ||
217 | } | ||
218 | } | 213 | } |
219 | 214 | ||
220 | static int acpi_hibernation_pre_restore(void) | 215 | static int acpi_hibernation_pre_restore(void) |
diff --git a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/tables/tbfadt.c index 1285e91474fb..002bb33003af 100644 --- a/drivers/acpi/tables/tbfadt.c +++ b/drivers/acpi/tables/tbfadt.c | |||
@@ -211,14 +211,17 @@ void acpi_tb_parse_fadt(acpi_native_uint table_index, u8 flags) | |||
211 | * DESCRIPTION: Get a local copy of the FADT and convert it to a common format. | 211 | * DESCRIPTION: Get a local copy of the FADT and convert it to a common format. |
212 | * Performs validation on some important FADT fields. | 212 | * Performs validation on some important FADT fields. |
213 | * | 213 | * |
214 | * NOTE: We create a local copy of the FADT regardless of the version. | ||
215 | * | ||
214 | ******************************************************************************/ | 216 | ******************************************************************************/ |
215 | 217 | ||
216 | void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) | 218 | void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) |
217 | { | 219 | { |
218 | 220 | ||
219 | /* | 221 | /* |
220 | * Check if the FADT is larger than what we know about (ACPI 2.0 version). | 222 | * Check if the FADT is larger than the largest table that we expect |
221 | * Truncate the table, but make some noise. | 223 | * (the ACPI 2.0/3.0 version). If so, truncate the table, and issue |
224 | * a warning. | ||
222 | */ | 225 | */ |
223 | if (length > sizeof(struct acpi_table_fadt)) { | 226 | if (length > sizeof(struct acpi_table_fadt)) { |
224 | ACPI_WARNING((AE_INFO, | 227 | ACPI_WARNING((AE_INFO, |
@@ -227,10 +230,12 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) | |||
227 | sizeof(struct acpi_table_fadt))); | 230 | sizeof(struct acpi_table_fadt))); |
228 | } | 231 | } |
229 | 232 | ||
230 | /* Copy the entire FADT locally. Zero first for tb_convert_fadt */ | 233 | /* Clear the entire local FADT */ |
231 | 234 | ||
232 | ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt)); | 235 | ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt)); |
233 | 236 | ||
237 | /* Copy the original FADT, up to sizeof (struct acpi_table_fadt) */ | ||
238 | |||
234 | ACPI_MEMCPY(&acpi_gbl_FADT, table, | 239 | ACPI_MEMCPY(&acpi_gbl_FADT, table, |
235 | ACPI_MIN(length, sizeof(struct acpi_table_fadt))); | 240 | ACPI_MIN(length, sizeof(struct acpi_table_fadt))); |
236 | 241 | ||
@@ -251,7 +256,7 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) | |||
251 | * RETURN: None | 256 | * RETURN: None |
252 | * | 257 | * |
253 | * DESCRIPTION: Converts all versions of the FADT to a common internal format. | 258 | * DESCRIPTION: Converts all versions of the FADT to a common internal format. |
254 | * -> Expand all 32-bit addresses to 64-bit. | 259 | * Expand all 32-bit addresses to 64-bit. |
255 | * | 260 | * |
256 | * NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt), | 261 | * NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt), |
257 | * and must contain a copy of the actual FADT. | 262 | * and must contain a copy of the actual FADT. |
@@ -292,8 +297,23 @@ static void acpi_tb_convert_fadt(void) | |||
292 | } | 297 | } |
293 | 298 | ||
294 | /* | 299 | /* |
295 | * Expand the 32-bit V1.0 addresses to the 64-bit "X" generic address | 300 | * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which |
296 | * structures as necessary. | 301 | * should be zero are indeed zero. This will workaround BIOSs that |
302 | * inadvertently place values in these fields. | ||
303 | * | ||
304 | * The ACPI 1.0 reserved fields that will be zeroed are the bytes located at | ||
305 | * offset 45, 55, 95, and the word located at offset 109, 110. | ||
306 | */ | ||
307 | if (acpi_gbl_FADT.header.revision < 3) { | ||
308 | acpi_gbl_FADT.preferred_profile = 0; | ||
309 | acpi_gbl_FADT.pstate_control = 0; | ||
310 | acpi_gbl_FADT.cst_control = 0; | ||
311 | acpi_gbl_FADT.boot_flags = 0; | ||
312 | } | ||
313 | |||
314 | /* | ||
315 | * Expand the ACPI 1.0 32-bit V1.0 addresses to the ACPI 2.0 64-bit "X" | ||
316 | * generic address structures as necessary. | ||
297 | */ | 317 | */ |
298 | for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { | 318 | for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { |
299 | target = | 319 | target = |
@@ -349,18 +369,6 @@ static void acpi_tb_convert_fadt(void) | |||
349 | acpi_gbl_FADT.xpm1a_event_block.space_id; | 369 | acpi_gbl_FADT.xpm1a_event_block.space_id; |
350 | 370 | ||
351 | } | 371 | } |
352 | |||
353 | /* | ||
354 | * For ACPI 1.0 FADTs, ensure that reserved fields (which should be zero) | ||
355 | * are indeed zero. This will workaround BIOSs that inadvertently placed | ||
356 | * values in these fields. | ||
357 | */ | ||
358 | if (acpi_gbl_FADT.header.revision < 3) { | ||
359 | acpi_gbl_FADT.preferred_profile = 0; | ||
360 | acpi_gbl_FADT.pstate_control = 0; | ||
361 | acpi_gbl_FADT.cst_control = 0; | ||
362 | acpi_gbl_FADT.boot_flags = 0; | ||
363 | } | ||
364 | } | 372 | } |
365 | 373 | ||
366 | /****************************************************************************** | 374 | /****************************************************************************** |
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c index 9623eaf4f89f..303e48ca0e8a 100644 --- a/drivers/misc/sony-laptop.c +++ b/drivers/misc/sony-laptop.c | |||
@@ -142,43 +142,124 @@ struct sony_laptop_keypress { | |||
142 | int key; | 142 | int key; |
143 | }; | 143 | }; |
144 | 144 | ||
145 | /* Correspondance table between sonypi events and input layer events */ | 145 | /* Correspondance table between sonypi events |
146 | static struct { | 146 | * and input layer indexes in the keymap |
147 | int sonypiev; | 147 | */ |
148 | int inputev; | 148 | static int sony_laptop_input_index[] = { |
149 | } sony_laptop_inputkeys[] = { | 149 | -1, /* no event */ |
150 | { SONYPI_EVENT_CAPTURE_PRESSED, KEY_CAMERA }, | 150 | -1, /* SONYPI_EVENT_JOGDIAL_DOWN */ |
151 | { SONYPI_EVENT_FNKEY_ONLY, KEY_FN }, | 151 | -1, /* SONYPI_EVENT_JOGDIAL_UP */ |
152 | { SONYPI_EVENT_FNKEY_ESC, KEY_FN_ESC }, | 152 | -1, /* SONYPI_EVENT_JOGDIAL_DOWN_PRESSED */ |
153 | { SONYPI_EVENT_FNKEY_F1, KEY_FN_F1 }, | 153 | -1, /* SONYPI_EVENT_JOGDIAL_UP_PRESSED */ |
154 | { SONYPI_EVENT_FNKEY_F2, KEY_FN_F2 }, | 154 | -1, /* SONYPI_EVENT_JOGDIAL_PRESSED */ |
155 | { SONYPI_EVENT_FNKEY_F3, KEY_FN_F3 }, | 155 | -1, /* SONYPI_EVENT_JOGDIAL_RELEASED */ |
156 | { SONYPI_EVENT_FNKEY_F4, KEY_FN_F4 }, | 156 | 0, /* SONYPI_EVENT_CAPTURE_PRESSED */ |
157 | { SONYPI_EVENT_FNKEY_F5, KEY_FN_F5 }, | 157 | 1, /* SONYPI_EVENT_CAPTURE_RELEASED */ |
158 | { SONYPI_EVENT_FNKEY_F6, KEY_FN_F6 }, | 158 | 2, /* SONYPI_EVENT_CAPTURE_PARTIALPRESSED */ |
159 | { SONYPI_EVENT_FNKEY_F7, KEY_FN_F7 }, | 159 | 3, /* SONYPI_EVENT_CAPTURE_PARTIALRELEASED */ |
160 | { SONYPI_EVENT_FNKEY_F8, KEY_FN_F8 }, | 160 | 4, /* SONYPI_EVENT_FNKEY_ESC */ |
161 | { SONYPI_EVENT_FNKEY_F9, KEY_FN_F9 }, | 161 | 5, /* SONYPI_EVENT_FNKEY_F1 */ |
162 | { SONYPI_EVENT_FNKEY_F10, KEY_FN_F10 }, | 162 | 6, /* SONYPI_EVENT_FNKEY_F2 */ |
163 | { SONYPI_EVENT_FNKEY_F11, KEY_FN_F11 }, | 163 | 7, /* SONYPI_EVENT_FNKEY_F3 */ |
164 | { SONYPI_EVENT_FNKEY_F12, KEY_FN_F12 }, | 164 | 8, /* SONYPI_EVENT_FNKEY_F4 */ |
165 | { SONYPI_EVENT_FNKEY_1, KEY_FN_1 }, | 165 | 9, /* SONYPI_EVENT_FNKEY_F5 */ |
166 | { SONYPI_EVENT_FNKEY_2, KEY_FN_2 }, | 166 | 10, /* SONYPI_EVENT_FNKEY_F6 */ |
167 | { SONYPI_EVENT_FNKEY_D, KEY_FN_D }, | 167 | 11, /* SONYPI_EVENT_FNKEY_F7 */ |
168 | { SONYPI_EVENT_FNKEY_E, KEY_FN_E }, | 168 | 12, /* SONYPI_EVENT_FNKEY_F8 */ |
169 | { SONYPI_EVENT_FNKEY_F, KEY_FN_F }, | 169 | 13, /* SONYPI_EVENT_FNKEY_F9 */ |
170 | { SONYPI_EVENT_FNKEY_S, KEY_FN_S }, | 170 | 14, /* SONYPI_EVENT_FNKEY_F10 */ |
171 | { SONYPI_EVENT_FNKEY_B, KEY_FN_B }, | 171 | 15, /* SONYPI_EVENT_FNKEY_F11 */ |
172 | { SONYPI_EVENT_BLUETOOTH_PRESSED, KEY_BLUE }, | 172 | 16, /* SONYPI_EVENT_FNKEY_F12 */ |
173 | { SONYPI_EVENT_BLUETOOTH_ON, KEY_BLUE }, | 173 | 17, /* SONYPI_EVENT_FNKEY_1 */ |
174 | { SONYPI_EVENT_PKEY_P1, KEY_PROG1 }, | 174 | 18, /* SONYPI_EVENT_FNKEY_2 */ |
175 | { SONYPI_EVENT_PKEY_P2, KEY_PROG2 }, | 175 | 19, /* SONYPI_EVENT_FNKEY_D */ |
176 | { SONYPI_EVENT_PKEY_P3, KEY_PROG3 }, | 176 | 20, /* SONYPI_EVENT_FNKEY_E */ |
177 | { SONYPI_EVENT_BACK_PRESSED, KEY_BACK }, | 177 | 21, /* SONYPI_EVENT_FNKEY_F */ |
178 | { SONYPI_EVENT_HELP_PRESSED, KEY_HELP }, | 178 | 22, /* SONYPI_EVENT_FNKEY_S */ |
179 | { SONYPI_EVENT_ZOOM_PRESSED, KEY_ZOOM }, | 179 | 23, /* SONYPI_EVENT_FNKEY_B */ |
180 | { SONYPI_EVENT_THUMBPHRASE_PRESSED, BTN_THUMB }, | 180 | 24, /* SONYPI_EVENT_BLUETOOTH_PRESSED */ |
181 | { 0, 0 }, | 181 | 25, /* SONYPI_EVENT_PKEY_P1 */ |
182 | 26, /* SONYPI_EVENT_PKEY_P2 */ | ||
183 | 27, /* SONYPI_EVENT_PKEY_P3 */ | ||
184 | 28, /* SONYPI_EVENT_BACK_PRESSED */ | ||
185 | -1, /* SONYPI_EVENT_LID_CLOSED */ | ||
186 | -1, /* SONYPI_EVENT_LID_OPENED */ | ||
187 | 29, /* SONYPI_EVENT_BLUETOOTH_ON */ | ||
188 | 30, /* SONYPI_EVENT_BLUETOOTH_OFF */ | ||
189 | 31, /* SONYPI_EVENT_HELP_PRESSED */ | ||
190 | 32, /* SONYPI_EVENT_FNKEY_ONLY */ | ||
191 | 33, /* SONYPI_EVENT_JOGDIAL_FAST_DOWN */ | ||
192 | 34, /* SONYPI_EVENT_JOGDIAL_FAST_UP */ | ||
193 | 35, /* SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED */ | ||
194 | 36, /* SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED */ | ||
195 | 37, /* SONYPI_EVENT_JOGDIAL_VFAST_DOWN */ | ||
196 | 38, /* SONYPI_EVENT_JOGDIAL_VFAST_UP */ | ||
197 | 39, /* SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED */ | ||
198 | 40, /* SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED */ | ||
199 | 41, /* SONYPI_EVENT_ZOOM_PRESSED */ | ||
200 | 42, /* SONYPI_EVENT_THUMBPHRASE_PRESSED */ | ||
201 | 43, /* SONYPI_EVENT_MEYE_FACE */ | ||
202 | 44, /* SONYPI_EVENT_MEYE_OPPOSITE */ | ||
203 | 45, /* SONYPI_EVENT_MEMORYSTICK_INSERT */ | ||
204 | 46, /* SONYPI_EVENT_MEMORYSTICK_EJECT */ | ||
205 | -1, /* SONYPI_EVENT_ANYBUTTON_RELEASED */ | ||
206 | -1, /* SONYPI_EVENT_BATTERY_INSERT */ | ||
207 | -1, /* SONYPI_EVENT_BATTERY_REMOVE */ | ||
208 | -1, /* SONYPI_EVENT_FNKEY_RELEASED */ | ||
209 | 47, /* SONYPI_EVENT_WIRELESS_ON */ | ||
210 | 48, /* SONYPI_EVENT_WIRELESS_OFF */ | ||
211 | }; | ||
212 | |||
213 | static int sony_laptop_input_keycode_map[] = { | ||
214 | KEY_CAMERA, /* 0 SONYPI_EVENT_CAPTURE_PRESSED */ | ||
215 | KEY_RESERVED, /* 1 SONYPI_EVENT_CAPTURE_RELEASED */ | ||
216 | KEY_RESERVED, /* 2 SONYPI_EVENT_CAPTURE_PARTIALPRESSED */ | ||
217 | KEY_RESERVED, /* 3 SONYPI_EVENT_CAPTURE_PARTIALRELEASED */ | ||
218 | KEY_FN_ESC, /* 4 SONYPI_EVENT_FNKEY_ESC */ | ||
219 | KEY_FN_F1, /* 5 SONYPI_EVENT_FNKEY_F1 */ | ||
220 | KEY_FN_F2, /* 6 SONYPI_EVENT_FNKEY_F2 */ | ||
221 | KEY_FN_F3, /* 7 SONYPI_EVENT_FNKEY_F3 */ | ||
222 | KEY_FN_F4, /* 8 SONYPI_EVENT_FNKEY_F4 */ | ||
223 | KEY_FN_F5, /* 9 SONYPI_EVENT_FNKEY_F5 */ | ||
224 | KEY_FN_F6, /* 10 SONYPI_EVENT_FNKEY_F6 */ | ||
225 | KEY_FN_F7, /* 11 SONYPI_EVENT_FNKEY_F7 */ | ||
226 | KEY_FN_F8, /* 12 SONYPI_EVENT_FNKEY_F8 */ | ||
227 | KEY_FN_F9, /* 13 SONYPI_EVENT_FNKEY_F9 */ | ||
228 | KEY_FN_F10, /* 14 SONYPI_EVENT_FNKEY_F10 */ | ||
229 | KEY_FN_F11, /* 15 SONYPI_EVENT_FNKEY_F11 */ | ||
230 | KEY_FN_F12, /* 16 SONYPI_EVENT_FNKEY_F12 */ | ||
231 | KEY_FN_F1, /* 17 SONYPI_EVENT_FNKEY_1 */ | ||
232 | KEY_FN_F2, /* 18 SONYPI_EVENT_FNKEY_2 */ | ||
233 | KEY_FN_D, /* 19 SONYPI_EVENT_FNKEY_D */ | ||
234 | KEY_FN_E, /* 20 SONYPI_EVENT_FNKEY_E */ | ||
235 | KEY_FN_F, /* 21 SONYPI_EVENT_FNKEY_F */ | ||
236 | KEY_FN_S, /* 22 SONYPI_EVENT_FNKEY_S */ | ||
237 | KEY_FN_B, /* 23 SONYPI_EVENT_FNKEY_B */ | ||
238 | KEY_BLUETOOTH, /* 24 SONYPI_EVENT_BLUETOOTH_PRESSED */ | ||
239 | KEY_PROG1, /* 25 SONYPI_EVENT_PKEY_P1 */ | ||
240 | KEY_PROG2, /* 26 SONYPI_EVENT_PKEY_P2 */ | ||
241 | KEY_PROG3, /* 27 SONYPI_EVENT_PKEY_P3 */ | ||
242 | KEY_BACK, /* 28 SONYPI_EVENT_BACK_PRESSED */ | ||
243 | KEY_BLUETOOTH, /* 29 SONYPI_EVENT_BLUETOOTH_ON */ | ||
244 | KEY_BLUETOOTH, /* 30 SONYPI_EVENT_BLUETOOTH_OFF */ | ||
245 | KEY_HELP, /* 31 SONYPI_EVENT_HELP_PRESSED */ | ||
246 | KEY_FN, /* 32 SONYPI_EVENT_FNKEY_ONLY */ | ||
247 | KEY_RESERVED, /* 33 SONYPI_EVENT_JOGDIAL_FAST_DOWN */ | ||
248 | KEY_RESERVED, /* 34 SONYPI_EVENT_JOGDIAL_FAST_UP */ | ||
249 | KEY_RESERVED, /* 35 SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED */ | ||
250 | KEY_RESERVED, /* 36 SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED */ | ||
251 | KEY_RESERVED, /* 37 SONYPI_EVENT_JOGDIAL_VFAST_DOWN */ | ||
252 | KEY_RESERVED, /* 38 SONYPI_EVENT_JOGDIAL_VFAST_UP */ | ||
253 | KEY_RESERVED, /* 39 SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED */ | ||
254 | KEY_RESERVED, /* 40 SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED */ | ||
255 | KEY_ZOOM, /* 41 SONYPI_EVENT_ZOOM_PRESSED */ | ||
256 | BTN_THUMB, /* 42 SONYPI_EVENT_THUMBPHRASE_PRESSED */ | ||
257 | KEY_RESERVED, /* 43 SONYPI_EVENT_MEYE_FACE */ | ||
258 | KEY_RESERVED, /* 44 SONYPI_EVENT_MEYE_OPPOSITE */ | ||
259 | KEY_RESERVED, /* 45 SONYPI_EVENT_MEMORYSTICK_INSERT */ | ||
260 | KEY_RESERVED, /* 46 SONYPI_EVENT_MEMORYSTICK_EJECT */ | ||
261 | KEY_WLAN, /* 47 SONYPI_EVENT_WIRELESS_ON */ | ||
262 | KEY_WLAN, /* 48 SONYPI_EVENT_WIRELESS_OFF */ | ||
182 | }; | 263 | }; |
183 | 264 | ||
184 | /* release buttons after a short delay if pressed */ | 265 | /* release buttons after a short delay if pressed */ |
@@ -202,7 +283,6 @@ static void sony_laptop_report_input_event(u8 event) | |||
202 | struct input_dev *jog_dev = sony_laptop_input.jog_dev; | 283 | struct input_dev *jog_dev = sony_laptop_input.jog_dev; |
203 | struct input_dev *key_dev = sony_laptop_input.key_dev; | 284 | struct input_dev *key_dev = sony_laptop_input.key_dev; |
204 | struct sony_laptop_keypress kp = { NULL }; | 285 | struct sony_laptop_keypress kp = { NULL }; |
205 | int i; | ||
206 | 286 | ||
207 | if (event == SONYPI_EVENT_FNKEY_RELEASED) { | 287 | if (event == SONYPI_EVENT_FNKEY_RELEASED) { |
208 | /* Nothing, not all VAIOs generate this event */ | 288 | /* Nothing, not all VAIOs generate this event */ |
@@ -231,17 +311,22 @@ static void sony_laptop_report_input_event(u8 event) | |||
231 | break; | 311 | break; |
232 | 312 | ||
233 | default: | 313 | default: |
234 | for (i = 0; sony_laptop_inputkeys[i].sonypiev; i++) | 314 | if (event > ARRAY_SIZE (sony_laptop_input_keycode_map)) { |
235 | if (event == sony_laptop_inputkeys[i].sonypiev) { | 315 | dprintk("sony_laptop_report_input_event, event not known: %d\n", event); |
316 | break; | ||
317 | } | ||
318 | if (sony_laptop_input_index[event] != -1) { | ||
319 | kp.key = sony_laptop_input_keycode_map[sony_laptop_input_index[event]]; | ||
320 | if (kp.key != KEY_UNKNOWN) | ||
236 | kp.dev = key_dev; | 321 | kp.dev = key_dev; |
237 | kp.key = sony_laptop_inputkeys[i].inputev; | 322 | } |
238 | break; | ||
239 | } | ||
240 | break; | 323 | break; |
241 | } | 324 | } |
242 | 325 | ||
243 | if (kp.dev) { | 326 | if (kp.dev) { |
244 | input_report_key(kp.dev, kp.key, 1); | 327 | input_report_key(kp.dev, kp.key, 1); |
328 | /* we emit the scancode so we can always remap the key */ | ||
329 | input_event(kp.dev, EV_MSC, MSC_SCAN, event); | ||
245 | input_sync(kp.dev); | 330 | input_sync(kp.dev); |
246 | kfifo_put(sony_laptop_input.fifo, | 331 | kfifo_put(sony_laptop_input.fifo, |
247 | (unsigned char *)&kp, sizeof(kp)); | 332 | (unsigned char *)&kp, sizeof(kp)); |
@@ -296,11 +381,18 @@ static int sony_laptop_setup_input(void) | |||
296 | key_dev->id.vendor = PCI_VENDOR_ID_SONY; | 381 | key_dev->id.vendor = PCI_VENDOR_ID_SONY; |
297 | 382 | ||
298 | /* Initialize the Input Drivers: special keys */ | 383 | /* Initialize the Input Drivers: special keys */ |
299 | key_dev->evbit[0] = BIT(EV_KEY); | 384 | set_bit(EV_KEY, key_dev->evbit); |
300 | for (i = 0; sony_laptop_inputkeys[i].sonypiev; i++) | 385 | set_bit(EV_MSC, key_dev->evbit); |
301 | if (sony_laptop_inputkeys[i].inputev) | 386 | set_bit(MSC_SCAN, key_dev->mscbit); |
302 | set_bit(sony_laptop_inputkeys[i].inputev, | 387 | key_dev->keycodesize = sizeof(sony_laptop_input_keycode_map[0]); |
303 | key_dev->keybit); | 388 | key_dev->keycodemax = ARRAY_SIZE(sony_laptop_input_keycode_map); |
389 | key_dev->keycode = &sony_laptop_input_keycode_map; | ||
390 | for (i = 0; i < ARRAY_SIZE(sony_laptop_input_keycode_map); i++) { | ||
391 | if (sony_laptop_input_keycode_map[i] != KEY_RESERVED) { | ||
392 | set_bit(sony_laptop_input_keycode_map[i], | ||
393 | key_dev->keybit); | ||
394 | } | ||
395 | } | ||
304 | 396 | ||
305 | error = input_register_device(key_dev); | 397 | error = input_register_device(key_dev); |
306 | if (error) | 398 | if (error) |
@@ -487,6 +579,14 @@ SNC_HANDLE_NAMES(audiopower_set, "AZPW"); | |||
487 | SNC_HANDLE_NAMES(lanpower_get, "GLNP"); | 579 | SNC_HANDLE_NAMES(lanpower_get, "GLNP"); |
488 | SNC_HANDLE_NAMES(lanpower_set, "LNPW"); | 580 | SNC_HANDLE_NAMES(lanpower_set, "LNPW"); |
489 | 581 | ||
582 | SNC_HANDLE_NAMES(lidstate_get, "GLID"); | ||
583 | |||
584 | SNC_HANDLE_NAMES(indicatorlamp_get, "GILS"); | ||
585 | SNC_HANDLE_NAMES(indicatorlamp_set, "SILS"); | ||
586 | |||
587 | SNC_HANDLE_NAMES(gainbass_get, "GMGB"); | ||
588 | SNC_HANDLE_NAMES(gainbass_set, "CMGB"); | ||
589 | |||
490 | SNC_HANDLE_NAMES(PID_get, "GPID"); | 590 | SNC_HANDLE_NAMES(PID_get, "GPID"); |
491 | 591 | ||
492 | SNC_HANDLE_NAMES(CTR_get, "GCTR"); | 592 | SNC_HANDLE_NAMES(CTR_get, "GCTR"); |
@@ -507,6 +607,12 @@ static struct sony_nc_value sony_nc_values[] = { | |||
507 | boolean_validate, 0), | 607 | boolean_validate, 0), |
508 | SNC_HANDLE(lanpower, snc_lanpower_get, snc_lanpower_set, | 608 | SNC_HANDLE(lanpower, snc_lanpower_get, snc_lanpower_set, |
509 | boolean_validate, 1), | 609 | boolean_validate, 1), |
610 | SNC_HANDLE(lidstate, snc_lidstate_get, NULL, | ||
611 | boolean_validate, 0), | ||
612 | SNC_HANDLE(indicatorlamp, snc_indicatorlamp_get, snc_indicatorlamp_set, | ||
613 | boolean_validate, 0), | ||
614 | SNC_HANDLE(gainbass, snc_gainbass_get, snc_gainbass_set, | ||
615 | boolean_validate, 0), | ||
510 | /* unknown methods */ | 616 | /* unknown methods */ |
511 | SNC_HANDLE(PID, snc_PID_get, NULL, NULL, 1), | 617 | SNC_HANDLE(PID, snc_PID_get, NULL, NULL, 1), |
512 | SNC_HANDLE(CTR, snc_CTR_get, snc_CTR_set, NULL, 1), | 618 | SNC_HANDLE(CTR, snc_CTR_get, snc_CTR_set, NULL, 1), |
@@ -689,13 +795,116 @@ static struct backlight_ops sony_backlight_ops = { | |||
689 | }; | 795 | }; |
690 | 796 | ||
691 | /* | 797 | /* |
798 | * New SNC-only Vaios event mapping to driver known keys | ||
799 | */ | ||
800 | struct sony_nc_event { | ||
801 | u8 data; | ||
802 | u8 event; | ||
803 | }; | ||
804 | |||
805 | static struct sony_nc_event *sony_nc_events; | ||
806 | |||
807 | /* Vaio C* --maybe also FE*, N* and AR* ?-- special init sequence | ||
808 | * for Fn keys | ||
809 | */ | ||
810 | static int sony_nc_C_enable(struct dmi_system_id *id) | ||
811 | { | ||
812 | int result = 0; | ||
813 | |||
814 | printk(KERN_NOTICE DRV_PFX "detected %s\n", id->ident); | ||
815 | |||
816 | sony_nc_events = id->driver_data; | ||
817 | |||
818 | if (acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x4, &result) < 0 | ||
819 | || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x2, &result) < 0 | ||
820 | || acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x10, &result) < 0 | ||
821 | || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x0, &result) < 0 | ||
822 | || acpi_callsetfunc(sony_nc_acpi_handle, "SN03", 0x2, &result) < 0 | ||
823 | || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x101, &result) < 0) { | ||
824 | printk(KERN_WARNING DRV_PFX "failed to initialize SNC, some " | ||
825 | "functionalities may be missing\n"); | ||
826 | return 1; | ||
827 | } | ||
828 | return 0; | ||
829 | } | ||
830 | |||
831 | static struct sony_nc_event sony_C_events[] = { | ||
832 | { 0x81, SONYPI_EVENT_FNKEY_F1 }, | ||
833 | { 0x01, SONYPI_EVENT_FNKEY_RELEASED }, | ||
834 | { 0x85, SONYPI_EVENT_FNKEY_F5 }, | ||
835 | { 0x05, SONYPI_EVENT_FNKEY_RELEASED }, | ||
836 | { 0x86, SONYPI_EVENT_FNKEY_F6 }, | ||
837 | { 0x06, SONYPI_EVENT_FNKEY_RELEASED }, | ||
838 | { 0x87, SONYPI_EVENT_FNKEY_F7 }, | ||
839 | { 0x07, SONYPI_EVENT_FNKEY_RELEASED }, | ||
840 | { 0x8A, SONYPI_EVENT_FNKEY_F10 }, | ||
841 | { 0x0A, SONYPI_EVENT_FNKEY_RELEASED }, | ||
842 | { 0x8C, SONYPI_EVENT_FNKEY_F12 }, | ||
843 | { 0x0C, SONYPI_EVENT_FNKEY_RELEASED }, | ||
844 | { 0, 0 }, | ||
845 | }; | ||
846 | |||
847 | /* SNC-only model map */ | ||
848 | struct dmi_system_id sony_nc_ids[] = { | ||
849 | { | ||
850 | .ident = "Sony Vaio FE Series", | ||
851 | .callback = sony_nc_C_enable, | ||
852 | .driver_data = sony_C_events, | ||
853 | .matches = { | ||
854 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
855 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FE"), | ||
856 | }, | ||
857 | }, | ||
858 | { | ||
859 | .ident = "Sony Vaio C Series", | ||
860 | .callback = sony_nc_C_enable, | ||
861 | .driver_data = sony_C_events, | ||
862 | .matches = { | ||
863 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
864 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-C"), | ||
865 | }, | ||
866 | }, | ||
867 | { } | ||
868 | }; | ||
869 | |||
870 | /* | ||
692 | * ACPI callbacks | 871 | * ACPI callbacks |
693 | */ | 872 | */ |
694 | static void sony_acpi_notify(acpi_handle handle, u32 event, void *data) | 873 | static void sony_acpi_notify(acpi_handle handle, u32 event, void *data) |
695 | { | 874 | { |
696 | dprintk("sony_acpi_notify, event: %d\n", event); | 875 | struct sony_nc_event *evmap; |
697 | sony_laptop_report_input_event(event); | 876 | u32 ev = event; |
698 | acpi_bus_generate_event(sony_nc_acpi_device, 1, event); | 877 | int result; |
878 | |||
879 | if (ev == 0x92) { | ||
880 | /* read the key pressed from EC.GECR | ||
881 | * A call to SN07 with 0x0202 will do it as well respecting | ||
882 | * the current protocol on different OSes | ||
883 | * | ||
884 | * Note: the path for GECR may be | ||
885 | * \_SB.PCI0.LPCB.EC (C, FE, AR, N and friends) | ||
886 | * \_SB.PCI0.PIB.EC0 (VGN-FR notifications are sent directly, no GECR) | ||
887 | * | ||
888 | * TODO: we may want to do the same for the older GHKE -need | ||
889 | * dmi list- so this snippet may become one more callback. | ||
890 | */ | ||
891 | if (acpi_callsetfunc(handle, "SN07", 0x0202, &result) < 0) | ||
892 | dprintk("sony_acpi_notify, unable to decode event 0x%.2x\n", ev); | ||
893 | else | ||
894 | ev = result & 0xFF; | ||
895 | } | ||
896 | |||
897 | if (sony_nc_events) | ||
898 | for (evmap = sony_nc_events; evmap->event; evmap++) { | ||
899 | if (evmap->data == ev) { | ||
900 | ev = evmap->event; | ||
901 | break; | ||
902 | } | ||
903 | } | ||
904 | |||
905 | dprintk("sony_acpi_notify, event: 0x%.2x\n", ev); | ||
906 | sony_laptop_report_input_event(ev); | ||
907 | acpi_bus_generate_event(sony_nc_acpi_device, 1, ev); | ||
699 | } | 908 | } |
700 | 909 | ||
701 | static acpi_status sony_walk_callback(acpi_handle handle, u32 level, | 910 | static acpi_status sony_walk_callback(acpi_handle handle, u32 level, |
@@ -732,6 +941,10 @@ static int sony_nc_resume(struct acpi_device *device) | |||
732 | break; | 941 | break; |
733 | } | 942 | } |
734 | } | 943 | } |
944 | |||
945 | /* re-initialize models with specific requirements */ | ||
946 | dmi_check_system(sony_nc_ids); | ||
947 | |||
735 | return 0; | 948 | return 0; |
736 | } | 949 | } |
737 | 950 | ||
@@ -750,6 +963,15 @@ static int sony_nc_add(struct acpi_device *device) | |||
750 | 963 | ||
751 | sony_nc_acpi_handle = device->handle; | 964 | sony_nc_acpi_handle = device->handle; |
752 | 965 | ||
966 | /* read device status */ | ||
967 | result = acpi_bus_get_status(device); | ||
968 | /* bail IFF the above call was successful and the device is not present */ | ||
969 | if (!result && !device->status.present) { | ||
970 | dprintk("Device not present\n"); | ||
971 | result = -ENODEV; | ||
972 | goto outwalk; | ||
973 | } | ||
974 | |||
753 | if (debug) { | 975 | if (debug) { |
754 | status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_nc_acpi_handle, | 976 | status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_nc_acpi_handle, |
755 | 1, sony_walk_callback, NULL, NULL); | 977 | 1, sony_walk_callback, NULL, NULL); |
@@ -760,6 +982,15 @@ static int sony_nc_add(struct acpi_device *device) | |||
760 | } | 982 | } |
761 | } | 983 | } |
762 | 984 | ||
985 | /* try to _INI the device if such method exists (ACPI spec 3.0-6.5.1 | ||
986 | * should be respected as we already checked for the device presence above */ | ||
987 | if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, METHOD_NAME__INI, &handle))) { | ||
988 | dprintk("Invoking _INI\n"); | ||
989 | if (ACPI_FAILURE(acpi_evaluate_object(sony_nc_acpi_handle, METHOD_NAME__INI, | ||
990 | NULL, NULL))) | ||
991 | dprintk("_INI Method failed\n"); | ||
992 | } | ||
993 | |||
763 | /* setup input devices and helper fifo */ | 994 | /* setup input devices and helper fifo */ |
764 | result = sony_laptop_setup_input(); | 995 | result = sony_laptop_setup_input(); |
765 | if (result) { | 996 | if (result) { |
@@ -772,7 +1003,7 @@ static int sony_nc_add(struct acpi_device *device) | |||
772 | ACPI_DEVICE_NOTIFY, | 1003 | ACPI_DEVICE_NOTIFY, |
773 | sony_acpi_notify, NULL); | 1004 | sony_acpi_notify, NULL); |
774 | if (ACPI_FAILURE(status)) { | 1005 | if (ACPI_FAILURE(status)) { |
775 | printk(KERN_WARNING DRV_PFX "unable to install notify handler\n"); | 1006 | printk(KERN_WARNING DRV_PFX "unable to install notify handler (%u)\n", status); |
776 | result = -ENODEV; | 1007 | result = -ENODEV; |
777 | goto outinput; | 1008 | goto outinput; |
778 | } | 1009 | } |
@@ -795,6 +1026,9 @@ static int sony_nc_add(struct acpi_device *device) | |||
795 | 1026 | ||
796 | } | 1027 | } |
797 | 1028 | ||
1029 | /* initialize models with specific requirements */ | ||
1030 | dmi_check_system(sony_nc_ids); | ||
1031 | |||
798 | result = sony_pf_add(); | 1032 | result = sony_pf_add(); |
799 | if (result) | 1033 | if (result) |
800 | goto outbacklight; | 1034 | goto outbacklight; |
@@ -908,7 +1142,9 @@ static struct acpi_driver sony_nc_driver = { | |||
908 | #define SONYPI_DEVICE_TYPE2 0x00000002 | 1142 | #define SONYPI_DEVICE_TYPE2 0x00000002 |
909 | #define SONYPI_DEVICE_TYPE3 0x00000004 | 1143 | #define SONYPI_DEVICE_TYPE3 0x00000004 |
910 | 1144 | ||
911 | #define SONY_PIC_EV_MASK 0xff | 1145 | #define SONYPI_TYPE1_OFFSET 0x04 |
1146 | #define SONYPI_TYPE2_OFFSET 0x12 | ||
1147 | #define SONYPI_TYPE3_OFFSET 0x12 | ||
912 | 1148 | ||
913 | struct sony_pic_ioport { | 1149 | struct sony_pic_ioport { |
914 | struct acpi_resource_io io; | 1150 | struct acpi_resource_io io; |
@@ -922,6 +1158,7 @@ struct sony_pic_irq { | |||
922 | 1158 | ||
923 | struct sony_pic_dev { | 1159 | struct sony_pic_dev { |
924 | int model; | 1160 | int model; |
1161 | u16 evport_offset; | ||
925 | u8 camera_power; | 1162 | u8 camera_power; |
926 | u8 bluetooth_power; | 1163 | u8 bluetooth_power; |
927 | u8 wwan_power; | 1164 | u8 wwan_power; |
@@ -1999,20 +2236,17 @@ end: | |||
1999 | static irqreturn_t sony_pic_irq(int irq, void *dev_id) | 2236 | static irqreturn_t sony_pic_irq(int irq, void *dev_id) |
2000 | { | 2237 | { |
2001 | int i, j; | 2238 | int i, j; |
2002 | u32 port_val = 0; | ||
2003 | u8 ev = 0; | 2239 | u8 ev = 0; |
2004 | u8 data_mask = 0; | 2240 | u8 data_mask = 0; |
2005 | u8 device_event = 0; | 2241 | u8 device_event = 0; |
2006 | 2242 | ||
2007 | struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id; | 2243 | struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id; |
2008 | 2244 | ||
2009 | acpi_os_read_port(dev->cur_ioport->io.minimum, &port_val, | 2245 | ev = inb_p(dev->cur_ioport->io.minimum); |
2010 | dev->cur_ioport->io.address_length); | 2246 | data_mask = inb_p(dev->cur_ioport->io.minimum + dev->evport_offset); |
2011 | ev = port_val & SONY_PIC_EV_MASK; | ||
2012 | data_mask = 0xff & (port_val >> (dev->cur_ioport->io.address_length - 8)); | ||
2013 | 2247 | ||
2014 | dprintk("event (0x%.8x [%.2x] [%.2x]) at port 0x%.4x\n", | 2248 | dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", |
2015 | port_val, ev, data_mask, dev->cur_ioport->io.minimum); | 2249 | ev, data_mask, dev->cur_ioport->io.minimum, dev->evport_offset); |
2016 | 2250 | ||
2017 | if (ev == 0x00 || ev == 0xff) | 2251 | if (ev == 0x00 || ev == 0xff) |
2018 | return IRQ_HANDLED; | 2252 | return IRQ_HANDLED; |
@@ -2103,6 +2337,20 @@ static int sony_pic_add(struct acpi_device *device) | |||
2103 | spic_dev.model = sony_pic_detect_device_type(); | 2337 | spic_dev.model = sony_pic_detect_device_type(); |
2104 | mutex_init(&spic_dev.lock); | 2338 | mutex_init(&spic_dev.lock); |
2105 | 2339 | ||
2340 | /* model specific characteristics */ | ||
2341 | switch(spic_dev.model) { | ||
2342 | case SONYPI_DEVICE_TYPE1: | ||
2343 | spic_dev.evport_offset = SONYPI_TYPE1_OFFSET; | ||
2344 | break; | ||
2345 | case SONYPI_DEVICE_TYPE3: | ||
2346 | spic_dev.evport_offset = SONYPI_TYPE3_OFFSET; | ||
2347 | break; | ||
2348 | case SONYPI_DEVICE_TYPE2: | ||
2349 | default: | ||
2350 | spic_dev.evport_offset = SONYPI_TYPE2_OFFSET; | ||
2351 | break; | ||
2352 | } | ||
2353 | |||
2106 | /* read _PRS resources */ | 2354 | /* read _PRS resources */ |
2107 | result = sony_pic_possible_resources(device); | 2355 | result = sony_pic_possible_resources(device); |
2108 | if (result) { | 2356 | if (result) { |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 3073f679584b..f8a602caabcb 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -5,6 +5,7 @@ | |||
5 | 5 | ||
6 | menuconfig NETDEVICES | 6 | menuconfig NETDEVICES |
7 | default y if UML | 7 | default y if UML |
8 | depends on NET | ||
8 | bool "Network device support" | 9 | bool "Network device support" |
9 | ---help--- | 10 | ---help--- |
10 | You can say N here if you don't intend to connect your Linux box to | 11 | You can say N here if you don't intend to connect your Linux box to |
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig index 829da9a1d113..2098d0af8ff5 100644 --- a/drivers/net/irda/Kconfig +++ b/drivers/net/irda/Kconfig | |||
@@ -155,6 +155,15 @@ config KINGSUN_DONGLE | |||
155 | To compile it as a module, choose M here: the module will be called | 155 | To compile it as a module, choose M here: the module will be called |
156 | kingsun-sir. | 156 | kingsun-sir. |
157 | 157 | ||
158 | config EP7211_DONGLE | ||
159 | tristate "EP7211 I/R support" | ||
160 | depends on IRTTY_SIR && ARCH_EP7211 && IRDA && EXPERIMENTAL | ||
161 | help | ||
162 | Say Y here if you want to build support for the Cirrus logic | ||
163 | EP7211 chipset's infrared module. | ||
164 | |||
165 | |||
166 | |||
158 | comment "Old SIR device drivers" | 167 | comment "Old SIR device drivers" |
159 | 168 | ||
160 | config IRPORT_SIR | 169 | config IRPORT_SIR |
@@ -355,7 +364,7 @@ config WINBOND_FIR | |||
355 | 364 | ||
356 | config TOSHIBA_FIR | 365 | config TOSHIBA_FIR |
357 | tristate "Toshiba Type-O IR Port" | 366 | tristate "Toshiba Type-O IR Port" |
358 | depends on IRDA && PCI && !64BIT | 367 | depends on IRDA && PCI && !64BIT && VIRT_TO_BUS |
359 | help | 368 | help |
360 | Say Y here if you want to build support for the Toshiba Type-O IR | 369 | Say Y here if you want to build support for the Toshiba Type-O IR |
361 | and Donau oboe chipsets. These chipsets are used by the Toshiba | 370 | and Donau oboe chipsets. These chipsets are used by the Toshiba |
diff --git a/drivers/net/irda/Makefile b/drivers/net/irda/Makefile index 233a2f923730..2808ef5c7b79 100644 --- a/drivers/net/irda/Makefile +++ b/drivers/net/irda/Makefile | |||
@@ -45,6 +45,7 @@ obj-$(CONFIG_MCP2120_DONGLE) += mcp2120-sir.o | |||
45 | obj-$(CONFIG_ACT200L_DONGLE) += act200l-sir.o | 45 | obj-$(CONFIG_ACT200L_DONGLE) += act200l-sir.o |
46 | obj-$(CONFIG_MA600_DONGLE) += ma600-sir.o | 46 | obj-$(CONFIG_MA600_DONGLE) += ma600-sir.o |
47 | obj-$(CONFIG_TOIM3232_DONGLE) += toim3232-sir.o | 47 | obj-$(CONFIG_TOIM3232_DONGLE) += toim3232-sir.o |
48 | obj-$(CONFIG_EP7211_DONGLE) += ep7211-sir.o | ||
48 | obj-$(CONFIG_KINGSUN_DONGLE) += kingsun-sir.o | 49 | obj-$(CONFIG_KINGSUN_DONGLE) += kingsun-sir.o |
49 | 50 | ||
50 | # The SIR helper module | 51 | # The SIR helper module |
diff --git a/drivers/net/irda/ep7211-sir.c b/drivers/net/irda/ep7211-sir.c new file mode 100644 index 000000000000..831572429bb9 --- /dev/null +++ b/drivers/net/irda/ep7211-sir.c | |||
@@ -0,0 +1,89 @@ | |||
1 | /* | ||
2 | * IR port driver for the Cirrus Logic EP7211 processor. | ||
3 | * | ||
4 | * Copyright 2001, Blue Mug Inc. All rights reserved. | ||
5 | * Copyright 2007, Samuel Ortiz <samuel@sortiz.org> | ||
6 | */ | ||
7 | #include <linux/module.h> | ||
8 | #include <linux/delay.h> | ||
9 | #include <linux/tty.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/spinlock.h> | ||
12 | |||
13 | #include <net/irda/irda.h> | ||
14 | #include <net/irda/irda_device.h> | ||
15 | |||
16 | #include <asm/io.h> | ||
17 | #include <asm/hardware.h> | ||
18 | |||
19 | #include "sir-dev.h" | ||
20 | |||
21 | #define MIN_DELAY 25 /* 15 us, but wait a little more to be sure */ | ||
22 | #define MAX_DELAY 10000 /* 1 ms */ | ||
23 | |||
24 | static int ep7211_open(struct sir_dev *dev); | ||
25 | static int ep7211_close(struct sir_dev *dev); | ||
26 | static int ep7211_change_speed(struct sir_dev *dev, unsigned speed); | ||
27 | static int ep7211_reset(struct sir_dev *dev); | ||
28 | |||
29 | static struct dongle_driver ep7211 = { | ||
30 | .owner = THIS_MODULE, | ||
31 | .driver_name = "EP7211 IR driver", | ||
32 | .type = IRDA_EP7211_DONGLE, | ||
33 | .open = ep7211_open, | ||
34 | .close = ep7211_close, | ||
35 | .reset = ep7211_reset, | ||
36 | .set_speed = ep7211_change_speed, | ||
37 | }; | ||
38 | |||
39 | static int __init ep7211_sir_init(void) | ||
40 | { | ||
41 | return irda_register_dongle(&ep7211); | ||
42 | } | ||
43 | |||
44 | static void __exit ep7211_sir_cleanup(void) | ||
45 | { | ||
46 | irda_unregister_dongle(&ep7211); | ||
47 | } | ||
48 | |||
49 | static int ep7211_open(struct sir_dev *dev) | ||
50 | { | ||
51 | unsigned int syscon; | ||
52 | |||
53 | /* Turn on the SIR encoder. */ | ||
54 | syscon = clps_readl(SYSCON1); | ||
55 | syscon |= SYSCON1_SIREN; | ||
56 | clps_writel(syscon, SYSCON1); | ||
57 | |||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | static int ep7211_close(struct sir_dev *dev) | ||
62 | { | ||
63 | unsigned int syscon; | ||
64 | |||
65 | /* Turn off the SIR encoder. */ | ||
66 | syscon = clps_readl(SYSCON1); | ||
67 | syscon &= ~SYSCON1_SIREN; | ||
68 | clps_writel(syscon, SYSCON1); | ||
69 | |||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | static int ep7211_change_speed(struct sir_dev *dev, unsigned speed) | ||
74 | { | ||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | static int ep7211_reset(struct sir_dev *dev) | ||
79 | { | ||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | MODULE_AUTHOR("Samuel Ortiz <samuel@sortiz.org>"); | ||
84 | MODULE_DESCRIPTION("EP7211 IR dongle driver"); | ||
85 | MODULE_LICENSE("GPL"); | ||
86 | MODULE_ALIAS("irda-dongle-13"); /* IRDA_EP7211_DONGLE */ | ||
87 | |||
88 | module_init(ep7211_sir_init); | ||
89 | module_exit(ep7211_sir_cleanup); | ||
diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h index 8948a6461834..45662f6dbdb6 100644 --- a/include/acpi/acmacros.h +++ b/include/acpi/acmacros.h | |||
@@ -486,6 +486,8 @@ | |||
486 | #define ACPI_FUNCTION_NAME(name) | 486 | #define ACPI_FUNCTION_NAME(name) |
487 | #endif | 487 | #endif |
488 | 488 | ||
489 | #ifdef DEBUG_FUNC_TRACE | ||
490 | |||
489 | #define ACPI_FUNCTION_TRACE(a) ACPI_FUNCTION_NAME(a) \ | 491 | #define ACPI_FUNCTION_TRACE(a) ACPI_FUNCTION_NAME(a) \ |
490 | acpi_ut_trace(ACPI_DEBUG_PARAMETERS) | 492 | acpi_ut_trace(ACPI_DEBUG_PARAMETERS) |
491 | #define ACPI_FUNCTION_TRACE_PTR(a,b) ACPI_FUNCTION_NAME(a) \ | 493 | #define ACPI_FUNCTION_TRACE_PTR(a,b) ACPI_FUNCTION_NAME(a) \ |
@@ -563,6 +565,27 @@ | |||
563 | 565 | ||
564 | #endif /* ACPI_SIMPLE_RETURN_MACROS */ | 566 | #endif /* ACPI_SIMPLE_RETURN_MACROS */ |
565 | 567 | ||
568 | #else /* !DEBUG_FUNC_TRACE */ | ||
569 | |||
570 | #define ACPI_FUNCTION_TRACE(a) | ||
571 | #define ACPI_FUNCTION_TRACE_PTR(a,b) | ||
572 | #define ACPI_FUNCTION_TRACE_U32(a,b) | ||
573 | #define ACPI_FUNCTION_TRACE_STR(a,b) | ||
574 | #define ACPI_FUNCTION_EXIT | ||
575 | #define ACPI_FUNCTION_STATUS_EXIT(s) | ||
576 | #define ACPI_FUNCTION_VALUE_EXIT(s) | ||
577 | #define ACPI_FUNCTION_TRACE(a) | ||
578 | #define ACPI_FUNCTION_ENTRY() | ||
579 | |||
580 | #define return_VOID return | ||
581 | #define return_ACPI_STATUS(s) return(s) | ||
582 | #define return_VALUE(s) return(s) | ||
583 | #define return_UINT8(s) return(s) | ||
584 | #define return_UINT32(s) return(s) | ||
585 | #define return_PTR(s) return(s) | ||
586 | |||
587 | #endif /* DEBUG_FUNC_TRACE */ | ||
588 | |||
566 | /* Conditional execution */ | 589 | /* Conditional execution */ |
567 | 590 | ||
568 | #define ACPI_DEBUG_EXEC(a) a | 591 | #define ACPI_DEBUG_EXEC(a) a |
@@ -599,26 +622,26 @@ | |||
599 | #define ACPI_DEBUG_EXEC(a) | 622 | #define ACPI_DEBUG_EXEC(a) |
600 | #define ACPI_NORMAL_EXEC(a) a; | 623 | #define ACPI_NORMAL_EXEC(a) a; |
601 | 624 | ||
602 | #define ACPI_DEBUG_DEFINE(a) | 625 | #define ACPI_DEBUG_DEFINE(a) do { } while(0) |
603 | #define ACPI_DEBUG_ONLY_MEMBERS(a) | 626 | #define ACPI_DEBUG_ONLY_MEMBERS(a) do { } while(0) |
604 | #define ACPI_FUNCTION_NAME(a) | 627 | #define ACPI_FUNCTION_NAME(a) do { } while(0) |
605 | #define ACPI_FUNCTION_TRACE(a) | 628 | #define ACPI_FUNCTION_TRACE(a) do { } while(0) |
606 | #define ACPI_FUNCTION_TRACE_PTR(a,b) | 629 | #define ACPI_FUNCTION_TRACE_PTR(a,b) do { } while(0) |
607 | #define ACPI_FUNCTION_TRACE_U32(a,b) | 630 | #define ACPI_FUNCTION_TRACE_U32(a,b) do { } while(0) |
608 | #define ACPI_FUNCTION_TRACE_STR(a,b) | 631 | #define ACPI_FUNCTION_TRACE_STR(a,b) do { } while(0) |
609 | #define ACPI_FUNCTION_EXIT | 632 | #define ACPI_FUNCTION_EXIT do { } while(0) |
610 | #define ACPI_FUNCTION_STATUS_EXIT(s) | 633 | #define ACPI_FUNCTION_STATUS_EXIT(s) do { } while(0) |
611 | #define ACPI_FUNCTION_VALUE_EXIT(s) | 634 | #define ACPI_FUNCTION_VALUE_EXIT(s) do { } while(0) |
612 | #define ACPI_FUNCTION_ENTRY() | 635 | #define ACPI_FUNCTION_ENTRY() do { } while(0) |
613 | #define ACPI_DUMP_STACK_ENTRY(a) | 636 | #define ACPI_DUMP_STACK_ENTRY(a) do { } while(0) |
614 | #define ACPI_DUMP_OPERANDS(a,b,c,d,e) | 637 | #define ACPI_DUMP_OPERANDS(a,b,c,d,e) do { } while(0) |
615 | #define ACPI_DUMP_ENTRY(a,b) | 638 | #define ACPI_DUMP_ENTRY(a,b) do { } while(0) |
616 | #define ACPI_DUMP_TABLES(a,b) | 639 | #define ACPI_DUMP_TABLES(a,b) do { } while(0) |
617 | #define ACPI_DUMP_PATHNAME(a,b,c,d) | 640 | #define ACPI_DUMP_PATHNAME(a,b,c,d) do { } while(0) |
618 | #define ACPI_DUMP_RESOURCE_LIST(a) | 641 | #define ACPI_DUMP_RESOURCE_LIST(a) do { } while(0) |
619 | #define ACPI_DUMP_BUFFER(a,b) | 642 | #define ACPI_DUMP_BUFFER(a,b) do { } while(0) |
620 | #define ACPI_DEBUG_PRINT(pl) | 643 | #define ACPI_DEBUG_PRINT(pl) do { } while(0) |
621 | #define ACPI_DEBUG_PRINT_RAW(pl) | 644 | #define ACPI_DEBUG_PRINT_RAW(pl) do { } while(0) |
622 | 645 | ||
623 | #define return_VOID return | 646 | #define return_VOID return |
624 | #define return_ACPI_STATUS(s) return(s) | 647 | #define return_ACPI_STATUS(s) return(s) |
diff --git a/include/acpi/acoutput.h b/include/acpi/acoutput.h index 7812267b577f..c090a8b0bc99 100644 --- a/include/acpi/acoutput.h +++ b/include/acpi/acoutput.h | |||
@@ -178,8 +178,8 @@ | |||
178 | 178 | ||
179 | /* Defaults for debug_level, debug and normal */ | 179 | /* Defaults for debug_level, debug and normal */ |
180 | 180 | ||
181 | #define ACPI_DEBUG_DEFAULT (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR | ACPI_LV_DEBUG_OBJECT) | 181 | #define ACPI_DEBUG_DEFAULT (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR) |
182 | #define ACPI_NORMAL_DEFAULT (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR | ACPI_LV_DEBUG_OBJECT) | 182 | #define ACPI_NORMAL_DEFAULT (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR) |
183 | #define ACPI_DEBUG_ALL (ACPI_LV_AML_DISASSEMBLE | ACPI_LV_ALL_EXCEPTIONS | ACPI_LV_ALL) | 183 | #define ACPI_DEBUG_ALL (ACPI_LV_AML_DISASSEMBLE | ACPI_LV_ALL_EXCEPTIONS | ACPI_LV_ALL) |
184 | 184 | ||
185 | #endif /* __ACOUTPUT_H__ */ | 185 | #endif /* __ACOUTPUT_H__ */ |
diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h index dab2ec59a3b0..c785485e62a6 100644 --- a/include/acpi/platform/acenv.h +++ b/include/acpi/platform/acenv.h | |||
@@ -136,7 +136,7 @@ | |||
136 | 136 | ||
137 | /*! [Begin] no source code translation */ | 137 | /*! [Begin] no source code translation */ |
138 | 138 | ||
139 | #if defined(__linux__) | 139 | #if defined(_LINUX) || defined(__linux__) |
140 | #include "aclinux.h" | 140 | #include "aclinux.h" |
141 | 141 | ||
142 | #elif defined(_AED_EFI) | 142 | #elif defined(_AED_EFI) |
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h index a568717f98c6..6ed15a0978eb 100644 --- a/include/acpi/platform/aclinux.h +++ b/include/acpi/platform/aclinux.h | |||
@@ -91,7 +91,10 @@ | |||
91 | #define ACPI_USE_NATIVE_DIVIDE | 91 | #define ACPI_USE_NATIVE_DIVIDE |
92 | #endif | 92 | #endif |
93 | 93 | ||
94 | #ifndef __cdecl | ||
94 | #define __cdecl | 95 | #define __cdecl |
96 | #endif | ||
97 | |||
95 | #define ACPI_FLUSH_CPU_CACHE() | 98 | #define ACPI_FLUSH_CPU_CACHE() |
96 | #endif /* __KERNEL__ */ | 99 | #endif /* __KERNEL__ */ |
97 | 100 | ||
diff --git a/include/asm-sparc/irq.h b/include/asm-sparc/irq.h index ff520ea97473..afb88a5973f0 100644 --- a/include/asm-sparc/irq.h +++ b/include/asm-sparc/irq.h | |||
@@ -7,178 +7,16 @@ | |||
7 | #ifndef _SPARC_IRQ_H | 7 | #ifndef _SPARC_IRQ_H |
8 | #define _SPARC_IRQ_H | 8 | #define _SPARC_IRQ_H |
9 | 9 | ||
10 | #include <linux/linkage.h> | ||
11 | #include <linux/threads.h> /* For NR_CPUS */ | ||
12 | #include <linux/interrupt.h> | 10 | #include <linux/interrupt.h> |
13 | 11 | ||
14 | #include <asm/system.h> /* For SUN4M_NCPUS */ | ||
15 | #include <asm/btfixup.h> | ||
16 | |||
17 | #define __irq_ino(irq) irq | ||
18 | #define __irq_pil(irq) irq | ||
19 | |||
20 | #define NR_IRQS 16 | 12 | #define NR_IRQS 16 |
21 | 13 | ||
22 | #define irq_canonicalize(irq) (irq) | 14 | #define irq_canonicalize(irq) (irq) |
23 | 15 | ||
24 | /* Dave Redman (djhr@tadpole.co.uk) | 16 | extern void disable_irq_nosync(unsigned int irq); |
25 | * changed these to function pointers.. it saves cycles and will allow | 17 | extern void disable_irq(unsigned int irq); |
26 | * the irq dependencies to be split into different files at a later date | 18 | extern void enable_irq(unsigned int irq); |
27 | * sun4c_irq.c, sun4m_irq.c etc so we could reduce the kernel size. | ||
28 | * Jakub Jelinek (jj@sunsite.mff.cuni.cz) | ||
29 | * Changed these to btfixup entities... It saves cycles :) | ||
30 | */ | ||
31 | BTFIXUPDEF_CALL(void, disable_irq, unsigned int) | ||
32 | BTFIXUPDEF_CALL(void, enable_irq, unsigned int) | ||
33 | BTFIXUPDEF_CALL(void, disable_pil_irq, unsigned int) | ||
34 | BTFIXUPDEF_CALL(void, enable_pil_irq, unsigned int) | ||
35 | BTFIXUPDEF_CALL(void, clear_clock_irq, void) | ||
36 | BTFIXUPDEF_CALL(void, clear_profile_irq, int) | ||
37 | BTFIXUPDEF_CALL(void, load_profile_irq, int, unsigned int) | ||
38 | |||
39 | static inline void disable_irq_nosync(unsigned int irq) | ||
40 | { | ||
41 | BTFIXUP_CALL(disable_irq)(irq); | ||
42 | } | ||
43 | |||
44 | static inline void disable_irq(unsigned int irq) | ||
45 | { | ||
46 | BTFIXUP_CALL(disable_irq)(irq); | ||
47 | } | ||
48 | |||
49 | static inline void enable_irq(unsigned int irq) | ||
50 | { | ||
51 | BTFIXUP_CALL(enable_irq)(irq); | ||
52 | } | ||
53 | |||
54 | static inline void disable_pil_irq(unsigned int irq) | ||
55 | { | ||
56 | BTFIXUP_CALL(disable_pil_irq)(irq); | ||
57 | } | ||
58 | |||
59 | static inline void enable_pil_irq(unsigned int irq) | ||
60 | { | ||
61 | BTFIXUP_CALL(enable_pil_irq)(irq); | ||
62 | } | ||
63 | |||
64 | static inline void clear_clock_irq(void) | ||
65 | { | ||
66 | BTFIXUP_CALL(clear_clock_irq)(); | ||
67 | } | ||
68 | |||
69 | static inline void clear_profile_irq(int irq) | ||
70 | { | ||
71 | BTFIXUP_CALL(clear_profile_irq)(irq); | ||
72 | } | ||
73 | |||
74 | static inline void load_profile_irq(int cpu, int limit) | ||
75 | { | ||
76 | BTFIXUP_CALL(load_profile_irq)(cpu, limit); | ||
77 | } | ||
78 | |||
79 | extern void (*sparc_init_timers)(irq_handler_t lvl10_irq); | ||
80 | extern void claim_ticker14(irq_handler_t irq_handler, | ||
81 | int irq, | ||
82 | unsigned int timeout); | ||
83 | |||
84 | #ifdef CONFIG_SMP | ||
85 | BTFIXUPDEF_CALL(void, set_cpu_int, int, int) | ||
86 | BTFIXUPDEF_CALL(void, clear_cpu_int, int, int) | ||
87 | BTFIXUPDEF_CALL(void, set_irq_udt, int) | ||
88 | |||
89 | #define set_cpu_int(cpu,level) BTFIXUP_CALL(set_cpu_int)(cpu,level) | ||
90 | #define clear_cpu_int(cpu,level) BTFIXUP_CALL(clear_cpu_int)(cpu,level) | ||
91 | #define set_irq_udt(cpu) BTFIXUP_CALL(set_irq_udt)(cpu) | ||
92 | #endif | ||
93 | 19 | ||
94 | extern int request_fast_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, __const__ char *devname); | 20 | extern int request_fast_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, __const__ char *devname); |
95 | 21 | ||
96 | /* On the sun4m, just like the timers, we have both per-cpu and master | ||
97 | * interrupt registers. | ||
98 | */ | ||
99 | |||
100 | /* These registers are used for sending/receiving irqs from/to | ||
101 | * different cpu's. | ||
102 | */ | ||
103 | struct sun4m_intreg_percpu { | ||
104 | unsigned int tbt; /* Interrupts still pending for this cpu. */ | ||
105 | |||
106 | /* These next two registers are WRITE-ONLY and are only | ||
107 | * "on bit" sensitive, "off bits" written have NO affect. | ||
108 | */ | ||
109 | unsigned int clear; /* Clear this cpus irqs here. */ | ||
110 | unsigned int set; /* Set this cpus irqs here. */ | ||
111 | unsigned char space[PAGE_SIZE - 12]; | ||
112 | }; | ||
113 | |||
114 | /* | ||
115 | * djhr | ||
116 | * Actually the clear and set fields in this struct are misleading.. | ||
117 | * according to the SLAVIO manual (and the same applies for the SEC) | ||
118 | * the clear field clears bits in the mask which will ENABLE that IRQ | ||
119 | * the set field sets bits in the mask to DISABLE the IRQ. | ||
120 | * | ||
121 | * Also the undirected_xx address in the SLAVIO is defined as | ||
122 | * RESERVED and write only.. | ||
123 | * | ||
124 | * DAVEM_NOTE: The SLAVIO only specifies behavior on uniprocessor | ||
125 | * sun4m machines, for MP the layout makes more sense. | ||
126 | */ | ||
127 | struct sun4m_intregs { | ||
128 | struct sun4m_intreg_percpu cpu_intregs[SUN4M_NCPUS]; | ||
129 | unsigned int tbt; /* IRQ's that are still pending. */ | ||
130 | unsigned int irqs; /* Master IRQ bits. */ | ||
131 | |||
132 | /* Again, like the above, two these registers are WRITE-ONLY. */ | ||
133 | unsigned int clear; /* Clear master IRQ's by setting bits here. */ | ||
134 | unsigned int set; /* Set master IRQ's by setting bits here. */ | ||
135 | |||
136 | /* This register is both READ and WRITE. */ | ||
137 | unsigned int undirected_target; /* Which cpu gets undirected irqs. */ | ||
138 | }; | ||
139 | |||
140 | extern struct sun4m_intregs *sun4m_interrupts; | ||
141 | |||
142 | /* | ||
143 | * Bit field defines for the interrupt registers on various | ||
144 | * Sparc machines. | ||
145 | */ | ||
146 | |||
147 | /* The sun4c interrupt register. */ | ||
148 | #define SUN4C_INT_ENABLE 0x01 /* Allow interrupts. */ | ||
149 | #define SUN4C_INT_E14 0x80 /* Enable level 14 IRQ. */ | ||
150 | #define SUN4C_INT_E10 0x20 /* Enable level 10 IRQ. */ | ||
151 | #define SUN4C_INT_E8 0x10 /* Enable level 8 IRQ. */ | ||
152 | #define SUN4C_INT_E6 0x08 /* Enable level 6 IRQ. */ | ||
153 | #define SUN4C_INT_E4 0x04 /* Enable level 4 IRQ. */ | ||
154 | #define SUN4C_INT_E1 0x02 /* Enable level 1 IRQ. */ | ||
155 | |||
156 | /* Dave Redman (djhr@tadpole.co.uk) | ||
157 | * The sun4m interrupt registers. | ||
158 | */ | ||
159 | #define SUN4M_INT_ENABLE 0x80000000 | ||
160 | #define SUN4M_INT_E14 0x00000080 | ||
161 | #define SUN4M_INT_E10 0x00080000 | ||
162 | |||
163 | #define SUN4M_HARD_INT(x) (0x000000001 << (x)) | ||
164 | #define SUN4M_SOFT_INT(x) (0x000010000 << (x)) | ||
165 | |||
166 | #define SUN4M_INT_MASKALL 0x80000000 /* mask all interrupts */ | ||
167 | #define SUN4M_INT_MODULE_ERR 0x40000000 /* module error */ | ||
168 | #define SUN4M_INT_M2S_WRITE 0x20000000 /* write buffer error */ | ||
169 | #define SUN4M_INT_ECC 0x10000000 /* ecc memory error */ | ||
170 | #define SUN4M_INT_FLOPPY 0x00400000 /* floppy disk */ | ||
171 | #define SUN4M_INT_MODULE 0x00200000 /* module interrupt */ | ||
172 | #define SUN4M_INT_VIDEO 0x00100000 /* onboard video */ | ||
173 | #define SUN4M_INT_REALTIME 0x00080000 /* system timer */ | ||
174 | #define SUN4M_INT_SCSI 0x00040000 /* onboard scsi */ | ||
175 | #define SUN4M_INT_AUDIO 0x00020000 /* audio/isdn */ | ||
176 | #define SUN4M_INT_ETHERNET 0x00010000 /* onboard ethernet */ | ||
177 | #define SUN4M_INT_SERIAL 0x00008000 /* serial ports */ | ||
178 | #define SUN4M_INT_KBDMS 0x00004000 /* keyboard/mouse */ | ||
179 | #define SUN4M_INT_SBUSBITS 0x00003F80 /* sbus int bits */ | ||
180 | |||
181 | #define SUN4M_INT_SBUS(x) (1 << (x+7)) | ||
182 | #define SUN4M_INT_VME(x) (1 << (x)) | ||
183 | |||
184 | #endif | 22 | #endif |
diff --git a/include/asm-sparc/pgtable.h b/include/asm-sparc/pgtable.h index a55f4c3488b0..2cc235b74d94 100644 --- a/include/asm-sparc/pgtable.h +++ b/include/asm-sparc/pgtable.h | |||
@@ -46,7 +46,6 @@ BTFIXUPDEF_SIMM13(user_ptrs_per_pgd) | |||
46 | #define pgd_ERROR(e) __builtin_trap() | 46 | #define pgd_ERROR(e) __builtin_trap() |
47 | 47 | ||
48 | BTFIXUPDEF_INT(page_none) | 48 | BTFIXUPDEF_INT(page_none) |
49 | BTFIXUPDEF_INT(page_shared) | ||
50 | BTFIXUPDEF_INT(page_copy) | 49 | BTFIXUPDEF_INT(page_copy) |
51 | BTFIXUPDEF_INT(page_readonly) | 50 | BTFIXUPDEF_INT(page_readonly) |
52 | BTFIXUPDEF_INT(page_kernel) | 51 | BTFIXUPDEF_INT(page_kernel) |
@@ -66,7 +65,7 @@ BTFIXUPDEF_INT(page_kernel) | |||
66 | #define PTE_SIZE (PTRS_PER_PTE*4) | 65 | #define PTE_SIZE (PTRS_PER_PTE*4) |
67 | 66 | ||
68 | #define PAGE_NONE __pgprot(BTFIXUP_INT(page_none)) | 67 | #define PAGE_NONE __pgprot(BTFIXUP_INT(page_none)) |
69 | #define PAGE_SHARED __pgprot(BTFIXUP_INT(page_shared)) | 68 | extern pgprot_t PAGE_SHARED; |
70 | #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy)) | 69 | #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy)) |
71 | #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly)) | 70 | #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly)) |
72 | 71 | ||
diff --git a/include/linux/irda.h b/include/linux/irda.h index 8e3735714c1c..28f88ecba344 100644 --- a/include/linux/irda.h +++ b/include/linux/irda.h | |||
@@ -77,6 +77,7 @@ typedef enum { | |||
77 | IRDA_ACT200L_DONGLE = 10, | 77 | IRDA_ACT200L_DONGLE = 10, |
78 | IRDA_MA600_DONGLE = 11, | 78 | IRDA_MA600_DONGLE = 11, |
79 | IRDA_TOIM3232_DONGLE = 12, | 79 | IRDA_TOIM3232_DONGLE = 12, |
80 | IRDA_EP7211_DONGLE = 13, | ||
80 | } IRDA_DONGLE; | 81 | } IRDA_DONGLE; |
81 | 82 | ||
82 | /* Protocol types to be used for SOCK_DGRAM */ | 83 | /* Protocol types to be used for SOCK_DGRAM */ |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 9820ca1e45e2..4a616d73cc25 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -575,7 +575,7 @@ struct net_device | |||
575 | 575 | ||
576 | /* The TX queue control structures */ | 576 | /* The TX queue control structures */ |
577 | unsigned int egress_subqueue_count; | 577 | unsigned int egress_subqueue_count; |
578 | struct net_device_subqueue egress_subqueue[0]; | 578 | struct net_device_subqueue egress_subqueue[1]; |
579 | }; | 579 | }; |
580 | #define to_net_dev(d) container_of(d, struct net_device, dev) | 580 | #define to_net_dev(d) container_of(d, struct net_device, dev) |
581 | 581 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index 38212c3f9971..ee4035571c21 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -3624,7 +3624,7 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, | |||
3624 | 3624 | ||
3625 | /* ensure 32-byte alignment of both the device and private area */ | 3625 | /* ensure 32-byte alignment of both the device and private area */ |
3626 | alloc_size = (sizeof(*dev) + NETDEV_ALIGN_CONST + | 3626 | alloc_size = (sizeof(*dev) + NETDEV_ALIGN_CONST + |
3627 | (sizeof(struct net_device_subqueue) * queue_count)) & | 3627 | (sizeof(struct net_device_subqueue) * (queue_count - 1))) & |
3628 | ~NETDEV_ALIGN_CONST; | 3628 | ~NETDEV_ALIGN_CONST; |
3629 | alloc_size += sizeof_priv + NETDEV_ALIGN_CONST; | 3629 | alloc_size += sizeof_priv + NETDEV_ALIGN_CONST; |
3630 | 3630 | ||
@@ -3642,7 +3642,7 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, | |||
3642 | dev->priv = ((char *)dev + | 3642 | dev->priv = ((char *)dev + |
3643 | ((sizeof(struct net_device) + | 3643 | ((sizeof(struct net_device) + |
3644 | (sizeof(struct net_device_subqueue) * | 3644 | (sizeof(struct net_device_subqueue) * |
3645 | queue_count) + NETDEV_ALIGN_CONST) | 3645 | (queue_count - 1)) + NETDEV_ALIGN_CONST) |
3646 | & ~NETDEV_ALIGN_CONST)); | 3646 | & ~NETDEV_ALIGN_CONST)); |
3647 | } | 3647 | } |
3648 | 3648 | ||
diff --git a/net/core/sock.c b/net/core/sock.c index bd209c4477a9..cfed7d42c485 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -182,7 +182,8 @@ static const char *af_family_clock_key_strings[AF_MAX+1] = { | |||
182 | "clock-21" , "clock-AF_SNA" , "clock-AF_IRDA" , | 182 | "clock-21" , "clock-AF_SNA" , "clock-AF_IRDA" , |
183 | "clock-AF_PPPOX" , "clock-AF_WANPIPE" , "clock-AF_LLC" , | 183 | "clock-AF_PPPOX" , "clock-AF_WANPIPE" , "clock-AF_LLC" , |
184 | "clock-27" , "clock-28" , "clock-29" , | 184 | "clock-27" , "clock-28" , "clock-29" , |
185 | "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_MAX" | 185 | "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , |
186 | "clock-AF_RXRPC" , "clock-AF_MAX" | ||
186 | }; | 187 | }; |
187 | #endif | 188 | #endif |
188 | 189 | ||
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index 6cbce96a54ce..771031dfbd0f 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c | |||
@@ -158,7 +158,7 @@ static void unlink_from_unused(struct inet_peer *p) | |||
158 | #define lookup(_daddr,_stack) \ | 158 | #define lookup(_daddr,_stack) \ |
159 | ({ \ | 159 | ({ \ |
160 | struct inet_peer *u, **v; \ | 160 | struct inet_peer *u, **v; \ |
161 | if (_stack) { \ | 161 | if (_stack != NULL) { \ |
162 | stackptr = _stack; \ | 162 | stackptr = _stack; \ |
163 | *stackptr++ = &peer_root; \ | 163 | *stackptr++ = &peer_root; \ |
164 | } \ | 164 | } \ |
@@ -169,7 +169,7 @@ static void unlink_from_unused(struct inet_peer *p) | |||
169 | v = &u->avl_left; \ | 169 | v = &u->avl_left; \ |
170 | else \ | 170 | else \ |
171 | v = &u->avl_right; \ | 171 | v = &u->avl_right; \ |
172 | if (_stack) \ | 172 | if (_stack != NULL) \ |
173 | *stackptr++ = v; \ | 173 | *stackptr++ = v; \ |
174 | u = *v; \ | 174 | u = *v; \ |
175 | } \ | 175 | } \ |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 281aee42d3f0..df30976f6dfd 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -962,8 +962,8 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) | |||
962 | dsfield = ipv4_get_dsfield(iph); | 962 | dsfield = ipv4_get_dsfield(iph); |
963 | 963 | ||
964 | if ((t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)) | 964 | if ((t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)) |
965 | fl.fl6_flowlabel |= ntohl(((__u32)iph->tos << IPV6_TCLASS_SHIFT) | 965 | fl.fl6_flowlabel |= htonl((__u32)iph->tos << IPV6_TCLASS_SHIFT) |
966 | & IPV6_TCLASS_MASK); | 966 | & IPV6_TCLASS_MASK; |
967 | 967 | ||
968 | err = ip6_tnl_xmit2(skb, dev, dsfield, &fl, encap_limit, &mtu); | 968 | err = ip6_tnl_xmit2(skb, dev, dsfield, &fl, encap_limit, &mtu); |
969 | if (err != 0) { | 969 | if (err != 0) { |
diff --git a/net/irda/irnetlink.c b/net/irda/irnetlink.c index db716580e1ae..694ea4d92fa8 100644 --- a/net/irda/irnetlink.c +++ b/net/irda/irnetlink.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * IrDA netlink layer, for stack configuration. | 2 | * IrDA netlink layer, for stack configuration. |
3 | * | 3 | * |
4 | * Copyright (c) 2007 Samuel Ortiz <samuel@sortiz> | 4 | * Copyright (c) 2007 Samuel Ortiz <samuel@sortiz.org> |
5 | * | 5 | * |
6 | * Partly based on the 802.11 nelink implementation | 6 | * Partly based on the 802.11 nelink implementation |
7 | * (see net/wireless/nl80211.c) which is: | 7 | * (see net/wireless/nl80211.c) which is: |