提交 4314652b 编写于 作者: L Linus Torvalds

Merge branch 'release-2.6.27' of...

Merge branch 'release-2.6.27' of git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-acpi-merge-2.6

* 'release-2.6.27' of git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-acpi-merge-2.6: (87 commits)
  Fix FADT parsing
  Add the ability to reset the machine using the RESET_REG in ACPI's FADT table.
  ACPI: use dev_printk when possible
  PNPACPI: add support for HP vendor-specific CCSR descriptors
  PNP: avoid legacy IDE IRQs
  PNP: convert resource options to single linked list
  ISAPNP: handle independent options following dependent ones
  PNP: remove extra 0x100 bit from option priority
  PNP: support optional IRQ resources
  PNP: rename pnp_register_*_resource() local variables
  PNPACPI: ignore _PRS interrupt numbers larger than PNP_IRQ_NR
  PNP: centralize resource option allocations
  PNP: remove redundant pnp_can_configure() check
  PNP: make resource assignment functions return 0 (success) or -EBUSY (failure)
  PNP: in debug resource dump, make empty list obvious
  PNP: improve resource assignment debug
  PNP: increase I/O port & memory option address sizes
  PNP: introduce pnp_irq_mask_t typedef
  PNP: make resource option structures private to PNP subsystem
  PNP: define PNP-specific IORESOURCE_IO_* flags alongside IRQ, DMA, MEM
  ...
...@@ -29,46 +29,46 @@ Description: ...@@ -29,46 +29,46 @@ Description:
$ cd /sys/firmware/acpi/interrupts $ cd /sys/firmware/acpi/interrupts
$ grep . * $ grep . *
error:0 error: 0
ff_gbl_lock:0 ff_gbl_lock: 0 enable
ff_pmtimer:0 ff_pmtimer: 0 invalid
ff_pwr_btn:0 ff_pwr_btn: 0 enable
ff_rt_clk:0 ff_rt_clk: 2 disable
ff_slp_btn:0 ff_slp_btn: 0 invalid
gpe00:0 gpe00: 0 invalid
gpe01:0 gpe01: 0 enable
gpe02:0 gpe02: 108 enable
gpe03:0 gpe03: 0 invalid
gpe04:0 gpe04: 0 invalid
gpe05:0 gpe05: 0 invalid
gpe06:0 gpe06: 0 enable
gpe07:0 gpe07: 0 enable
gpe08:0 gpe08: 0 invalid
gpe09:174 gpe09: 0 invalid
gpe0A:0 gpe0A: 0 invalid
gpe0B:0 gpe0B: 0 invalid
gpe0C:0 gpe0C: 0 invalid
gpe0D:0 gpe0D: 0 invalid
gpe0E:0 gpe0E: 0 invalid
gpe0F:0 gpe0F: 0 invalid
gpe10:0 gpe10: 0 invalid
gpe11:60 gpe11: 0 invalid
gpe12:0 gpe12: 0 invalid
gpe13:0 gpe13: 0 invalid
gpe14:0 gpe14: 0 invalid
gpe15:0 gpe15: 0 invalid
gpe16:0 gpe16: 0 invalid
gpe17:0 gpe17: 1084 enable
gpe18:0 gpe18: 0 enable
gpe19:7 gpe19: 0 invalid
gpe1A:0 gpe1A: 0 invalid
gpe1B:0 gpe1B: 0 invalid
gpe1C:0 gpe1C: 0 invalid
gpe1D:0 gpe1D: 0 invalid
gpe1E:0 gpe1E: 0 invalid
gpe1F:0 gpe1F: 0 invalid
gpe_all:241 gpe_all: 1192
sci:241 sci: 1194
sci - The total number of times the ACPI SCI sci - The total number of times the ACPI SCI
has claimed an interrupt. has claimed an interrupt.
...@@ -89,6 +89,13 @@ Description: ...@@ -89,6 +89,13 @@ Description:
error - an interrupt that can't be accounted for above. error - an interrupt that can't be accounted for above.
invalid: it's either a wakeup GPE or a GPE/Fixed Event that
doesn't have an event handler.
disable: the GPE/Fixed Event is valid but disabled.
enable: the GPE/Fixed Event is valid and enabled.
Root has permission to clear any of these counters. Eg. Root has permission to clear any of these counters. Eg.
# echo 0 > gpe11 # echo 0 > gpe11
...@@ -97,3 +104,43 @@ Description: ...@@ -97,3 +104,43 @@ Description:
None of these counters has an effect on the function None of these counters has an effect on the function
of the system, they are simply statistics. of the system, they are simply statistics.
Besides this, user can also write specific strings to these files
to enable/disable/clear ACPI interrupts in user space, which can be
used to debug some ACPI interrupt storm issues.
Note that only writting to VALID GPE/Fixed Event is allowed,
i.e. user can only change the status of runtime GPE and
Fixed Event with event handler installed.
Let's take power button fixed event for example, please kill acpid
and other user space applications so that the machine won't shutdown
when pressing the power button.
# cat ff_pwr_btn
0
# press the power button for 3 times;
# cat ff_pwr_btn
3
# echo disable > ff_pwr_btn
# cat ff_pwr_btn
disable
# press the power button for 3 times;
# cat ff_pwr_btn
disable
# echo enable > ff_pwr_btn
# cat ff_pwr_btn
4
/*
* this is because the status bit is set even if the enable bit is cleared,
* and it triggers an ACPI fixed event when the enable bit is set again
*/
# press the power button for 3 times;
# cat ff_pwr_btn
7
# echo disable > ff_pwr_btn
# press the power button for 3 times;
# echo clear > ff_pwr_btn /* clear the status bit */
# echo disable > ff_pwr_btn
# cat ff_pwr_btn
7
...@@ -818,7 +818,7 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -818,7 +818,7 @@ and is between 256 and 4096 characters. It is defined in the file
See Documentation/ide/ide.txt. See Documentation/ide/ide.txt.
idle= [X86] idle= [X86]
Format: idle=poll or idle=mwait Format: idle=poll or idle=mwait, idle=halt, idle=nomwait
Poll forces a polling idle loop that can slightly improves the performance Poll forces a polling idle loop that can slightly improves the performance
of waking up a idle CPU, but will use a lot of power and make the system of waking up a idle CPU, but will use a lot of power and make the system
run hot. Not recommended. run hot. Not recommended.
...@@ -826,6 +826,9 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -826,6 +826,9 @@ and is between 256 and 4096 characters. It is defined in the file
to not use it because it doesn't save as much power as a normal idle to not use it because it doesn't save as much power as a normal idle
loop use the MONITOR/MWAIT idle loop anyways. Performance should be the same loop use the MONITOR/MWAIT idle loop anyways. Performance should be the same
as idle=poll. as idle=poll.
idle=halt. Halt is forced to be used for CPU idle.
In such case C2/C3 won't be used again.
idle=nomwait. Disable mwait for CPU C-states
ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem
Claim all unknown PCI IDE storage controllers. Claim all unknown PCI IDE storage controllers.
......
...@@ -174,8 +174,6 @@ The LED is exposed through the LED subsystem, and can be found in: ...@@ -174,8 +174,6 @@ The LED is exposed through the LED subsystem, and can be found in:
The mail LED is autodetected, so if you don't have one, the LED device won't The mail LED is autodetected, so if you don't have one, the LED device won't
be registered. be registered.
If you have a mail LED that is not green, please report this to me.
Backlight Backlight
********* *********
......
...@@ -216,8 +216,8 @@ W: http://code.google.com/p/aceracpi ...@@ -216,8 +216,8 @@ W: http://code.google.com/p/aceracpi
S: Maintained S: Maintained
ACPI ACPI
P: Len Brown P: Andi Kleen
M: len.brown@intel.com M: ak@linux.intel.com
M: lenb@kernel.org M: lenb@kernel.org
L: linux-acpi@vger.kernel.org L: linux-acpi@vger.kernel.org
W: http://www.lesswatts.org/projects/acpi/ W: http://www.lesswatts.org/projects/acpi/
...@@ -239,8 +239,8 @@ W: http://www.lesswatts.org/projects/acpi/ ...@@ -239,8 +239,8 @@ W: http://www.lesswatts.org/projects/acpi/
S: Supported S: Supported
ACPI FAN DRIVER ACPI FAN DRIVER
P: Len Brown P: Zhang Rui
M: len.brown@intel.com M: rui.zhang@intel.com
L: linux-acpi@vger.kernel.org L: linux-acpi@vger.kernel.org
W: http://www.lesswatts.org/projects/acpi/ W: http://www.lesswatts.org/projects/acpi/
S: Supported S: Supported
...@@ -252,14 +252,14 @@ L: pcihpd-discuss@lists.sourceforge.net ...@@ -252,14 +252,14 @@ L: pcihpd-discuss@lists.sourceforge.net
S: Supported S: Supported
ACPI THERMAL DRIVER ACPI THERMAL DRIVER
P: Len Brown P: Zhang Rui
M: len.brown@intel.com M: rui.zhang@intel.com
L: linux-acpi@vger.kernel.org L: linux-acpi@vger.kernel.org
W: http://www.lesswatts.org/projects/acpi/ W: http://www.lesswatts.org/projects/acpi/
S: Supported S: Supported
ACPI VIDEO DRIVER ACPI VIDEO DRIVER
P: Rui Zhang P: Zhang Rui
M: rui.zhang@intel.com M: rui.zhang@intel.com
L: linux-acpi@vger.kernel.org L: linux-acpi@vger.kernel.org
W: http://www.lesswatts.org/projects/acpi/ W: http://www.lesswatts.org/projects/acpi/
...@@ -1160,6 +1160,11 @@ M: scott@spiteful.org ...@@ -1160,6 +1160,11 @@ M: scott@spiteful.org
L: pcihpd-discuss@lists.sourceforge.net L: pcihpd-discuss@lists.sourceforge.net
S: Supported S: Supported
COMPAL LAPTOP SUPPORT
P: Cezary Jackiewicz
M: cezary.jackiewicz@gmail.com
S: Maintained
COMPUTONE INTELLIPORT MULTIPORT CARD COMPUTONE INTELLIPORT MULTIPORT CARD
P: Michael H. Warfield P: Michael H. Warfield
M: mhw@wittsend.com M: mhw@wittsend.com
...@@ -1787,6 +1792,12 @@ P: David Howells ...@@ -1787,6 +1792,12 @@ P: David Howells
M: dhowells@redhat.com M: dhowells@redhat.com
S: Maintained S: Maintained
FUJITSU LAPTOP EXTRAS
P: Jonathan Woithe
M: jwoithe@physics.adelaide.edu.au
L: linux-acpi@vger.kernel.org
S: Maintained
FUSE: FILESYSTEM IN USERSPACE FUSE: FILESYSTEM IN USERSPACE
P: Miklos Szeredi P: Miklos Szeredi
M: miklos@szeredi.hu M: miklos@szeredi.hu
......
...@@ -55,6 +55,10 @@ void (*ia64_mark_idle)(int); ...@@ -55,6 +55,10 @@ void (*ia64_mark_idle)(int);
unsigned long boot_option_idle_override = 0; unsigned long boot_option_idle_override = 0;
EXPORT_SYMBOL(boot_option_idle_override); EXPORT_SYMBOL(boot_option_idle_override);
unsigned long idle_halt;
EXPORT_SYMBOL(idle_halt);
unsigned long idle_nomwait;
EXPORT_SYMBOL(idle_nomwait);
void void
ia64_do_show_stack (struct unw_frame_info *info, void *arg) ia64_do_show_stack (struct unw_frame_info *info, void *arg)
......
...@@ -56,6 +56,12 @@ static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c) ...@@ -56,6 +56,12 @@ static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c)
if (cpu_has(c, X86_FEATURE_ACPI)) if (cpu_has(c, X86_FEATURE_ACPI))
buf[2] |= ACPI_PDC_T_FFH; buf[2] |= ACPI_PDC_T_FFH;
/*
* If mwait/monitor is unsupported, C2/C3_FFH will be disabled
*/
if (!cpu_has(c, X86_FEATURE_MWAIT))
buf[2] &= ~(ACPI_PDC_C_C2C3_FFH);
obj->type = ACPI_TYPE_BUFFER; obj->type = ACPI_TYPE_BUFFER;
obj->buffer.length = 12; obj->buffer.length = 12;
obj->buffer.pointer = (u8 *) buf; obj->buffer.pointer = (u8 *) buf;
......
...@@ -7,6 +7,12 @@ ...@@ -7,6 +7,12 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/clockchips.h> #include <linux/clockchips.h>
#include <asm/system.h>
unsigned long idle_halt;
EXPORT_SYMBOL(idle_halt);
unsigned long idle_nomwait;
EXPORT_SYMBOL(idle_nomwait);
struct kmem_cache *task_xstate_cachep; struct kmem_cache *task_xstate_cachep;
...@@ -325,7 +331,27 @@ static int __init idle_setup(char *str) ...@@ -325,7 +331,27 @@ static int __init idle_setup(char *str)
pm_idle = poll_idle; pm_idle = poll_idle;
} else if (!strcmp(str, "mwait")) } else if (!strcmp(str, "mwait"))
force_mwait = 1; force_mwait = 1;
else else if (!strcmp(str, "halt")) {
/*
* When the boot option of idle=halt is added, halt is
* forced to be used for CPU idle. In such case CPU C2/C3
* won't be used again.
* To continue to load the CPU idle driver, don't touch
* the boot_option_idle_override.
*/
pm_idle = default_idle;
idle_halt = 1;
return 0;
} else if (!strcmp(str, "nomwait")) {
/*
* If the boot option of "idle=nomwait" is added,
* it means that mwait will be disabled for CPU C2/C3
* states. In such case it won't touch the variable
* of boot_option_idle_override.
*/
idle_nomwait = 1;
return 0;
} else
return -1; return -1;
boot_option_idle_override = 1; boot_option_idle_override = 1;
......
...@@ -156,10 +156,9 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *memory_affinity) ...@@ -156,10 +156,9 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *memory_affinity)
num_memory_chunks++; num_memory_chunks++;
printk(KERN_DEBUG "Memory range %08lx to %08lx (type %x)" printk(KERN_DEBUG "Memory range %08lx to %08lx"
" in proximity domain %02x %s\n", " in proximity domain %02x %s\n",
start_pfn, end_pfn, start_pfn, end_pfn,
memory_affinity->memory_type,
pxm, pxm,
((memory_affinity->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) ? ((memory_affinity->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) ?
"enabled and removable" : "enabled" ) ); "enabled and removable" : "enabled" ) );
......
...@@ -21,7 +21,7 @@ obj-$(CONFIG_X86) += blacklist.o ...@@ -21,7 +21,7 @@ obj-$(CONFIG_X86) += blacklist.o
# #
# ACPI Core Subsystem (Interpreter) # ACPI Core Subsystem (Interpreter)
# #
obj-y += osl.o utils.o \ obj-y += osl.o utils.o reboot.o\
dispatcher/ events/ executer/ hardware/ \ dispatcher/ events/ executer/ hardware/ \
namespace/ parser/ resources/ tables/ \ namespace/ parser/ resources/ tables/ \
utilities/ utilities/
......
...@@ -377,6 +377,9 @@ static int __init bay_init(void) ...@@ -377,6 +377,9 @@ static int __init bay_init(void)
INIT_LIST_HEAD(&drive_bays); INIT_LIST_HEAD(&drive_bays);
if (acpi_disabled)
return -ENODEV;
if (acpi_disabled) if (acpi_disabled)
return -ENODEV; return -ENODEV;
......
...@@ -612,7 +612,7 @@ static int __init acpi_bus_init_irq(void) ...@@ -612,7 +612,7 @@ static int __init acpi_bus_init_irq(void)
return 0; return 0;
} }
acpi_native_uint acpi_gbl_permanent_mmap; u8 acpi_gbl_permanent_mmap;
void __init acpi_early_init(void) void __init acpi_early_init(void)
......
...@@ -151,7 +151,7 @@ acpi_ds_init_one_object(acpi_handle obj_handle, ...@@ -151,7 +151,7 @@ acpi_ds_init_one_object(acpi_handle obj_handle,
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status
acpi_ds_initialize_objects(acpi_native_uint table_index, acpi_ds_initialize_objects(u32 table_index,
struct acpi_namespace_node * start_node) struct acpi_namespace_node * start_node)
{ {
acpi_status status; acpi_status status;
......
...@@ -377,7 +377,6 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, ...@@ -377,7 +377,6 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
} }
info->parameters = &this_walk_state->operands[0]; info->parameters = &this_walk_state->operands[0];
info->parameter_type = ACPI_PARAM_ARGS;
status = acpi_ds_init_aml_walk(next_walk_state, NULL, method_node, status = acpi_ds_init_aml_walk(next_walk_state, NULL, method_node,
obj_desc->method.aml_start, obj_desc->method.aml_start,
......
...@@ -691,12 +691,6 @@ acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state, ...@@ -691,12 +691,6 @@ acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state,
status = acpi_ex_resolve_operands(op->common.aml_opcode, status = acpi_ex_resolve_operands(op->common.aml_opcode,
ACPI_WALK_OPERANDS, walk_state); ACPI_WALK_OPERANDS, walk_state);
ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
acpi_ps_get_opcode_name(op->common.aml_opcode),
walk_state->num_operands,
"after AcpiExResolveOperands");
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
ACPI_ERROR((AE_INFO, "(%s) bad operand(s) (%X)", ACPI_ERROR((AE_INFO, "(%s) bad operand(s) (%X)",
acpi_ps_get_opcode_name(op->common.aml_opcode), acpi_ps_get_opcode_name(op->common.aml_opcode),
...@@ -785,10 +779,6 @@ acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state, ...@@ -785,10 +779,6 @@ acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state,
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
acpi_ps_get_opcode_name(op->common.aml_opcode),
1, "after AcpiExResolveOperands");
obj_desc = acpi_ns_get_attached_object(node); obj_desc = acpi_ns_get_attached_object(node);
if (!obj_desc) { if (!obj_desc) {
return_ACPI_STATUS(AE_NOT_EXIST); return_ACPI_STATUS(AE_NOT_EXIST);
...@@ -848,7 +838,7 @@ acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state, ...@@ -848,7 +838,7 @@ acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state,
union acpi_operand_object **operand; union acpi_operand_object **operand;
struct acpi_namespace_node *node; struct acpi_namespace_node *node;
union acpi_parse_object *next_op; union acpi_parse_object *next_op;
acpi_native_uint table_index; u32 table_index;
struct acpi_table_header *table; struct acpi_table_header *table;
ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op); ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op);
...@@ -882,10 +872,6 @@ acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state, ...@@ -882,10 +872,6 @@ acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state,
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
acpi_ps_get_opcode_name(op->common.aml_opcode),
1, "after AcpiExResolveOperands");
operand = &walk_state->operands[0]; operand = &walk_state->operands[0];
/* Find the ACPI table */ /* Find the ACPI table */
...@@ -1091,10 +1077,8 @@ acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state, ...@@ -1091,10 +1077,8 @@ acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state,
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE, ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS,
acpi_ps_get_opcode_name(op->common.aml_opcode), acpi_ps_get_opcode_name(op->common.aml_opcode), 1);
1, "after AcpiExResolveOperands");
/* /*
* Get the bank_value operand and save it * Get the bank_value operand and save it
* (at Top of stack) * (at Top of stack)
......
...@@ -408,14 +408,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) ...@@ -408,14 +408,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
[walk_state-> [walk_state->
num_operands - 1]), num_operands - 1]),
walk_state); walk_state);
if (ACPI_SUCCESS(status)) {
ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS,
ACPI_IMODE_EXECUTE,
acpi_ps_get_opcode_name
(walk_state->opcode),
walk_state->num_operands,
"after ExResolveOperands");
}
} }
if (ACPI_SUCCESS(status)) { if (ACPI_SUCCESS(status)) {
......
...@@ -70,7 +70,7 @@ acpi_status ...@@ -70,7 +70,7 @@ acpi_status
acpi_ds_result_pop(union acpi_operand_object **object, acpi_ds_result_pop(union acpi_operand_object **object,
struct acpi_walk_state *walk_state) struct acpi_walk_state *walk_state)
{ {
acpi_native_uint index; u32 index;
union acpi_generic_state *state; union acpi_generic_state *state;
acpi_status status; acpi_status status;
...@@ -122,7 +122,7 @@ acpi_ds_result_pop(union acpi_operand_object **object, ...@@ -122,7 +122,7 @@ acpi_ds_result_pop(union acpi_operand_object **object,
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"Obj=%p [%s] Index=%X State=%p Num=%X\n", *object, "Obj=%p [%s] Index=%X State=%p Num=%X\n", *object,
acpi_ut_get_object_type_name(*object), acpi_ut_get_object_type_name(*object),
(u32) index, walk_state, walk_state->result_count)); index, walk_state, walk_state->result_count));
return (AE_OK); return (AE_OK);
} }
...@@ -146,7 +146,7 @@ acpi_ds_result_push(union acpi_operand_object * object, ...@@ -146,7 +146,7 @@ acpi_ds_result_push(union acpi_operand_object * object,
{ {
union acpi_generic_state *state; union acpi_generic_state *state;
acpi_status status; acpi_status status;
acpi_native_uint index; u32 index;
ACPI_FUNCTION_NAME(ds_result_push); ACPI_FUNCTION_NAME(ds_result_push);
...@@ -400,7 +400,7 @@ void ...@@ -400,7 +400,7 @@ void
acpi_ds_obj_stack_pop_and_delete(u32 pop_count, acpi_ds_obj_stack_pop_and_delete(u32 pop_count,
struct acpi_walk_state *walk_state) struct acpi_walk_state *walk_state)
{ {
acpi_native_int i; s32 i;
union acpi_operand_object *obj_desc; union acpi_operand_object *obj_desc;
ACPI_FUNCTION_NAME(ds_obj_stack_pop_and_delete); ACPI_FUNCTION_NAME(ds_obj_stack_pop_and_delete);
...@@ -409,7 +409,7 @@ acpi_ds_obj_stack_pop_and_delete(u32 pop_count, ...@@ -409,7 +409,7 @@ acpi_ds_obj_stack_pop_and_delete(u32 pop_count,
return; return;
} }
for (i = (acpi_native_int) (pop_count - 1); i >= 0; i--) { for (i = (s32) pop_count - 1; i >= 0; i--) {
if (walk_state->num_operands == 0) { if (walk_state->num_operands == 0) {
return; return;
} }
...@@ -615,14 +615,8 @@ acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state, ...@@ -615,14 +615,8 @@ acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state,
walk_state->pass_number = pass_number; walk_state->pass_number = pass_number;
if (info) { if (info) {
if (info->parameter_type == ACPI_PARAM_GPE) { walk_state->params = info->parameters;
walk_state->gpe_event_info = walk_state->caller_return_desc = &info->return_object;
ACPI_CAST_PTR(struct acpi_gpe_event_info,
info->parameters);
} else {
walk_state->params = info->parameters;
walk_state->caller_return_desc = &info->return_object;
}
} }
status = acpi_ps_init_scope(&walk_state->parser_state, op); status = acpi_ps_init_scope(&walk_state->parser_state, op);
......
...@@ -917,6 +917,9 @@ static int __init dock_init(void) ...@@ -917,6 +917,9 @@ static int __init dock_init(void)
dock_station = NULL; dock_station = NULL;
if (acpi_disabled)
return 0;
if (acpi_disabled) if (acpi_disabled)
return 0; return 0;
......
...@@ -188,7 +188,7 @@ acpi_status acpi_ev_install_xrupt_handlers(void) ...@@ -188,7 +188,7 @@ acpi_status acpi_ev_install_xrupt_handlers(void)
static acpi_status acpi_ev_fixed_event_initialize(void) static acpi_status acpi_ev_fixed_event_initialize(void)
{ {
acpi_native_uint i; u32 i;
acpi_status status; acpi_status status;
/* /*
...@@ -231,7 +231,7 @@ u32 acpi_ev_fixed_event_detect(void) ...@@ -231,7 +231,7 @@ u32 acpi_ev_fixed_event_detect(void)
u32 int_status = ACPI_INTERRUPT_NOT_HANDLED; u32 int_status = ACPI_INTERRUPT_NOT_HANDLED;
u32 fixed_status; u32 fixed_status;
u32 fixed_enable; u32 fixed_enable;
acpi_native_uint i; u32 i;
ACPI_FUNCTION_NAME(ev_fixed_event_detect); ACPI_FUNCTION_NAME(ev_fixed_event_detect);
...@@ -260,7 +260,7 @@ u32 acpi_ev_fixed_event_detect(void) ...@@ -260,7 +260,7 @@ u32 acpi_ev_fixed_event_detect(void)
/* Found an active (signalled) event */ /* Found an active (signalled) event */
acpi_os_fixed_event_count(i); acpi_os_fixed_event_count(i);
int_status |= acpi_ev_fixed_event_dispatch((u32) i); int_status |= acpi_ev_fixed_event_dispatch(i);
} }
} }
......
...@@ -256,7 +256,7 @@ acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) ...@@ -256,7 +256,7 @@ acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
/* Mark wake-disabled or HW disable, or both */ /* Clear the appropriate enabled flags for this GPE */
switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) { switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) {
case ACPI_GPE_TYPE_WAKE: case ACPI_GPE_TYPE_WAKE:
...@@ -273,13 +273,23 @@ acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) ...@@ -273,13 +273,23 @@ acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
/* Disable the requested runtime GPE */ /* Disable the requested runtime GPE */
ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_RUN_ENABLED); ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_RUN_ENABLED);
break;
/* fallthrough */
default: default:
acpi_hw_write_gpe_enable_reg(gpe_event_info); break;
} }
/*
* Even if we don't know the GPE type, make sure that we always
* disable it. low_disable_gpe will just clear the enable bit for this
* GPE and write it. It will not write out the current GPE enable mask,
* since this may inadvertently enable GPEs too early, if a rogue GPE has
* come in during ACPICA initialization - possibly as a result of AML or
* other code that has enabled the GPE.
*/
status = acpi_hw_low_disable_gpe(gpe_event_info);
return_ACPI_STATUS(status);
return_ACPI_STATUS(AE_OK); return_ACPI_STATUS(AE_OK);
} }
...@@ -305,7 +315,7 @@ struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, ...@@ -305,7 +315,7 @@ struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device,
{ {
union acpi_operand_object *obj_desc; union acpi_operand_object *obj_desc;
struct acpi_gpe_block_info *gpe_block; struct acpi_gpe_block_info *gpe_block;
acpi_native_uint i; u32 i;
ACPI_FUNCTION_ENTRY(); ACPI_FUNCTION_ENTRY();
...@@ -379,8 +389,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) ...@@ -379,8 +389,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
u32 status_reg; u32 status_reg;
u32 enable_reg; u32 enable_reg;
acpi_cpu_flags flags; acpi_cpu_flags flags;
acpi_native_uint i; u32 i;
acpi_native_uint j; u32 j;
ACPI_FUNCTION_NAME(ev_gpe_detect); ACPI_FUNCTION_NAME(ev_gpe_detect);
...@@ -462,13 +472,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) ...@@ -462,13 +472,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
*/ */
int_status |= int_status |=
acpi_ev_gpe_dispatch(&gpe_block-> acpi_ev_gpe_dispatch(&gpe_block->
event_info[(i * event_info[((acpi_size) i * ACPI_GPE_REGISTER_WIDTH) + j], j + gpe_register_info->base_gpe_number);
ACPI_GPE_REGISTER_WIDTH)
+
j],
(u32) j +
gpe_register_info->
base_gpe_number);
} }
} }
} }
...@@ -555,10 +559,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) ...@@ -555,10 +559,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
*/ */
info->prefix_node = info->prefix_node =
local_gpe_event_info.dispatch.method_node; local_gpe_event_info.dispatch.method_node;
info->parameters =
ACPI_CAST_PTR(union acpi_operand_object *,
gpe_event_info);
info->parameter_type = ACPI_PARAM_GPE;
info->flags = ACPI_IGNORE_RETURN_VALUE; info->flags = ACPI_IGNORE_RETURN_VALUE;
status = acpi_ns_evaluate(info); status = acpi_ns_evaluate(info);
......
...@@ -189,8 +189,8 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info, ...@@ -189,8 +189,8 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
struct acpi_gpe_block_info *gpe_block) struct acpi_gpe_block_info *gpe_block)
{ {
struct acpi_gpe_event_info *gpe_event_info; struct acpi_gpe_event_info *gpe_event_info;
acpi_native_uint i; u32 i;
acpi_native_uint j; u32 j;
ACPI_FUNCTION_TRACE(ev_delete_gpe_handlers); ACPI_FUNCTION_TRACE(ev_delete_gpe_handlers);
...@@ -203,7 +203,8 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info, ...@@ -203,7 +203,8 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
gpe_event_info = gpe_event_info =
&gpe_block-> &gpe_block->
event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j]; event_info[((acpi_size) i *
ACPI_GPE_REGISTER_WIDTH) + j];
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_HANDLER) { ACPI_GPE_DISPATCH_HANDLER) {
...@@ -744,8 +745,8 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) ...@@ -744,8 +745,8 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block)
struct acpi_gpe_event_info *gpe_event_info = NULL; struct acpi_gpe_event_info *gpe_event_info = NULL;
struct acpi_gpe_event_info *this_event; struct acpi_gpe_event_info *this_event;
struct acpi_gpe_register_info *this_register; struct acpi_gpe_register_info *this_register;
acpi_native_uint i; u32 i;
acpi_native_uint j; u32 j;
acpi_status status; acpi_status status;
ACPI_FUNCTION_TRACE(ev_create_gpe_info_blocks); ACPI_FUNCTION_TRACE(ev_create_gpe_info_blocks);
...@@ -983,8 +984,8 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, ...@@ -983,8 +984,8 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
struct acpi_gpe_walk_info gpe_info; struct acpi_gpe_walk_info gpe_info;
u32 wake_gpe_count; u32 wake_gpe_count;
u32 gpe_enabled_count; u32 gpe_enabled_count;
acpi_native_uint i; u32 i;
acpi_native_uint j; u32 j;
ACPI_FUNCTION_TRACE(ev_initialize_gpe_block); ACPI_FUNCTION_TRACE(ev_initialize_gpe_block);
...@@ -1033,7 +1034,8 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, ...@@ -1033,7 +1034,8 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
gpe_event_info = gpe_event_info =
&gpe_block-> &gpe_block->
event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j]; event_info[((acpi_size) i *
ACPI_GPE_REGISTER_WIDTH) + j];
if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_METHOD) ACPI_GPE_DISPATCH_METHOD)
......
...@@ -575,7 +575,7 @@ acpi_status acpi_ev_release_global_lock(void) ...@@ -575,7 +575,7 @@ acpi_status acpi_ev_release_global_lock(void)
void acpi_ev_terminate(void) void acpi_ev_terminate(void)
{ {
acpi_native_uint i; u32 i;
acpi_status status; acpi_status status;
ACPI_FUNCTION_TRACE(ev_terminate); ACPI_FUNCTION_TRACE(ev_terminate);
...@@ -589,7 +589,7 @@ void acpi_ev_terminate(void) ...@@ -589,7 +589,7 @@ void acpi_ev_terminate(void)
/* Disable all fixed events */ /* Disable all fixed events */
for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
status = acpi_disable_event((u32) i, 0); status = acpi_disable_event(i, 0);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
ACPI_ERROR((AE_INFO, ACPI_ERROR((AE_INFO,
"Could not disable fixed event %d", "Could not disable fixed event %d",
......
...@@ -81,7 +81,7 @@ acpi_ev_install_handler(acpi_handle obj_handle, ...@@ -81,7 +81,7 @@ acpi_ev_install_handler(acpi_handle obj_handle,
acpi_status acpi_ev_install_region_handlers(void) acpi_status acpi_ev_install_region_handlers(void)
{ {
acpi_status status; acpi_status status;
acpi_native_uint i; u32 i;
ACPI_FUNCTION_TRACE(ev_install_region_handlers); ACPI_FUNCTION_TRACE(ev_install_region_handlers);
...@@ -151,7 +151,7 @@ acpi_status acpi_ev_install_region_handlers(void) ...@@ -151,7 +151,7 @@ acpi_status acpi_ev_install_region_handlers(void)
acpi_status acpi_ev_initialize_op_regions(void) acpi_status acpi_ev_initialize_op_regions(void)
{ {
acpi_status status; acpi_status status;
acpi_native_uint i; u32 i;
ACPI_FUNCTION_TRACE(ev_initialize_op_regions); ACPI_FUNCTION_TRACE(ev_initialize_op_regions);
...@@ -219,7 +219,6 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) ...@@ -219,7 +219,6 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
info->prefix_node = region_obj2->extra.method_REG; info->prefix_node = region_obj2->extra.method_REG;
info->pathname = NULL; info->pathname = NULL;
info->parameters = args; info->parameters = args;
info->parameter_type = ACPI_PARAM_ARGS;
info->flags = ACPI_IGNORE_RETURN_VALUE; info->flags = ACPI_IGNORE_RETURN_VALUE;
/* /*
......
...@@ -380,7 +380,7 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) ...@@ -380,7 +380,7 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
acpi_status status; acpi_status status;
struct acpica_device_id hid; struct acpica_device_id hid;
struct acpi_compatible_id_list *cid; struct acpi_compatible_id_list *cid;
acpi_native_uint i; u32 i;
/* /*
* Get the _HID and check for a PCI Root Bridge * Get the _HID and check for a PCI Root Bridge
......
...@@ -472,7 +472,6 @@ acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) ...@@ -472,7 +472,6 @@ acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
} }
ACPI_EXPORT_SYMBOL(acpi_clear_gpe) ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
#ifdef ACPI_FUTURE_USAGE
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_get_event_status * FUNCTION: acpi_get_event_status
...@@ -489,6 +488,7 @@ ACPI_EXPORT_SYMBOL(acpi_clear_gpe) ...@@ -489,6 +488,7 @@ ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
{ {
acpi_status status = AE_OK; acpi_status status = AE_OK;
u32 value;
ACPI_FUNCTION_TRACE(acpi_get_event_status); ACPI_FUNCTION_TRACE(acpi_get_event_status);
...@@ -506,7 +506,20 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) ...@@ -506,7 +506,20 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
status = status =
acpi_get_register(acpi_gbl_fixed_event_info[event]. acpi_get_register(acpi_gbl_fixed_event_info[event].
status_register_id, event_status); enable_register_id, &value);
if (ACPI_FAILURE(status))
return_ACPI_STATUS(status);
*event_status = value;
status =
acpi_get_register(acpi_gbl_fixed_event_info[event].
status_register_id, &value);
if (ACPI_FAILURE(status))
return_ACPI_STATUS(status);
if (value)
*event_status |= ACPI_EVENT_FLAG_SET;
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
...@@ -566,7 +579,6 @@ acpi_get_gpe_status(acpi_handle gpe_device, ...@@ -566,7 +579,6 @@ acpi_get_gpe_status(acpi_handle gpe_device,
} }
ACPI_EXPORT_SYMBOL(acpi_get_gpe_status) ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
#endif /* ACPI_FUTURE_USAGE */
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_install_gpe_block * FUNCTION: acpi_install_gpe_block
......
...@@ -53,7 +53,7 @@ ACPI_MODULE_NAME("exconfig") ...@@ -53,7 +53,7 @@ ACPI_MODULE_NAME("exconfig")
/* Local prototypes */ /* Local prototypes */
static acpi_status static acpi_status
acpi_ex_add_table(acpi_native_uint table_index, acpi_ex_add_table(u32 table_index,
struct acpi_namespace_node *parent_node, struct acpi_namespace_node *parent_node,
union acpi_operand_object **ddb_handle); union acpi_operand_object **ddb_handle);
...@@ -73,7 +73,7 @@ acpi_ex_add_table(acpi_native_uint table_index, ...@@ -73,7 +73,7 @@ acpi_ex_add_table(acpi_native_uint table_index,
******************************************************************************/ ******************************************************************************/
static acpi_status static acpi_status
acpi_ex_add_table(acpi_native_uint table_index, acpi_ex_add_table(u32 table_index,
struct acpi_namespace_node *parent_node, struct acpi_namespace_node *parent_node,
union acpi_operand_object **ddb_handle) union acpi_operand_object **ddb_handle)
{ {
...@@ -96,7 +96,8 @@ acpi_ex_add_table(acpi_native_uint table_index, ...@@ -96,7 +96,8 @@ acpi_ex_add_table(acpi_native_uint table_index,
/* Install the new table into the local data structures */ /* Install the new table into the local data structures */
obj_desc->reference.object = ACPI_CAST_PTR(void, table_index); obj_desc->reference.object = ACPI_CAST_PTR(void,
(unsigned long)table_index);
/* Add the table to the namespace */ /* Add the table to the namespace */
...@@ -128,12 +129,12 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, ...@@ -128,12 +129,12 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
{ {
acpi_status status; acpi_status status;
union acpi_operand_object **operand = &walk_state->operands[0]; union acpi_operand_object **operand = &walk_state->operands[0];
acpi_native_uint table_index;
struct acpi_namespace_node *parent_node; struct acpi_namespace_node *parent_node;
struct acpi_namespace_node *start_node; struct acpi_namespace_node *start_node;
struct acpi_namespace_node *parameter_node = NULL; struct acpi_namespace_node *parameter_node = NULL;
union acpi_operand_object *ddb_handle; union acpi_operand_object *ddb_handle;
struct acpi_table_header *table; struct acpi_table_header *table;
u32 table_index;
ACPI_FUNCTION_TRACE(ex_load_table_op); ACPI_FUNCTION_TRACE(ex_load_table_op);
...@@ -280,7 +281,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, ...@@ -280,7 +281,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
{ {
union acpi_operand_object *ddb_handle; union acpi_operand_object *ddb_handle;
struct acpi_table_desc table_desc; struct acpi_table_desc table_desc;
acpi_native_uint table_index; u32 table_index;
acpi_status status; acpi_status status;
u32 length; u32 length;
...@@ -437,7 +438,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) ...@@ -437,7 +438,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
{ {
acpi_status status = AE_OK; acpi_status status = AE_OK;
union acpi_operand_object *table_desc = ddb_handle; union acpi_operand_object *table_desc = ddb_handle;
acpi_native_uint table_index; u32 table_index;
struct acpi_table_header *table; struct acpi_table_header *table;
ACPI_FUNCTION_TRACE(ex_unload_table); ACPI_FUNCTION_TRACE(ex_unload_table);
...@@ -454,9 +455,9 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) ...@@ -454,9 +455,9 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
return_ACPI_STATUS(AE_BAD_PARAMETER); return_ACPI_STATUS(AE_BAD_PARAMETER);
} }
/* Get the table index from the ddb_handle */ /* Get the table index from the ddb_handle (acpi_size for 64-bit case) */
table_index = (acpi_native_uint) table_desc->reference.object; table_index = (u32) (acpi_size) table_desc->reference.object;
/* Invoke table handler if present */ /* Invoke table handler if present */
......
...@@ -288,11 +288,11 @@ acpi_ex_convert_to_ascii(acpi_integer integer, ...@@ -288,11 +288,11 @@ acpi_ex_convert_to_ascii(acpi_integer integer,
u16 base, u8 * string, u8 data_width) u16 base, u8 * string, u8 data_width)
{ {
acpi_integer digit; acpi_integer digit;
acpi_native_uint i; u32 i;
acpi_native_uint j; u32 j;
acpi_native_uint k = 0; u32 k = 0;
acpi_native_uint hex_length; u32 hex_length;
acpi_native_uint decimal_length; u32 decimal_length;
u32 remainder; u32 remainder;
u8 supress_zeros; u8 supress_zeros;
...@@ -348,7 +348,7 @@ acpi_ex_convert_to_ascii(acpi_integer integer, ...@@ -348,7 +348,7 @@ acpi_ex_convert_to_ascii(acpi_integer integer,
/* hex_length: 2 ascii hex chars per data byte */ /* hex_length: 2 ascii hex chars per data byte */
hex_length = (acpi_native_uint) ACPI_MUL_2(data_width); hex_length = ACPI_MUL_2(data_width);
for (i = 0, j = (hex_length - 1); i < hex_length; i++, j--) { for (i = 0, j = (hex_length - 1); i < hex_length; i++, j--) {
/* Get one hex digit, most significant digits first */ /* Get one hex digit, most significant digits first */
......
...@@ -45,8 +45,6 @@ ...@@ -45,8 +45,6 @@
#include <acpi/acinterp.h> #include <acpi/acinterp.h>
#include <acpi/amlcode.h> #include <acpi/amlcode.h>
#include <acpi/acnamesp.h> #include <acpi/acnamesp.h>
#include <acpi/acevents.h>
#include <acpi/actables.h>
#define _COMPONENT ACPI_EXECUTER #define _COMPONENT ACPI_EXECUTER
ACPI_MODULE_NAME("excreate") ACPI_MODULE_NAME("excreate")
......
...@@ -580,25 +580,22 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) ...@@ -580,25 +580,22 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
case ACPI_TYPE_BUFFER: case ACPI_TYPE_BUFFER:
acpi_os_printf("Buffer len %X @ %p\n", acpi_os_printf("Buffer length %.2X @ %p\n",
obj_desc->buffer.length, obj_desc->buffer.length,
obj_desc->buffer.pointer); obj_desc->buffer.pointer);
length = obj_desc->buffer.length;
if (length > 64) {
length = 64;
}
/* Debug only -- dump the buffer contents */ /* Debug only -- dump the buffer contents */
if (obj_desc->buffer.pointer) { if (obj_desc->buffer.pointer) {
acpi_os_printf("Buffer Contents: "); length = obj_desc->buffer.length;
if (length > 128) {
for (index = 0; index < length; index++) { length = 128;
acpi_os_printf(" %02x",
obj_desc->buffer.pointer[index]);
} }
acpi_os_printf("\n");
acpi_os_printf
("Buffer Contents: (displaying length 0x%.2X)\n",
length);
ACPI_DUMP_BUFFER(obj_desc->buffer.pointer, length);
} }
break; break;
...@@ -756,54 +753,42 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) ...@@ -756,54 +753,42 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
* *
* FUNCTION: acpi_ex_dump_operands * FUNCTION: acpi_ex_dump_operands
* *
* PARAMETERS: Operands - Operand list * PARAMETERS: Operands - A list of Operand objects
* interpreter_mode - Load or Exec * opcode_name - AML opcode name
* Ident - Identification * num_operands - Operand count for this opcode
* num_levels - # of stack entries to dump above line
* Note - Output notation
* module_name - Caller's module name
* line_number - Caller's invocation line number
* *
* DESCRIPTION: Dump the object stack * DESCRIPTION: Dump the operands associated with the opcode
* *
******************************************************************************/ ******************************************************************************/
void void
acpi_ex_dump_operands(union acpi_operand_object **operands, acpi_ex_dump_operands(union acpi_operand_object **operands,
acpi_interpreter_mode interpreter_mode, const char *opcode_name, u32 num_operands)
char *ident,
u32 num_levels,
char *note, char *module_name, u32 line_number)
{ {
acpi_native_uint i;
ACPI_FUNCTION_NAME(ex_dump_operands); ACPI_FUNCTION_NAME(ex_dump_operands);
if (!ident) { if (!opcode_name) {
ident = "?"; opcode_name = "UNKNOWN";
}
if (!note) {
note = "?";
} }
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"************* Operand Stack Contents (Opcode [%s], %d Operands)\n", "**** Start operand dump for opcode [%s], %d operands\n",
ident, num_levels)); opcode_name, num_operands));
if (num_levels == 0) { if (num_operands == 0) {
num_levels = 1; num_operands = 1;
} }
/* Dump the operand stack starting at the top */ /* Dump the individual operands */
for (i = 0; num_levels > 0; i--, num_levels--) { while (num_operands) {
acpi_ex_dump_operand(operands[i], 0); acpi_ex_dump_operand(*operands, 0);
operands++;
num_operands--;
} }
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"************* Operand Stack dump from %s(%d), %s\n", "**** End operand dump for [%s]\n", opcode_name));
module_name, line_number, note));
return; return;
} }
......
...@@ -153,14 +153,15 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, ...@@ -153,14 +153,15 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
/* /*
* Slack mode only: We will go ahead and allow access to this * Slack mode only: We will go ahead and allow access to this
* field if it is within the region length rounded up to the next * field if it is within the region length rounded up to the next
* access width boundary. * access width boundary. acpi_size cast for 64-bit compile.
*/ */
if (ACPI_ROUND_UP(rgn_desc->region.length, if (ACPI_ROUND_UP(rgn_desc->region.length,
obj_desc->common_field. obj_desc->common_field.
access_byte_width) >= access_byte_width) >=
(obj_desc->common_field.base_byte_offset + ((acpi_size) obj_desc->common_field.
(acpi_native_uint) obj_desc->common_field. base_byte_offset +
access_byte_width + field_datum_byte_offset)) { obj_desc->common_field.access_byte_width +
field_datum_byte_offset)) {
return_ACPI_STATUS(AE_OK); return_ACPI_STATUS(AE_OK);
} }
} }
......
...@@ -329,8 +329,8 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, ...@@ -329,8 +329,8 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
/* Result of two Strings is a String */ /* Result of two Strings is a String */
return_desc = acpi_ut_create_string_object((acpi_size) return_desc = acpi_ut_create_string_object(((acpi_size)
(operand0->string. operand0->string.
length + length +
local_operand1-> local_operand1->
string.length)); string.length));
...@@ -352,8 +352,8 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, ...@@ -352,8 +352,8 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
/* Result of two Buffers is a Buffer */ /* Result of two Buffers is a Buffer */
return_desc = acpi_ut_create_buffer_object((acpi_size) return_desc = acpi_ut_create_buffer_object(((acpi_size)
(operand0->buffer. operand0->buffer.
length + length +
local_operand1-> local_operand1->
buffer.length)); buffer.length));
......
...@@ -503,11 +503,11 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info) ...@@ -503,11 +503,11 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
*/ */
second_desc = obj_desc->common.next_object; second_desc = obj_desc->common.next_object;
second_desc->extra.aml_start = second_desc->extra.aml_start =
((union acpi_parse_object *)(info->data_register_node))-> ACPI_CAST_PTR(union acpi_parse_object,
named.data; info->data_register_node)->named.data;
second_desc->extra.aml_length = second_desc->extra.aml_length =
((union acpi_parse_object *)(info->data_register_node))-> ACPI_CAST_PTR(union acpi_parse_object,
named.length; info->data_register_node)->named.length;
break; break;
......
...@@ -156,7 +156,7 @@ acpi_ex_system_memory_space_handler(u32 function, ...@@ -156,7 +156,7 @@ acpi_ex_system_memory_space_handler(u32 function,
/* Create a new mapping starting at the address given */ /* Create a new mapping starting at the address given */
mem_info->mapped_logical_address = mem_info->mapped_logical_address =
acpi_os_map_memory((acpi_native_uint) address, window_size); acpi_os_map_memory((acpi_physical_address) address, window_size);
if (!mem_info->mapped_logical_address) { if (!mem_info->mapped_logical_address) {
ACPI_ERROR((AE_INFO, ACPI_ERROR((AE_INFO,
"Could not map memory at %8.8X%8.8X, size %X", "Could not map memory at %8.8X%8.8X, size %X",
......
...@@ -698,5 +698,9 @@ acpi_ex_resolve_operands(u16 opcode, ...@@ -698,5 +698,9 @@ acpi_ex_resolve_operands(u16 opcode,
} }
} }
ACPI_DUMP_OPERANDS(walk_state->operands,
acpi_ps_get_opcode_name(opcode),
walk_state->num_operands);
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
...@@ -343,12 +343,6 @@ acpi_ex_store(union acpi_operand_object *source_desc, ...@@ -343,12 +343,6 @@ acpi_ex_store(union acpi_operand_object *source_desc,
acpi_ut_get_object_type_name(dest_desc), acpi_ut_get_object_type_name(dest_desc),
dest_desc)); dest_desc));
ACPI_DUMP_STACK_ENTRY(source_desc);
ACPI_DUMP_STACK_ENTRY(dest_desc);
ACPI_DUMP_OPERANDS(&dest_desc, ACPI_IMODE_EXECUTE, "ExStore",
2,
"Target is not a Reference or Constant object");
return_ACPI_STATUS(AE_AML_OPERAND_TYPE); return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
} }
......
...@@ -148,7 +148,7 @@ acpi_fan_write_state(struct file *file, const char __user * buffer, ...@@ -148,7 +148,7 @@ acpi_fan_write_state(struct file *file, const char __user * buffer,
int result = 0; int result = 0;
struct seq_file *m = file->private_data; struct seq_file *m = file->private_data;
struct acpi_device *device = m->private; struct acpi_device *device = m->private;
char state_string[12] = { '\0' }; char state_string[3] = { '\0' };
if (count > sizeof(state_string) - 1) if (count > sizeof(state_string) - 1)
return -EINVAL; return -EINVAL;
...@@ -157,6 +157,12 @@ acpi_fan_write_state(struct file *file, const char __user * buffer, ...@@ -157,6 +157,12 @@ acpi_fan_write_state(struct file *file, const char __user * buffer,
return -EFAULT; return -EFAULT;
state_string[count] = '\0'; state_string[count] = '\0';
if ((state_string[0] < '0') || (state_string[0] > '3'))
return -EINVAL;
if (state_string[1] == '\n')
state_string[1] = '\0';
if (state_string[1] != '\0')
return -EINVAL;
result = acpi_bus_set_power(device->handle, result = acpi_bus_set_power(device->handle,
simple_strtoul(state_string, NULL, 0)); simple_strtoul(state_string, NULL, 0));
......
...@@ -333,6 +333,9 @@ static int __init acpi_rtc_init(void) ...@@ -333,6 +333,9 @@ static int __init acpi_rtc_init(void)
{ {
struct device *dev = get_rtc_dev(); struct device *dev = get_rtc_dev();
if (acpi_disabled)
return 0;
if (acpi_disabled) if (acpi_disabled)
return 0; return 0;
......
...@@ -53,6 +53,54 @@ static acpi_status ...@@ -53,6 +53,54 @@ static acpi_status
acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
struct acpi_gpe_block_info *gpe_block); struct acpi_gpe_block_info *gpe_block);
/******************************************************************************
*
* FUNCTION: acpi_hw_low_disable_gpe
*
* PARAMETERS: gpe_event_info - Info block for the GPE to be disabled
*
* RETURN: Status
*
* DESCRIPTION: Disable a single GPE in the enable register.
*
******************************************************************************/
acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
{
struct acpi_gpe_register_info *gpe_register_info;
acpi_status status;
u32 enable_mask;
/* Get the info block for the entire GPE register */
gpe_register_info = gpe_event_info->register_info;
if (!gpe_register_info) {
return (AE_NOT_EXIST);
}
/* Get current value of the enable register that contains this GPE */
status = acpi_hw_low_level_read(ACPI_GPE_REGISTER_WIDTH, &enable_mask,
&gpe_register_info->enable_address);
if (ACPI_FAILURE(status)) {
return (status);
}
/* Clear just the bit that corresponds to this GPE */
ACPI_CLEAR_BIT(enable_mask,
((u32) 1 <<
(gpe_event_info->gpe_number -
gpe_register_info->base_gpe_number)));
/* Write the updated enable mask */
status = acpi_hw_low_level_write(ACPI_GPE_REGISTER_WIDTH, enable_mask,
&gpe_register_info->enable_address);
return (status);
}
/****************************************************************************** /******************************************************************************
* *
* FUNCTION: acpi_hw_write_gpe_enable_reg * FUNCTION: acpi_hw_write_gpe_enable_reg
...@@ -68,7 +116,7 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, ...@@ -68,7 +116,7 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status
acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info *gpe_event_info) acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info * gpe_event_info)
{ {
struct acpi_gpe_register_info *gpe_register_info; struct acpi_gpe_register_info *gpe_register_info;
acpi_status status; acpi_status status;
...@@ -138,7 +186,6 @@ acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) ...@@ -138,7 +186,6 @@ acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info)
* *
******************************************************************************/ ******************************************************************************/
#ifdef ACPI_FUTURE_USAGE
acpi_status acpi_status
acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info,
acpi_event_status * event_status) acpi_event_status * event_status)
...@@ -198,7 +245,6 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, ...@@ -198,7 +245,6 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info,
unlock_and_exit: unlock_and_exit:
return (status); return (status);
} }
#endif /* ACPI_FUTURE_USAGE */
/****************************************************************************** /******************************************************************************
* *
......
...@@ -73,7 +73,7 @@ acpi_ns_dump_one_device(acpi_handle obj_handle, ...@@ -73,7 +73,7 @@ acpi_ns_dump_one_device(acpi_handle obj_handle,
void acpi_ns_print_pathname(u32 num_segments, char *pathname) void acpi_ns_print_pathname(u32 num_segments, char *pathname)
{ {
acpi_native_uint i; u32 i;
ACPI_FUNCTION_NAME(ns_print_pathname); ACPI_FUNCTION_NAME(ns_print_pathname);
...@@ -515,12 +515,12 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, ...@@ -515,12 +515,12 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
if (obj_type > ACPI_TYPE_LOCAL_MAX) { if (obj_type > ACPI_TYPE_LOCAL_MAX) {
acpi_os_printf acpi_os_printf
("(Ptr to ACPI Object type %X [UNKNOWN])\n", ("(Pointer to ACPI Object type %.2X [UNKNOWN])\n",
obj_type); obj_type);
bytes_to_dump = 32; bytes_to_dump = 32;
} else { } else {
acpi_os_printf acpi_os_printf
("(Ptr to ACPI Object type %X [%s])\n", ("(Pointer to ACPI Object type %.2X [%s])\n",
obj_type, acpi_ut_get_type_name(obj_type)); obj_type, acpi_ut_get_type_name(obj_type));
bytes_to_dump = bytes_to_dump =
sizeof(union acpi_operand_object); sizeof(union acpi_operand_object);
......
...@@ -138,6 +138,41 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) ...@@ -138,6 +138,41 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info)
return_ACPI_STATUS(AE_NULL_OBJECT); return_ACPI_STATUS(AE_NULL_OBJECT);
} }
/*
* Calculate the number of arguments being passed to the method
*/
info->param_count = 0;
if (info->parameters) {
while (info->parameters[info->param_count])
info->param_count++;
}
/* Error if too few arguments were passed in */
if (info->param_count < info->obj_desc->method.param_count) {
ACPI_ERROR((AE_INFO,
"Insufficient arguments - "
"method [%4.4s] needs %d, found %d",
acpi_ut_get_node_name(info->resolved_node),
info->obj_desc->method.param_count,
info->param_count));
return_ACPI_STATUS(AE_MISSING_ARGUMENTS);
}
/* Just a warning if too many arguments */
else if (info->param_count >
info->obj_desc->method.param_count) {
ACPI_WARNING((AE_INFO,
"Excess arguments - "
"method [%4.4s] needs %d, found %d",
acpi_ut_get_node_name(info->
resolved_node),
info->obj_desc->method.param_count,
info->param_count));
}
ACPI_DUMP_PATHNAME(info->resolved_node, "Execute Method:", ACPI_DUMP_PATHNAME(info->resolved_node, "Execute Method:",
ACPI_LV_INFO, _COMPONENT); ACPI_LV_INFO, _COMPONENT);
......
...@@ -542,7 +542,6 @@ acpi_ns_init_one_device(acpi_handle obj_handle, ...@@ -542,7 +542,6 @@ acpi_ns_init_one_device(acpi_handle obj_handle,
info->prefix_node = device_node; info->prefix_node = device_node;
info->pathname = METHOD_NAME__INI; info->pathname = METHOD_NAME__INI;
info->parameters = NULL; info->parameters = NULL;
info->parameter_type = ACPI_PARAM_ARGS;
info->flags = ACPI_IGNORE_RETURN_VALUE; info->flags = ACPI_IGNORE_RETURN_VALUE;
/* /*
......
...@@ -71,8 +71,7 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle); ...@@ -71,8 +71,7 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle);
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status
acpi_ns_load_table(acpi_native_uint table_index, acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node)
struct acpi_namespace_node *node)
{ {
acpi_status status; acpi_status status;
......
...@@ -63,13 +63,13 @@ ACPI_MODULE_NAME("nsparse") ...@@ -63,13 +63,13 @@ ACPI_MODULE_NAME("nsparse")
* *
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status
acpi_ns_one_complete_parse(acpi_native_uint pass_number, acpi_ns_one_complete_parse(u32 pass_number,
acpi_native_uint table_index, u32 table_index,
struct acpi_namespace_node * start_node) struct acpi_namespace_node *start_node)
{ {
union acpi_parse_object *parse_root; union acpi_parse_object *parse_root;
acpi_status status; acpi_status status;
acpi_native_uint aml_length; u32 aml_length;
u8 *aml_start; u8 *aml_start;
struct acpi_walk_state *walk_state; struct acpi_walk_state *walk_state;
struct acpi_table_header *table; struct acpi_table_header *table;
...@@ -112,8 +112,8 @@ acpi_ns_one_complete_parse(acpi_native_uint pass_number, ...@@ -112,8 +112,8 @@ acpi_ns_one_complete_parse(acpi_native_uint pass_number,
aml_start = (u8 *) table + sizeof(struct acpi_table_header); aml_start = (u8 *) table + sizeof(struct acpi_table_header);
aml_length = table->length - sizeof(struct acpi_table_header); aml_length = table->length - sizeof(struct acpi_table_header);
status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL, status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL,
aml_start, (u32) aml_length, aml_start, aml_length, NULL,
NULL, (u8) pass_number); (u8) pass_number);
} }
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
...@@ -158,8 +158,7 @@ acpi_ns_one_complete_parse(acpi_native_uint pass_number, ...@@ -158,8 +158,7 @@ acpi_ns_one_complete_parse(acpi_native_uint pass_number,
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status
acpi_ns_parse_table(acpi_native_uint table_index, acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node)
struct acpi_namespace_node *start_node)
{ {
acpi_status status; acpi_status status;
......
...@@ -73,9 +73,9 @@ acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node *node_to_search); ...@@ -73,9 +73,9 @@ acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node *node_to_search);
******************************************************************************/ ******************************************************************************/
void void
acpi_ns_report_error(char *module_name, acpi_ns_report_error(const char *module_name,
u32 line_number, u32 line_number,
char *internal_name, acpi_status lookup_status) const char *internal_name, acpi_status lookup_status)
{ {
acpi_status status; acpi_status status;
u32 bad_name; u32 bad_name;
...@@ -130,11 +130,11 @@ acpi_ns_report_error(char *module_name, ...@@ -130,11 +130,11 @@ acpi_ns_report_error(char *module_name,
******************************************************************************/ ******************************************************************************/
void void
acpi_ns_report_method_error(char *module_name, acpi_ns_report_method_error(const char *module_name,
u32 line_number, u32 line_number,
char *message, const char *message,
struct acpi_namespace_node *prefix_node, struct acpi_namespace_node *prefix_node,
char *path, acpi_status method_status) const char *path, acpi_status method_status)
{ {
acpi_status status; acpi_status status;
struct acpi_namespace_node *node = prefix_node; struct acpi_namespace_node *node = prefix_node;
...@@ -167,7 +167,8 @@ acpi_ns_report_method_error(char *module_name, ...@@ -167,7 +167,8 @@ acpi_ns_report_method_error(char *module_name,
******************************************************************************/ ******************************************************************************/
void void
acpi_ns_print_node_pathname(struct acpi_namespace_node *node, char *message) acpi_ns_print_node_pathname(struct acpi_namespace_node *node,
const char *message)
{ {
struct acpi_buffer buffer; struct acpi_buffer buffer;
acpi_status status; acpi_status status;
...@@ -296,7 +297,7 @@ u32 acpi_ns_local(acpi_object_type type) ...@@ -296,7 +297,7 @@ u32 acpi_ns_local(acpi_object_type type)
void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info) void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info)
{ {
char *next_external_char; const char *next_external_char;
u32 i; u32 i;
ACPI_FUNCTION_ENTRY(); ACPI_FUNCTION_ENTRY();
...@@ -363,9 +364,9 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info) ...@@ -363,9 +364,9 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info)
{ {
u32 num_segments = info->num_segments; u32 num_segments = info->num_segments;
char *internal_name = info->internal_name; char *internal_name = info->internal_name;
char *external_name = info->next_external_char; const char *external_name = info->next_external_char;
char *result = NULL; char *result = NULL;
acpi_native_uint i; u32 i;
ACPI_FUNCTION_TRACE(ns_build_internal_name); ACPI_FUNCTION_TRACE(ns_build_internal_name);
...@@ -400,12 +401,11 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info) ...@@ -400,12 +401,11 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info)
result = &internal_name[i]; result = &internal_name[i];
} else if (num_segments == 2) { } else if (num_segments == 2) {
internal_name[i] = AML_DUAL_NAME_PREFIX; internal_name[i] = AML_DUAL_NAME_PREFIX;
result = &internal_name[(acpi_native_uint) (i + 1)]; result = &internal_name[(acpi_size) i + 1];
} else { } else {
internal_name[i] = AML_MULTI_NAME_PREFIX_OP; internal_name[i] = AML_MULTI_NAME_PREFIX_OP;
internal_name[(acpi_native_uint) (i + 1)] = internal_name[(acpi_size) i + 1] = (char)num_segments;
(char)num_segments; result = &internal_name[(acpi_size) i + 2];
result = &internal_name[(acpi_native_uint) (i + 2)];
} }
} }
...@@ -472,7 +472,8 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info) ...@@ -472,7 +472,8 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info)
* *
*******************************************************************************/ *******************************************************************************/
acpi_status acpi_ns_internalize_name(char *external_name, char **converted_name) acpi_status
acpi_ns_internalize_name(const char *external_name, char **converted_name)
{ {
char *internal_name; char *internal_name;
struct acpi_namestring_info info; struct acpi_namestring_info info;
...@@ -528,15 +529,15 @@ acpi_status acpi_ns_internalize_name(char *external_name, char **converted_name) ...@@ -528,15 +529,15 @@ acpi_status acpi_ns_internalize_name(char *external_name, char **converted_name)
acpi_status acpi_status
acpi_ns_externalize_name(u32 internal_name_length, acpi_ns_externalize_name(u32 internal_name_length,
char *internal_name, const char *internal_name,
u32 * converted_name_length, char **converted_name) u32 * converted_name_length, char **converted_name)
{ {
acpi_native_uint names_index = 0; u32 names_index = 0;
acpi_native_uint num_segments = 0; u32 num_segments = 0;
acpi_native_uint required_length; u32 required_length;
acpi_native_uint prefix_length = 0; u32 prefix_length = 0;
acpi_native_uint i = 0; u32 i = 0;
acpi_native_uint j = 0; u32 j = 0;
ACPI_FUNCTION_TRACE(ns_externalize_name); ACPI_FUNCTION_TRACE(ns_externalize_name);
...@@ -582,9 +583,8 @@ acpi_ns_externalize_name(u32 internal_name_length, ...@@ -582,9 +583,8 @@ acpi_ns_externalize_name(u32 internal_name_length,
/* <count> 4-byte names */ /* <count> 4-byte names */
names_index = prefix_length + 2; names_index = prefix_length + 2;
num_segments = (acpi_native_uint) (u8) num_segments = (u8)
internal_name[(acpi_native_uint) internal_name[(acpi_size) prefix_length + 1];
(prefix_length + 1)];
break; break;
case AML_DUAL_NAME_PREFIX: case AML_DUAL_NAME_PREFIX:
...@@ -823,7 +823,7 @@ u32 acpi_ns_opens_scope(acpi_object_type type) ...@@ -823,7 +823,7 @@ u32 acpi_ns_opens_scope(acpi_object_type type)
acpi_status acpi_status
acpi_ns_get_node(struct acpi_namespace_node *prefix_node, acpi_ns_get_node(struct acpi_namespace_node *prefix_node,
char *pathname, const char *pathname,
u32 flags, struct acpi_namespace_node **return_node) u32 flags, struct acpi_namespace_node **return_node)
{ {
union acpi_generic_state scope_info; union acpi_generic_state scope_info;
......
...@@ -182,7 +182,6 @@ acpi_evaluate_object(acpi_handle handle, ...@@ -182,7 +182,6 @@ acpi_evaluate_object(acpi_handle handle,
} }
info->pathname = pathname; info->pathname = pathname;
info->parameter_type = ACPI_PARAM_ARGS;
/* Convert and validate the device handle */ /* Convert and validate the device handle */
...@@ -442,7 +441,7 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, ...@@ -442,7 +441,7 @@ acpi_ns_get_device_callback(acpi_handle obj_handle,
u32 flags; u32 flags;
struct acpica_device_id hid; struct acpica_device_id hid;
struct acpi_compatible_id_list *cid; struct acpi_compatible_id_list *cid;
acpi_native_uint i; u32 i;
int found; int found;
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
......
...@@ -120,10 +120,10 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header) ...@@ -120,10 +120,10 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header)
struct acpi_srat_mem_affinity *p = struct acpi_srat_mem_affinity *p =
(struct acpi_srat_mem_affinity *)header; (struct acpi_srat_mem_affinity *)header;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"SRAT Memory (0x%lx length 0x%lx type 0x%x) in proximity domain %d %s%s\n", "SRAT Memory (0x%lx length 0x%lx) in proximity domain %d %s%s\n",
(unsigned long)p->base_address, (unsigned long)p->base_address,
(unsigned long)p->length, (unsigned long)p->length,
p->memory_type, p->proximity_domain, p->proximity_domain,
(p->flags & ACPI_SRAT_MEM_ENABLED)? (p->flags & ACPI_SRAT_MEM_ENABLED)?
"enabled" : "disabled", "enabled" : "disabled",
(p->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)? (p->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)?
......
...@@ -76,7 +76,7 @@ acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state) ...@@ -76,7 +76,7 @@ acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state)
{ {
u8 *aml = parser_state->aml; u8 *aml = parser_state->aml;
u32 package_length = 0; u32 package_length = 0;
acpi_native_uint byte_count; u32 byte_count;
u8 byte_zero_mask = 0x3F; /* Default [0:5] */ u8 byte_zero_mask = 0x3F; /* Default [0:5] */
ACPI_FUNCTION_TRACE(ps_get_next_package_length); ACPI_FUNCTION_TRACE(ps_get_next_package_length);
...@@ -86,7 +86,7 @@ acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state) ...@@ -86,7 +86,7 @@ acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state)
* used to encode the package length, either 0,1,2, or 3 * used to encode the package length, either 0,1,2, or 3
*/ */
byte_count = (aml[0] >> 6); byte_count = (aml[0] >> 6);
parser_state->aml += (byte_count + 1); parser_state->aml += ((acpi_size) byte_count + 1);
/* Get bytes 3, 2, 1 as needed */ /* Get bytes 3, 2, 1 as needed */
......
...@@ -333,9 +333,9 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) ...@@ -333,9 +333,9 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
static void static void
acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action) acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action)
{ {
acpi_native_uint i; u32 i;
if ((info->parameter_type == ACPI_PARAM_ARGS) && (info->parameters)) { if (info->parameters) {
/* Update reference count for each parameter */ /* Update reference count for each parameter */
......
...@@ -162,7 +162,7 @@ do_prt_fixups(struct acpi_prt_entry *entry, struct acpi_pci_routing_table *prt) ...@@ -162,7 +162,7 @@ do_prt_fixups(struct acpi_prt_entry *entry, struct acpi_pci_routing_table *prt)
!strcmp(prt->source, quirk->source) && !strcmp(prt->source, quirk->source) &&
strlen(prt->source) >= strlen(quirk->actual_source)) { strlen(prt->source) >= strlen(quirk->actual_source)) {
printk(KERN_WARNING PREFIX "firmware reports " printk(KERN_WARNING PREFIX "firmware reports "
"%04x:%02x:%02x[%c] connected to %s; " "%04x:%02x:%02x PCI INT %c connected to %s; "
"changing to %s\n", "changing to %s\n",
entry->id.segment, entry->id.bus, entry->id.segment, entry->id.bus,
entry->id.device, 'A' + entry->pin, entry->id.device, 'A' + entry->pin,
...@@ -429,7 +429,7 @@ acpi_pci_irq_derive(struct pci_dev *dev, ...@@ -429,7 +429,7 @@ acpi_pci_irq_derive(struct pci_dev *dev,
{ {
struct pci_dev *bridge = dev; struct pci_dev *bridge = dev;
int irq = -1; int irq = -1;
u8 bridge_pin = 0; u8 bridge_pin = 0, orig_pin = pin;
if (!dev) if (!dev)
...@@ -463,8 +463,8 @@ acpi_pci_irq_derive(struct pci_dev *dev, ...@@ -463,8 +463,8 @@ acpi_pci_irq_derive(struct pci_dev *dev,
} }
if (irq < 0) { if (irq < 0) {
printk(KERN_WARNING PREFIX "Unable to derive IRQ for device %s\n", dev_warn(&dev->dev, "can't derive routing for PCI INT %c\n",
pci_name(dev)); 'A' + orig_pin);
return -1; return -1;
} }
...@@ -487,6 +487,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev) ...@@ -487,6 +487,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
int triggering = ACPI_LEVEL_SENSITIVE; int triggering = ACPI_LEVEL_SENSITIVE;
int polarity = ACPI_ACTIVE_LOW; int polarity = ACPI_ACTIVE_LOW;
char *link = NULL; char *link = NULL;
char link_desc[16];
int rc; int rc;
...@@ -503,7 +504,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev) ...@@ -503,7 +504,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
pin--; pin--;
if (!dev->bus) { if (!dev->bus) {
printk(KERN_ERR PREFIX "Invalid (NULL) 'bus' field\n"); dev_err(&dev->dev, "invalid (NULL) 'bus' field\n");
return -ENODEV; return -ENODEV;
} }
...@@ -538,8 +539,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev) ...@@ -538,8 +539,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
* driver reported one, then use it. Exit in any case. * driver reported one, then use it. Exit in any case.
*/ */
if (irq < 0) { if (irq < 0) {
printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: no GSI", dev_warn(&dev->dev, "PCI INT %c: no GSI", 'A' + pin);
pci_name(dev), ('A' + pin));
/* Interrupt Line values above 0xF are forbidden */ /* Interrupt Line values above 0xF are forbidden */
if (dev->irq > 0 && (dev->irq <= 0xF)) { if (dev->irq > 0 && (dev->irq <= 0xF)) {
printk(" - using IRQ %d\n", dev->irq); printk(" - using IRQ %d\n", dev->irq);
...@@ -554,21 +554,21 @@ int acpi_pci_irq_enable(struct pci_dev *dev) ...@@ -554,21 +554,21 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
rc = acpi_register_gsi(irq, triggering, polarity); rc = acpi_register_gsi(irq, triggering, polarity);
if (rc < 0) { if (rc < 0) {
printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: failed " dev_warn(&dev->dev, "PCI INT %c: failed to register GSI\n",
"to register GSI\n", pci_name(dev), ('A' + pin)); 'A' + pin);
return rc; return rc;
} }
dev->irq = rc; dev->irq = rc;
printk(KERN_INFO PREFIX "PCI Interrupt %s[%c] -> ",
pci_name(dev), 'A' + pin);
if (link) if (link)
printk("Link [%s] -> ", link); snprintf(link_desc, sizeof(link_desc), " -> Link[%s]", link);
else
link_desc[0] = '\0';
printk("GSI %u (%s, %s) -> IRQ %d\n", irq, dev_info(&dev->dev, "PCI INT %c%s -> GSI %u (%s, %s) -> IRQ %d\n",
(triggering == ACPI_LEVEL_SENSITIVE) ? "level" : "edge", 'A' + pin, link_desc, irq,
(polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq); (triggering == ACPI_LEVEL_SENSITIVE) ? "level" : "edge",
(polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq);
return 0; return 0;
} }
...@@ -616,10 +616,6 @@ void acpi_pci_irq_disable(struct pci_dev *dev) ...@@ -616,10 +616,6 @@ void acpi_pci_irq_disable(struct pci_dev *dev)
* (e.g. PCI_UNDEFINED_IRQ). * (e.g. PCI_UNDEFINED_IRQ).
*/ */
printk(KERN_INFO PREFIX "PCI interrupt for device %s disabled\n", dev_info(&dev->dev, "PCI INT %c disabled\n", 'A' + pin);
pci_name(dev));
acpi_unregister_gsi(gsi); acpi_unregister_gsi(gsi);
return;
} }
...@@ -118,8 +118,31 @@ static const struct file_operations acpi_processor_info_fops = { ...@@ -118,8 +118,31 @@ static const struct file_operations acpi_processor_info_fops = {
.release = single_release, .release = single_release,
}; };
struct acpi_processor *processors[NR_CPUS]; DEFINE_PER_CPU(struct acpi_processor *, processors);
struct acpi_processor_errata errata __read_mostly; struct acpi_processor_errata errata __read_mostly;
static int set_no_mwait(const struct dmi_system_id *id)
{
printk(KERN_NOTICE PREFIX "%s detected - "
"disable mwait for CPU C-stetes\n", id->ident);
idle_nomwait = 1;
return 0;
}
static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = {
{
set_no_mwait, "IFL91 board", {
DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"),
DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"),
DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL},
{
set_no_mwait, "Extensa 5220", {
DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
DMI_MATCH(DMI_SYS_VENDOR, "ACER"),
DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL},
{},
};
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
Errata Handling Errata Handling
...@@ -265,7 +288,20 @@ static int acpi_processor_set_pdc(struct acpi_processor *pr) ...@@ -265,7 +288,20 @@ static int acpi_processor_set_pdc(struct acpi_processor *pr)
if (!pdc_in) if (!pdc_in)
return status; return status;
if (idle_nomwait) {
/*
* If mwait is disabled for CPU C-states, the C2C3_FFH access
* mode will be disabled in the parameter of _PDC object.
* Of course C1_FFH access mode will also be disabled.
*/
union acpi_object *obj;
u32 *buffer = NULL;
obj = pdc_in->pointer;
buffer = (u32 *)(obj->buffer.pointer);
buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH);
}
status = acpi_evaluate_object(pr->handle, "_PDC", pdc_in, NULL); status = acpi_evaluate_object(pr->handle, "_PDC", pdc_in, NULL);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
...@@ -614,14 +650,14 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) ...@@ -614,14 +650,14 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid)
return 0; return 0;
} }
static void *processor_device_array[NR_CPUS]; static DEFINE_PER_CPU(void *, processor_device_array);
static int __cpuinit acpi_processor_start(struct acpi_device *device) static int __cpuinit acpi_processor_start(struct acpi_device *device)
{ {
int result = 0; int result = 0;
acpi_status status = AE_OK; acpi_status status = AE_OK;
struct acpi_processor *pr; struct acpi_processor *pr;
struct sys_device *sysdev;
pr = acpi_driver_data(device); pr = acpi_driver_data(device);
...@@ -638,20 +674,24 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device) ...@@ -638,20 +674,24 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
* ACPI id of processors can be reported wrongly by the BIOS. * ACPI id of processors can be reported wrongly by the BIOS.
* Don't trust it blindly * Don't trust it blindly
*/ */
if (processor_device_array[pr->id] != NULL && if (per_cpu(processor_device_array, pr->id) != NULL &&
processor_device_array[pr->id] != device) { per_cpu(processor_device_array, pr->id) != device) {
printk(KERN_WARNING "BIOS reported wrong ACPI id " printk(KERN_WARNING "BIOS reported wrong ACPI id "
"for the processor\n"); "for the processor\n");
return -ENODEV; return -ENODEV;
} }
processor_device_array[pr->id] = device; per_cpu(processor_device_array, pr->id) = device;
processors[pr->id] = pr; per_cpu(processors, pr->id) = pr;
result = acpi_processor_add_fs(device); result = acpi_processor_add_fs(device);
if (result) if (result)
goto end; goto end;
sysdev = get_cpu_sysdev(pr->id);
if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev"))
return -EFAULT;
status = acpi_install_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY, status = acpi_install_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY,
acpi_processor_notify, pr); acpi_processor_notify, pr);
...@@ -749,7 +789,7 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb, ...@@ -749,7 +789,7 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb,
unsigned long action, void *hcpu) unsigned long action, void *hcpu)
{ {
unsigned int cpu = (unsigned long)hcpu; unsigned int cpu = (unsigned long)hcpu;
struct acpi_processor *pr = processors[cpu]; struct acpi_processor *pr = per_cpu(processors, cpu);
if (action == CPU_ONLINE && pr) { if (action == CPU_ONLINE && pr) {
acpi_processor_ppc_has_changed(pr); acpi_processor_ppc_has_changed(pr);
...@@ -810,6 +850,8 @@ static int acpi_processor_remove(struct acpi_device *device, int type) ...@@ -810,6 +850,8 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
status = acpi_remove_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY, status = acpi_remove_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY,
acpi_processor_notify); acpi_processor_notify);
sysfs_remove_link(&device->dev.kobj, "sysdev");
acpi_processor_remove_fs(device); acpi_processor_remove_fs(device);
if (pr->cdev) { if (pr->cdev) {
...@@ -819,8 +861,8 @@ static int acpi_processor_remove(struct acpi_device *device, int type) ...@@ -819,8 +861,8 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
pr->cdev = NULL; pr->cdev = NULL;
} }
processors[pr->id] = NULL; per_cpu(processors, pr->id) = NULL;
processor_device_array[pr->id] = NULL; per_cpu(processor_device_array, pr->id) = NULL;
kfree(pr); kfree(pr);
return 0; return 0;
...@@ -1014,9 +1056,9 @@ static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu) ...@@ -1014,9 +1056,9 @@ static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu)
static int acpi_processor_handle_eject(struct acpi_processor *pr) static int acpi_processor_handle_eject(struct acpi_processor *pr)
{ {
if (cpu_online(pr->id)) { if (cpu_online(pr->id))
return (-EINVAL); cpu_down(pr->id);
}
arch_unregister_cpu(pr->id); arch_unregister_cpu(pr->id);
acpi_unmap_lsapic(pr->id); acpi_unmap_lsapic(pr->id);
return (0); return (0);
...@@ -1068,8 +1110,6 @@ static int __init acpi_processor_init(void) ...@@ -1068,8 +1110,6 @@ static int __init acpi_processor_init(void)
{ {
int result = 0; int result = 0;
memset(&processors, 0, sizeof(processors));
memset(&errata, 0, sizeof(errata)); memset(&errata, 0, sizeof(errata));
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
...@@ -1083,6 +1123,11 @@ static int __init acpi_processor_init(void) ...@@ -1083,6 +1123,11 @@ static int __init acpi_processor_init(void)
return -ENOMEM; return -ENOMEM;
acpi_processor_dir->owner = THIS_MODULE; acpi_processor_dir->owner = THIS_MODULE;
/*
* Check whether the system is DMI table. If yes, OSPM
* should not use mwait for CPU-states.
*/
dmi_check_system(processor_idle_dmi_table);
result = cpuidle_register_driver(&acpi_idle_driver); result = cpuidle_register_driver(&acpi_idle_driver);
if (result < 0) if (result < 0)
goto out_proc; goto out_proc;
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include <linux/pm_qos_params.h> #include <linux/pm_qos_params.h>
#include <linux/clockchips.h> #include <linux/clockchips.h>
#include <linux/cpuidle.h> #include <linux/cpuidle.h>
#include <linux/cpuidle.h>
/* /*
* Include the apic definitions for x86 to have the APIC timer related defines * Include the apic definitions for x86 to have the APIC timer related defines
...@@ -57,6 +58,7 @@ ...@@ -57,6 +58,7 @@
#include <acpi/acpi_bus.h> #include <acpi/acpi_bus.h>
#include <acpi/processor.h> #include <acpi/processor.h>
#include <asm/processor.h>
#define ACPI_PROCESSOR_COMPONENT 0x01000000 #define ACPI_PROCESSOR_COMPONENT 0x01000000
#define ACPI_PROCESSOR_CLASS "processor" #define ACPI_PROCESSOR_CLASS "processor"
...@@ -401,7 +403,7 @@ static void acpi_processor_idle(void) ...@@ -401,7 +403,7 @@ static void acpi_processor_idle(void)
*/ */
local_irq_disable(); local_irq_disable();
pr = processors[smp_processor_id()]; pr = __get_cpu_var(processors);
if (!pr) { if (!pr) {
local_irq_enable(); local_irq_enable();
return; return;
...@@ -955,6 +957,21 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) ...@@ -955,6 +957,21 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
} else { } else {
continue; continue;
} }
if (cx.type == ACPI_STATE_C1 &&
(idle_halt || idle_nomwait)) {
/*
* In most cases the C1 space_id obtained from
* _CST object is FIXED_HARDWARE access mode.
* But when the option of idle=halt is added,
* the entry_method type should be changed from
* CSTATE_FFH to CSTATE_HALT.
* When the option of idle=nomwait is added,
* the C1 entry_method type should be
* CSTATE_HALT.
*/
cx.entry_method = ACPI_CSTATE_HALT;
snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI HLT");
}
} else { } else {
snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI IOPORT 0x%x", snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI IOPORT 0x%x",
cx.address); cx.address);
...@@ -1431,7 +1448,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, ...@@ -1431,7 +1448,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
struct acpi_processor *pr; struct acpi_processor *pr;
struct acpi_processor_cx *cx = cpuidle_get_statedata(state); struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
pr = processors[smp_processor_id()]; pr = __get_cpu_var(processors);
if (unlikely(!pr)) if (unlikely(!pr))
return 0; return 0;
...@@ -1471,7 +1488,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, ...@@ -1471,7 +1488,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
u32 t1, t2; u32 t1, t2;
int sleep_ticks = 0; int sleep_ticks = 0;
pr = processors[smp_processor_id()]; pr = __get_cpu_var(processors);
if (unlikely(!pr)) if (unlikely(!pr))
return 0; return 0;
...@@ -1549,7 +1566,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, ...@@ -1549,7 +1566,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
u32 t1, t2; u32 t1, t2;
int sleep_ticks = 0; int sleep_ticks = 0;
pr = processors[smp_processor_id()]; pr = __get_cpu_var(processors);
if (unlikely(!pr)) if (unlikely(!pr))
return 0; return 0;
...@@ -1780,6 +1797,15 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, ...@@ -1780,6 +1797,15 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
return 0; return 0;
if (!first_run) { if (!first_run) {
if (idle_halt) {
/*
* When the boot option of "idle=halt" is added, halt
* is used for CPU IDLE.
* In such case C2/C3 is meaningless. So the max_cstate
* is set to one.
*/
max_cstate = 1;
}
dmi_check_system(processor_power_dmi_table); dmi_check_system(processor_power_dmi_table);
max_cstate = acpi_processor_cstate_check(max_cstate); max_cstate = acpi_processor_cstate_check(max_cstate);
if (max_cstate < ACPI_C_STATES_MAX) if (max_cstate < ACPI_C_STATES_MAX)
......
...@@ -89,7 +89,7 @@ static int acpi_processor_ppc_notifier(struct notifier_block *nb, ...@@ -89,7 +89,7 @@ static int acpi_processor_ppc_notifier(struct notifier_block *nb,
if (event != CPUFREQ_INCOMPATIBLE) if (event != CPUFREQ_INCOMPATIBLE)
goto out; goto out;
pr = processors[policy->cpu]; pr = per_cpu(processors, policy->cpu);
if (!pr || !pr->performance) if (!pr || !pr->performance)
goto out; goto out;
...@@ -572,7 +572,7 @@ int acpi_processor_preregister_performance( ...@@ -572,7 +572,7 @@ int acpi_processor_preregister_performance(
/* Call _PSD for all CPUs */ /* Call _PSD for all CPUs */
for_each_possible_cpu(i) { for_each_possible_cpu(i) {
pr = processors[i]; pr = per_cpu(processors, i);
if (!pr) { if (!pr) {
/* Look only at processors in ACPI namespace */ /* Look only at processors in ACPI namespace */
continue; continue;
...@@ -603,7 +603,7 @@ int acpi_processor_preregister_performance( ...@@ -603,7 +603,7 @@ int acpi_processor_preregister_performance(
* domain info. * domain info.
*/ */
for_each_possible_cpu(i) { for_each_possible_cpu(i) {
pr = processors[i]; pr = per_cpu(processors, i);
if (!pr) if (!pr)
continue; continue;
...@@ -624,7 +624,7 @@ int acpi_processor_preregister_performance( ...@@ -624,7 +624,7 @@ int acpi_processor_preregister_performance(
cpus_clear(covered_cpus); cpus_clear(covered_cpus);
for_each_possible_cpu(i) { for_each_possible_cpu(i) {
pr = processors[i]; pr = per_cpu(processors, i);
if (!pr) if (!pr)
continue; continue;
...@@ -651,7 +651,7 @@ int acpi_processor_preregister_performance( ...@@ -651,7 +651,7 @@ int acpi_processor_preregister_performance(
if (i == j) if (i == j)
continue; continue;
match_pr = processors[j]; match_pr = per_cpu(processors, j);
if (!match_pr) if (!match_pr)
continue; continue;
...@@ -680,7 +680,7 @@ int acpi_processor_preregister_performance( ...@@ -680,7 +680,7 @@ int acpi_processor_preregister_performance(
if (i == j) if (i == j)
continue; continue;
match_pr = processors[j]; match_pr = per_cpu(processors, j);
if (!match_pr) if (!match_pr)
continue; continue;
...@@ -697,7 +697,7 @@ int acpi_processor_preregister_performance( ...@@ -697,7 +697,7 @@ int acpi_processor_preregister_performance(
err_ret: err_ret:
for_each_possible_cpu(i) { for_each_possible_cpu(i) {
pr = processors[i]; pr = per_cpu(processors, i);
if (!pr || !pr->performance) if (!pr || !pr->performance)
continue; continue;
...@@ -728,7 +728,7 @@ acpi_processor_register_performance(struct acpi_processor_performance ...@@ -728,7 +728,7 @@ acpi_processor_register_performance(struct acpi_processor_performance
mutex_lock(&performance_mutex); mutex_lock(&performance_mutex);
pr = processors[cpu]; pr = per_cpu(processors, cpu);
if (!pr) { if (!pr) {
mutex_unlock(&performance_mutex); mutex_unlock(&performance_mutex);
return -ENODEV; return -ENODEV;
...@@ -766,7 +766,7 @@ acpi_processor_unregister_performance(struct acpi_processor_performance ...@@ -766,7 +766,7 @@ acpi_processor_unregister_performance(struct acpi_processor_performance
mutex_lock(&performance_mutex); mutex_lock(&performance_mutex);
pr = processors[cpu]; pr = per_cpu(processors, cpu);
if (!pr) { if (!pr) {
mutex_unlock(&performance_mutex); mutex_unlock(&performance_mutex);
return; return;
......
...@@ -71,7 +71,7 @@ static int acpi_processor_update_tsd_coord(void) ...@@ -71,7 +71,7 @@ static int acpi_processor_update_tsd_coord(void)
* coordination between all CPUs. * coordination between all CPUs.
*/ */
for_each_possible_cpu(i) { for_each_possible_cpu(i) {
pr = processors[i]; pr = per_cpu(processors, i);
if (!pr) if (!pr)
continue; continue;
...@@ -93,7 +93,7 @@ static int acpi_processor_update_tsd_coord(void) ...@@ -93,7 +93,7 @@ static int acpi_processor_update_tsd_coord(void)
cpus_clear(covered_cpus); cpus_clear(covered_cpus);
for_each_possible_cpu(i) { for_each_possible_cpu(i) {
pr = processors[i]; pr = per_cpu(processors, i);
if (!pr) if (!pr)
continue; continue;
...@@ -119,7 +119,7 @@ static int acpi_processor_update_tsd_coord(void) ...@@ -119,7 +119,7 @@ static int acpi_processor_update_tsd_coord(void)
if (i == j) if (i == j)
continue; continue;
match_pr = processors[j]; match_pr = per_cpu(processors, j);
if (!match_pr) if (!match_pr)
continue; continue;
...@@ -152,7 +152,7 @@ static int acpi_processor_update_tsd_coord(void) ...@@ -152,7 +152,7 @@ static int acpi_processor_update_tsd_coord(void)
if (i == j) if (i == j)
continue; continue;
match_pr = processors[j]; match_pr = per_cpu(processors, j);
if (!match_pr) if (!match_pr)
continue; continue;
...@@ -172,7 +172,7 @@ static int acpi_processor_update_tsd_coord(void) ...@@ -172,7 +172,7 @@ static int acpi_processor_update_tsd_coord(void)
err_ret: err_ret:
for_each_possible_cpu(i) { for_each_possible_cpu(i) {
pr = processors[i]; pr = per_cpu(processors, i);
if (!pr) if (!pr)
continue; continue;
...@@ -214,7 +214,7 @@ static int acpi_processor_throttling_notifier(unsigned long event, void *data) ...@@ -214,7 +214,7 @@ static int acpi_processor_throttling_notifier(unsigned long event, void *data)
struct acpi_processor_throttling *p_throttling; struct acpi_processor_throttling *p_throttling;
cpu = p_tstate->cpu; cpu = p_tstate->cpu;
pr = processors[cpu]; pr = per_cpu(processors, cpu);
if (!pr) { if (!pr) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid pr pointer\n")); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid pr pointer\n"));
return 0; return 0;
...@@ -1035,7 +1035,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state) ...@@ -1035,7 +1035,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
* cpus. * cpus.
*/ */
for_each_cpu_mask(i, online_throttling_cpus) { for_each_cpu_mask(i, online_throttling_cpus) {
match_pr = processors[i]; match_pr = per_cpu(processors, i);
/* /*
* If the pointer is invalid, we will report the * If the pointer is invalid, we will report the
* error message and continue. * error message and continue.
...@@ -1232,7 +1232,10 @@ static ssize_t acpi_processor_write_throttling(struct file *file, ...@@ -1232,7 +1232,10 @@ static ssize_t acpi_processor_write_throttling(struct file *file,
int result = 0; int result = 0;
struct seq_file *m = file->private_data; struct seq_file *m = file->private_data;
struct acpi_processor *pr = m->private; struct acpi_processor *pr = m->private;
char state_string[12] = { '\0' }; char state_string[5] = "";
char *charp = NULL;
size_t state_val = 0;
char tmpbuf[5] = "";
if (!pr || (count > sizeof(state_string) - 1)) if (!pr || (count > sizeof(state_string) - 1))
return -EINVAL; return -EINVAL;
...@@ -1241,10 +1244,23 @@ static ssize_t acpi_processor_write_throttling(struct file *file, ...@@ -1241,10 +1244,23 @@ static ssize_t acpi_processor_write_throttling(struct file *file,
return -EFAULT; return -EFAULT;
state_string[count] = '\0'; state_string[count] = '\0';
if ((count > 0) && (state_string[count-1] == '\n'))
state_string[count-1] = '\0';
result = acpi_processor_set_throttling(pr, charp = state_string;
simple_strtoul(state_string, if ((state_string[0] == 't') || (state_string[0] == 'T'))
NULL, 0)); charp++;
state_val = simple_strtoul(charp, NULL, 0);
if (state_val >= pr->throttling.state_count)
return -EINVAL;
snprintf(tmpbuf, 5, "%zu", state_val);
if (strcmp(tmpbuf, charp) != 0)
return -EINVAL;
result = acpi_processor_set_throttling(pr, state_val);
if (result) if (result)
return result; return result;
......
#include <linux/pci.h>
#include <linux/acpi.h>
#include <acpi/reboot.h>
void acpi_reboot(void)
{
struct acpi_generic_address *rr;
struct pci_bus *bus0;
u8 reset_value;
unsigned int devfn;
if (acpi_disabled)
return;
rr = &acpi_gbl_FADT.reset_register;
/* Is the reset register supported? */
if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) ||
rr->bit_width != 8 || rr->bit_offset != 0)
return;
reset_value = acpi_gbl_FADT.reset_value;
/* The reset register can only exist in I/O, Memory or PCI config space
* on a device on bus 0. */
switch (rr->space_id) {
case ACPI_ADR_SPACE_PCI_CONFIG:
/* The reset register can only live on bus 0. */
bus0 = pci_find_bus(0, 0);
if (!bus0)
return;
/* Form PCI device/function pair. */
devfn = PCI_DEVFN((rr->address >> 32) & 0xffff,
(rr->address >> 16) & 0xffff);
printk(KERN_DEBUG "Resetting with ACPI PCI RESET_REG.");
/* Write the value that resets us. */
pci_bus_write_config_byte(bus0, devfn,
(rr->address & 0xffff), reset_value);
break;
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
case ACPI_ADR_SPACE_SYSTEM_IO:
printk(KERN_DEBUG "ACPI MEMORY or I/O RESET_REG.\n");
acpi_hw_low_level_write(8, reset_value, rr);
break;
}
/* Wait ten seconds */
acpi_os_stall(10000000);
}
...@@ -73,7 +73,7 @@ acpi_rs_stream_option_length(u32 resource_length, u32 minimum_total_length); ...@@ -73,7 +73,7 @@ acpi_rs_stream_option_length(u32 resource_length, u32 minimum_total_length);
static u8 acpi_rs_count_set_bits(u16 bit_field) static u8 acpi_rs_count_set_bits(u16 bit_field)
{ {
acpi_native_uint bits_set; u8 bits_set;
ACPI_FUNCTION_ENTRY(); ACPI_FUNCTION_ENTRY();
...@@ -84,7 +84,7 @@ static u8 acpi_rs_count_set_bits(u16 bit_field) ...@@ -84,7 +84,7 @@ static u8 acpi_rs_count_set_bits(u16 bit_field)
bit_field &= (u16) (bit_field - 1); bit_field &= (u16) (bit_field - 1);
} }
return ((u8) bits_set); return bits_set;
} }
/******************************************************************************* /*******************************************************************************
......
...@@ -181,9 +181,9 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, ...@@ -181,9 +181,9 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
} }
/* /*
* Loop through the ACPI_INTERNAL_OBJECTS - Each object * Loop through the ACPI_INTERNAL_OBJECTS - Each object should be a
* should be a package that in turn contains an * package that in turn contains an acpi_integer Address, a u8 Pin,
* acpi_integer Address, a u8 Pin, a Name and a u8 source_index. * a Name, and a u8 source_index.
*/ */
top_object_list = package_object->package.elements; top_object_list = package_object->package.elements;
number_of_elements = package_object->package.count; number_of_elements = package_object->package.count;
...@@ -240,9 +240,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, ...@@ -240,9 +240,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
/* 1) First subobject: Dereference the PRT.Address */ /* 1) First subobject: Dereference the PRT.Address */
obj_desc = sub_object_list[0]; obj_desc = sub_object_list[0];
if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
user_prt->address = obj_desc->integer.value;
} else {
ACPI_ERROR((AE_INFO, ACPI_ERROR((AE_INFO,
"(PRT[%X].Address) Need Integer, found %s", "(PRT[%X].Address) Need Integer, found %s",
index, index,
...@@ -250,12 +248,12 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, ...@@ -250,12 +248,12 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
return_ACPI_STATUS(AE_BAD_DATA); return_ACPI_STATUS(AE_BAD_DATA);
} }
user_prt->address = obj_desc->integer.value;
/* 2) Second subobject: Dereference the PRT.Pin */ /* 2) Second subobject: Dereference the PRT.Pin */
obj_desc = sub_object_list[1]; obj_desc = sub_object_list[1];
if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
user_prt->pin = (u32) obj_desc->integer.value;
} else {
ACPI_ERROR((AE_INFO, ACPI_ERROR((AE_INFO,
"(PRT[%X].Pin) Need Integer, found %s", "(PRT[%X].Pin) Need Integer, found %s",
index, index,
...@@ -284,6 +282,25 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, ...@@ -284,6 +282,25 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
} }
} }
user_prt->pin = (u32) obj_desc->integer.value;
/*
* If the BIOS has erroneously reversed the _PRT source_name (index 2)
* and the source_index (index 3), fix it. _PRT is important enough to
* workaround this BIOS error. This also provides compatibility with
* other ACPI implementations.
*/
obj_desc = sub_object_list[3];
if (!obj_desc
|| (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) {
sub_object_list[3] = sub_object_list[2];
sub_object_list[2] = obj_desc;
ACPI_WARNING((AE_INFO,
"(PRT[%X].Source) SourceName and SourceIndex are reversed, fixed",
index));
}
/* /*
* 3) Third subobject: Dereference the PRT.source_name * 3) Third subobject: Dereference the PRT.source_name
* The name may be unresolved (slack mode), so allow a null object * The name may be unresolved (slack mode), so allow a null object
...@@ -364,9 +381,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, ...@@ -364,9 +381,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
/* 4) Fourth subobject: Dereference the PRT.source_index */ /* 4) Fourth subobject: Dereference the PRT.source_index */
obj_desc = sub_object_list[source_index_index]; obj_desc = sub_object_list[source_index_index];
if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
user_prt->source_index = (u32) obj_desc->integer.value;
} else {
ACPI_ERROR((AE_INFO, ACPI_ERROR((AE_INFO,
"(PRT[%X].SourceIndex) Need Integer, found %s", "(PRT[%X].SourceIndex) Need Integer, found %s",
index, index,
...@@ -374,6 +389,8 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, ...@@ -374,6 +389,8 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
return_ACPI_STATUS(AE_BAD_DATA); return_ACPI_STATUS(AE_BAD_DATA);
} }
user_prt->source_index = (u32) obj_desc->integer.value;
/* Point to the next union acpi_operand_object in the top level package */ /* Point to the next union acpi_operand_object in the top level package */
top_object_list++; top_object_list++;
......
...@@ -82,7 +82,7 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, ...@@ -82,7 +82,7 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
ACPI_FUNCTION_TRACE(rs_convert_aml_to_resource); ACPI_FUNCTION_TRACE(rs_convert_aml_to_resource);
if (((acpi_native_uint) resource) & 0x3) { if (((acpi_size) resource) & 0x3) {
/* Each internal resource struct is expected to be 32-bit aligned */ /* Each internal resource struct is expected to be 32-bit aligned */
......
...@@ -62,7 +62,7 @@ ACPI_MODULE_NAME("rsutils") ...@@ -62,7 +62,7 @@ ACPI_MODULE_NAME("rsutils")
******************************************************************************/ ******************************************************************************/
u8 acpi_rs_decode_bitmask(u16 mask, u8 * list) u8 acpi_rs_decode_bitmask(u16 mask, u8 * list)
{ {
acpi_native_uint i; u8 i;
u8 bit_count; u8 bit_count;
ACPI_FUNCTION_ENTRY(); ACPI_FUNCTION_ENTRY();
...@@ -71,7 +71,7 @@ u8 acpi_rs_decode_bitmask(u16 mask, u8 * list) ...@@ -71,7 +71,7 @@ u8 acpi_rs_decode_bitmask(u16 mask, u8 * list)
for (i = 0, bit_count = 0; mask; i++) { for (i = 0, bit_count = 0; mask; i++) {
if (mask & 0x0001) { if (mask & 0x0001) {
list[bit_count] = (u8) i; list[bit_count] = i;
bit_count++; bit_count++;
} }
...@@ -96,8 +96,8 @@ u8 acpi_rs_decode_bitmask(u16 mask, u8 * list) ...@@ -96,8 +96,8 @@ u8 acpi_rs_decode_bitmask(u16 mask, u8 * list)
u16 acpi_rs_encode_bitmask(u8 * list, u8 count) u16 acpi_rs_encode_bitmask(u8 * list, u8 count)
{ {
acpi_native_uint i; u32 i;
acpi_native_uint mask; u16 mask;
ACPI_FUNCTION_ENTRY(); ACPI_FUNCTION_ENTRY();
...@@ -107,7 +107,7 @@ u16 acpi_rs_encode_bitmask(u8 * list, u8 count) ...@@ -107,7 +107,7 @@ u16 acpi_rs_encode_bitmask(u8 * list, u8 count)
mask |= (0x1 << list[i]); mask |= (0x1 << list[i]);
} }
return ((u16) mask); return mask;
} }
/******************************************************************************* /*******************************************************************************
...@@ -130,7 +130,7 @@ u16 acpi_rs_encode_bitmask(u8 * list, u8 count) ...@@ -130,7 +130,7 @@ u16 acpi_rs_encode_bitmask(u8 * list, u8 count)
void void
acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type) acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type)
{ {
acpi_native_uint i; u32 i;
ACPI_FUNCTION_ENTRY(); ACPI_FUNCTION_ENTRY();
...@@ -679,7 +679,6 @@ acpi_rs_set_srs_method_data(struct acpi_namespace_node *node, ...@@ -679,7 +679,6 @@ acpi_rs_set_srs_method_data(struct acpi_namespace_node *node,
info->prefix_node = node; info->prefix_node = node;
info->pathname = METHOD_NAME__SRS; info->pathname = METHOD_NAME__SRS;
info->parameters = args; info->parameters = args;
info->parameter_type = ACPI_PARAM_ARGS;
info->flags = ACPI_IGNORE_RETURN_VALUE; info->flags = ACPI_IGNORE_RETURN_VALUE;
/* /*
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/signal.h>
#include <linux/kthread.h>
#include <acpi/acpi_drivers.h> #include <acpi/acpi_drivers.h>
#include <acpi/acinterp.h> /* for acpi_ex_eisa_id_to_string() */ #include <acpi/acinterp.h> /* for acpi_ex_eisa_id_to_string() */
...@@ -92,17 +94,37 @@ acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, cha ...@@ -92,17 +94,37 @@ acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, cha
} }
static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL);
static int acpi_eject_operation(acpi_handle handle, int lockable) static int acpi_bus_hot_remove_device(void *context)
{ {
struct acpi_device *device;
acpi_handle handle = context;
struct acpi_object_list arg_list; struct acpi_object_list arg_list;
union acpi_object arg; union acpi_object arg;
acpi_status status = AE_OK; acpi_status status = AE_OK;
/* if (acpi_bus_get_device(handle, &device))
* TBD: evaluate _PS3? return 0;
*/
if (lockable) { if (!device)
return 0;
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Hot-removing device %s...\n", device->dev.bus_id));
if (acpi_bus_trim(device, 1)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Removing device failed\n"));
return -1;
}
/* power off device */
status = acpi_evaluate_object(handle, "_PS3", NULL, NULL);
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
ACPI_DEBUG_PRINT((ACPI_DB_WARN,
"Power-off device failed\n"));
if (device->flags.lockable) {
arg_list.count = 1; arg_list.count = 1;
arg_list.pointer = &arg; arg_list.pointer = &arg;
arg.type = ACPI_TYPE_INTEGER; arg.type = ACPI_TYPE_INTEGER;
...@@ -118,26 +140,22 @@ static int acpi_eject_operation(acpi_handle handle, int lockable) ...@@ -118,26 +140,22 @@ static int acpi_eject_operation(acpi_handle handle, int lockable)
/* /*
* TBD: _EJD support. * TBD: _EJD support.
*/ */
status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL); status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status))
return (-ENODEV); return -ENODEV;
}
return (0); return 0;
} }
static ssize_t static ssize_t
acpi_eject_store(struct device *d, struct device_attribute *attr, acpi_eject_store(struct device *d, struct device_attribute *attr,
const char *buf, size_t count) const char *buf, size_t count)
{ {
int result;
int ret = count; int ret = count;
int islockable;
acpi_status status; acpi_status status;
acpi_handle handle;
acpi_object_type type = 0; acpi_object_type type = 0;
struct acpi_device *acpi_device = to_acpi_device(d); struct acpi_device *acpi_device = to_acpi_device(d);
struct task_struct *task;
if ((!count) || (buf[0] != '1')) { if ((!count) || (buf[0] != '1')) {
return -EINVAL; return -EINVAL;
...@@ -154,18 +172,12 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, ...@@ -154,18 +172,12 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
goto err; goto err;
} }
islockable = acpi_device->flags.lockable; /* remove the device in another thread to fix the deadlock issue */
handle = acpi_device->handle; task = kthread_run(acpi_bus_hot_remove_device,
acpi_device->handle, "acpi_hot_remove_device");
result = acpi_bus_trim(acpi_device, 1); if (IS_ERR(task))
ret = PTR_ERR(task);
if (!result) err:
result = acpi_eject_operation(handle, islockable);
if (result) {
ret = -EBUSY;
}
err:
return ret; return ret;
} }
......
...@@ -61,8 +61,6 @@ static u32 acpi_suspend_states[] = { ...@@ -61,8 +61,6 @@ static u32 acpi_suspend_states[] = {
[PM_SUSPEND_MAX] = ACPI_STATE_S5 [PM_SUSPEND_MAX] = ACPI_STATE_S5
}; };
static int init_8259A_after_S1;
/** /**
* acpi_suspend_begin - Set the target system sleep state to the state * acpi_suspend_begin - Set the target system sleep state to the state
* associated with given @pm_state, if supported. * associated with given @pm_state, if supported.
...@@ -185,13 +183,6 @@ static void acpi_suspend_finish(void) ...@@ -185,13 +183,6 @@ static void acpi_suspend_finish(void)
acpi_set_firmware_waking_vector((acpi_physical_address) 0); acpi_set_firmware_waking_vector((acpi_physical_address) 0);
acpi_target_sleep_state = ACPI_STATE_S0; acpi_target_sleep_state = ACPI_STATE_S0;
#ifdef CONFIG_X86
if (init_8259A_after_S1) {
printk("Broken toshiba laptop -> kicking interrupts\n");
init_8259A(0);
}
#endif
} }
/** /**
...@@ -231,26 +222,6 @@ static struct platform_suspend_ops acpi_suspend_ops = { ...@@ -231,26 +222,6 @@ static struct platform_suspend_ops acpi_suspend_ops = {
.finish = acpi_suspend_finish, .finish = acpi_suspend_finish,
.end = acpi_suspend_end, .end = acpi_suspend_end,
}; };
/*
* Toshiba fails to preserve interrupts over S1, reinitialization
* of 8259 is needed after S1 resume.
*/
static int __init init_ints_after_s1(const struct dmi_system_id *d)
{
printk(KERN_WARNING "%s with broken S1 detected.\n", d->ident);
init_8259A_after_S1 = 1;
return 0;
}
static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
{
.callback = init_ints_after_s1,
.ident = "Toshiba Satellite 4030cdt",
.matches = {DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),},
},
{},
};
#endif /* CONFIG_SUSPEND */ #endif /* CONFIG_SUSPEND */
#ifdef CONFIG_HIBERNATION #ifdef CONFIG_HIBERNATION
...@@ -368,8 +339,8 @@ int acpi_suspend(u32 acpi_state) ...@@ -368,8 +339,8 @@ int acpi_suspend(u32 acpi_state)
/** /**
* acpi_pm_device_sleep_state - return preferred power state of ACPI device * acpi_pm_device_sleep_state - return preferred power state of ACPI device
* in the system sleep state given by %acpi_target_sleep_state * in the system sleep state given by %acpi_target_sleep_state
* @dev: device to examine * @dev: device to examine; its driver model wakeup flags control
* @wake: if set, the device should be able to wake up the system * whether it should be able to wake up the system
* @d_min_p: used to store the upper limit of allowed states range * @d_min_p: used to store the upper limit of allowed states range
* Return value: preferred power state of the device on success, -ENODEV on * Return value: preferred power state of the device on success, -ENODEV on
* failure (ie. if there's no 'struct acpi_device' for @dev) * failure (ie. if there's no 'struct acpi_device' for @dev)
...@@ -387,7 +358,7 @@ int acpi_suspend(u32 acpi_state) ...@@ -387,7 +358,7 @@ int acpi_suspend(u32 acpi_state)
* via @wake. * via @wake.
*/ */
int acpi_pm_device_sleep_state(struct device *dev, int wake, int *d_min_p) int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p)
{ {
acpi_handle handle = DEVICE_ACPI_HANDLE(dev); acpi_handle handle = DEVICE_ACPI_HANDLE(dev);
struct acpi_device *adev; struct acpi_device *adev;
...@@ -426,7 +397,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int wake, int *d_min_p) ...@@ -426,7 +397,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int wake, int *d_min_p)
* can wake the system. _S0W may be valid, too. * can wake the system. _S0W may be valid, too.
*/ */
if (acpi_target_sleep_state == ACPI_STATE_S0 || if (acpi_target_sleep_state == ACPI_STATE_S0 ||
(wake && adev->wakeup.state.enabled && (device_may_wakeup(dev) && adev->wakeup.state.enabled &&
adev->wakeup.sleep_state <= acpi_target_sleep_state)) { adev->wakeup.sleep_state <= acpi_target_sleep_state)) {
acpi_status status; acpi_status status;
...@@ -472,8 +443,6 @@ int __init acpi_sleep_init(void) ...@@ -472,8 +443,6 @@ int __init acpi_sleep_init(void)
u8 type_a, type_b; u8 type_a, type_b;
#ifdef CONFIG_SUSPEND #ifdef CONFIG_SUSPEND
int i = 0; int i = 0;
dmi_check_system(acpisleep_dmi_table);
#endif #endif
if (acpi_disabled) if (acpi_disabled)
......
...@@ -167,7 +167,13 @@ static int acpi_system_sysfs_init(void) ...@@ -167,7 +167,13 @@ static int acpi_system_sysfs_init(void)
#define COUNT_ERROR 2 /* other */ #define COUNT_ERROR 2 /* other */
#define NUM_COUNTERS_EXTRA 3 #define NUM_COUNTERS_EXTRA 3
static u32 *all_counters; #define ACPI_EVENT_VALID 0x01
struct event_counter {
u32 count;
u32 flags;
};
static struct event_counter *all_counters;
static u32 num_gpes; static u32 num_gpes;
static u32 num_counters; static u32 num_counters;
static struct attribute **all_attrs; static struct attribute **all_attrs;
...@@ -202,9 +208,44 @@ static int count_num_gpes(void) ...@@ -202,9 +208,44 @@ static int count_num_gpes(void)
return count; return count;
} }
static int get_gpe_device(int index, acpi_handle *handle)
{
struct acpi_gpe_xrupt_info *gpe_xrupt_info;
struct acpi_gpe_block_info *gpe_block;
acpi_cpu_flags flags;
struct acpi_namespace_node *node;
flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head;
while (gpe_xrupt_info) {
gpe_block = gpe_xrupt_info->gpe_block_list_head;
node = gpe_block->node;
while (gpe_block) {
index -= gpe_block->register_count *
ACPI_GPE_REGISTER_WIDTH;
if (index < 0) {
acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
/* return NULL if it's FADT GPE */
if (node->type != ACPI_TYPE_DEVICE)
*handle = NULL;
else
*handle = node;
return 0;
}
node = gpe_block->node;
gpe_block = gpe_block->next;
}
gpe_xrupt_info = gpe_xrupt_info->next;
}
acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
return -ENODEV;
}
static void delete_gpe_attr_array(void) static void delete_gpe_attr_array(void)
{ {
u32 *tmp = all_counters; struct event_counter *tmp = all_counters;
all_counters = NULL; all_counters = NULL;
kfree(tmp); kfree(tmp);
...@@ -230,9 +271,10 @@ void acpi_os_gpe_count(u32 gpe_number) ...@@ -230,9 +271,10 @@ void acpi_os_gpe_count(u32 gpe_number)
return; return;
if (gpe_number < num_gpes) if (gpe_number < num_gpes)
all_counters[gpe_number]++; all_counters[gpe_number].count++;
else else
all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR]++; all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR].
count++;
return; return;
} }
...@@ -243,44 +285,144 @@ void acpi_os_fixed_event_count(u32 event_number) ...@@ -243,44 +285,144 @@ void acpi_os_fixed_event_count(u32 event_number)
return; return;
if (event_number < ACPI_NUM_FIXED_EVENTS) if (event_number < ACPI_NUM_FIXED_EVENTS)
all_counters[num_gpes + event_number]++; all_counters[num_gpes + event_number].count++;
else else
all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR]++; all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR].
count++;
return; return;
} }
static int get_status(u32 index, acpi_event_status *status, acpi_handle *handle)
{
int result = 0;
if (index >= num_gpes + ACPI_NUM_FIXED_EVENTS)
goto end;
if (index < num_gpes) {
result = get_gpe_device(index, handle);
if (result) {
ACPI_EXCEPTION((AE_INFO, AE_NOT_FOUND,
"Invalid GPE 0x%x\n", index));
goto end;
}
result = acpi_get_gpe_status(*handle, index,
ACPI_NOT_ISR, status);
} else if (index < (num_gpes + ACPI_NUM_FIXED_EVENTS))
result = acpi_get_event_status(index - num_gpes, status);
/*
* sleep/power button GPE/Fixed Event is enabled after acpi_system_init,
* check the status at runtime and mark it as valid once it's enabled
*/
if (!result && (*status & ACPI_EVENT_FLAG_ENABLED))
all_counters[index].flags |= ACPI_EVENT_VALID;
end:
return result;
}
static ssize_t counter_show(struct kobject *kobj, static ssize_t counter_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf) struct kobj_attribute *attr, char *buf)
{ {
all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI] = int index = attr - counter_attrs;
int size;
acpi_handle handle;
acpi_event_status status;
int result = 0;
all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI].count =
acpi_irq_handled; acpi_irq_handled;
all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE] = all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE].count =
acpi_gpe_count; acpi_gpe_count;
return sprintf(buf, "%d\n", all_counters[attr - counter_attrs]); size = sprintf(buf, "%8d", all_counters[index].count);
/* "gpe_all" or "sci" */
if (index >= num_gpes + ACPI_NUM_FIXED_EVENTS)
goto end;
result = get_status(index, &status, &handle);
if (result)
goto end;
if (!(all_counters[index].flags & ACPI_EVENT_VALID))
size += sprintf(buf + size, " invalid");
else if (status & ACPI_EVENT_FLAG_ENABLED)
size += sprintf(buf + size, " enable");
else
size += sprintf(buf + size, " disable");
end:
size += sprintf(buf + size, "\n");
return result ? result : size;
} }
/* /*
* counter_set() sets the specified counter. * counter_set() sets the specified counter.
* setting the total "sci" file to any value clears all counters. * setting the total "sci" file to any value clears all counters.
* enable/disable/clear a gpe/fixed event in user space.
*/ */
static ssize_t counter_set(struct kobject *kobj, static ssize_t counter_set(struct kobject *kobj,
struct kobj_attribute *attr, const char *buf, size_t size) struct kobj_attribute *attr, const char *buf, size_t size)
{ {
int index = attr - counter_attrs; int index = attr - counter_attrs;
acpi_event_status status;
acpi_handle handle;
int result = 0;
if (index == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI) { if (index == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI) {
int i; int i;
for (i = 0; i < num_counters; ++i) for (i = 0; i < num_counters; ++i)
all_counters[i] = 0; all_counters[i].count = 0;
acpi_gpe_count = 0; acpi_gpe_count = 0;
acpi_irq_handled = 0; acpi_irq_handled = 0;
goto end;
}
/* show the event status for both GPEs and Fixed Events */
result = get_status(index, &status, &handle);
if (result)
goto end;
if (!(all_counters[index].flags & ACPI_EVENT_VALID)) {
ACPI_DEBUG_PRINT((ACPI_DB_WARN,
"Can not change Invalid GPE/Fixed Event status\n"));
return -EINVAL;
}
if (index < num_gpes) {
if (!strcmp(buf, "disable\n") &&
(status & ACPI_EVENT_FLAG_ENABLED))
result = acpi_disable_gpe(handle, index, ACPI_NOT_ISR);
else if (!strcmp(buf, "enable\n") &&
!(status & ACPI_EVENT_FLAG_ENABLED))
result = acpi_enable_gpe(handle, index, ACPI_NOT_ISR);
else if (!strcmp(buf, "clear\n") &&
(status & ACPI_EVENT_FLAG_SET))
result = acpi_clear_gpe(handle, index, ACPI_NOT_ISR);
else
all_counters[index].count = strtoul(buf, NULL, 0);
} else if (index < num_gpes + ACPI_NUM_FIXED_EVENTS) {
int event = index - num_gpes;
if (!strcmp(buf, "disable\n") &&
(status & ACPI_EVENT_FLAG_ENABLED))
result = acpi_disable_event(event, ACPI_NOT_ISR);
else if (!strcmp(buf, "enable\n") &&
!(status & ACPI_EVENT_FLAG_ENABLED))
result = acpi_enable_event(event, ACPI_NOT_ISR);
else if (!strcmp(buf, "clear\n") &&
(status & ACPI_EVENT_FLAG_SET))
result = acpi_clear_event(event);
else
all_counters[index].count = strtoul(buf, NULL, 0);
} else } else
all_counters[index] = strtoul(buf, NULL, 0); all_counters[index].count = strtoul(buf, NULL, 0);
return size; if (ACPI_FAILURE(result))
result = -EINVAL;
end:
return result ? result : size;
} }
void acpi_irq_stats_init(void) void acpi_irq_stats_init(void)
...@@ -298,7 +440,8 @@ void acpi_irq_stats_init(void) ...@@ -298,7 +440,8 @@ void acpi_irq_stats_init(void)
if (all_attrs == NULL) if (all_attrs == NULL)
return; return;
all_counters = kzalloc(sizeof(u32) * (num_counters), GFP_KERNEL); all_counters = kzalloc(sizeof(struct event_counter) * (num_counters),
GFP_KERNEL);
if (all_counters == NULL) if (all_counters == NULL)
goto fail; goto fail;
......
...@@ -124,7 +124,7 @@ static struct acpi_fadt_info fadt_info_table[] = { ...@@ -124,7 +124,7 @@ static struct acpi_fadt_info fadt_info_table[] = {
static void inline static void inline
acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
u8 bit_width, u64 address) u8 byte_width, u64 address)
{ {
/* /*
...@@ -136,7 +136,7 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, ...@@ -136,7 +136,7 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
/* All other fields are byte-wide */ /* All other fields are byte-wide */
generic_address->space_id = ACPI_ADR_SPACE_SYSTEM_IO; generic_address->space_id = ACPI_ADR_SPACE_SYSTEM_IO;
generic_address->bit_width = bit_width; generic_address->bit_width = byte_width << 3;
generic_address->bit_offset = 0; generic_address->bit_offset = 0;
generic_address->access_width = 0; generic_address->access_width = 0;
} }
...@@ -155,7 +155,7 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, ...@@ -155,7 +155,7 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
* *
******************************************************************************/ ******************************************************************************/
void acpi_tb_parse_fadt(acpi_native_uint table_index, u8 flags) void acpi_tb_parse_fadt(u32 table_index, u8 flags)
{ {
u32 length; u32 length;
struct acpi_table_header *table; struct acpi_table_header *table;
...@@ -280,7 +280,7 @@ static void acpi_tb_convert_fadt(void) ...@@ -280,7 +280,7 @@ static void acpi_tb_convert_fadt(void)
{ {
u8 pm1_register_length; u8 pm1_register_length;
struct acpi_generic_address *target; struct acpi_generic_address *target;
acpi_native_uint i; u32 i;
/* Update the local FADT table header length */ /* Update the local FADT table header length */
...@@ -343,9 +343,11 @@ static void acpi_tb_convert_fadt(void) ...@@ -343,9 +343,11 @@ static void acpi_tb_convert_fadt(void)
* *
* The PM event blocks are split into two register blocks, first is the * The PM event blocks are split into two register blocks, first is the
* PM Status Register block, followed immediately by the PM Enable Register * PM Status Register block, followed immediately by the PM Enable Register
* block. Each is of length (pm1_event_length/2) * block. Each is of length (xpm1x_event_block.bit_width/2)
*/ */
pm1_register_length = (u8) ACPI_DIV_2(acpi_gbl_FADT.pm1_event_length); WARN_ON(ACPI_MOD_16(acpi_gbl_FADT.xpm1a_event_block.bit_width));
pm1_register_length = (u8) ACPI_DIV_16(acpi_gbl_FADT
.xpm1a_event_block.bit_width);
/* The PM1A register block is required */ /* The PM1A register block is required */
...@@ -360,14 +362,17 @@ static void acpi_tb_convert_fadt(void) ...@@ -360,14 +362,17 @@ static void acpi_tb_convert_fadt(void)
/* The PM1B register block is optional, ignore if not present */ /* The PM1B register block is optional, ignore if not present */
if (acpi_gbl_FADT.xpm1b_event_block.address) { if (acpi_gbl_FADT.xpm1b_event_block.address) {
WARN_ON(ACPI_MOD_16(acpi_gbl_FADT.xpm1b_event_block.bit_width));
pm1_register_length = (u8) ACPI_DIV_16(acpi_gbl_FADT
.xpm1b_event_block
.bit_width);
acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable, acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable,
pm1_register_length, pm1_register_length,
(acpi_gbl_FADT.xpm1b_event_block. (acpi_gbl_FADT.xpm1b_event_block.
address + pm1_register_length)); address + pm1_register_length));
/* Don't forget to copy space_id of the GAS */ /* Don't forget to copy space_id of the GAS */
acpi_gbl_xpm1b_enable.space_id = acpi_gbl_xpm1b_enable.space_id =
acpi_gbl_FADT.xpm1a_event_block.space_id; acpi_gbl_FADT.xpm1b_event_block.space_id;
} }
} }
...@@ -396,7 +401,7 @@ static void acpi_tb_validate_fadt(void) ...@@ -396,7 +401,7 @@ static void acpi_tb_validate_fadt(void)
u32 *address32; u32 *address32;
struct acpi_generic_address *address64; struct acpi_generic_address *address64;
u8 length; u8 length;
acpi_native_uint i; u32 i;
/* Examine all of the 64-bit extended address fields (X fields) */ /* Examine all of the 64-bit extended address fields (X fields) */
......
...@@ -65,10 +65,9 @@ ACPI_MODULE_NAME("tbfind") ...@@ -65,10 +65,9 @@ ACPI_MODULE_NAME("tbfind")
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status
acpi_tb_find_table(char *signature, acpi_tb_find_table(char *signature,
char *oem_id, char *oem_id, char *oem_table_id, u32 *table_index)
char *oem_table_id, acpi_native_uint * table_index)
{ {
acpi_native_uint i; u32 i;
acpi_status status; acpi_status status;
struct acpi_table_header header; struct acpi_table_header header;
......
...@@ -107,11 +107,10 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) ...@@ -107,11 +107,10 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc)
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status
acpi_tb_add_table(struct acpi_table_desc *table_desc, acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
acpi_native_uint * table_index)
{ {
acpi_native_uint i; u32 i;
acpi_native_uint length; u32 length;
acpi_status status = AE_OK; acpi_status status = AE_OK;
ACPI_FUNCTION_TRACE(tb_add_table); ACPI_FUNCTION_TRACE(tb_add_table);
...@@ -207,8 +206,8 @@ acpi_status acpi_tb_resize_root_table_list(void) ...@@ -207,8 +206,8 @@ acpi_status acpi_tb_resize_root_table_list(void)
/* Increase the Table Array size */ /* Increase the Table Array size */
tables = ACPI_ALLOCATE_ZEROED((acpi_gbl_root_table_list.size + tables = ACPI_ALLOCATE_ZEROED(((acpi_size) acpi_gbl_root_table_list.
ACPI_ROOT_TABLE_SIZE_INCREMENT) size + ACPI_ROOT_TABLE_SIZE_INCREMENT)
* sizeof(struct acpi_table_desc)); * sizeof(struct acpi_table_desc));
if (!tables) { if (!tables) {
ACPI_ERROR((AE_INFO, ACPI_ERROR((AE_INFO,
...@@ -220,7 +219,7 @@ acpi_status acpi_tb_resize_root_table_list(void) ...@@ -220,7 +219,7 @@ acpi_status acpi_tb_resize_root_table_list(void)
if (acpi_gbl_root_table_list.tables) { if (acpi_gbl_root_table_list.tables) {
ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables,
acpi_gbl_root_table_list.size * (acpi_size) acpi_gbl_root_table_list.size *
sizeof(struct acpi_table_desc)); sizeof(struct acpi_table_desc));
if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
...@@ -253,7 +252,7 @@ acpi_status acpi_tb_resize_root_table_list(void) ...@@ -253,7 +252,7 @@ acpi_status acpi_tb_resize_root_table_list(void)
acpi_status acpi_status
acpi_tb_store_table(acpi_physical_address address, acpi_tb_store_table(acpi_physical_address address,
struct acpi_table_header *table, struct acpi_table_header *table,
u32 length, u8 flags, acpi_native_uint * table_index) u32 length, u8 flags, u32 *table_index)
{ {
acpi_status status = AE_OK; acpi_status status = AE_OK;
...@@ -334,7 +333,7 @@ void acpi_tb_delete_table(struct acpi_table_desc *table_desc) ...@@ -334,7 +333,7 @@ void acpi_tb_delete_table(struct acpi_table_desc *table_desc)
void acpi_tb_terminate(void) void acpi_tb_terminate(void)
{ {
acpi_native_uint i; u32 i;
ACPI_FUNCTION_TRACE(tb_terminate); ACPI_FUNCTION_TRACE(tb_terminate);
...@@ -374,7 +373,7 @@ void acpi_tb_terminate(void) ...@@ -374,7 +373,7 @@ void acpi_tb_terminate(void)
* *
******************************************************************************/ ******************************************************************************/
void acpi_tb_delete_namespace_by_owner(acpi_native_uint table_index) void acpi_tb_delete_namespace_by_owner(u32 table_index)
{ {
acpi_owner_id owner_id; acpi_owner_id owner_id;
...@@ -403,7 +402,7 @@ void acpi_tb_delete_namespace_by_owner(acpi_native_uint table_index) ...@@ -403,7 +402,7 @@ void acpi_tb_delete_namespace_by_owner(acpi_native_uint table_index)
* *
******************************************************************************/ ******************************************************************************/
acpi_status acpi_tb_allocate_owner_id(acpi_native_uint table_index) acpi_status acpi_tb_allocate_owner_id(u32 table_index)
{ {
acpi_status status = AE_BAD_PARAMETER; acpi_status status = AE_BAD_PARAMETER;
...@@ -431,7 +430,7 @@ acpi_status acpi_tb_allocate_owner_id(acpi_native_uint table_index) ...@@ -431,7 +430,7 @@ acpi_status acpi_tb_allocate_owner_id(acpi_native_uint table_index)
* *
******************************************************************************/ ******************************************************************************/
acpi_status acpi_tb_release_owner_id(acpi_native_uint table_index) acpi_status acpi_tb_release_owner_id(u32 table_index)
{ {
acpi_status status = AE_BAD_PARAMETER; acpi_status status = AE_BAD_PARAMETER;
...@@ -462,8 +461,7 @@ acpi_status acpi_tb_release_owner_id(acpi_native_uint table_index) ...@@ -462,8 +461,7 @@ acpi_status acpi_tb_release_owner_id(acpi_native_uint table_index)
* *
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id)
acpi_tb_get_owner_id(acpi_native_uint table_index, acpi_owner_id * owner_id)
{ {
acpi_status status = AE_BAD_PARAMETER; acpi_status status = AE_BAD_PARAMETER;
...@@ -490,7 +488,7 @@ acpi_tb_get_owner_id(acpi_native_uint table_index, acpi_owner_id * owner_id) ...@@ -490,7 +488,7 @@ acpi_tb_get_owner_id(acpi_native_uint table_index, acpi_owner_id * owner_id)
* *
******************************************************************************/ ******************************************************************************/
u8 acpi_tb_is_table_loaded(acpi_native_uint table_index) u8 acpi_tb_is_table_loaded(u32 table_index)
{ {
u8 is_loaded = FALSE; u8 is_loaded = FALSE;
...@@ -518,7 +516,7 @@ u8 acpi_tb_is_table_loaded(acpi_native_uint table_index) ...@@ -518,7 +516,7 @@ u8 acpi_tb_is_table_loaded(acpi_native_uint table_index)
* *
******************************************************************************/ ******************************************************************************/
void acpi_tb_set_table_loaded_flag(acpi_native_uint table_index, u8 is_loaded) void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded)
{ {
(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
......
...@@ -49,8 +49,8 @@ ACPI_MODULE_NAME("tbutils") ...@@ -49,8 +49,8 @@ ACPI_MODULE_NAME("tbutils")
/* Local prototypes */ /* Local prototypes */
static acpi_physical_address static acpi_physical_address
acpi_tb_get_root_table_entry(u8 * table_entry, acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size);
acpi_native_uint table_entry_size);
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_tb_check_xsdt * FUNCTION: acpi_tb_check_xsdt
...@@ -238,7 +238,7 @@ acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length) ...@@ -238,7 +238,7 @@ acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length)
* *
******************************************************************************/ ******************************************************************************/
u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length) u8 acpi_tb_checksum(u8 *buffer, u32 length)
{ {
u8 sum = 0; u8 sum = 0;
u8 *end = buffer + length; u8 *end = buffer + length;
...@@ -268,7 +268,7 @@ u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length) ...@@ -268,7 +268,7 @@ u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length)
void void
acpi_tb_install_table(acpi_physical_address address, acpi_tb_install_table(acpi_physical_address address,
u8 flags, char *signature, acpi_native_uint table_index) u8 flags, char *signature, u32 table_index)
{ {
struct acpi_table_header *table; struct acpi_table_header *table;
...@@ -336,8 +336,7 @@ acpi_tb_install_table(acpi_physical_address address, ...@@ -336,8 +336,7 @@ acpi_tb_install_table(acpi_physical_address address,
******************************************************************************/ ******************************************************************************/
static acpi_physical_address static acpi_physical_address
acpi_tb_get_root_table_entry(u8 * table_entry, acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size)
acpi_native_uint table_entry_size)
{ {
u64 address64; u64 address64;
...@@ -395,8 +394,8 @@ acpi_status __init ...@@ -395,8 +394,8 @@ acpi_status __init
acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
{ {
struct acpi_table_rsdp *rsdp; struct acpi_table_rsdp *rsdp;
acpi_native_uint table_entry_size; u32 table_entry_size;
acpi_native_uint i; u32 i;
u32 table_count; u32 table_count;
struct acpi_table_header *table; struct acpi_table_header *table;
acpi_physical_address address; acpi_physical_address address;
......
...@@ -125,7 +125,7 @@ acpi_initialize_tables(struct acpi_table_desc * initial_table_array, ...@@ -125,7 +125,7 @@ acpi_initialize_tables(struct acpi_table_desc * initial_table_array,
/* Root Table Array has been statically allocated by the host */ /* Root Table Array has been statically allocated by the host */
ACPI_MEMSET(initial_table_array, 0, ACPI_MEMSET(initial_table_array, 0,
initial_table_count * (acpi_size) initial_table_count *
sizeof(struct acpi_table_desc)); sizeof(struct acpi_table_desc));
acpi_gbl_root_table_list.tables = initial_table_array; acpi_gbl_root_table_list.tables = initial_table_array;
...@@ -183,9 +183,9 @@ acpi_status acpi_reallocate_root_table(void) ...@@ -183,9 +183,9 @@ acpi_status acpi_reallocate_root_table(void)
return_ACPI_STATUS(AE_SUPPORT); return_ACPI_STATUS(AE_SUPPORT);
} }
new_size = new_size = ((acpi_size) acpi_gbl_root_table_list.count +
(acpi_gbl_root_table_list.count + ACPI_ROOT_TABLE_SIZE_INCREMENT) *
ACPI_ROOT_TABLE_SIZE_INCREMENT) * sizeof(struct acpi_table_desc); sizeof(struct acpi_table_desc);
/* Create new array and copy the old array */ /* Create new array and copy the old array */
...@@ -222,7 +222,7 @@ acpi_status acpi_reallocate_root_table(void) ...@@ -222,7 +222,7 @@ acpi_status acpi_reallocate_root_table(void)
acpi_status acpi_load_table(struct acpi_table_header *table_ptr) acpi_status acpi_load_table(struct acpi_table_header *table_ptr)
{ {
acpi_status status; acpi_status status;
acpi_native_uint table_index; u32 table_index;
struct acpi_table_desc table_desc; struct acpi_table_desc table_desc;
if (!table_ptr) if (!table_ptr)
...@@ -264,11 +264,10 @@ ACPI_EXPORT_SYMBOL(acpi_load_table) ...@@ -264,11 +264,10 @@ ACPI_EXPORT_SYMBOL(acpi_load_table)
*****************************************************************************/ *****************************************************************************/
acpi_status acpi_status
acpi_get_table_header(char *signature, acpi_get_table_header(char *signature,
acpi_native_uint instance, u32 instance, struct acpi_table_header *out_table_header)
struct acpi_table_header * out_table_header)
{ {
acpi_native_uint i; u32 i;
acpi_native_uint j; u32 j;
struct acpi_table_header *header; struct acpi_table_header *header;
/* Parameter validation */ /* Parameter validation */
...@@ -378,10 +377,10 @@ ACPI_EXPORT_SYMBOL(acpi_unload_table_id) ...@@ -378,10 +377,10 @@ ACPI_EXPORT_SYMBOL(acpi_unload_table_id)
*****************************************************************************/ *****************************************************************************/
acpi_status acpi_status
acpi_get_table(char *signature, acpi_get_table(char *signature,
acpi_native_uint instance, struct acpi_table_header **out_table) u32 instance, struct acpi_table_header **out_table)
{ {
acpi_native_uint i; u32 i;
acpi_native_uint j; u32 j;
acpi_status status; acpi_status status;
/* Parameter validation */ /* Parameter validation */
...@@ -435,8 +434,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_table) ...@@ -435,8 +434,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_table)
* *
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status
acpi_get_table_by_index(acpi_native_uint table_index, acpi_get_table_by_index(u32 table_index, struct acpi_table_header **table)
struct acpi_table_header ** table)
{ {
acpi_status status; acpi_status status;
...@@ -493,7 +491,7 @@ static acpi_status acpi_tb_load_namespace(void) ...@@ -493,7 +491,7 @@ static acpi_status acpi_tb_load_namespace(void)
{ {
acpi_status status; acpi_status status;
struct acpi_table_header *table; struct acpi_table_header *table;
acpi_native_uint i; u32 i;
ACPI_FUNCTION_TRACE(tb_load_namespace); ACPI_FUNCTION_TRACE(tb_load_namespace);
......
...@@ -118,7 +118,7 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) ...@@ -118,7 +118,7 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp)
* *
******************************************************************************/ ******************************************************************************/
acpi_status acpi_find_root_pointer(acpi_native_uint * table_address) acpi_status acpi_find_root_pointer(acpi_size *table_address)
{ {
u8 *table_ptr; u8 *table_ptr;
u8 *mem_rover; u8 *mem_rover;
...@@ -153,7 +153,7 @@ acpi_status acpi_find_root_pointer(acpi_native_uint * table_address) ...@@ -153,7 +153,7 @@ acpi_status acpi_find_root_pointer(acpi_native_uint * table_address)
* 1b) Search EBDA paragraphs (EBDA is required to be a * 1b) Search EBDA paragraphs (EBDA is required to be a
* minimum of 1_k length) * minimum of 1_k length)
*/ */
table_ptr = acpi_os_map_memory((acpi_native_uint) table_ptr = acpi_os_map_memory((acpi_physical_address)
physical_address, physical_address,
ACPI_EBDA_WINDOW_SIZE); ACPI_EBDA_WINDOW_SIZE);
if (!table_ptr) { if (!table_ptr) {
......
...@@ -309,7 +309,8 @@ acpi_ut_initialize_buffer(struct acpi_buffer * buffer, ...@@ -309,7 +309,8 @@ acpi_ut_initialize_buffer(struct acpi_buffer * buffer,
* *
******************************************************************************/ ******************************************************************************/
void *acpi_ut_allocate(acpi_size size, u32 component, char *module, u32 line) void *acpi_ut_allocate(acpi_size size,
u32 component, const char *module, u32 line)
{ {
void *allocation; void *allocation;
...@@ -353,7 +354,7 @@ void *acpi_ut_allocate(acpi_size size, u32 component, char *module, u32 line) ...@@ -353,7 +354,7 @@ void *acpi_ut_allocate(acpi_size size, u32 component, char *module, u32 line)
******************************************************************************/ ******************************************************************************/
void *acpi_ut_allocate_zeroed(acpi_size size, void *acpi_ut_allocate_zeroed(acpi_size size,
u32 component, char *module, u32 line) u32 component, const char *module, u32 line)
{ {
void *allocation; void *allocation;
......
...@@ -572,7 +572,7 @@ acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object, ...@@ -572,7 +572,7 @@ acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,
acpi_status status = AE_OK; acpi_status status = AE_OK;
union acpi_operand_object *package_object; union acpi_operand_object *package_object;
union acpi_operand_object **package_elements; union acpi_operand_object **package_elements;
acpi_native_uint i; u32 i;
ACPI_FUNCTION_TRACE(ut_copy_epackage_to_ipackage); ACPI_FUNCTION_TRACE(ut_copy_epackage_to_ipackage);
...@@ -599,7 +599,7 @@ acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object, ...@@ -599,7 +599,7 @@ acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,
/* Truncate package and delete it */ /* Truncate package and delete it */
package_object->package.count = (u32) i; package_object->package.count = i;
package_elements[i] = NULL; package_elements[i] = NULL;
acpi_ut_remove_reference(package_object); acpi_ut_remove_reference(package_object);
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
......
...@@ -157,7 +157,8 @@ void ACPI_INTERNAL_VAR_XFACE ...@@ -157,7 +157,8 @@ void ACPI_INTERNAL_VAR_XFACE
acpi_ut_debug_print(u32 requested_debug_level, acpi_ut_debug_print(u32 requested_debug_level,
u32 line_number, u32 line_number,
const char *function_name, const char *function_name,
char *module_name, u32 component_id, char *format, ...) const char *module_name,
u32 component_id, const char *format, ...)
{ {
acpi_thread_id thread_id; acpi_thread_id thread_id;
va_list args; va_list args;
...@@ -228,7 +229,8 @@ void ACPI_INTERNAL_VAR_XFACE ...@@ -228,7 +229,8 @@ void ACPI_INTERNAL_VAR_XFACE
acpi_ut_debug_print_raw(u32 requested_debug_level, acpi_ut_debug_print_raw(u32 requested_debug_level,
u32 line_number, u32 line_number,
const char *function_name, const char *function_name,
char *module_name, u32 component_id, char *format, ...) const char *module_name,
u32 component_id, const char *format, ...)
{ {
va_list args; va_list args;
...@@ -261,7 +263,8 @@ ACPI_EXPORT_SYMBOL(acpi_ut_debug_print_raw) ...@@ -261,7 +263,8 @@ ACPI_EXPORT_SYMBOL(acpi_ut_debug_print_raw)
******************************************************************************/ ******************************************************************************/
void void
acpi_ut_trace(u32 line_number, acpi_ut_trace(u32 line_number,
const char *function_name, char *module_name, u32 component_id) const char *function_name,
const char *module_name, u32 component_id)
{ {
acpi_gbl_nesting_level++; acpi_gbl_nesting_level++;
...@@ -293,7 +296,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_trace) ...@@ -293,7 +296,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_trace)
void void
acpi_ut_trace_ptr(u32 line_number, acpi_ut_trace_ptr(u32 line_number,
const char *function_name, const char *function_name,
char *module_name, u32 component_id, void *pointer) const char *module_name, u32 component_id, void *pointer)
{ {
acpi_gbl_nesting_level++; acpi_gbl_nesting_level++;
acpi_ut_track_stack_ptr(); acpi_ut_track_stack_ptr();
...@@ -324,7 +327,7 @@ acpi_ut_trace_ptr(u32 line_number, ...@@ -324,7 +327,7 @@ acpi_ut_trace_ptr(u32 line_number,
void void
acpi_ut_trace_str(u32 line_number, acpi_ut_trace_str(u32 line_number,
const char *function_name, const char *function_name,
char *module_name, u32 component_id, char *string) const char *module_name, u32 component_id, char *string)
{ {
acpi_gbl_nesting_level++; acpi_gbl_nesting_level++;
...@@ -356,7 +359,7 @@ acpi_ut_trace_str(u32 line_number, ...@@ -356,7 +359,7 @@ acpi_ut_trace_str(u32 line_number,
void void
acpi_ut_trace_u32(u32 line_number, acpi_ut_trace_u32(u32 line_number,
const char *function_name, const char *function_name,
char *module_name, u32 component_id, u32 integer) const char *module_name, u32 component_id, u32 integer)
{ {
acpi_gbl_nesting_level++; acpi_gbl_nesting_level++;
...@@ -386,7 +389,8 @@ acpi_ut_trace_u32(u32 line_number, ...@@ -386,7 +389,8 @@ acpi_ut_trace_u32(u32 line_number,
void void
acpi_ut_exit(u32 line_number, acpi_ut_exit(u32 line_number,
const char *function_name, char *module_name, u32 component_id) const char *function_name,
const char *module_name, u32 component_id)
{ {
acpi_ut_debug_print(ACPI_LV_FUNCTIONS, acpi_ut_debug_print(ACPI_LV_FUNCTIONS,
...@@ -417,7 +421,8 @@ ACPI_EXPORT_SYMBOL(acpi_ut_exit) ...@@ -417,7 +421,8 @@ ACPI_EXPORT_SYMBOL(acpi_ut_exit)
void void
acpi_ut_status_exit(u32 line_number, acpi_ut_status_exit(u32 line_number,
const char *function_name, const char *function_name,
char *module_name, u32 component_id, acpi_status status) const char *module_name,
u32 component_id, acpi_status status)
{ {
if (ACPI_SUCCESS(status)) { if (ACPI_SUCCESS(status)) {
...@@ -458,7 +463,8 @@ ACPI_EXPORT_SYMBOL(acpi_ut_status_exit) ...@@ -458,7 +463,8 @@ ACPI_EXPORT_SYMBOL(acpi_ut_status_exit)
void void
acpi_ut_value_exit(u32 line_number, acpi_ut_value_exit(u32 line_number,
const char *function_name, const char *function_name,
char *module_name, u32 component_id, acpi_integer value) const char *module_name,
u32 component_id, acpi_integer value)
{ {
acpi_ut_debug_print(ACPI_LV_FUNCTIONS, acpi_ut_debug_print(ACPI_LV_FUNCTIONS,
...@@ -490,7 +496,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_value_exit) ...@@ -490,7 +496,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_value_exit)
void void
acpi_ut_ptr_exit(u32 line_number, acpi_ut_ptr_exit(u32 line_number,
const char *function_name, const char *function_name,
char *module_name, u32 component_id, u8 * ptr) const char *module_name, u32 component_id, u8 *ptr)
{ {
acpi_ut_debug_print(ACPI_LV_FUNCTIONS, acpi_ut_debug_print(ACPI_LV_FUNCTIONS,
...@@ -519,8 +525,8 @@ acpi_ut_ptr_exit(u32 line_number, ...@@ -519,8 +525,8 @@ acpi_ut_ptr_exit(u32 line_number,
void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display) void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display)
{ {
acpi_native_uint i = 0; u32 i = 0;
acpi_native_uint j; u32 j;
u32 temp32; u32 temp32;
u8 buf_char; u8 buf_char;
...@@ -539,7 +545,7 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display) ...@@ -539,7 +545,7 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display)
/* Print current offset */ /* Print current offset */
acpi_os_printf("%6.4X: ", (u32) i); acpi_os_printf("%6.4X: ", i);
/* Print 16 hex chars */ /* Print 16 hex chars */
...@@ -549,7 +555,7 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display) ...@@ -549,7 +555,7 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display)
/* Dump fill spaces */ /* Dump fill spaces */
acpi_os_printf("%*s", ((display * 2) + 1), " "); acpi_os_printf("%*s", ((display * 2) + 1), " ");
j += (acpi_native_uint) display; j += display;
continue; continue;
} }
...@@ -557,32 +563,38 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display) ...@@ -557,32 +563,38 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display)
case DB_BYTE_DISPLAY: case DB_BYTE_DISPLAY:
default: /* Default is BYTE display */ default: /* Default is BYTE display */
acpi_os_printf("%02X ", buffer[i + j]); acpi_os_printf("%02X ",
buffer[(acpi_size) i + j]);
break; break;
case DB_WORD_DISPLAY: case DB_WORD_DISPLAY:
ACPI_MOVE_16_TO_32(&temp32, &buffer[i + j]); ACPI_MOVE_16_TO_32(&temp32,
&buffer[(acpi_size) i + j]);
acpi_os_printf("%04X ", temp32); acpi_os_printf("%04X ", temp32);
break; break;
case DB_DWORD_DISPLAY: case DB_DWORD_DISPLAY:
ACPI_MOVE_32_TO_32(&temp32, &buffer[i + j]); ACPI_MOVE_32_TO_32(&temp32,
&buffer[(acpi_size) i + j]);
acpi_os_printf("%08X ", temp32); acpi_os_printf("%08X ", temp32);
break; break;
case DB_QWORD_DISPLAY: case DB_QWORD_DISPLAY:
ACPI_MOVE_32_TO_32(&temp32, &buffer[i + j]); ACPI_MOVE_32_TO_32(&temp32,
&buffer[(acpi_size) i + j]);
acpi_os_printf("%08X", temp32); acpi_os_printf("%08X", temp32);
ACPI_MOVE_32_TO_32(&temp32, &buffer[i + j + 4]); ACPI_MOVE_32_TO_32(&temp32,
&buffer[(acpi_size) i + j +
4]);
acpi_os_printf("%08X ", temp32); acpi_os_printf("%08X ", temp32);
break; break;
} }
j += (acpi_native_uint) display; j += display;
} }
/* /*
...@@ -596,7 +608,7 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display) ...@@ -596,7 +608,7 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display)
return; return;
} }
buf_char = buffer[i + j]; buf_char = buffer[(acpi_size) i + j];
if (ACPI_IS_PRINT(buf_char)) { if (ACPI_IS_PRINT(buf_char)) {
acpi_os_printf("%c", buf_char); acpi_os_printf("%c", buf_char);
} else { } else {
......
...@@ -442,7 +442,7 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action) ...@@ -442,7 +442,7 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
union acpi_generic_state *state_list = NULL; union acpi_generic_state *state_list = NULL;
union acpi_operand_object *next_object = NULL; union acpi_operand_object *next_object = NULL;
union acpi_generic_state *state; union acpi_generic_state *state;
acpi_native_uint i; u32 i;
ACPI_FUNCTION_TRACE_PTR(ut_update_object_reference, object); ACPI_FUNCTION_TRACE_PTR(ut_update_object_reference, object);
......
...@@ -97,7 +97,7 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) ...@@ -97,7 +97,7 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
acpi_status status; acpi_status status;
union acpi_operand_object *string_desc; union acpi_operand_object *string_desc;
union acpi_operand_object *return_desc; union acpi_operand_object *return_desc;
acpi_native_uint i; u32 i;
ACPI_FUNCTION_TRACE(ut_osi_implementation); ACPI_FUNCTION_TRACE(ut_osi_implementation);
...@@ -217,7 +217,6 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, ...@@ -217,7 +217,6 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
info->prefix_node = prefix_node; info->prefix_node = prefix_node;
info->pathname = path; info->pathname = path;
info->parameter_type = ACPI_PARAM_ARGS;
/* Evaluate the object/method */ /* Evaluate the object/method */
...@@ -514,7 +513,7 @@ acpi_ut_execute_CID(struct acpi_namespace_node * device_node, ...@@ -514,7 +513,7 @@ acpi_ut_execute_CID(struct acpi_namespace_node * device_node,
u32 count; u32 count;
u32 size; u32 size;
struct acpi_compatible_id_list *cid_list; struct acpi_compatible_id_list *cid_list;
acpi_native_uint i; u32 i;
ACPI_FUNCTION_TRACE(ut_execute_CID); ACPI_FUNCTION_TRACE(ut_execute_CID);
......
...@@ -64,7 +64,7 @@ ACPI_MODULE_NAME("utmisc") ...@@ -64,7 +64,7 @@ ACPI_MODULE_NAME("utmisc")
******************************************************************************/ ******************************************************************************/
const char *acpi_ut_validate_exception(acpi_status status) const char *acpi_ut_validate_exception(acpi_status status)
{ {
acpi_status sub_status; u32 sub_status;
const char *exception = NULL; const char *exception = NULL;
ACPI_FUNCTION_ENTRY(); ACPI_FUNCTION_ENTRY();
...@@ -85,32 +85,28 @@ const char *acpi_ut_validate_exception(acpi_status status) ...@@ -85,32 +85,28 @@ const char *acpi_ut_validate_exception(acpi_status status)
case AE_CODE_PROGRAMMER: case AE_CODE_PROGRAMMER:
if (sub_status <= AE_CODE_PGM_MAX) { if (sub_status <= AE_CODE_PGM_MAX) {
exception = exception = acpi_gbl_exception_names_pgm[sub_status];
acpi_gbl_exception_names_pgm[sub_status - 1];
} }
break; break;
case AE_CODE_ACPI_TABLES: case AE_CODE_ACPI_TABLES:
if (sub_status <= AE_CODE_TBL_MAX) { if (sub_status <= AE_CODE_TBL_MAX) {
exception = exception = acpi_gbl_exception_names_tbl[sub_status];
acpi_gbl_exception_names_tbl[sub_status - 1];
} }
break; break;
case AE_CODE_AML: case AE_CODE_AML:
if (sub_status <= AE_CODE_AML_MAX) { if (sub_status <= AE_CODE_AML_MAX) {
exception = exception = acpi_gbl_exception_names_aml[sub_status];
acpi_gbl_exception_names_aml[sub_status - 1];
} }
break; break;
case AE_CODE_CONTROL: case AE_CODE_CONTROL:
if (sub_status <= AE_CODE_CTRL_MAX) { if (sub_status <= AE_CODE_CTRL_MAX) {
exception = exception = acpi_gbl_exception_names_ctrl[sub_status];
acpi_gbl_exception_names_ctrl[sub_status - 1];
} }
break; break;
...@@ -165,9 +161,9 @@ u8 acpi_ut_is_aml_table(struct acpi_table_header *table) ...@@ -165,9 +161,9 @@ u8 acpi_ut_is_aml_table(struct acpi_table_header *table)
acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id)
{ {
acpi_native_uint i; u32 i;
acpi_native_uint j; u32 j;
acpi_native_uint k; u32 k;
acpi_status status; acpi_status status;
ACPI_FUNCTION_TRACE(ut_allocate_owner_id); ACPI_FUNCTION_TRACE(ut_allocate_owner_id);
...@@ -273,7 +269,7 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr) ...@@ -273,7 +269,7 @@ void acpi_ut_release_owner_id(acpi_owner_id * owner_id_ptr)
{ {
acpi_owner_id owner_id = *owner_id_ptr; acpi_owner_id owner_id = *owner_id_ptr;
acpi_status status; acpi_status status;
acpi_native_uint index; u32 index;
u32 bit; u32 bit;
ACPI_FUNCTION_TRACE_U32(ut_release_owner_id, owner_id); ACPI_FUNCTION_TRACE_U32(ut_release_owner_id, owner_id);
...@@ -593,7 +589,7 @@ acpi_ut_display_init_pathname(u8 type, ...@@ -593,7 +589,7 @@ acpi_ut_display_init_pathname(u8 type,
* *
******************************************************************************/ ******************************************************************************/
u8 acpi_ut_valid_acpi_char(char character, acpi_native_uint position) u8 acpi_ut_valid_acpi_char(char character, u32 position)
{ {
if (!((character >= 'A' && character <= 'Z') || if (!((character >= 'A' && character <= 'Z') ||
...@@ -628,7 +624,7 @@ u8 acpi_ut_valid_acpi_char(char character, acpi_native_uint position) ...@@ -628,7 +624,7 @@ u8 acpi_ut_valid_acpi_char(char character, acpi_native_uint position)
u8 acpi_ut_valid_acpi_name(u32 name) u8 acpi_ut_valid_acpi_name(u32 name)
{ {
acpi_native_uint i; u32 i;
ACPI_FUNCTION_ENTRY(); ACPI_FUNCTION_ENTRY();
...@@ -657,7 +653,7 @@ u8 acpi_ut_valid_acpi_name(u32 name) ...@@ -657,7 +653,7 @@ u8 acpi_ut_valid_acpi_name(u32 name)
acpi_name acpi_ut_repair_name(char *name) acpi_name acpi_ut_repair_name(char *name)
{ {
acpi_native_uint i; u32 i;
char new_name[ACPI_NAME_SIZE]; char new_name[ACPI_NAME_SIZE];
for (i = 0; i < ACPI_NAME_SIZE; i++) { for (i = 0; i < ACPI_NAME_SIZE; i++) {
...@@ -1024,7 +1020,7 @@ acpi_ut_walk_package_tree(union acpi_operand_object * source_object, ...@@ -1024,7 +1020,7 @@ acpi_ut_walk_package_tree(union acpi_operand_object * source_object,
******************************************************************************/ ******************************************************************************/
void ACPI_INTERNAL_VAR_XFACE void ACPI_INTERNAL_VAR_XFACE
acpi_ut_error(char *module_name, u32 line_number, char *format, ...) acpi_ut_error(const char *module_name, u32 line_number, const char *format, ...)
{ {
va_list args; va_list args;
...@@ -1037,8 +1033,8 @@ acpi_ut_error(char *module_name, u32 line_number, char *format, ...) ...@@ -1037,8 +1033,8 @@ acpi_ut_error(char *module_name, u32 line_number, char *format, ...)
} }
void ACPI_INTERNAL_VAR_XFACE void ACPI_INTERNAL_VAR_XFACE
acpi_ut_exception(char *module_name, acpi_ut_exception(const char *module_name,
u32 line_number, acpi_status status, char *format, ...) u32 line_number, acpi_status status, const char *format, ...)
{ {
va_list args; va_list args;
...@@ -1054,7 +1050,8 @@ acpi_ut_exception(char *module_name, ...@@ -1054,7 +1050,8 @@ acpi_ut_exception(char *module_name,
EXPORT_SYMBOL(acpi_ut_exception); EXPORT_SYMBOL(acpi_ut_exception);
void ACPI_INTERNAL_VAR_XFACE void ACPI_INTERNAL_VAR_XFACE
acpi_ut_warning(char *module_name, u32 line_number, char *format, ...) acpi_ut_warning(const char *module_name,
u32 line_number, const char *format, ...)
{ {
va_list args; va_list args;
...@@ -1067,7 +1064,7 @@ acpi_ut_warning(char *module_name, u32 line_number, char *format, ...) ...@@ -1067,7 +1064,7 @@ acpi_ut_warning(char *module_name, u32 line_number, char *format, ...)
} }
void ACPI_INTERNAL_VAR_XFACE void ACPI_INTERNAL_VAR_XFACE
acpi_ut_info(char *module_name, u32 line_number, char *format, ...) acpi_ut_info(const char *module_name, u32 line_number, const char *format, ...)
{ {
va_list args; va_list args;
......
...@@ -218,7 +218,7 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) ...@@ -218,7 +218,7 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
* the mutex ordering rule. This indicates a coding error somewhere in * the mutex ordering rule. This indicates a coding error somewhere in
* the ACPI subsystem code. * the ACPI subsystem code.
*/ */
for (i = mutex_id; i < ACPI_MAX_MUTEX; i++) { for (i = mutex_id; i < ACPI_NUM_MUTEX; i++) {
if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) { if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) {
if (i == mutex_id) { if (i == mutex_id) {
ACPI_ERROR((AE_INFO, ACPI_ERROR((AE_INFO,
...@@ -315,7 +315,7 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) ...@@ -315,7 +315,7 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id)
* ordering rule. This indicates a coding error somewhere in * ordering rule. This indicates a coding error somewhere in
* the ACPI subsystem code. * the ACPI subsystem code.
*/ */
for (i = mutex_id; i < ACPI_MAX_MUTEX; i++) { for (i = mutex_id; i < ACPI_NUM_MUTEX; i++) {
if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) { if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) {
if (i == mutex_id) { if (i == mutex_id) {
continue; continue;
......
...@@ -83,7 +83,8 @@ acpi_ut_get_element_length(u8 object_type, ...@@ -83,7 +83,8 @@ acpi_ut_get_element_length(u8 object_type,
* *
******************************************************************************/ ******************************************************************************/
union acpi_operand_object *acpi_ut_create_internal_object_dbg(char *module_name, union acpi_operand_object *acpi_ut_create_internal_object_dbg(const char
*module_name,
u32 line_number, u32 line_number,
u32 component_id, u32 component_id,
acpi_object_type acpi_object_type
...@@ -175,8 +176,8 @@ union acpi_operand_object *acpi_ut_create_package_object(u32 count) ...@@ -175,8 +176,8 @@ union acpi_operand_object *acpi_ut_create_package_object(u32 count)
* Create the element array. Count+1 allows the array to be null * Create the element array. Count+1 allows the array to be null
* terminated. * terminated.
*/ */
package_elements = ACPI_ALLOCATE_ZEROED((acpi_size) package_elements = ACPI_ALLOCATE_ZEROED(((acpi_size) count +
(count + 1) * sizeof(void *)); 1) * sizeof(void *));
if (!package_elements) { if (!package_elements) {
acpi_ut_remove_reference(package_desc); acpi_ut_remove_reference(package_desc);
return_PTR(NULL); return_PTR(NULL);
...@@ -347,7 +348,7 @@ u8 acpi_ut_valid_internal_object(void *object) ...@@ -347,7 +348,7 @@ u8 acpi_ut_valid_internal_object(void *object)
* *
******************************************************************************/ ******************************************************************************/
void *acpi_ut_allocate_object_desc_dbg(char *module_name, void *acpi_ut_allocate_object_desc_dbg(const char *module_name,
u32 line_number, u32 component_id) u32 line_number, u32 component_id)
{ {
union acpi_operand_object *object; union acpi_operand_object *object;
......
...@@ -631,6 +631,76 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) ...@@ -631,6 +631,76 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag)
* device : video output device (LCD, CRT, ..) * device : video output device (LCD, CRT, ..)
* *
* Return Value: * Return Value:
* Maximum brightness level
*
* Allocate and initialize device->brightness.
*/
static int
acpi_video_init_brightness(struct acpi_video_device *device)
{
union acpi_object *obj = NULL;
int i, max_level = 0, count = 0;
union acpi_object *o;
struct acpi_video_device_brightness *br = NULL;
if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available "
"LCD brightness level\n"));
goto out;
}
if (obj->package.count < 2)
goto out;
br = kzalloc(sizeof(*br), GFP_KERNEL);
if (!br) {
printk(KERN_ERR "can't allocate memory\n");
goto out;
}
br->levels = kmalloc(obj->package.count * sizeof *(br->levels),
GFP_KERNEL);
if (!br->levels)
goto out_free;
for (i = 0; i < obj->package.count; i++) {
o = (union acpi_object *)&obj->package.elements[i];
if (o->type != ACPI_TYPE_INTEGER) {
printk(KERN_ERR PREFIX "Invalid data\n");
continue;
}
br->levels[count] = (u32) o->integer.value;
if (br->levels[count] > max_level)
max_level = br->levels[count];
count++;
}
if (count < 2)
goto out_free_levels;
br->count = count;
device->brightness = br;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count));
kfree(obj);
return max_level;
out_free_levels:
kfree(br->levels);
out_free:
kfree(br);
out:
device->brightness = NULL;
kfree(obj);
return 0;
}
/*
* Arg:
* device : video output device (LCD, CRT, ..)
*
* Return Value:
* None * None
* *
* Find out all required AML methods defined under the output * Find out all required AML methods defined under the output
...@@ -640,10 +710,7 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) ...@@ -640,10 +710,7 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag)
static void acpi_video_device_find_cap(struct acpi_video_device *device) static void acpi_video_device_find_cap(struct acpi_video_device *device)
{ {
acpi_handle h_dummy1; acpi_handle h_dummy1;
int i;
u32 max_level = 0; u32 max_level = 0;
union acpi_object *obj = NULL;
struct acpi_video_device_brightness *br = NULL;
memset(&device->cap, 0, sizeof(device->cap)); memset(&device->cap, 0, sizeof(device->cap));
...@@ -672,53 +739,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) ...@@ -672,53 +739,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
device->cap._DSS = 1; device->cap._DSS = 1;
} }
if (ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) { max_level = acpi_video_init_brightness(device);
if (obj->package.count >= 2) {
int count = 0;
union acpi_object *o;
br = kzalloc(sizeof(*br), GFP_KERNEL);
if (!br) {
printk(KERN_ERR "can't allocate memory\n");
} else {
br->levels = kmalloc(obj->package.count *
sizeof *(br->levels), GFP_KERNEL);
if (!br->levels)
goto out;
for (i = 0; i < obj->package.count; i++) {
o = (union acpi_object *)&obj->package.
elements[i];
if (o->type != ACPI_TYPE_INTEGER) {
printk(KERN_ERR PREFIX "Invalid data\n");
continue;
}
br->levels[count] = (u32) o->integer.value;
if (br->levels[count] > max_level)
max_level = br->levels[count];
count++;
}
out:
if (count < 2) {
kfree(br->levels);
kfree(br);
} else {
br->count = count;
device->brightness = br;
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"found %d brightness levels\n",
count));
}
}
}
} else {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available LCD brightness level\n"));
}
kfree(obj);
if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){ if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){
int result; int result;
...@@ -1695,6 +1716,8 @@ static void ...@@ -1695,6 +1716,8 @@ static void
acpi_video_switch_brightness(struct acpi_video_device *device, int event) acpi_video_switch_brightness(struct acpi_video_device *device, int event)
{ {
unsigned long level_current, level_next; unsigned long level_current, level_next;
if (!device->brightness)
return;
acpi_video_device_lcd_get_level_current(device, &level_current); acpi_video_device_lcd_get_level_current(device, &level_current);
level_next = acpi_video_get_next_level(device, level_current, event); level_next = acpi_video_get_next_level(device, level_current, event);
acpi_video_device_lcd_set_level(device, level_next); acpi_video_device_lcd_set_level(device, level_next);
......
...@@ -58,6 +58,55 @@ struct apm_queue { ...@@ -58,6 +58,55 @@ struct apm_queue {
apm_event_t events[APM_MAX_EVENTS]; apm_event_t events[APM_MAX_EVENTS];
}; };
/*
* thread states (for threads using a writable /dev/apm_bios fd):
*
* SUSPEND_NONE: nothing happening
* SUSPEND_PENDING: suspend event queued for thread and pending to be read
* SUSPEND_READ: suspend event read, pending acknowledgement
* SUSPEND_ACKED: acknowledgement received from thread (via ioctl),
* waiting for resume
* SUSPEND_ACKTO: acknowledgement timeout
* SUSPEND_DONE: thread had acked suspend and is now notified of
* resume
*
* SUSPEND_WAIT: this thread invoked suspend and is waiting for resume
*
* A thread migrates in one of three paths:
* NONE -1-> PENDING -2-> READ -3-> ACKED -4-> DONE -5-> NONE
* -6-> ACKTO -7-> NONE
* NONE -8-> WAIT -9-> NONE
*
* While in PENDING or READ, the thread is accounted for in the
* suspend_acks_pending counter.
*
* The transitions are invoked as follows:
* 1: suspend event is signalled from the core PM code
* 2: the suspend event is read from the fd by the userspace thread
* 3: userspace thread issues the APM_IOC_SUSPEND ioctl (as ack)
* 4: core PM code signals that we have resumed
* 5: APM_IOC_SUSPEND ioctl returns
*
* 6: the notifier invoked from the core PM code timed out waiting
* for all relevant threds to enter ACKED state and puts those
* that haven't into ACKTO
* 7: those threads issue APM_IOC_SUSPEND ioctl too late,
* get an error
*
* 8: userspace thread issues the APM_IOC_SUSPEND ioctl (to suspend),
* ioctl code invokes pm_suspend()
* 9: pm_suspend() returns indicating resume
*/
enum apm_suspend_state {
SUSPEND_NONE,
SUSPEND_PENDING,
SUSPEND_READ,
SUSPEND_ACKED,
SUSPEND_ACKTO,
SUSPEND_WAIT,
SUSPEND_DONE,
};
/* /*
* The per-file APM data * The per-file APM data
*/ */
...@@ -69,13 +118,7 @@ struct apm_user { ...@@ -69,13 +118,7 @@ struct apm_user {
unsigned int reader: 1; unsigned int reader: 1;
int suspend_result; int suspend_result;
unsigned int suspend_state; enum apm_suspend_state suspend_state;
#define SUSPEND_NONE 0 /* no suspend pending */
#define SUSPEND_PENDING 1 /* suspend pending read */
#define SUSPEND_READ 2 /* suspend read, pending ack */
#define SUSPEND_ACKED 3 /* suspend acked */
#define SUSPEND_WAIT 4 /* waiting for suspend */
#define SUSPEND_DONE 5 /* suspend completed */
struct apm_queue queue; struct apm_queue queue;
}; };
...@@ -83,7 +126,8 @@ struct apm_user { ...@@ -83,7 +126,8 @@ struct apm_user {
/* /*
* Local variables * Local variables
*/ */
static int suspends_pending; static atomic_t suspend_acks_pending = ATOMIC_INIT(0);
static atomic_t userspace_notification_inhibit = ATOMIC_INIT(0);
static int apm_disabled; static int apm_disabled;
static struct task_struct *kapmd_tsk; static struct task_struct *kapmd_tsk;
...@@ -166,78 +210,6 @@ static void queue_event(apm_event_t event) ...@@ -166,78 +210,6 @@ static void queue_event(apm_event_t event)
wake_up_interruptible(&apm_waitqueue); wake_up_interruptible(&apm_waitqueue);
} }
/*
* queue_suspend_event - queue an APM suspend event.
*
* Check that we're in a state where we can suspend. If not,
* return -EBUSY. Otherwise, queue an event to all "writer"
* users. If there are no "writer" users, return '1' to
* indicate that we can immediately suspend.
*/
static int queue_suspend_event(apm_event_t event, struct apm_user *sender)
{
struct apm_user *as;
int ret = 1;
mutex_lock(&state_lock);
down_read(&user_list_lock);
/*
* If a thread is still processing, we can't suspend, so reject
* the request.
*/
list_for_each_entry(as, &apm_user_list, list) {
if (as != sender && as->reader && as->writer && as->suser &&
as->suspend_state != SUSPEND_NONE) {
ret = -EBUSY;
goto out;
}
}
list_for_each_entry(as, &apm_user_list, list) {
if (as != sender && as->reader && as->writer && as->suser) {
as->suspend_state = SUSPEND_PENDING;
suspends_pending++;
queue_add_event(&as->queue, event);
ret = 0;
}
}
out:
up_read(&user_list_lock);
mutex_unlock(&state_lock);
wake_up_interruptible(&apm_waitqueue);
return ret;
}
static void apm_suspend(void)
{
struct apm_user *as;
int err = pm_suspend(PM_SUSPEND_MEM);
/*
* Anyone on the APM queues will think we're still suspended.
* Send a message so everyone knows we're now awake again.
*/
queue_event(APM_NORMAL_RESUME);
/*
* Finally, wake up anyone who is sleeping on the suspend.
*/
mutex_lock(&state_lock);
down_read(&user_list_lock);
list_for_each_entry(as, &apm_user_list, list) {
if (as->suspend_state == SUSPEND_WAIT ||
as->suspend_state == SUSPEND_ACKED) {
as->suspend_result = err;
as->suspend_state = SUSPEND_DONE;
}
}
up_read(&user_list_lock);
mutex_unlock(&state_lock);
wake_up(&apm_suspend_waitqueue);
}
static ssize_t apm_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos) static ssize_t apm_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos)
{ {
struct apm_user *as = fp->private_data; struct apm_user *as = fp->private_data;
...@@ -308,25 +280,22 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) ...@@ -308,25 +280,22 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg)
as->suspend_result = -EINTR; as->suspend_result = -EINTR;
if (as->suspend_state == SUSPEND_READ) { switch (as->suspend_state) {
int pending; case SUSPEND_READ:
/* /*
* If we read a suspend command from /dev/apm_bios, * If we read a suspend command from /dev/apm_bios,
* then the corresponding APM_IOC_SUSPEND ioctl is * then the corresponding APM_IOC_SUSPEND ioctl is
* interpreted as an acknowledge. * interpreted as an acknowledge.
*/ */
as->suspend_state = SUSPEND_ACKED; as->suspend_state = SUSPEND_ACKED;
suspends_pending--; atomic_dec(&suspend_acks_pending);
pending = suspends_pending == 0;
mutex_unlock(&state_lock); mutex_unlock(&state_lock);
/* /*
* If there are no further acknowledges required, * suspend_acks_pending changed, the notifier needs to
* suspend the system. * be woken up for this
*/ */
if (pending) wake_up(&apm_suspend_waitqueue);
apm_suspend();
/* /*
* Wait for the suspend/resume to complete. If there * Wait for the suspend/resume to complete. If there
...@@ -342,35 +311,21 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) ...@@ -342,35 +311,21 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg)
* try_to_freeze() in freezer_count() will not trigger * try_to_freeze() in freezer_count() will not trigger
*/ */
freezer_count(); freezer_count();
} else { break;
case SUSPEND_ACKTO:
as->suspend_result = -ETIMEDOUT;
mutex_unlock(&state_lock);
break;
default:
as->suspend_state = SUSPEND_WAIT; as->suspend_state = SUSPEND_WAIT;
mutex_unlock(&state_lock); mutex_unlock(&state_lock);
/* /*
* Otherwise it is a request to suspend the system. * Otherwise it is a request to suspend the system.
* Queue an event for all readers, and expect an * Just invoke pm_suspend(), we'll handle it from
* acknowledge from all writers who haven't already * there via the notifier.
* acknowledged.
*/
err = queue_suspend_event(APM_USER_SUSPEND, as);
if (err < 0) {
/*
* Avoid taking the lock here - this
* should be fine.
*/
as->suspend_state = SUSPEND_NONE;
break;
}
if (err > 0)
apm_suspend();
/*
* Wait for the suspend/resume to complete. If there
* are pending acknowledges, we wait here for them.
*/ */
wait_event_freezable(apm_suspend_waitqueue, as->suspend_result = pm_suspend(PM_SUSPEND_MEM);
as->suspend_state == SUSPEND_DONE);
} }
mutex_lock(&state_lock); mutex_lock(&state_lock);
...@@ -386,7 +341,6 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) ...@@ -386,7 +341,6 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg)
static int apm_release(struct inode * inode, struct file * filp) static int apm_release(struct inode * inode, struct file * filp)
{ {
struct apm_user *as = filp->private_data; struct apm_user *as = filp->private_data;
int pending = 0;
filp->private_data = NULL; filp->private_data = NULL;
...@@ -396,18 +350,15 @@ static int apm_release(struct inode * inode, struct file * filp) ...@@ -396,18 +350,15 @@ static int apm_release(struct inode * inode, struct file * filp)
/* /*
* We are now unhooked from the chain. As far as new * We are now unhooked from the chain. As far as new
* events are concerned, we no longer exist. However, we * events are concerned, we no longer exist.
* need to balance suspends_pending, which means the
* possibility of sleeping.
*/ */
mutex_lock(&state_lock); mutex_lock(&state_lock);
if (as->suspend_state != SUSPEND_NONE) { if (as->suspend_state == SUSPEND_PENDING ||
suspends_pending -= 1; as->suspend_state == SUSPEND_READ)
pending = suspends_pending == 0; atomic_dec(&suspend_acks_pending);
}
mutex_unlock(&state_lock); mutex_unlock(&state_lock);
if (pending)
apm_suspend(); wake_up(&apm_suspend_waitqueue);
kfree(as); kfree(as);
return 0; return 0;
...@@ -545,7 +496,6 @@ static int kapmd(void *arg) ...@@ -545,7 +496,6 @@ static int kapmd(void *arg)
{ {
do { do {
apm_event_t event; apm_event_t event;
int ret;
wait_event_interruptible(kapmd_wait, wait_event_interruptible(kapmd_wait,
!queue_empty(&kapmd_queue) || kthread_should_stop()); !queue_empty(&kapmd_queue) || kthread_should_stop());
...@@ -570,20 +520,13 @@ static int kapmd(void *arg) ...@@ -570,20 +520,13 @@ static int kapmd(void *arg)
case APM_USER_SUSPEND: case APM_USER_SUSPEND:
case APM_SYS_SUSPEND: case APM_SYS_SUSPEND:
ret = queue_suspend_event(event, NULL); pm_suspend(PM_SUSPEND_MEM);
if (ret < 0) {
/*
* We were busy. Try again in 50ms.
*/
queue_add_event(&kapmd_queue, event);
msleep(50);
}
if (ret > 0)
apm_suspend();
break; break;
case APM_CRITICAL_SUSPEND: case APM_CRITICAL_SUSPEND:
apm_suspend(); atomic_inc(&userspace_notification_inhibit);
pm_suspend(PM_SUSPEND_MEM);
atomic_dec(&userspace_notification_inhibit);
break; break;
} }
} while (1); } while (1);
...@@ -591,6 +534,120 @@ static int kapmd(void *arg) ...@@ -591,6 +534,120 @@ static int kapmd(void *arg)
return 0; return 0;
} }
static int apm_suspend_notifier(struct notifier_block *nb,
unsigned long event,
void *dummy)
{
struct apm_user *as;
int err;
/* short-cut emergency suspends */
if (atomic_read(&userspace_notification_inhibit))
return NOTIFY_DONE;
switch (event) {
case PM_SUSPEND_PREPARE:
/*
* Queue an event to all "writer" users that we want
* to suspend and need their ack.
*/
mutex_lock(&state_lock);
down_read(&user_list_lock);
list_for_each_entry(as, &apm_user_list, list) {
if (as->suspend_state != SUSPEND_WAIT && as->reader &&
as->writer && as->suser) {
as->suspend_state = SUSPEND_PENDING;
atomic_inc(&suspend_acks_pending);
queue_add_event(&as->queue, APM_USER_SUSPEND);
}
}
up_read(&user_list_lock);
mutex_unlock(&state_lock);
wake_up_interruptible(&apm_waitqueue);
/*
* Wait for the the suspend_acks_pending variable to drop to
* zero, meaning everybody acked the suspend event (or the
* process was killed.)
*
* If the app won't answer within a short while we assume it
* locked up and ignore it.
*/
err = wait_event_interruptible_timeout(
apm_suspend_waitqueue,
atomic_read(&suspend_acks_pending) == 0,
5*HZ);
/* timed out */
if (err == 0) {
/*
* Move anybody who timed out to "ack timeout" state.
*
* We could time out and the userspace does the ACK
* right after we time out but before we enter the
* locked section here, but that's fine.
*/
mutex_lock(&state_lock);
down_read(&user_list_lock);
list_for_each_entry(as, &apm_user_list, list) {
if (as->suspend_state == SUSPEND_PENDING ||
as->suspend_state == SUSPEND_READ) {
as->suspend_state = SUSPEND_ACKTO;
atomic_dec(&suspend_acks_pending);
}
}
up_read(&user_list_lock);
mutex_unlock(&state_lock);
}
/* let suspend proceed */
if (err >= 0)
return NOTIFY_OK;
/* interrupted by signal */
return NOTIFY_BAD;
case PM_POST_SUSPEND:
/*
* Anyone on the APM queues will think we're still suspended.
* Send a message so everyone knows we're now awake again.
*/
queue_event(APM_NORMAL_RESUME);
/*
* Finally, wake up anyone who is sleeping on the suspend.
*/
mutex_lock(&state_lock);
down_read(&user_list_lock);
list_for_each_entry(as, &apm_user_list, list) {
if (as->suspend_state == SUSPEND_ACKED) {
/*
* TODO: maybe grab error code, needs core
* changes to push the error to the notifier
* chain (could use the second parameter if
* implemented)
*/
as->suspend_result = 0;
as->suspend_state = SUSPEND_DONE;
}
}
up_read(&user_list_lock);
mutex_unlock(&state_lock);
wake_up(&apm_suspend_waitqueue);
return NOTIFY_OK;
default:
return NOTIFY_DONE;
}
}
static struct notifier_block apm_notif_block = {
.notifier_call = apm_suspend_notifier,
};
static int __init apm_init(void) static int __init apm_init(void)
{ {
int ret; int ret;
...@@ -604,7 +661,7 @@ static int __init apm_init(void) ...@@ -604,7 +661,7 @@ static int __init apm_init(void)
if (IS_ERR(kapmd_tsk)) { if (IS_ERR(kapmd_tsk)) {
ret = PTR_ERR(kapmd_tsk); ret = PTR_ERR(kapmd_tsk);
kapmd_tsk = NULL; kapmd_tsk = NULL;
return ret; goto out;
} }
wake_up_process(kapmd_tsk); wake_up_process(kapmd_tsk);
...@@ -613,16 +670,27 @@ static int __init apm_init(void) ...@@ -613,16 +670,27 @@ static int __init apm_init(void)
#endif #endif
ret = misc_register(&apm_device); ret = misc_register(&apm_device);
if (ret != 0) { if (ret)
remove_proc_entry("apm", NULL); goto out_stop;
kthread_stop(kapmd_tsk);
}
ret = register_pm_notifier(&apm_notif_block);
if (ret)
goto out_unregister;
return 0;
out_unregister:
misc_deregister(&apm_device);
out_stop:
remove_proc_entry("apm", NULL);
kthread_stop(kapmd_tsk);
out:
return ret; return ret;
} }
static void __exit apm_exit(void) static void __exit apm_exit(void)
{ {
unregister_pm_notifier(&apm_notif_block);
misc_deregister(&apm_device); misc_deregister(&apm_device);
remove_proc_entry("apm", NULL); remove_proc_entry("apm", NULL);
......
...@@ -179,17 +179,29 @@ config FUJITSU_LAPTOP ...@@ -179,17 +179,29 @@ config FUJITSU_LAPTOP
tristate "Fujitsu Laptop Extras" tristate "Fujitsu Laptop Extras"
depends on X86 depends on X86
depends on ACPI depends on ACPI
depends on INPUT
depends on BACKLIGHT_CLASS_DEVICE depends on BACKLIGHT_CLASS_DEVICE
---help--- ---help---
This is a driver for laptops built by Fujitsu: This is a driver for laptops built by Fujitsu:
* P2xxx/P5xxx/S6xxx/S7xxx series Lifebooks * P2xxx/P5xxx/S6xxx/S7xxx series Lifebooks
* Possibly other Fujitsu laptop models * Possibly other Fujitsu laptop models
* Tested with S6410 and S7020
It adds support for LCD brightness control. It adds support for LCD brightness control and some hotkeys.
If you have a Fujitsu laptop, say Y or M here. If you have a Fujitsu laptop, say Y or M here.
config FUJITSU_LAPTOP_DEBUG
bool "Verbose debug mode for Fujitsu Laptop Extras"
depends on FUJITSU_LAPTOP
default n
---help---
Enables extra debug output from the fujitsu extras driver, at the
expense of a slight increase in driver size.
If you are not sure, say N here.
config TC1100_WMI config TC1100_WMI
tristate "HP Compaq TC1100 Tablet WMI Extras (EXPERIMENTAL)" tristate "HP Compaq TC1100 Tablet WMI Extras (EXPERIMENTAL)"
depends on X86 && !X86_64 depends on X86 && !X86_64
...@@ -219,6 +231,23 @@ config MSI_LAPTOP ...@@ -219,6 +231,23 @@ config MSI_LAPTOP
If you have an MSI S270 laptop, say Y or M here. If you have an MSI S270 laptop, say Y or M here.
config COMPAL_LAPTOP
tristate "Compal Laptop Extras"
depends on X86
depends on ACPI_EC
depends on BACKLIGHT_CLASS_DEVICE
---help---
This is a driver for laptops built by Compal:
Compal FL90/IFL90
Compal FL91/IFL91
Compal FL92/JFL92
Compal FT00/IFT00
It adds support for Bluetooth, WLAN and LCD brightness control.
If you have an Compal FL9x/IFL9x/FT00 laptop, say Y or M here.
config SONY_LAPTOP config SONY_LAPTOP
tristate "Sony Laptop Extras" tristate "Sony Laptop Extras"
depends on X86 && ACPI depends on X86 && ACPI
......
...@@ -5,10 +5,11 @@ obj- := misc.o # Dummy rule to force built-in.o to be made ...@@ -5,10 +5,11 @@ obj- := misc.o # Dummy rule to force built-in.o to be made
obj-$(CONFIG_IBM_ASM) += ibmasm/ obj-$(CONFIG_IBM_ASM) += ibmasm/
obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/
obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o
obj-$(CONFIG_ACER_WMI) += acer-wmi.o
obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o
obj-$(CONFIG_EEEPC_LAPTOP) += eeepc-laptop.o obj-$(CONFIG_EEEPC_LAPTOP) += eeepc-laptop.o
obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o
obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o
obj-$(CONFIG_ACER_WMI) += acer-wmi.o
obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o
obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o
obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o
......
...@@ -22,18 +22,18 @@ ...@@ -22,18 +22,18 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#define ACER_WMI_VERSION "0.1"
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/dmi.h> #include <linux/dmi.h>
#include <linux/fb.h>
#include <linux/backlight.h> #include <linux/backlight.h>
#include <linux/leds.h> #include <linux/leds.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/i8042.h> #include <linux/i8042.h>
#include <linux/debugfs.h>
#include <acpi/acpi_drivers.h> #include <acpi/acpi_drivers.h>
...@@ -87,6 +87,7 @@ struct acer_quirks { ...@@ -87,6 +87,7 @@ struct acer_quirks {
* Acer ACPI method GUIDs * Acer ACPI method GUIDs
*/ */
#define AMW0_GUID1 "67C3371D-95A3-4C37-BB61-DD47B491DAAB" #define AMW0_GUID1 "67C3371D-95A3-4C37-BB61-DD47B491DAAB"
#define AMW0_GUID2 "431F16ED-0C2B-444C-B267-27DEB140CF9C"
#define WMID_GUID1 "6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3" #define WMID_GUID1 "6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3"
#define WMID_GUID2 "95764E09-FB56-4e83-B31A-37761F60994A" #define WMID_GUID2 "95764E09-FB56-4e83-B31A-37761F60994A"
...@@ -150,6 +151,12 @@ struct acer_data { ...@@ -150,6 +151,12 @@ struct acer_data {
int brightness; int brightness;
}; };
struct acer_debug {
struct dentry *root;
struct dentry *devices;
u32 wmid_devices;
};
/* Each low-level interface must define at least some of the following */ /* Each low-level interface must define at least some of the following */
struct wmi_interface { struct wmi_interface {
/* The WMI device type */ /* The WMI device type */
...@@ -160,6 +167,9 @@ struct wmi_interface { ...@@ -160,6 +167,9 @@ struct wmi_interface {
/* Private data for the current interface */ /* Private data for the current interface */
struct acer_data data; struct acer_data data;
/* debugfs entries associated with this interface */
struct acer_debug debug;
}; };
/* The static interface pointer, points to the currently detected interface */ /* The static interface pointer, points to the currently detected interface */
...@@ -174,7 +184,7 @@ static struct wmi_interface *interface; ...@@ -174,7 +184,7 @@ static struct wmi_interface *interface;
struct quirk_entry { struct quirk_entry {
u8 wireless; u8 wireless;
u8 mailled; u8 mailled;
u8 brightness; s8 brightness;
u8 bluetooth; u8 bluetooth;
}; };
...@@ -198,6 +208,10 @@ static int dmi_matched(const struct dmi_system_id *dmi) ...@@ -198,6 +208,10 @@ static int dmi_matched(const struct dmi_system_id *dmi)
static struct quirk_entry quirk_unknown = { static struct quirk_entry quirk_unknown = {
}; };
static struct quirk_entry quirk_acer_aspire_1520 = {
.brightness = -1,
};
static struct quirk_entry quirk_acer_travelmate_2490 = { static struct quirk_entry quirk_acer_travelmate_2490 = {
.mailled = 1, .mailled = 1,
}; };
...@@ -207,7 +221,29 @@ static struct quirk_entry quirk_medion_md_98300 = { ...@@ -207,7 +221,29 @@ static struct quirk_entry quirk_medion_md_98300 = {
.wireless = 1, .wireless = 1,
}; };
static struct quirk_entry quirk_fujitsu_amilo_li_1718 = {
.wireless = 2,
};
static struct dmi_system_id acer_quirks[] = { static struct dmi_system_id acer_quirks[] = {
{
.callback = dmi_matched,
.ident = "Acer Aspire 1360",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"),
},
.driver_data = &quirk_acer_aspire_1520,
},
{
.callback = dmi_matched,
.ident = "Acer Aspire 1520",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1520"),
},
.driver_data = &quirk_acer_aspire_1520,
},
{ {
.callback = dmi_matched, .callback = dmi_matched,
.ident = "Acer Aspire 3100", .ident = "Acer Aspire 3100",
...@@ -298,6 +334,15 @@ static struct dmi_system_id acer_quirks[] = { ...@@ -298,6 +334,15 @@ static struct dmi_system_id acer_quirks[] = {
}, },
.driver_data = &quirk_acer_travelmate_2490, .driver_data = &quirk_acer_travelmate_2490,
}, },
{
.callback = dmi_matched,
.ident = "Fujitsu Siemens Amilo Li 1718",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Li 1718"),
},
.driver_data = &quirk_fujitsu_amilo_li_1718,
},
{ {
.callback = dmi_matched, .callback = dmi_matched,
.ident = "Medion MD 98300", .ident = "Medion MD 98300",
...@@ -393,6 +438,12 @@ struct wmi_interface *iface) ...@@ -393,6 +438,12 @@ struct wmi_interface *iface)
return AE_ERROR; return AE_ERROR;
*value = result & 0x1; *value = result & 0x1;
return AE_OK; return AE_OK;
case 2:
err = ec_read(0x71, &result);
if (err)
return AE_ERROR;
*value = result & 0x1;
return AE_OK;
default: default:
err = ec_read(0xA, &result); err = ec_read(0xA, &result);
if (err) if (err)
...@@ -506,6 +557,15 @@ static acpi_status AMW0_set_capabilities(void) ...@@ -506,6 +557,15 @@ static acpi_status AMW0_set_capabilities(void)
struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL }; struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *obj; union acpi_object *obj;
/*
* On laptops with this strange GUID (non Acer), normal probing doesn't
* work.
*/
if (wmi_has_guid(AMW0_GUID2)) {
interface->capability |= ACER_CAP_WIRELESS;
return AE_OK;
}
args.eax = ACER_AMW0_WRITE; args.eax = ACER_AMW0_WRITE;
args.ecx = args.edx = 0; args.ecx = args.edx = 0;
...@@ -552,7 +612,8 @@ static acpi_status AMW0_set_capabilities(void) ...@@ -552,7 +612,8 @@ static acpi_status AMW0_set_capabilities(void)
* appear to use the same EC register for brightness, even if they * appear to use the same EC register for brightness, even if they
* differ for wireless, etc * differ for wireless, etc
*/ */
interface->capability |= ACER_CAP_BRIGHTNESS; if (quirks->brightness >= 0)
interface->capability |= ACER_CAP_BRIGHTNESS;
return AE_OK; return AE_OK;
} }
...@@ -807,7 +868,15 @@ static int read_brightness(struct backlight_device *bd) ...@@ -807,7 +868,15 @@ static int read_brightness(struct backlight_device *bd)
static int update_bl_status(struct backlight_device *bd) static int update_bl_status(struct backlight_device *bd)
{ {
set_u32(bd->props.brightness, ACER_CAP_BRIGHTNESS); int intensity = bd->props.brightness;
if (bd->props.power != FB_BLANK_UNBLANK)
intensity = 0;
if (bd->props.fb_blank != FB_BLANK_UNBLANK)
intensity = 0;
set_u32(intensity, ACER_CAP_BRIGHTNESS);
return 0; return 0;
} }
...@@ -829,8 +898,9 @@ static int __devinit acer_backlight_init(struct device *dev) ...@@ -829,8 +898,9 @@ static int __devinit acer_backlight_init(struct device *dev)
acer_backlight_device = bd; acer_backlight_device = bd;
bd->props.power = FB_BLANK_UNBLANK;
bd->props.brightness = max_brightness;
bd->props.max_brightness = max_brightness; bd->props.max_brightness = max_brightness;
bd->props.brightness = read_brightness(NULL);
backlight_update_status(bd); backlight_update_status(bd);
return 0; return 0;
} }
...@@ -893,6 +963,28 @@ static ssize_t show_interface(struct device *dev, struct device_attribute *attr, ...@@ -893,6 +963,28 @@ static ssize_t show_interface(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR(interface, S_IWUGO | S_IRUGO | S_IWUSR, static DEVICE_ATTR(interface, S_IWUGO | S_IRUGO | S_IWUSR,
show_interface, NULL); show_interface, NULL);
/*
* debugfs functions
*/
static u32 get_wmid_devices(void)
{
struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
union acpi_object *obj;
acpi_status status;
status = wmi_query_block(WMID_GUID2, 1, &out);
if (ACPI_FAILURE(status))
return 0;
obj = (union acpi_object *) out.pointer;
if (obj && obj->type == ACPI_TYPE_BUFFER &&
obj->buffer.length == sizeof(u32)) {
return *((u32 *) obj->buffer.pointer);
} else {
return 0;
}
}
/* /*
* Platform device * Platform device
*/ */
...@@ -1052,12 +1144,40 @@ static int create_sysfs(void) ...@@ -1052,12 +1144,40 @@ static int create_sysfs(void)
return retval; return retval;
} }
static void remove_debugfs(void)
{
debugfs_remove(interface->debug.devices);
debugfs_remove(interface->debug.root);
}
static int create_debugfs(void)
{
interface->debug.root = debugfs_create_dir("acer-wmi", NULL);
if (!interface->debug.root) {
printk(ACER_ERR "Failed to create debugfs directory");
return -ENOMEM;
}
interface->debug.devices = debugfs_create_u32("devices", S_IRUGO,
interface->debug.root,
&interface->debug.wmid_devices);
if (!interface->debug.devices)
goto error_debugfs;
return 0;
error_debugfs:
remove_debugfs();
return -ENOMEM;
}
static int __init acer_wmi_init(void) static int __init acer_wmi_init(void)
{ {
int err; int err;
printk(ACER_INFO "Acer Laptop ACPI-WMI Extras version %s\n", printk(ACER_INFO "Acer Laptop ACPI-WMI Extras\n");
ACER_WMI_VERSION);
find_quirks();
/* /*
* Detect which ACPI-WMI interface we're using. * Detect which ACPI-WMI interface we're using.
...@@ -1092,8 +1212,6 @@ static int __init acer_wmi_init(void) ...@@ -1092,8 +1212,6 @@ static int __init acer_wmi_init(void)
if (wmi_has_guid(AMW0_GUID1)) if (wmi_has_guid(AMW0_GUID1))
AMW0_find_mailled(); AMW0_find_mailled();
find_quirks();
if (!interface) { if (!interface) {
printk(ACER_ERR "No or unsupported WMI interface, unable to " printk(ACER_ERR "No or unsupported WMI interface, unable to "
"load\n"); "load\n");
...@@ -1111,6 +1229,13 @@ static int __init acer_wmi_init(void) ...@@ -1111,6 +1229,13 @@ static int __init acer_wmi_init(void)
if (err) if (err)
return err; return err;
if (wmi_has_guid(WMID_GUID2)) {
interface->debug.wmid_devices = get_wmid_devices();
err = create_debugfs();
if (err)
return err;
}
/* Override any initial settings with values from the commandline */ /* Override any initial settings with values from the commandline */
acer_commandline_init(); acer_commandline_init();
......
/*-*-linux-c-*-*/
/*
Copyright (C) 2008 Cezary Jackiewicz <cezary.jackiewicz (at) gmail.com>
based on MSI driver
Copyright (C) 2006 Lennart Poettering <mzxreary (at) 0pointer (dot) de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
/*
* comapl-laptop.c - Compal laptop support.
*
* This driver exports a few files in /sys/devices/platform/compal-laptop/:
*
* wlan - wlan subsystem state: contains 0 or 1 (rw)
*
* bluetooth - Bluetooth subsystem state: contains 0 or 1 (rw)
*
* raw - raw value taken from embedded controller register (ro)
*
* In addition to these platform device attributes the driver
* registers itself in the Linux backlight control subsystem and is
* available to userspace under /sys/class/backlight/compal-laptop/.
*
* This driver might work on other laptops produced by Compal. If you
* want to try it you can pass force=1 as argument to the module which
* will force it to load even when the DMI data doesn't identify the
* laptop as FL9x.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/acpi.h>
#include <linux/dmi.h>
#include <linux/backlight.h>
#include <linux/platform_device.h>
#include <linux/autoconf.h>
#define COMPAL_DRIVER_VERSION "0.2.6"
#define COMPAL_LCD_LEVEL_MAX 8
#define COMPAL_EC_COMMAND_WIRELESS 0xBB
#define COMPAL_EC_COMMAND_LCD_LEVEL 0xB9
#define KILLSWITCH_MASK 0x10
#define WLAN_MASK 0x01
#define BT_MASK 0x02
static int force;
module_param(force, bool, 0);
MODULE_PARM_DESC(force, "Force driver load, ignore DMI data");
/* Hardware access */
static int set_lcd_level(int level)
{
if (level < 0 || level >= COMPAL_LCD_LEVEL_MAX)
return -EINVAL;
ec_write(COMPAL_EC_COMMAND_LCD_LEVEL, level);
return 0;
}
static int get_lcd_level(void)
{
u8 result;
ec_read(COMPAL_EC_COMMAND_LCD_LEVEL, &result);
return (int) result;
}
static int set_wlan_state(int state)
{
u8 result, value;
ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
if ((result & KILLSWITCH_MASK) == 0)
return -EINVAL;
else {
if (state)
value = (u8) (result | WLAN_MASK);
else
value = (u8) (result & ~WLAN_MASK);
ec_write(COMPAL_EC_COMMAND_WIRELESS, value);
}
return 0;
}
static int set_bluetooth_state(int state)
{
u8 result, value;
ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
if ((result & KILLSWITCH_MASK) == 0)
return -EINVAL;
else {
if (state)
value = (u8) (result | BT_MASK);
else
value = (u8) (result & ~BT_MASK);
ec_write(COMPAL_EC_COMMAND_WIRELESS, value);
}
return 0;
}
static int get_wireless_state(int *wlan, int *bluetooth)
{
u8 result;
ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
if (wlan) {
if ((result & KILLSWITCH_MASK) == 0)
*wlan = 0;
else
*wlan = result & WLAN_MASK;
}
if (bluetooth) {
if ((result & KILLSWITCH_MASK) == 0)
*bluetooth = 0;
else
*bluetooth = (result & BT_MASK) >> 1;
}
return 0;
}
/* Backlight device stuff */
static int bl_get_brightness(struct backlight_device *b)
{
return get_lcd_level();
}
static int bl_update_status(struct backlight_device *b)
{
return set_lcd_level(b->props.brightness);
}
static struct backlight_ops compalbl_ops = {
.get_brightness = bl_get_brightness,
.update_status = bl_update_status,
};
static struct backlight_device *compalbl_device;
/* Platform device */
static ssize_t show_wlan(struct device *dev,
struct device_attribute *attr, char *buf)
{
int ret, enabled;
ret = get_wireless_state(&enabled, NULL);
if (ret < 0)
return ret;
return sprintf(buf, "%i\n", enabled);
}
static ssize_t show_raw(struct device *dev,
struct device_attribute *attr, char *buf)
{
u8 result;
ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
return sprintf(buf, "%i\n", result);
}
static ssize_t show_bluetooth(struct device *dev,
struct device_attribute *attr, char *buf)
{
int ret, enabled;
ret = get_wireless_state(NULL, &enabled);
if (ret < 0)
return ret;
return sprintf(buf, "%i\n", enabled);
}
static ssize_t store_wlan_state(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int state, ret;
if (sscanf(buf, "%i", &state) != 1 || (state < 0 || state > 1))
return -EINVAL;
ret = set_wlan_state(state);
if (ret < 0)
return ret;
return count;
}
static ssize_t store_bluetooth_state(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int state, ret;
if (sscanf(buf, "%i", &state) != 1 || (state < 0 || state > 1))
return -EINVAL;
ret = set_bluetooth_state(state);
if (ret < 0)
return ret;
return count;
}
static DEVICE_ATTR(bluetooth, 0644, show_bluetooth, store_bluetooth_state);
static DEVICE_ATTR(wlan, 0644, show_wlan, store_wlan_state);
static DEVICE_ATTR(raw, 0444, show_raw, NULL);
static struct attribute *compal_attributes[] = {
&dev_attr_bluetooth.attr,
&dev_attr_wlan.attr,
&dev_attr_raw.attr,
NULL
};
static struct attribute_group compal_attribute_group = {
.attrs = compal_attributes
};
static struct platform_driver compal_driver = {
.driver = {
.name = "compal-laptop",
.owner = THIS_MODULE,
}
};
static struct platform_device *compal_device;
/* Initialization */
static int dmi_check_cb(const struct dmi_system_id *id)
{
printk(KERN_INFO "compal-laptop: Identified laptop model '%s'.\n",
id->ident);
return 0;
}
static struct dmi_system_id __initdata compal_dmi_table[] = {
{
.ident = "FL90/IFL90",
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "IFL90"),
DMI_MATCH(DMI_BOARD_VERSION, "IFT00"),
},
.callback = dmi_check_cb
},
{
.ident = "FL90/IFL90",
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "IFL90"),
DMI_MATCH(DMI_BOARD_VERSION, "REFERENCE"),
},
.callback = dmi_check_cb
},
{
.ident = "FL91/IFL91",
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "IFL91"),
DMI_MATCH(DMI_BOARD_VERSION, "IFT00"),
},
.callback = dmi_check_cb
},
{
.ident = "FL92/JFL92",
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "JFL92"),
DMI_MATCH(DMI_BOARD_VERSION, "IFT00"),
},
.callback = dmi_check_cb
},
{
.ident = "FT00/IFT00",
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "IFT00"),
DMI_MATCH(DMI_BOARD_VERSION, "IFT00"),
},
.callback = dmi_check_cb
},
{ }
};
static int __init compal_init(void)
{
int ret;
if (acpi_disabled)
return -ENODEV;
if (!force && !dmi_check_system(compal_dmi_table))
return -ENODEV;
/* Register backlight stuff */
compalbl_device = backlight_device_register("compal-laptop", NULL, NULL,
&compalbl_ops);
if (IS_ERR(compalbl_device))
return PTR_ERR(compalbl_device);
compalbl_device->props.max_brightness = COMPAL_LCD_LEVEL_MAX-1;
ret = platform_driver_register(&compal_driver);
if (ret)
goto fail_backlight;
/* Register platform stuff */
compal_device = platform_device_alloc("compal-laptop", -1);
if (!compal_device) {
ret = -ENOMEM;
goto fail_platform_driver;
}
ret = platform_device_add(compal_device);
if (ret)
goto fail_platform_device1;
ret = sysfs_create_group(&compal_device->dev.kobj,
&compal_attribute_group);
if (ret)
goto fail_platform_device2;
printk(KERN_INFO "compal-laptop: driver "COMPAL_DRIVER_VERSION
" successfully loaded.\n");
return 0;
fail_platform_device2:
platform_device_del(compal_device);
fail_platform_device1:
platform_device_put(compal_device);
fail_platform_driver:
platform_driver_unregister(&compal_driver);
fail_backlight:
backlight_device_unregister(compalbl_device);
return ret;
}
static void __exit compal_cleanup(void)
{
sysfs_remove_group(&compal_device->dev.kobj, &compal_attribute_group);
platform_device_unregister(compal_device);
platform_driver_unregister(&compal_driver);
backlight_device_unregister(compalbl_device);
printk(KERN_INFO "compal-laptop: driver unloaded.\n");
}
module_init(compal_init);
module_exit(compal_cleanup);
MODULE_AUTHOR("Cezary Jackiewicz");
MODULE_DESCRIPTION("Compal Laptop Support");
MODULE_VERSION(COMPAL_DRIVER_VERSION);
MODULE_LICENSE("GPL");
MODULE_ALIAS("dmi:*:rnIFL90:rvrIFT00:*");
MODULE_ALIAS("dmi:*:rnIFL90:rvrREFERENCE:*");
MODULE_ALIAS("dmi:*:rnIFL91:rvrIFT00:*");
MODULE_ALIAS("dmi:*:rnJFL92:rvrIFT00:*");
MODULE_ALIAS("dmi:*:rnIFT00:rvrIFT00:*");
...@@ -87,7 +87,7 @@ enum { ...@@ -87,7 +87,7 @@ enum {
CM_ASL_LID CM_ASL_LID
}; };
const char *cm_getv[] = { static const char *cm_getv[] = {
"WLDG", NULL, NULL, NULL, "WLDG", NULL, NULL, NULL,
"CAMG", NULL, NULL, NULL, "CAMG", NULL, NULL, NULL,
NULL, "PBLG", NULL, NULL, NULL, "PBLG", NULL, NULL,
...@@ -96,7 +96,7 @@ const char *cm_getv[] = { ...@@ -96,7 +96,7 @@ const char *cm_getv[] = {
"CRDG", "LIDG" "CRDG", "LIDG"
}; };
const char *cm_setv[] = { static const char *cm_setv[] = {
"WLDS", NULL, NULL, NULL, "WLDS", NULL, NULL, NULL,
"CAMS", NULL, NULL, NULL, "CAMS", NULL, NULL, NULL,
"SDSP", "PBLS", "HDPS", NULL, "SDSP", "PBLS", "HDPS", NULL,
......
/*-*-linux-c-*-*/ /*-*-linux-c-*-*/
/* /*
Copyright (C) 2007 Jonathan Woithe <jwoithe@physics.adelaide.edu.au> Copyright (C) 2007,2008 Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
Copyright (C) 2008 Peter Gruber <nokos@gmx.net>
Based on earlier work: Based on earlier work:
Copyright (C) 2003 Shane Spencer <shane@bogomip.com> Copyright (C) 2003 Shane Spencer <shane@bogomip.com>
Adrian Yee <brewt-fujitsu@brewt.org> Adrian Yee <brewt-fujitsu@brewt.org>
Templated from msi-laptop.c which is copyright by its respective authors. Templated from msi-laptop.c and thinkpad_acpi.c which is copyright
by its respective authors.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -39,8 +41,17 @@ ...@@ -39,8 +41,17 @@
* registers itself in the Linux backlight control subsystem and is * registers itself in the Linux backlight control subsystem and is
* available to userspace under /sys/class/backlight/fujitsu-laptop/. * available to userspace under /sys/class/backlight/fujitsu-laptop/.
* *
* This driver has been tested on a Fujitsu Lifebook S7020. It should * Hotkeys present on certain Fujitsu laptops (eg: the S6xxx series) are
* work on most P-series and S-series Lifebooks, but YMMV. * also supported by this driver.
*
* This driver has been tested on a Fujitsu Lifebook S6410 and S7020. It
* should work on most P-series and S-series Lifebooks, but YMMV.
*
* The module parameter use_alt_lcd_levels switches between different ACPI
* brightness controls which are used by different Fujitsu laptops. In most
* cases the correct method is automatically detected. "use_alt_lcd_levels=1"
* is applicable for a Fujitsu Lifebook S6410 if autodetection fails.
*
*/ */
#include <linux/module.h> #include <linux/module.h>
...@@ -49,30 +60,105 @@ ...@@ -49,30 +60,105 @@
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/dmi.h> #include <linux/dmi.h>
#include <linux/backlight.h> #include <linux/backlight.h>
#include <linux/input.h>
#include <linux/kfifo.h>
#include <linux/video_output.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#define FUJITSU_DRIVER_VERSION "0.3" #define FUJITSU_DRIVER_VERSION "0.4.2"
#define FUJITSU_LCD_N_LEVELS 8 #define FUJITSU_LCD_N_LEVELS 8
#define ACPI_FUJITSU_CLASS "fujitsu" #define ACPI_FUJITSU_CLASS "fujitsu"
#define ACPI_FUJITSU_HID "FUJ02B1" #define ACPI_FUJITSU_HID "FUJ02B1"
#define ACPI_FUJITSU_DRIVER_NAME "Fujitsu laptop FUJ02B1 ACPI extras driver" #define ACPI_FUJITSU_DRIVER_NAME "Fujitsu laptop FUJ02B1 ACPI brightness driver"
#define ACPI_FUJITSU_DEVICE_NAME "Fujitsu FUJ02B1" #define ACPI_FUJITSU_DEVICE_NAME "Fujitsu FUJ02B1"
#define ACPI_FUJITSU_HOTKEY_HID "FUJ02E3"
#define ACPI_FUJITSU_HOTKEY_DRIVER_NAME "Fujitsu laptop FUJ02E3 ACPI hotkeys driver"
#define ACPI_FUJITSU_HOTKEY_DEVICE_NAME "Fujitsu FUJ02E3"
#define ACPI_FUJITSU_NOTIFY_CODE1 0x80
#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x86
#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87
/* Hotkey details */
#define LOCK_KEY 0x410 /* codes for the keys in the GIRB register */
#define DISPLAY_KEY 0x411 /* keys are mapped to KEY_SCREENLOCK (the key with the key symbol) */
#define ENERGY_KEY 0x412 /* KEY_MEDIA (the key with the laptop symbol, KEY_EMAIL (E key)) */
#define REST_KEY 0x413 /* KEY_SUSPEND (R key) */
#define MAX_HOTKEY_RINGBUFFER_SIZE 100
#define RINGBUFFERSIZE 40
/* Debugging */
#define FUJLAPTOP_LOG ACPI_FUJITSU_HID ": "
#define FUJLAPTOP_ERR KERN_ERR FUJLAPTOP_LOG
#define FUJLAPTOP_NOTICE KERN_NOTICE FUJLAPTOP_LOG
#define FUJLAPTOP_INFO KERN_INFO FUJLAPTOP_LOG
#define FUJLAPTOP_DEBUG KERN_DEBUG FUJLAPTOP_LOG
#define FUJLAPTOP_DBG_ALL 0xffff
#define FUJLAPTOP_DBG_ERROR 0x0001
#define FUJLAPTOP_DBG_WARN 0x0002
#define FUJLAPTOP_DBG_INFO 0x0004
#define FUJLAPTOP_DBG_TRACE 0x0008
#define dbg_printk(a_dbg_level, format, arg...) \
do { if (dbg_level & a_dbg_level) \
printk(FUJLAPTOP_DEBUG "%s: " format, __func__ , ## arg); \
} while (0)
#ifdef CONFIG_FUJITSU_LAPTOP_DEBUG
#define vdbg_printk(a_dbg_level, format, arg...) \
dbg_printk(a_dbg_level, format, ## arg)
#else
#define vdbg_printk(a_dbg_level, format, arg...)
#endif
/* Device controlling the backlight and associated keys */
struct fujitsu_t { struct fujitsu_t {
acpi_handle acpi_handle; acpi_handle acpi_handle;
struct acpi_device *dev;
struct input_dev *input;
char phys[32];
struct backlight_device *bl_device; struct backlight_device *bl_device;
struct platform_device *pf_device; struct platform_device *pf_device;
unsigned long fuj02b1_state; unsigned int max_brightness;
unsigned int brightness_changed; unsigned int brightness_changed;
unsigned int brightness_level; unsigned int brightness_level;
}; };
static struct fujitsu_t *fujitsu; static struct fujitsu_t *fujitsu;
static int use_alt_lcd_levels = -1;
static int disable_brightness_keys = -1;
static int disable_brightness_adjust = -1;
/* Device used to access other hotkeys on the laptop */
struct fujitsu_hotkey_t {
acpi_handle acpi_handle;
struct acpi_device *dev;
struct input_dev *input;
char phys[32];
struct platform_device *pf_device;
struct kfifo *fifo;
spinlock_t fifo_lock;
unsigned int irb; /* info about the pressed buttons */
};
/* Hardware access */ static struct fujitsu_hotkey_t *fujitsu_hotkey;
static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,
void *data);
#ifdef CONFIG_FUJITSU_LAPTOP_DEBUG
static u32 dbg_level = 0x03;
#endif
static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data);
/* Hardware access for LCD brightness control */
static int set_lcd_level(int level) static int set_lcd_level(int level)
{ {
...@@ -81,7 +167,10 @@ static int set_lcd_level(int level) ...@@ -81,7 +167,10 @@ static int set_lcd_level(int level)
struct acpi_object_list arg_list = { 1, &arg0 }; struct acpi_object_list arg_list = { 1, &arg0 };
acpi_handle handle = NULL; acpi_handle handle = NULL;
if (level < 0 || level >= FUJITSU_LCD_N_LEVELS) vdbg_printk(FUJLAPTOP_DBG_TRACE, "set lcd level via SBLL [%d]\n",
level);
if (level < 0 || level >= fujitsu->max_brightness)
return -EINVAL; return -EINVAL;
if (!fujitsu) if (!fujitsu)
...@@ -89,7 +178,38 @@ static int set_lcd_level(int level) ...@@ -89,7 +178,38 @@ static int set_lcd_level(int level)
status = acpi_get_handle(fujitsu->acpi_handle, "SBLL", &handle); status = acpi_get_handle(fujitsu->acpi_handle, "SBLL", &handle);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "SBLL not present\n")); vdbg_printk(FUJLAPTOP_DBG_ERROR, "SBLL not present\n");
return -ENODEV;
}
arg0.integer.value = level;
status = acpi_evaluate_object(handle, NULL, &arg_list, NULL);
if (ACPI_FAILURE(status))
return -ENODEV;
return 0;
}
static int set_lcd_level_alt(int level)
{
acpi_status status = AE_OK;
union acpi_object arg0 = { ACPI_TYPE_INTEGER };
struct acpi_object_list arg_list = { 1, &arg0 };
acpi_handle handle = NULL;
vdbg_printk(FUJLAPTOP_DBG_TRACE, "set lcd level via SBL2 [%d]\n",
level);
if (level < 0 || level >= fujitsu->max_brightness)
return -EINVAL;
if (!fujitsu)
return -EINVAL;
status = acpi_get_handle(fujitsu->acpi_handle, "SBL2", &handle);
if (ACPI_FAILURE(status)) {
vdbg_printk(FUJLAPTOP_DBG_ERROR, "SBL2 not present\n");
return -ENODEV; return -ENODEV;
} }
...@@ -107,13 +227,52 @@ static int get_lcd_level(void) ...@@ -107,13 +227,52 @@ static int get_lcd_level(void)
unsigned long state = 0; unsigned long state = 0;
acpi_status status = AE_OK; acpi_status status = AE_OK;
// Get the Brightness vdbg_printk(FUJLAPTOP_DBG_TRACE, "get lcd level via GBLL\n");
status = status =
acpi_evaluate_integer(fujitsu->acpi_handle, "GBLL", NULL, &state); acpi_evaluate_integer(fujitsu->acpi_handle, "GBLL", NULL, &state);
if (status < 0) if (status < 0)
return status; return status;
fujitsu->fuj02b1_state = state; fujitsu->brightness_level = state & 0x0fffffff;
if (state & 0x80000000)
fujitsu->brightness_changed = 1;
else
fujitsu->brightness_changed = 0;
return fujitsu->brightness_level;
}
static int get_max_brightness(void)
{
unsigned long state = 0;
acpi_status status = AE_OK;
vdbg_printk(FUJLAPTOP_DBG_TRACE, "get max lcd level via RBLL\n");
status =
acpi_evaluate_integer(fujitsu->acpi_handle, "RBLL", NULL, &state);
if (status < 0)
return status;
fujitsu->max_brightness = state;
return fujitsu->max_brightness;
}
static int get_lcd_level_alt(void)
{
unsigned long state = 0;
acpi_status status = AE_OK;
vdbg_printk(FUJLAPTOP_DBG_TRACE, "get lcd level via GBLS\n");
status =
acpi_evaluate_integer(fujitsu->acpi_handle, "GBLS", NULL, &state);
if (status < 0)
return status;
fujitsu->brightness_level = state & 0x0fffffff; fujitsu->brightness_level = state & 0x0fffffff;
if (state & 0x80000000) if (state & 0x80000000)
...@@ -128,12 +287,18 @@ static int get_lcd_level(void) ...@@ -128,12 +287,18 @@ static int get_lcd_level(void)
static int bl_get_brightness(struct backlight_device *b) static int bl_get_brightness(struct backlight_device *b)
{ {
return get_lcd_level(); if (use_alt_lcd_levels)
return get_lcd_level_alt();
else
return get_lcd_level();
} }
static int bl_update_status(struct backlight_device *b) static int bl_update_status(struct backlight_device *b)
{ {
return set_lcd_level(b->props.brightness); if (use_alt_lcd_levels)
return set_lcd_level_alt(b->props.brightness);
else
return set_lcd_level(b->props.brightness);
} }
static struct backlight_ops fujitsubl_ops = { static struct backlight_ops fujitsubl_ops = {
...@@ -141,7 +306,35 @@ static struct backlight_ops fujitsubl_ops = { ...@@ -141,7 +306,35 @@ static struct backlight_ops fujitsubl_ops = {
.update_status = bl_update_status, .update_status = bl_update_status,
}; };
/* Platform device */ /* Platform LCD brightness device */
static ssize_t
show_max_brightness(struct device *dev,
struct device_attribute *attr, char *buf)
{
int ret;
ret = get_max_brightness();
if (ret < 0)
return ret;
return sprintf(buf, "%i\n", ret);
}
static ssize_t
show_brightness_changed(struct device *dev,
struct device_attribute *attr, char *buf)
{
int ret;
ret = fujitsu->brightness_changed;
if (ret < 0)
return ret;
return sprintf(buf, "%i\n", ret);
}
static ssize_t show_lcd_level(struct device *dev, static ssize_t show_lcd_level(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
...@@ -149,7 +342,10 @@ static ssize_t show_lcd_level(struct device *dev, ...@@ -149,7 +342,10 @@ static ssize_t show_lcd_level(struct device *dev,
int ret; int ret;
ret = get_lcd_level(); if (use_alt_lcd_levels)
ret = get_lcd_level_alt();
else
ret = get_lcd_level();
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -164,19 +360,61 @@ static ssize_t store_lcd_level(struct device *dev, ...@@ -164,19 +360,61 @@ static ssize_t store_lcd_level(struct device *dev,
int level, ret; int level, ret;
if (sscanf(buf, "%i", &level) != 1 if (sscanf(buf, "%i", &level) != 1
|| (level < 0 || level >= FUJITSU_LCD_N_LEVELS)) || (level < 0 || level >= fujitsu->max_brightness))
return -EINVAL; return -EINVAL;
ret = set_lcd_level(level); if (use_alt_lcd_levels)
ret = set_lcd_level_alt(level);
else
ret = set_lcd_level(level);
if (ret < 0)
return ret;
if (use_alt_lcd_levels)
ret = get_lcd_level_alt();
else
ret = get_lcd_level();
if (ret < 0) if (ret < 0)
return ret; return ret;
return count; return count;
} }
/* Hardware access for hotkey device */
static int get_irb(void)
{
unsigned long state = 0;
acpi_status status = AE_OK;
vdbg_printk(FUJLAPTOP_DBG_TRACE, "Get irb\n");
status =
acpi_evaluate_integer(fujitsu_hotkey->acpi_handle, "GIRB", NULL,
&state);
if (status < 0)
return status;
fujitsu_hotkey->irb = state;
return fujitsu_hotkey->irb;
}
static ssize_t
ignore_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
return count;
}
static DEVICE_ATTR(max_brightness, 0444, show_max_brightness, ignore_store);
static DEVICE_ATTR(brightness_changed, 0444, show_brightness_changed,
ignore_store);
static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level); static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level);
static struct attribute *fujitsupf_attributes[] = { static struct attribute *fujitsupf_attributes[] = {
&dev_attr_brightness_changed.attr,
&dev_attr_max_brightness.attr,
&dev_attr_lcd_level.attr, &dev_attr_lcd_level.attr,
NULL NULL
}; };
...@@ -192,14 +430,52 @@ static struct platform_driver fujitsupf_driver = { ...@@ -192,14 +430,52 @@ static struct platform_driver fujitsupf_driver = {
} }
}; };
/* ACPI device */ static int dmi_check_cb_s6410(const struct dmi_system_id *id)
{
acpi_handle handle;
int have_blnf;
printk(KERN_INFO "fujitsu-laptop: Identified laptop model '%s'.\n",
id->ident);
have_blnf = ACPI_SUCCESS
(acpi_get_handle(NULL, "\\_SB.PCI0.GFX0.LCD.BLNF", &handle));
if (use_alt_lcd_levels == -1) {
vdbg_printk(FUJLAPTOP_DBG_TRACE, "auto-detecting usealt\n");
use_alt_lcd_levels = 1;
}
if (disable_brightness_keys == -1) {
vdbg_printk(FUJLAPTOP_DBG_TRACE,
"auto-detecting disable_keys\n");
disable_brightness_keys = have_blnf ? 1 : 0;
}
if (disable_brightness_adjust == -1) {
vdbg_printk(FUJLAPTOP_DBG_TRACE,
"auto-detecting disable_adjust\n");
disable_brightness_adjust = have_blnf ? 0 : 1;
}
return 0;
}
static struct dmi_system_id __initdata fujitsu_dmi_table[] = {
{
.ident = "Fujitsu Siemens",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK S6410"),
},
.callback = dmi_check_cb_s6410},
{}
};
/* ACPI device for LCD brightness control */
static int acpi_fujitsu_add(struct acpi_device *device) static int acpi_fujitsu_add(struct acpi_device *device)
{ {
acpi_status status;
acpi_handle handle;
int result = 0; int result = 0;
int state = 0; int state = 0;
struct input_dev *input;
ACPI_FUNCTION_TRACE("acpi_fujitsu_add"); int error;
if (!device) if (!device)
return -EINVAL; return -EINVAL;
...@@ -209,10 +485,42 @@ static int acpi_fujitsu_add(struct acpi_device *device) ...@@ -209,10 +485,42 @@ static int acpi_fujitsu_add(struct acpi_device *device)
sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS); sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
acpi_driver_data(device) = fujitsu; acpi_driver_data(device) = fujitsu;
status = acpi_install_notify_handler(device->handle,
ACPI_DEVICE_NOTIFY,
acpi_fujitsu_notify, fujitsu);
if (ACPI_FAILURE(status)) {
printk(KERN_ERR "Error installing notify handler\n");
error = -ENODEV;
goto err_stop;
}
fujitsu->input = input = input_allocate_device();
if (!input) {
error = -ENOMEM;
goto err_uninstall_notify;
}
snprintf(fujitsu->phys, sizeof(fujitsu->phys),
"%s/video/input0", acpi_device_hid(device));
input->name = acpi_device_name(device);
input->phys = fujitsu->phys;
input->id.bustype = BUS_HOST;
input->id.product = 0x06;
input->dev.parent = &device->dev;
input->evbit[0] = BIT(EV_KEY);
set_bit(KEY_BRIGHTNESSUP, input->keybit);
set_bit(KEY_BRIGHTNESSDOWN, input->keybit);
set_bit(KEY_UNKNOWN, input->keybit);
error = input_register_device(input);
if (error)
goto err_free_input_dev;
result = acpi_bus_get_power(fujitsu->acpi_handle, &state); result = acpi_bus_get_power(fujitsu->acpi_handle, &state);
if (result) { if (result) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR, printk(KERN_ERR "Error reading power state\n");
"Error reading power state\n"));
goto end; goto end;
} }
...@@ -220,22 +528,373 @@ static int acpi_fujitsu_add(struct acpi_device *device) ...@@ -220,22 +528,373 @@ static int acpi_fujitsu_add(struct acpi_device *device)
acpi_device_name(device), acpi_device_bid(device), acpi_device_name(device), acpi_device_bid(device),
!device->power.state ? "on" : "off"); !device->power.state ? "on" : "off");
end: fujitsu->dev = device;
if (ACPI_SUCCESS
(acpi_get_handle(device->handle, METHOD_NAME__INI, &handle))) {
vdbg_printk(FUJLAPTOP_DBG_INFO, "Invoking _INI\n");
if (ACPI_FAILURE
(acpi_evaluate_object
(device->handle, METHOD_NAME__INI, NULL, NULL)))
printk(KERN_ERR "_INI Method failed\n");
}
/* do config (detect defaults) */
dmi_check_system(fujitsu_dmi_table);
use_alt_lcd_levels = use_alt_lcd_levels == 1 ? 1 : 0;
disable_brightness_keys = disable_brightness_keys == 1 ? 1 : 0;
disable_brightness_adjust = disable_brightness_adjust == 1 ? 1 : 0;
vdbg_printk(FUJLAPTOP_DBG_INFO,
"config: [alt interface: %d], [key disable: %d], [adjust disable: %d]\n",
use_alt_lcd_levels, disable_brightness_keys,
disable_brightness_adjust);
if (get_max_brightness() <= 0)
fujitsu->max_brightness = FUJITSU_LCD_N_LEVELS;
if (use_alt_lcd_levels)
get_lcd_level_alt();
else
get_lcd_level();
return result;
end:
err_free_input_dev:
input_free_device(input);
err_uninstall_notify:
acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
acpi_fujitsu_notify);
err_stop:
return result; return result;
} }
static int acpi_fujitsu_remove(struct acpi_device *device, int type) static int acpi_fujitsu_remove(struct acpi_device *device, int type)
{ {
ACPI_FUNCTION_TRACE("acpi_fujitsu_remove"); acpi_status status;
struct fujitsu_t *fujitsu = NULL;
if (!device || !acpi_driver_data(device)) if (!device || !acpi_driver_data(device))
return -EINVAL; return -EINVAL;
fujitsu = acpi_driver_data(device);
status = acpi_remove_notify_handler(fujitsu->acpi_handle,
ACPI_DEVICE_NOTIFY,
acpi_fujitsu_notify);
if (!device || !acpi_driver_data(device))
return -EINVAL;
fujitsu->acpi_handle = NULL; fujitsu->acpi_handle = NULL;
return 0; return 0;
} }
/* Brightness notify */
static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data)
{
struct input_dev *input;
int keycode;
int oldb, newb;
input = fujitsu->input;
switch (event) {
case ACPI_FUJITSU_NOTIFY_CODE1:
keycode = 0;
oldb = fujitsu->brightness_level;
get_lcd_level(); /* the alt version always yields changed */
newb = fujitsu->brightness_level;
vdbg_printk(FUJLAPTOP_DBG_TRACE,
"brightness button event [%i -> %i (%i)]\n",
oldb, newb, fujitsu->brightness_changed);
if (oldb == newb && fujitsu->brightness_changed) {
keycode = 0;
if (disable_brightness_keys != 1) {
if (oldb == 0) {
acpi_bus_generate_proc_event(fujitsu->
dev,
ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS,
0);
keycode = KEY_BRIGHTNESSDOWN;
} else if (oldb ==
(fujitsu->max_brightness) - 1) {
acpi_bus_generate_proc_event(fujitsu->
dev,
ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS,
0);
keycode = KEY_BRIGHTNESSUP;
}
}
} else if (oldb < newb) {
if (disable_brightness_adjust != 1) {
if (use_alt_lcd_levels)
set_lcd_level_alt(newb);
else
set_lcd_level(newb);
}
if (disable_brightness_keys != 1) {
acpi_bus_generate_proc_event(fujitsu->dev,
ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS,
0);
keycode = KEY_BRIGHTNESSUP;
}
} else if (oldb > newb) {
if (disable_brightness_adjust != 1) {
if (use_alt_lcd_levels)
set_lcd_level_alt(newb);
else
set_lcd_level(newb);
}
if (disable_brightness_keys != 1) {
acpi_bus_generate_proc_event(fujitsu->dev,
ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS,
0);
keycode = KEY_BRIGHTNESSDOWN;
}
} else {
keycode = KEY_UNKNOWN;
}
break;
default:
keycode = KEY_UNKNOWN;
vdbg_printk(FUJLAPTOP_DBG_WARN,
"unsupported event [0x%x]\n", event);
break;
}
if (keycode != 0) {
input_report_key(input, keycode, 1);
input_sync(input);
input_report_key(input, keycode, 0);
input_sync(input);
}
return;
}
/* ACPI device for hotkey handling */
static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
{
acpi_status status;
acpi_handle handle;
int result = 0;
int state = 0;
struct input_dev *input;
int error;
int i;
if (!device)
return -EINVAL;
fujitsu_hotkey->acpi_handle = device->handle;
sprintf(acpi_device_name(device), "%s",
ACPI_FUJITSU_HOTKEY_DEVICE_NAME);
sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
acpi_driver_data(device) = fujitsu_hotkey;
status = acpi_install_notify_handler(device->handle,
ACPI_DEVICE_NOTIFY,
acpi_fujitsu_hotkey_notify,
fujitsu_hotkey);
if (ACPI_FAILURE(status)) {
printk(KERN_ERR "Error installing notify handler\n");
error = -ENODEV;
goto err_stop;
}
/* kfifo */
spin_lock_init(&fujitsu_hotkey->fifo_lock);
fujitsu_hotkey->fifo =
kfifo_alloc(RINGBUFFERSIZE * sizeof(int), GFP_KERNEL,
&fujitsu_hotkey->fifo_lock);
if (IS_ERR(fujitsu_hotkey->fifo)) {
printk(KERN_ERR "kfifo_alloc failed\n");
error = PTR_ERR(fujitsu_hotkey->fifo);
goto err_stop;
}
fujitsu_hotkey->input = input = input_allocate_device();
if (!input) {
error = -ENOMEM;
goto err_uninstall_notify;
}
snprintf(fujitsu_hotkey->phys, sizeof(fujitsu_hotkey->phys),
"%s/video/input0", acpi_device_hid(device));
input->name = acpi_device_name(device);
input->phys = fujitsu_hotkey->phys;
input->id.bustype = BUS_HOST;
input->id.product = 0x06;
input->dev.parent = &device->dev;
input->evbit[0] = BIT(EV_KEY);
set_bit(KEY_SCREENLOCK, input->keybit);
set_bit(KEY_MEDIA, input->keybit);
set_bit(KEY_EMAIL, input->keybit);
set_bit(KEY_SUSPEND, input->keybit);
set_bit(KEY_UNKNOWN, input->keybit);
error = input_register_device(input);
if (error)
goto err_free_input_dev;
result = acpi_bus_get_power(fujitsu_hotkey->acpi_handle, &state);
if (result) {
printk(KERN_ERR "Error reading power state\n");
goto end;
}
printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
acpi_device_name(device), acpi_device_bid(device),
!device->power.state ? "on" : "off");
fujitsu_hotkey->dev = device;
if (ACPI_SUCCESS
(acpi_get_handle(device->handle, METHOD_NAME__INI, &handle))) {
vdbg_printk(FUJLAPTOP_DBG_INFO, "Invoking _INI\n");
if (ACPI_FAILURE
(acpi_evaluate_object
(device->handle, METHOD_NAME__INI, NULL, NULL)))
printk(KERN_ERR "_INI Method failed\n");
}
i = 0; /* Discard hotkey ringbuffer */
while (get_irb() != 0 && (i++) < MAX_HOTKEY_RINGBUFFER_SIZE) ;
vdbg_printk(FUJLAPTOP_DBG_INFO, "Discarded %i ringbuffer entries\n", i);
return result;
end:
err_free_input_dev:
input_free_device(input);
err_uninstall_notify:
acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
acpi_fujitsu_hotkey_notify);
kfifo_free(fujitsu_hotkey->fifo);
err_stop:
return result;
}
static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type)
{
acpi_status status;
struct fujitsu_hotkey_t *fujitsu_hotkey = NULL;
if (!device || !acpi_driver_data(device))
return -EINVAL;
fujitsu_hotkey = acpi_driver_data(device);
status = acpi_remove_notify_handler(fujitsu_hotkey->acpi_handle,
ACPI_DEVICE_NOTIFY,
acpi_fujitsu_hotkey_notify);
fujitsu_hotkey->acpi_handle = NULL;
kfifo_free(fujitsu_hotkey->fifo);
return 0;
}
static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,
void *data)
{
struct input_dev *input;
int keycode, keycode_r;
unsigned int irb = 1;
int i, status;
input = fujitsu_hotkey->input;
vdbg_printk(FUJLAPTOP_DBG_TRACE, "Hotkey event\n");
switch (event) {
case ACPI_FUJITSU_NOTIFY_CODE1:
i = 0;
while ((irb = get_irb()) != 0
&& (i++) < MAX_HOTKEY_RINGBUFFER_SIZE) {
vdbg_printk(FUJLAPTOP_DBG_TRACE, "GIRB result [%x]\n",
irb);
switch (irb & 0x4ff) {
case LOCK_KEY:
keycode = KEY_SCREENLOCK;
break;
case DISPLAY_KEY:
keycode = KEY_MEDIA;
break;
case ENERGY_KEY:
keycode = KEY_EMAIL;
break;
case REST_KEY:
keycode = KEY_SUSPEND;
break;
case 0:
keycode = 0;
break;
default:
vdbg_printk(FUJLAPTOP_DBG_WARN,
"Unknown GIRB result [%x]\n", irb);
keycode = -1;
break;
}
if (keycode > 0) {
vdbg_printk(FUJLAPTOP_DBG_TRACE,
"Push keycode into ringbuffer [%d]\n",
keycode);
status = kfifo_put(fujitsu_hotkey->fifo,
(unsigned char *)&keycode,
sizeof(keycode));
if (status != sizeof(keycode)) {
vdbg_printk(FUJLAPTOP_DBG_WARN,
"Could not push keycode [0x%x]\n",
keycode);
} else {
input_report_key(input, keycode, 1);
input_sync(input);
}
} else if (keycode == 0) {
while ((status =
kfifo_get
(fujitsu_hotkey->fifo, (unsigned char *)
&keycode_r,
sizeof
(keycode_r))) == sizeof(keycode_r)) {
input_report_key(input, keycode_r, 0);
input_sync(input);
vdbg_printk(FUJLAPTOP_DBG_TRACE,
"Pop keycode from ringbuffer [%d]\n",
keycode_r);
}
}
}
break;
default:
keycode = KEY_UNKNOWN;
vdbg_printk(FUJLAPTOP_DBG_WARN,
"Unsupported event [0x%x]\n", event);
input_report_key(input, keycode, 1);
input_sync(input);
input_report_key(input, keycode, 0);
input_sync(input);
break;
}
return;
}
/* Initialization */
static const struct acpi_device_id fujitsu_device_ids[] = { static const struct acpi_device_id fujitsu_device_ids[] = {
{ACPI_FUJITSU_HID, 0}, {ACPI_FUJITSU_HID, 0},
{"", 0}, {"", 0},
...@@ -251,11 +910,24 @@ static struct acpi_driver acpi_fujitsu_driver = { ...@@ -251,11 +910,24 @@ static struct acpi_driver acpi_fujitsu_driver = {
}, },
}; };
/* Initialization */ static const struct acpi_device_id fujitsu_hotkey_device_ids[] = {
{ACPI_FUJITSU_HOTKEY_HID, 0},
{"", 0},
};
static struct acpi_driver acpi_fujitsu_hotkey_driver = {
.name = ACPI_FUJITSU_HOTKEY_DRIVER_NAME,
.class = ACPI_FUJITSU_CLASS,
.ids = fujitsu_hotkey_device_ids,
.ops = {
.add = acpi_fujitsu_hotkey_add,
.remove = acpi_fujitsu_hotkey_remove,
},
};
static int __init fujitsu_init(void) static int __init fujitsu_init(void)
{ {
int ret, result; int ret, result, max_brightness;
if (acpi_disabled) if (acpi_disabled)
return -ENODEV; return -ENODEV;
...@@ -271,19 +943,6 @@ static int __init fujitsu_init(void) ...@@ -271,19 +943,6 @@ static int __init fujitsu_init(void)
goto fail_acpi; goto fail_acpi;
} }
/* Register backlight stuff */
fujitsu->bl_device =
backlight_device_register("fujitsu-laptop", NULL, NULL,
&fujitsubl_ops);
if (IS_ERR(fujitsu->bl_device))
return PTR_ERR(fujitsu->bl_device);
fujitsu->bl_device->props.max_brightness = FUJITSU_LCD_N_LEVELS - 1;
ret = platform_driver_register(&fujitsupf_driver);
if (ret)
goto fail_backlight;
/* Register platform stuff */ /* Register platform stuff */
fujitsu->pf_device = platform_device_alloc("fujitsu-laptop", -1); fujitsu->pf_device = platform_device_alloc("fujitsu-laptop", -1);
...@@ -302,28 +961,68 @@ static int __init fujitsu_init(void) ...@@ -302,28 +961,68 @@ static int __init fujitsu_init(void)
if (ret) if (ret)
goto fail_platform_device2; goto fail_platform_device2;
/* Register backlight stuff */
fujitsu->bl_device =
backlight_device_register("fujitsu-laptop", NULL, NULL,
&fujitsubl_ops);
if (IS_ERR(fujitsu->bl_device))
return PTR_ERR(fujitsu->bl_device);
max_brightness = fujitsu->max_brightness;
fujitsu->bl_device->props.max_brightness = max_brightness - 1;
fujitsu->bl_device->props.brightness = fujitsu->brightness_level;
ret = platform_driver_register(&fujitsupf_driver);
if (ret)
goto fail_backlight;
/* Register hotkey driver */
fujitsu_hotkey = kmalloc(sizeof(struct fujitsu_hotkey_t), GFP_KERNEL);
if (!fujitsu_hotkey) {
ret = -ENOMEM;
goto fail_hotkey;
}
memset(fujitsu_hotkey, 0, sizeof(struct fujitsu_hotkey_t));
result = acpi_bus_register_driver(&acpi_fujitsu_hotkey_driver);
if (result < 0) {
ret = -ENODEV;
goto fail_hotkey1;
}
printk(KERN_INFO "fujitsu-laptop: driver " FUJITSU_DRIVER_VERSION printk(KERN_INFO "fujitsu-laptop: driver " FUJITSU_DRIVER_VERSION
" successfully loaded.\n"); " successfully loaded.\n");
return 0; return 0;
fail_platform_device2: fail_hotkey1:
platform_device_del(fujitsu->pf_device); kfree(fujitsu_hotkey);
fail_platform_device1:
platform_device_put(fujitsu->pf_device);
fail_platform_driver: fail_hotkey:
platform_driver_unregister(&fujitsupf_driver); platform_driver_unregister(&fujitsupf_driver);
fail_backlight: fail_backlight:
backlight_device_unregister(fujitsu->bl_device); backlight_device_unregister(fujitsu->bl_device);
fail_acpi: fail_platform_device2:
platform_device_del(fujitsu->pf_device);
fail_platform_device1:
platform_device_put(fujitsu->pf_device);
fail_platform_driver:
acpi_bus_unregister_driver(&acpi_fujitsu_driver);
fail_acpi:
kfree(fujitsu); kfree(fujitsu);
...@@ -342,19 +1041,43 @@ static void __exit fujitsu_cleanup(void) ...@@ -342,19 +1041,43 @@ static void __exit fujitsu_cleanup(void)
kfree(fujitsu); kfree(fujitsu);
acpi_bus_unregister_driver(&acpi_fujitsu_hotkey_driver);
kfree(fujitsu_hotkey);
printk(KERN_INFO "fujitsu-laptop: driver unloaded.\n"); printk(KERN_INFO "fujitsu-laptop: driver unloaded.\n");
} }
module_init(fujitsu_init); module_init(fujitsu_init);
module_exit(fujitsu_cleanup); module_exit(fujitsu_cleanup);
MODULE_AUTHOR("Jonathan Woithe"); module_param(use_alt_lcd_levels, uint, 0644);
MODULE_PARM_DESC(use_alt_lcd_levels,
"Use alternative interface for lcd_levels (needed for Lifebook s6410).");
module_param(disable_brightness_keys, uint, 0644);
MODULE_PARM_DESC(disable_brightness_keys,
"Disable brightness keys (eg. if they are already handled by the generic ACPI_VIDEO device).");
module_param(disable_brightness_adjust, uint, 0644);
MODULE_PARM_DESC(disable_brightness_adjust, "Disable brightness adjustment .");
#ifdef CONFIG_FUJITSU_LAPTOP_DEBUG
module_param_named(debug, dbg_level, uint, 0644);
MODULE_PARM_DESC(debug, "Sets debug level bit-mask");
#endif
MODULE_AUTHOR("Jonathan Woithe, Peter Gruber");
MODULE_DESCRIPTION("Fujitsu laptop extras support"); MODULE_DESCRIPTION("Fujitsu laptop extras support");
MODULE_VERSION(FUJITSU_DRIVER_VERSION); MODULE_VERSION(FUJITSU_DRIVER_VERSION);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS
("dmi:*:svnFUJITSUSIEMENS:*:pvr:rvnFUJITSU:rnFJNB1D3:*:cvrS6410:*");
MODULE_ALIAS
("dmi:*:svnFUJITSU:*:pvr:rvnFUJITSU:rnFJNB19C:*:cvrS7020:*");
static struct pnp_device_id pnp_ids[] = { static struct pnp_device_id pnp_ids[] = {
{ .id = "FUJ02bf" }, { .id = "FUJ02bf" },
{ .id = "FUJ02B1" },
{ .id = "FUJ02E3" },
{ .id = "" } { .id = "" }
}; };
MODULE_DEVICE_TABLE(pnp, pnp_ids); MODULE_DEVICE_TABLE(pnp, pnp_ids);
...@@ -293,13 +293,11 @@ EXPORT_SYMBOL(pci_osc_control_set); ...@@ -293,13 +293,11 @@ EXPORT_SYMBOL(pci_osc_control_set);
* choose highest power _SxD or any lower power * choose highest power _SxD or any lower power
*/ */
static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev, static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev)
pm_message_t state)
{ {
int acpi_state; int acpi_state;
acpi_state = acpi_pm_device_sleep_state(&pdev->dev, acpi_state = acpi_pm_device_sleep_state(&pdev->dev, NULL);
device_may_wakeup(&pdev->dev), NULL);
if (acpi_state < 0) if (acpi_state < 0)
return PCI_POWER_ERROR; return PCI_POWER_ERROR;
......
...@@ -508,7 +508,7 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) ...@@ -508,7 +508,7 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
return 0; return 0;
} }
pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state); pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev);
/** /**
* pci_choose_state - Choose the power state of a PCI device * pci_choose_state - Choose the power state of a PCI device
...@@ -528,7 +528,7 @@ pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state) ...@@ -528,7 +528,7 @@ pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state)
return PCI_D0; return PCI_D0;
if (platform_pci_choose_state) { if (platform_pci_choose_state) {
ret = platform_pci_choose_state(dev, state); ret = platform_pci_choose_state(dev);
if (ret != PCI_POWER_ERROR) if (ret != PCI_POWER_ERROR)
return ret; return ret;
} }
......
...@@ -6,8 +6,7 @@ extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); ...@@ -6,8 +6,7 @@ extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
extern void pci_cleanup_rom(struct pci_dev *dev); extern void pci_cleanup_rom(struct pci_dev *dev);
/* Firmware callbacks */ /* Firmware callbacks */
extern pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev, extern pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev);
pm_message_t state);
extern int (*platform_pci_set_power_state)(struct pci_dev *dev, extern int (*platform_pci_set_power_state)(struct pci_dev *dev,
pci_power_t state); pci_power_t state);
......
/*
* Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
* Bjorn Helgaas <bjorn.helgaas@hp.com>
*/
extern spinlock_t pnp_lock; extern spinlock_t pnp_lock;
void *pnp_alloc(long size); void *pnp_alloc(long size);
...@@ -19,22 +24,118 @@ void pnp_remove_card(struct pnp_card *card); ...@@ -19,22 +24,118 @@ void pnp_remove_card(struct pnp_card *card);
int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev); int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev);
void pnp_remove_card_device(struct pnp_dev *dev); void pnp_remove_card_device(struct pnp_dev *dev);
struct pnp_option *pnp_build_option(int priority); struct pnp_port {
struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev); resource_size_t min; /* min base number */
struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev, resource_size_t max; /* max base number */
int priority); resource_size_t align; /* align boundary */
int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option, resource_size_t size; /* size of range */
struct pnp_irq *data); unsigned char flags; /* port flags */
int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option, };
struct pnp_dma *data);
int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option, #define PNP_IRQ_NR 256
struct pnp_port *data); typedef struct { DECLARE_BITMAP(bits, PNP_IRQ_NR); } pnp_irq_mask_t;
int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option,
struct pnp_mem *data); struct pnp_irq {
pnp_irq_mask_t map; /* bitmap for IRQ lines */
unsigned char flags; /* IRQ flags */
};
struct pnp_dma {
unsigned char map; /* bitmask for DMA channels */
unsigned char flags; /* DMA flags */
};
struct pnp_mem {
resource_size_t min; /* min base number */
resource_size_t max; /* max base number */
resource_size_t align; /* align boundary */
resource_size_t size; /* size of range */
unsigned char flags; /* memory flags */
};
#define PNP_OPTION_DEPENDENT 0x80000000
#define PNP_OPTION_SET_MASK 0xffff
#define PNP_OPTION_SET_SHIFT 12
#define PNP_OPTION_PRIORITY_MASK 0xfff
#define PNP_OPTION_PRIORITY_SHIFT 0
#define PNP_RES_PRIORITY_PREFERRED 0
#define PNP_RES_PRIORITY_ACCEPTABLE 1
#define PNP_RES_PRIORITY_FUNCTIONAL 2
#define PNP_RES_PRIORITY_INVALID PNP_OPTION_PRIORITY_MASK
struct pnp_option {
struct list_head list;
unsigned int flags; /* independent/dependent, set, priority */
unsigned long type; /* IORESOURCE_{IO,MEM,IRQ,DMA} */
union {
struct pnp_port port;
struct pnp_irq irq;
struct pnp_dma dma;
struct pnp_mem mem;
} u;
};
int pnp_register_irq_resource(struct pnp_dev *dev, unsigned int option_flags,
pnp_irq_mask_t *map, unsigned char flags);
int pnp_register_dma_resource(struct pnp_dev *dev, unsigned int option_flags,
unsigned char map, unsigned char flags);
int pnp_register_port_resource(struct pnp_dev *dev, unsigned int option_flags,
resource_size_t min, resource_size_t max,
resource_size_t align, resource_size_t size,
unsigned char flags);
int pnp_register_mem_resource(struct pnp_dev *dev, unsigned int option_flags,
resource_size_t min, resource_size_t max,
resource_size_t align, resource_size_t size,
unsigned char flags);
static inline int pnp_option_is_dependent(struct pnp_option *option)
{
return option->flags & PNP_OPTION_DEPENDENT ? 1 : 0;
}
static inline unsigned int pnp_option_set(struct pnp_option *option)
{
return (option->flags >> PNP_OPTION_SET_SHIFT) & PNP_OPTION_SET_MASK;
}
static inline unsigned int pnp_option_priority(struct pnp_option *option)
{
return (option->flags >> PNP_OPTION_PRIORITY_SHIFT) &
PNP_OPTION_PRIORITY_MASK;
}
static inline unsigned int pnp_new_dependent_set(struct pnp_dev *dev,
int priority)
{
unsigned int flags;
if (priority > PNP_RES_PRIORITY_FUNCTIONAL) {
dev_warn(&dev->dev, "invalid dependent option priority %d "
"clipped to %d", priority,
PNP_RES_PRIORITY_INVALID);
priority = PNP_RES_PRIORITY_INVALID;
}
flags = PNP_OPTION_DEPENDENT |
((dev->num_dependent_sets & PNP_OPTION_SET_MASK) <<
PNP_OPTION_SET_SHIFT) |
((priority & PNP_OPTION_PRIORITY_MASK) <<
PNP_OPTION_PRIORITY_SHIFT);
dev->num_dependent_sets++;
return flags;
}
char *pnp_option_priority_name(struct pnp_option *option);
void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option);
void pnp_init_resources(struct pnp_dev *dev); void pnp_init_resources(struct pnp_dev *dev);
void pnp_fixup_device(struct pnp_dev *dev); void pnp_fixup_device(struct pnp_dev *dev);
void pnp_free_option(struct pnp_option *option); void pnp_free_options(struct pnp_dev *dev);
int __pnp_add_device(struct pnp_dev *dev); int __pnp_add_device(struct pnp_dev *dev);
void __pnp_remove_device(struct pnp_dev *dev); void __pnp_remove_device(struct pnp_dev *dev);
...@@ -43,29 +144,18 @@ int pnp_check_mem(struct pnp_dev *dev, struct resource *res); ...@@ -43,29 +144,18 @@ int pnp_check_mem(struct pnp_dev *dev, struct resource *res);
int pnp_check_irq(struct pnp_dev *dev, struct resource *res); int pnp_check_irq(struct pnp_dev *dev, struct resource *res);
int pnp_check_dma(struct pnp_dev *dev, struct resource *res); int pnp_check_dma(struct pnp_dev *dev, struct resource *res);
char *pnp_resource_type_name(struct resource *res);
void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc); void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc);
void pnp_init_resource(struct resource *res); void pnp_free_resources(struct pnp_dev *dev);
int pnp_resource_type(struct resource *res);
struct pnp_resource *pnp_get_pnp_resource(struct pnp_dev *dev,
unsigned int type, unsigned int num);
#define PNP_MAX_PORT 40
#define PNP_MAX_MEM 24
#define PNP_MAX_IRQ 2
#define PNP_MAX_DMA 2
struct pnp_resource { struct pnp_resource {
struct list_head list;
struct resource res; struct resource res;
unsigned int index; /* ISAPNP config register index */
}; };
struct pnp_resource_table { void pnp_free_resource(struct pnp_resource *pnp_res);
struct pnp_resource port[PNP_MAX_PORT];
struct pnp_resource mem[PNP_MAX_MEM];
struct pnp_resource dma[PNP_MAX_DMA];
struct pnp_resource irq[PNP_MAX_IRQ];
};
struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
int flags); int flags);
......
...@@ -99,14 +99,28 @@ static void pnp_free_ids(struct pnp_dev *dev) ...@@ -99,14 +99,28 @@ static void pnp_free_ids(struct pnp_dev *dev)
} }
} }
void pnp_free_resource(struct pnp_resource *pnp_res)
{
list_del(&pnp_res->list);
kfree(pnp_res);
}
void pnp_free_resources(struct pnp_dev *dev)
{
struct pnp_resource *pnp_res, *tmp;
list_for_each_entry_safe(pnp_res, tmp, &dev->resources, list) {
pnp_free_resource(pnp_res);
}
}
static void pnp_release_device(struct device *dmdev) static void pnp_release_device(struct device *dmdev)
{ {
struct pnp_dev *dev = to_pnp_dev(dmdev); struct pnp_dev *dev = to_pnp_dev(dmdev);
pnp_free_option(dev->independent);
pnp_free_option(dev->dependent);
pnp_free_ids(dev); pnp_free_ids(dev);
kfree(dev->res); pnp_free_resources(dev);
pnp_free_options(dev);
kfree(dev); kfree(dev);
} }
...@@ -119,12 +133,8 @@ struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, char *pnpid ...@@ -119,12 +133,8 @@ struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, char *pnpid
if (!dev) if (!dev)
return NULL; return NULL;
dev->res = kzalloc(sizeof(struct pnp_resource_table), GFP_KERNEL); INIT_LIST_HEAD(&dev->resources);
if (!dev->res) { INIT_LIST_HEAD(&dev->options);
kfree(dev);
return NULL;
}
dev->protocol = protocol; dev->protocol = protocol;
dev->number = id; dev->number = id;
dev->dma_mask = DMA_24BIT_MASK; dev->dma_mask = DMA_24BIT_MASK;
...@@ -140,7 +150,6 @@ struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, char *pnpid ...@@ -140,7 +150,6 @@ struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, char *pnpid
dev_id = pnp_add_id(dev, pnpid); dev_id = pnp_add_id(dev, pnpid);
if (!dev_id) { if (!dev_id) {
kfree(dev->res);
kfree(dev); kfree(dev);
return NULL; return NULL;
} }
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
* *
* Some code, especially possible resource dumping is based on isapnp_proc.c (c) Jaroslav Kysela <perex@perex.cz> * Some code, especially possible resource dumping is based on isapnp_proc.c (c) Jaroslav Kysela <perex@perex.cz>
* Copyright 2002 Adam Belay <ambx1@neo.rr.com> * Copyright 2002 Adam Belay <ambx1@neo.rr.com>
* Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
* Bjorn Helgaas <bjorn.helgaas@hp.com>
*/ */
#include <linux/pnp.h> #include <linux/pnp.h>
...@@ -53,11 +55,13 @@ static int pnp_printf(pnp_info_buffer_t * buffer, char *fmt, ...) ...@@ -53,11 +55,13 @@ static int pnp_printf(pnp_info_buffer_t * buffer, char *fmt, ...)
static void pnp_print_port(pnp_info_buffer_t * buffer, char *space, static void pnp_print_port(pnp_info_buffer_t * buffer, char *space,
struct pnp_port *port) struct pnp_port *port)
{ {
pnp_printf(buffer, pnp_printf(buffer, "%sport %#llx-%#llx, align %#llx, size %#llx, "
"%sport 0x%x-0x%x, align 0x%x, size 0x%x, %i-bit address decoding\n", "%i-bit address decoding\n", space,
space, port->min, port->max, (unsigned long long) port->min,
port->align ? (port->align - 1) : 0, port->size, (unsigned long long) port->max,
port->flags & PNP_PORT_FLAG_16BITADDR ? 16 : 10); port->align ? ((unsigned long long) port->align - 1) : 0,
(unsigned long long) port->size,
port->flags & IORESOURCE_IO_16BIT_ADDR ? 16 : 10);
} }
static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space, static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space,
...@@ -67,7 +71,7 @@ static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space, ...@@ -67,7 +71,7 @@ static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space,
pnp_printf(buffer, "%sirq ", space); pnp_printf(buffer, "%sirq ", space);
for (i = 0; i < PNP_IRQ_NR; i++) for (i = 0; i < PNP_IRQ_NR; i++)
if (test_bit(i, irq->map)) { if (test_bit(i, irq->map.bits)) {
if (!first) { if (!first) {
pnp_printf(buffer, ","); pnp_printf(buffer, ",");
} else { } else {
...@@ -78,7 +82,7 @@ static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space, ...@@ -78,7 +82,7 @@ static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space,
else else
pnp_printf(buffer, "%i", i); pnp_printf(buffer, "%i", i);
} }
if (bitmap_empty(irq->map, PNP_IRQ_NR)) if (bitmap_empty(irq->map.bits, PNP_IRQ_NR))
pnp_printf(buffer, "<none>"); pnp_printf(buffer, "<none>");
if (irq->flags & IORESOURCE_IRQ_HIGHEDGE) if (irq->flags & IORESOURCE_IRQ_HIGHEDGE)
pnp_printf(buffer, " High-Edge"); pnp_printf(buffer, " High-Edge");
...@@ -88,6 +92,8 @@ static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space, ...@@ -88,6 +92,8 @@ static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space,
pnp_printf(buffer, " High-Level"); pnp_printf(buffer, " High-Level");
if (irq->flags & IORESOURCE_IRQ_LOWLEVEL) if (irq->flags & IORESOURCE_IRQ_LOWLEVEL)
pnp_printf(buffer, " Low-Level"); pnp_printf(buffer, " Low-Level");
if (irq->flags & IORESOURCE_IRQ_OPTIONAL)
pnp_printf(buffer, " (optional)");
pnp_printf(buffer, "\n"); pnp_printf(buffer, "\n");
} }
...@@ -148,8 +154,11 @@ static void pnp_print_mem(pnp_info_buffer_t * buffer, char *space, ...@@ -148,8 +154,11 @@ static void pnp_print_mem(pnp_info_buffer_t * buffer, char *space,
{ {
char *s; char *s;
pnp_printf(buffer, "%sMemory 0x%x-0x%x, align 0x%x, size 0x%x", pnp_printf(buffer, "%sMemory %#llx-%#llx, align %#llx, size %#llx",
space, mem->min, mem->max, mem->align, mem->size); space, (unsigned long long) mem->min,
(unsigned long long) mem->max,
(unsigned long long) mem->align,
(unsigned long long) mem->size);
if (mem->flags & IORESOURCE_MEM_WRITEABLE) if (mem->flags & IORESOURCE_MEM_WRITEABLE)
pnp_printf(buffer, ", writeable"); pnp_printf(buffer, ", writeable");
if (mem->flags & IORESOURCE_MEM_CACHEABLE) if (mem->flags & IORESOURCE_MEM_CACHEABLE)
...@@ -177,65 +186,58 @@ static void pnp_print_mem(pnp_info_buffer_t * buffer, char *space, ...@@ -177,65 +186,58 @@ static void pnp_print_mem(pnp_info_buffer_t * buffer, char *space,
} }
static void pnp_print_option(pnp_info_buffer_t * buffer, char *space, static void pnp_print_option(pnp_info_buffer_t * buffer, char *space,
struct pnp_option *option, int dep) struct pnp_option *option)
{ {
char *s; switch (option->type) {
struct pnp_port *port; case IORESOURCE_IO:
struct pnp_irq *irq; pnp_print_port(buffer, space, &option->u.port);
struct pnp_dma *dma; break;
struct pnp_mem *mem; case IORESOURCE_MEM:
pnp_print_mem(buffer, space, &option->u.mem);
if (dep) { break;
switch (option->priority) { case IORESOURCE_IRQ:
case PNP_RES_PRIORITY_PREFERRED: pnp_print_irq(buffer, space, &option->u.irq);
s = "preferred"; break;
break; case IORESOURCE_DMA:
case PNP_RES_PRIORITY_ACCEPTABLE: pnp_print_dma(buffer, space, &option->u.dma);
s = "acceptable"; break;
break;
case PNP_RES_PRIORITY_FUNCTIONAL:
s = "functional";
break;
default:
s = "invalid";
}
pnp_printf(buffer, "Dependent: %02i - Priority %s\n", dep, s);
} }
for (port = option->port; port; port = port->next)
pnp_print_port(buffer, space, port);
for (irq = option->irq; irq; irq = irq->next)
pnp_print_irq(buffer, space, irq);
for (dma = option->dma; dma; dma = dma->next)
pnp_print_dma(buffer, space, dma);
for (mem = option->mem; mem; mem = mem->next)
pnp_print_mem(buffer, space, mem);
} }
static ssize_t pnp_show_options(struct device *dmdev, static ssize_t pnp_show_options(struct device *dmdev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct pnp_dev *dev = to_pnp_dev(dmdev); struct pnp_dev *dev = to_pnp_dev(dmdev);
struct pnp_option *independent = dev->independent; pnp_info_buffer_t *buffer;
struct pnp_option *dependent = dev->dependent; struct pnp_option *option;
int ret, dep = 1; int ret, dep = 0, set = 0;
char *indent;
pnp_info_buffer_t *buffer = (pnp_info_buffer_t *) buffer = pnp_alloc(sizeof(pnp_info_buffer_t));
pnp_alloc(sizeof(pnp_info_buffer_t));
if (!buffer) if (!buffer)
return -ENOMEM; return -ENOMEM;
buffer->len = PAGE_SIZE; buffer->len = PAGE_SIZE;
buffer->buffer = buf; buffer->buffer = buf;
buffer->curr = buffer->buffer; buffer->curr = buffer->buffer;
if (independent)
pnp_print_option(buffer, "", independent, 0);
while (dependent) { list_for_each_entry(option, &dev->options, list) {
pnp_print_option(buffer, " ", dependent, dep); if (pnp_option_is_dependent(option)) {
dependent = dependent->next; indent = " ";
dep++; if (!dep || pnp_option_set(option) != set) {
set = pnp_option_set(option);
dep = 1;
pnp_printf(buffer, "Dependent: %02i - "
"Priority %s\n", set,
pnp_option_priority_name(option));
}
} else {
dep = 0;
indent = "";
}
pnp_print_option(buffer, indent, option);
} }
ret = (buffer->curr - buf); ret = (buffer->curr - buf);
kfree(buffer); kfree(buffer);
return ret; return ret;
...@@ -248,79 +250,59 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, ...@@ -248,79 +250,59 @@ static ssize_t pnp_show_current_resources(struct device *dmdev,
char *buf) char *buf)
{ {
struct pnp_dev *dev = to_pnp_dev(dmdev); struct pnp_dev *dev = to_pnp_dev(dmdev);
struct resource *res;
int i, ret;
pnp_info_buffer_t *buffer; pnp_info_buffer_t *buffer;
struct pnp_resource *pnp_res;
struct resource *res;
int ret;
if (!dev) if (!dev)
return -EINVAL; return -EINVAL;
buffer = (pnp_info_buffer_t *) pnp_alloc(sizeof(pnp_info_buffer_t)); buffer = pnp_alloc(sizeof(pnp_info_buffer_t));
if (!buffer) if (!buffer)
return -ENOMEM; return -ENOMEM;
buffer->len = PAGE_SIZE; buffer->len = PAGE_SIZE;
buffer->buffer = buf; buffer->buffer = buf;
buffer->curr = buffer->buffer; buffer->curr = buffer->buffer;
pnp_printf(buffer, "state = "); pnp_printf(buffer, "state = %s\n", dev->active ? "active" : "disabled");
if (dev->active)
pnp_printf(buffer, "active\n"); list_for_each_entry(pnp_res, &dev->resources, list) {
else res = &pnp_res->res;
pnp_printf(buffer, "disabled\n");
pnp_printf(buffer, pnp_resource_type_name(res));
for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) {
if (pnp_resource_valid(res)) { if (res->flags & IORESOURCE_DISABLED) {
pnp_printf(buffer, "io"); pnp_printf(buffer, " disabled\n");
if (res->flags & IORESOURCE_DISABLED) continue;
pnp_printf(buffer, " disabled\n");
else
pnp_printf(buffer, " 0x%llx-0x%llx\n",
(unsigned long long) res->start,
(unsigned long long) res->end);
}
}
for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
if (pnp_resource_valid(res)) {
pnp_printf(buffer, "mem");
if (res->flags & IORESOURCE_DISABLED)
pnp_printf(buffer, " disabled\n");
else
pnp_printf(buffer, " 0x%llx-0x%llx\n",
(unsigned long long) res->start,
(unsigned long long) res->end);
}
}
for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IRQ, i)); i++) {
if (pnp_resource_valid(res)) {
pnp_printf(buffer, "irq");
if (res->flags & IORESOURCE_DISABLED)
pnp_printf(buffer, " disabled\n");
else
pnp_printf(buffer, " %lld\n",
(unsigned long long) res->start);
} }
}
for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_DMA, i)); i++) { switch (pnp_resource_type(res)) {
if (pnp_resource_valid(res)) { case IORESOURCE_IO:
pnp_printf(buffer, "dma"); case IORESOURCE_MEM:
if (res->flags & IORESOURCE_DISABLED) pnp_printf(buffer, " %#llx-%#llx\n",
pnp_printf(buffer, " disabled\n"); (unsigned long long) res->start,
else (unsigned long long) res->end);
pnp_printf(buffer, " %lld\n", break;
(unsigned long long) res->start); case IORESOURCE_IRQ:
case IORESOURCE_DMA:
pnp_printf(buffer, " %lld\n",
(unsigned long long) res->start);
break;
} }
} }
ret = (buffer->curr - buf); ret = (buffer->curr - buf);
kfree(buffer); kfree(buffer);
return ret; return ret;
} }
static ssize_t static ssize_t pnp_set_current_resources(struct device *dmdev,
pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, struct device_attribute *attr,
const char *ubuf, size_t count) const char *ubuf, size_t count)
{ {
struct pnp_dev *dev = to_pnp_dev(dmdev); struct pnp_dev *dev = to_pnp_dev(dmdev);
struct pnp_resource *pnp_res;
char *buf = (void *)ubuf; char *buf = (void *)ubuf;
int retval = 0; int retval = 0;
resource_size_t start, end; resource_size_t start, end;
...@@ -368,7 +350,6 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, ...@@ -368,7 +350,6 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
goto done; goto done;
} }
if (!strnicmp(buf, "set", 3)) { if (!strnicmp(buf, "set", 3)) {
int nport = 0, nmem = 0, nirq = 0, ndma = 0;
if (dev->active) if (dev->active)
goto done; goto done;
buf += 3; buf += 3;
...@@ -391,10 +372,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, ...@@ -391,10 +372,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
end = simple_strtoul(buf, &buf, 0); end = simple_strtoul(buf, &buf, 0);
} else } else
end = start; end = start;
pnp_res = pnp_add_io_resource(dev, start, end, pnp_add_io_resource(dev, start, end, 0);
0);
if (pnp_res)
pnp_res->index = nport++;
continue; continue;
} }
if (!strnicmp(buf, "mem", 3)) { if (!strnicmp(buf, "mem", 3)) {
...@@ -411,10 +389,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, ...@@ -411,10 +389,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
end = simple_strtoul(buf, &buf, 0); end = simple_strtoul(buf, &buf, 0);
} else } else
end = start; end = start;
pnp_res = pnp_add_mem_resource(dev, start, end, pnp_add_mem_resource(dev, start, end, 0);
0);
if (pnp_res)
pnp_res->index = nmem++;
continue; continue;
} }
if (!strnicmp(buf, "irq", 3)) { if (!strnicmp(buf, "irq", 3)) {
...@@ -422,9 +397,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, ...@@ -422,9 +397,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
while (isspace(*buf)) while (isspace(*buf))
++buf; ++buf;
start = simple_strtoul(buf, &buf, 0); start = simple_strtoul(buf, &buf, 0);
pnp_res = pnp_add_irq_resource(dev, start, 0); pnp_add_irq_resource(dev, start, 0);
if (pnp_res)
pnp_res->index = nirq++;
continue; continue;
} }
if (!strnicmp(buf, "dma", 3)) { if (!strnicmp(buf, "dma", 3)) {
...@@ -432,9 +405,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, ...@@ -432,9 +405,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
while (isspace(*buf)) while (isspace(*buf))
++buf; ++buf;
start = simple_strtoul(buf, &buf, 0); start = simple_strtoul(buf, &buf, 0);
pnp_res = pnp_add_dma_resource(dev, start, 0); pnp_add_dma_resource(dev, start, 0);
if (pnp_res)
pnp_res->index = ndma++;
continue; continue;
} }
break; break;
......
...@@ -429,154 +429,135 @@ static struct pnp_dev *__init isapnp_parse_device(struct pnp_card *card, ...@@ -429,154 +429,135 @@ static struct pnp_dev *__init isapnp_parse_device(struct pnp_card *card,
* Add IRQ resource to resources list. * Add IRQ resource to resources list.
*/ */
static void __init isapnp_parse_irq_resource(struct pnp_dev *dev, static void __init isapnp_parse_irq_resource(struct pnp_dev *dev,
struct pnp_option *option, unsigned int option_flags,
int size) int size)
{ {
unsigned char tmp[3]; unsigned char tmp[3];
struct pnp_irq *irq;
unsigned long bits; unsigned long bits;
pnp_irq_mask_t map;
unsigned char flags = IORESOURCE_IRQ_HIGHEDGE;
isapnp_peek(tmp, size); isapnp_peek(tmp, size);
irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
if (!irq)
return;
bits = (tmp[1] << 8) | tmp[0]; bits = (tmp[1] << 8) | tmp[0];
bitmap_copy(irq->map, &bits, 16);
bitmap_zero(map.bits, PNP_IRQ_NR);
bitmap_copy(map.bits, &bits, 16);
if (size > 2) if (size > 2)
irq->flags = tmp[2]; flags = tmp[2];
else
irq->flags = IORESOURCE_IRQ_HIGHEDGE; pnp_register_irq_resource(dev, option_flags, &map, flags);
pnp_register_irq_resource(dev, option, irq);
} }
/* /*
* Add DMA resource to resources list. * Add DMA resource to resources list.
*/ */
static void __init isapnp_parse_dma_resource(struct pnp_dev *dev, static void __init isapnp_parse_dma_resource(struct pnp_dev *dev,
struct pnp_option *option, unsigned int option_flags,
int size) int size)
{ {
unsigned char tmp[2]; unsigned char tmp[2];
struct pnp_dma *dma;
isapnp_peek(tmp, size); isapnp_peek(tmp, size);
dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL); pnp_register_dma_resource(dev, option_flags, tmp[0], tmp[1]);
if (!dma)
return;
dma->map = tmp[0];
dma->flags = tmp[1];
pnp_register_dma_resource(dev, option, dma);
} }
/* /*
* Add port resource to resources list. * Add port resource to resources list.
*/ */
static void __init isapnp_parse_port_resource(struct pnp_dev *dev, static void __init isapnp_parse_port_resource(struct pnp_dev *dev,
struct pnp_option *option, unsigned int option_flags,
int size) int size)
{ {
unsigned char tmp[7]; unsigned char tmp[7];
struct pnp_port *port; resource_size_t min, max, align, len;
unsigned char flags;
isapnp_peek(tmp, size); isapnp_peek(tmp, size);
port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL); min = (tmp[2] << 8) | tmp[1];
if (!port) max = (tmp[4] << 8) | tmp[3];
return; align = tmp[5];
port->min = (tmp[2] << 8) | tmp[1]; len = tmp[6];
port->max = (tmp[4] << 8) | tmp[3]; flags = tmp[0] ? IORESOURCE_IO_16BIT_ADDR : 0;
port->align = tmp[5]; pnp_register_port_resource(dev, option_flags,
port->size = tmp[6]; min, max, align, len, flags);
port->flags = tmp[0] ? PNP_PORT_FLAG_16BITADDR : 0;
pnp_register_port_resource(dev, option, port);
} }
/* /*
* Add fixed port resource to resources list. * Add fixed port resource to resources list.
*/ */
static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev, static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev,
struct pnp_option *option, unsigned int option_flags,
int size) int size)
{ {
unsigned char tmp[3]; unsigned char tmp[3];
struct pnp_port *port; resource_size_t base, len;
isapnp_peek(tmp, size); isapnp_peek(tmp, size);
port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL); base = (tmp[1] << 8) | tmp[0];
if (!port) len = tmp[2];
return; pnp_register_port_resource(dev, option_flags, base, base, 0, len,
port->min = port->max = (tmp[1] << 8) | tmp[0]; IORESOURCE_IO_FIXED);
port->size = tmp[2];
port->align = 0;
port->flags = PNP_PORT_FLAG_FIXED;
pnp_register_port_resource(dev, option, port);
} }
/* /*
* Add memory resource to resources list. * Add memory resource to resources list.
*/ */
static void __init isapnp_parse_mem_resource(struct pnp_dev *dev, static void __init isapnp_parse_mem_resource(struct pnp_dev *dev,
struct pnp_option *option, unsigned int option_flags,
int size) int size)
{ {
unsigned char tmp[9]; unsigned char tmp[9];
struct pnp_mem *mem; resource_size_t min, max, align, len;
unsigned char flags;
isapnp_peek(tmp, size); isapnp_peek(tmp, size);
mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); min = ((tmp[2] << 8) | tmp[1]) << 8;
if (!mem) max = ((tmp[4] << 8) | tmp[3]) << 8;
return; align = (tmp[6] << 8) | tmp[5];
mem->min = ((tmp[2] << 8) | tmp[1]) << 8; len = ((tmp[8] << 8) | tmp[7]) << 8;
mem->max = ((tmp[4] << 8) | tmp[3]) << 8; flags = tmp[0];
mem->align = (tmp[6] << 8) | tmp[5]; pnp_register_mem_resource(dev, option_flags,
mem->size = ((tmp[8] << 8) | tmp[7]) << 8; min, max, align, len, flags);
mem->flags = tmp[0];
pnp_register_mem_resource(dev, option, mem);
} }
/* /*
* Add 32-bit memory resource to resources list. * Add 32-bit memory resource to resources list.
*/ */
static void __init isapnp_parse_mem32_resource(struct pnp_dev *dev, static void __init isapnp_parse_mem32_resource(struct pnp_dev *dev,
struct pnp_option *option, unsigned int option_flags,
int size) int size)
{ {
unsigned char tmp[17]; unsigned char tmp[17];
struct pnp_mem *mem; resource_size_t min, max, align, len;
unsigned char flags;
isapnp_peek(tmp, size); isapnp_peek(tmp, size);
mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); min = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
if (!mem) max = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
return; align = (tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9];
mem->min = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1]; len = (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13];
mem->max = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5]; flags = tmp[0];
mem->align = pnp_register_mem_resource(dev, option_flags,
(tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9]; min, max, align, len, flags);
mem->size =
(tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13];
mem->flags = tmp[0];
pnp_register_mem_resource(dev, option, mem);
} }
/* /*
* Add 32-bit fixed memory resource to resources list. * Add 32-bit fixed memory resource to resources list.
*/ */
static void __init isapnp_parse_fixed_mem32_resource(struct pnp_dev *dev, static void __init isapnp_parse_fixed_mem32_resource(struct pnp_dev *dev,
struct pnp_option *option, unsigned int option_flags,
int size) int size)
{ {
unsigned char tmp[9]; unsigned char tmp[9];
struct pnp_mem *mem; resource_size_t base, len;
unsigned char flags;
isapnp_peek(tmp, size); isapnp_peek(tmp, size);
mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); base = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
if (!mem) len = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
return; flags = tmp[0];
mem->min = mem->max = pnp_register_mem_resource(dev, option_flags, base, base, 0, len, flags);
(tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
mem->size = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
mem->align = 0;
mem->flags = tmp[0];
pnp_register_mem_resource(dev, option, mem);
} }
/* /*
...@@ -604,20 +585,16 @@ isapnp_parse_name(char *name, unsigned int name_max, unsigned short *size) ...@@ -604,20 +585,16 @@ isapnp_parse_name(char *name, unsigned int name_max, unsigned short *size)
static int __init isapnp_create_device(struct pnp_card *card, static int __init isapnp_create_device(struct pnp_card *card,
unsigned short size) unsigned short size)
{ {
int number = 0, skip = 0, priority = 0, compat = 0; int number = 0, skip = 0, priority, compat = 0;
unsigned char type, tmp[17]; unsigned char type, tmp[17];
struct pnp_option *option; unsigned int option_flags;
struct pnp_dev *dev; struct pnp_dev *dev;
u32 eisa_id; u32 eisa_id;
char id[8]; char id[8];
if ((dev = isapnp_parse_device(card, size, number++)) == NULL) if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
return 1; return 1;
option = pnp_register_independent_option(dev); option_flags = 0;
if (!option) {
kfree(dev);
return 1;
}
pnp_add_card_device(card, dev); pnp_add_card_device(card, dev);
while (1) { while (1) {
...@@ -634,16 +611,11 @@ static int __init isapnp_create_device(struct pnp_card *card, ...@@ -634,16 +611,11 @@ static int __init isapnp_create_device(struct pnp_card *card,
return 1; return 1;
size = 0; size = 0;
skip = 0; skip = 0;
option = pnp_register_independent_option(dev); option_flags = 0;
if (!option) {
kfree(dev);
return 1;
}
pnp_add_card_device(card, dev); pnp_add_card_device(card, dev);
} else { } else {
skip = 1; skip = 1;
} }
priority = 0;
compat = 0; compat = 0;
break; break;
case _STAG_COMPATDEVID: case _STAG_COMPATDEVID:
...@@ -660,44 +632,42 @@ static int __init isapnp_create_device(struct pnp_card *card, ...@@ -660,44 +632,42 @@ static int __init isapnp_create_device(struct pnp_card *card,
case _STAG_IRQ: case _STAG_IRQ:
if (size < 2 || size > 3) if (size < 2 || size > 3)
goto __skip; goto __skip;
isapnp_parse_irq_resource(dev, option, size); isapnp_parse_irq_resource(dev, option_flags, size);
size = 0; size = 0;
break; break;
case _STAG_DMA: case _STAG_DMA:
if (size != 2) if (size != 2)
goto __skip; goto __skip;
isapnp_parse_dma_resource(dev, option, size); isapnp_parse_dma_resource(dev, option_flags, size);
size = 0; size = 0;
break; break;
case _STAG_STARTDEP: case _STAG_STARTDEP:
if (size > 1) if (size > 1)
goto __skip; goto __skip;
priority = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE; priority = PNP_RES_PRIORITY_ACCEPTABLE;
if (size > 0) { if (size > 0) {
isapnp_peek(tmp, size); isapnp_peek(tmp, size);
priority = 0x100 | tmp[0]; priority = tmp[0];
size = 0; size = 0;
} }
option = pnp_register_dependent_option(dev, priority); option_flags = pnp_new_dependent_set(dev, priority);
if (!option)
return 1;
break; break;
case _STAG_ENDDEP: case _STAG_ENDDEP:
if (size != 0) if (size != 0)
goto __skip; goto __skip;
priority = 0; option_flags = 0;
dev_dbg(&dev->dev, "end dependent options\n");
break; break;
case _STAG_IOPORT: case _STAG_IOPORT:
if (size != 7) if (size != 7)
goto __skip; goto __skip;
isapnp_parse_port_resource(dev, option, size); isapnp_parse_port_resource(dev, option_flags, size);
size = 0; size = 0;
break; break;
case _STAG_FIXEDIO: case _STAG_FIXEDIO:
if (size != 3) if (size != 3)
goto __skip; goto __skip;
isapnp_parse_fixed_port_resource(dev, option, size); isapnp_parse_fixed_port_resource(dev, option_flags,
size);
size = 0; size = 0;
break; break;
case _STAG_VENDOR: case _STAG_VENDOR:
...@@ -705,7 +675,7 @@ static int __init isapnp_create_device(struct pnp_card *card, ...@@ -705,7 +675,7 @@ static int __init isapnp_create_device(struct pnp_card *card,
case _LTAG_MEMRANGE: case _LTAG_MEMRANGE:
if (size != 9) if (size != 9)
goto __skip; goto __skip;
isapnp_parse_mem_resource(dev, option, size); isapnp_parse_mem_resource(dev, option_flags, size);
size = 0; size = 0;
break; break;
case _LTAG_ANSISTR: case _LTAG_ANSISTR:
...@@ -720,13 +690,14 @@ static int __init isapnp_create_device(struct pnp_card *card, ...@@ -720,13 +690,14 @@ static int __init isapnp_create_device(struct pnp_card *card,
case _LTAG_MEM32RANGE: case _LTAG_MEM32RANGE:
if (size != 17) if (size != 17)
goto __skip; goto __skip;
isapnp_parse_mem32_resource(dev, option, size); isapnp_parse_mem32_resource(dev, option_flags, size);
size = 0; size = 0;
break; break;
case _LTAG_FIXEDMEM32RANGE: case _LTAG_FIXEDMEM32RANGE:
if (size != 9) if (size != 9)
goto __skip; goto __skip;
isapnp_parse_fixed_mem32_resource(dev, option, size); isapnp_parse_fixed_mem32_resource(dev, option_flags,
size);
size = 0; size = 0;
break; break;
case _STAG_END: case _STAG_END:
...@@ -928,7 +899,6 @@ EXPORT_SYMBOL(isapnp_write_byte); ...@@ -928,7 +899,6 @@ EXPORT_SYMBOL(isapnp_write_byte);
static int isapnp_get_resources(struct pnp_dev *dev) static int isapnp_get_resources(struct pnp_dev *dev)
{ {
struct pnp_resource *pnp_res;
int i, ret; int i, ret;
dev_dbg(&dev->dev, "get resources\n"); dev_dbg(&dev->dev, "get resources\n");
...@@ -940,35 +910,23 @@ static int isapnp_get_resources(struct pnp_dev *dev) ...@@ -940,35 +910,23 @@ static int isapnp_get_resources(struct pnp_dev *dev)
for (i = 0; i < ISAPNP_MAX_PORT; i++) { for (i = 0; i < ISAPNP_MAX_PORT; i++) {
ret = isapnp_read_word(ISAPNP_CFG_PORT + (i << 1)); ret = isapnp_read_word(ISAPNP_CFG_PORT + (i << 1));
if (ret) { pnp_add_io_resource(dev, ret, ret,
pnp_res = pnp_add_io_resource(dev, ret, ret, 0); ret == 0 ? IORESOURCE_DISABLED : 0);
if (pnp_res)
pnp_res->index = i;
}
} }
for (i = 0; i < ISAPNP_MAX_MEM; i++) { for (i = 0; i < ISAPNP_MAX_MEM; i++) {
ret = isapnp_read_word(ISAPNP_CFG_MEM + (i << 3)) << 8; ret = isapnp_read_word(ISAPNP_CFG_MEM + (i << 3)) << 8;
if (ret) { pnp_add_mem_resource(dev, ret, ret,
pnp_res = pnp_add_mem_resource(dev, ret, ret, 0); ret == 0 ? IORESOURCE_DISABLED : 0);
if (pnp_res)
pnp_res->index = i;
}
} }
for (i = 0; i < ISAPNP_MAX_IRQ; i++) { for (i = 0; i < ISAPNP_MAX_IRQ; i++) {
ret = isapnp_read_word(ISAPNP_CFG_IRQ + (i << 1)) >> 8; ret = isapnp_read_word(ISAPNP_CFG_IRQ + (i << 1)) >> 8;
if (ret) { pnp_add_irq_resource(dev, ret,
pnp_res = pnp_add_irq_resource(dev, ret, 0); ret == 0 ? IORESOURCE_DISABLED : 0);
if (pnp_res)
pnp_res->index = i;
}
} }
for (i = 0; i < ISAPNP_MAX_DMA; i++) { for (i = 0; i < ISAPNP_MAX_DMA; i++) {
ret = isapnp_read_byte(ISAPNP_CFG_DMA + i); ret = isapnp_read_byte(ISAPNP_CFG_DMA + i);
if (ret != 4) { pnp_add_dma_resource(dev, ret,
pnp_res = pnp_add_dma_resource(dev, ret, 0); ret == 4 ? IORESOURCE_DISABLED : 0);
if (pnp_res)
pnp_res->index = i;
}
} }
__end: __end:
...@@ -978,62 +936,45 @@ static int isapnp_get_resources(struct pnp_dev *dev) ...@@ -978,62 +936,45 @@ static int isapnp_get_resources(struct pnp_dev *dev)
static int isapnp_set_resources(struct pnp_dev *dev) static int isapnp_set_resources(struct pnp_dev *dev)
{ {
struct pnp_resource *pnp_res;
struct resource *res; struct resource *res;
int tmp, index; int tmp;
dev_dbg(&dev->dev, "set resources\n"); dev_dbg(&dev->dev, "set resources\n");
isapnp_cfg_begin(dev->card->number, dev->number); isapnp_cfg_begin(dev->card->number, dev->number);
dev->active = 1; dev->active = 1;
for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) { for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) {
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, tmp); res = pnp_get_resource(dev, IORESOURCE_IO, tmp);
if (!pnp_res) if (pnp_resource_enabled(res)) {
continue;
res = &pnp_res->res;
if (pnp_resource_valid(res)) {
index = pnp_res->index;
dev_dbg(&dev->dev, " set io %d to %#llx\n", dev_dbg(&dev->dev, " set io %d to %#llx\n",
index, (unsigned long long) res->start); tmp, (unsigned long long) res->start);
isapnp_write_word(ISAPNP_CFG_PORT + (index << 1), isapnp_write_word(ISAPNP_CFG_PORT + (tmp << 1),
res->start); res->start);
} }
} }
for (tmp = 0; tmp < ISAPNP_MAX_IRQ; tmp++) { for (tmp = 0; tmp < ISAPNP_MAX_IRQ; tmp++) {
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, tmp); res = pnp_get_resource(dev, IORESOURCE_IRQ, tmp);
if (!pnp_res) if (pnp_resource_enabled(res)) {
continue;
res = &pnp_res->res;
if (pnp_resource_valid(res)) {
int irq = res->start; int irq = res->start;
if (irq == 2) if (irq == 2)
irq = 9; irq = 9;
index = pnp_res->index; dev_dbg(&dev->dev, " set irq %d to %d\n", tmp, irq);
dev_dbg(&dev->dev, " set irq %d to %d\n", index, irq); isapnp_write_byte(ISAPNP_CFG_IRQ + (tmp << 1), irq);
isapnp_write_byte(ISAPNP_CFG_IRQ + (index << 1), irq);
} }
} }
for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) { for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) {
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, tmp); res = pnp_get_resource(dev, IORESOURCE_DMA, tmp);
if (!pnp_res) if (pnp_resource_enabled(res)) {
continue;
res = &pnp_res->res;
if (pnp_resource_valid(res)) {
index = pnp_res->index;
dev_dbg(&dev->dev, " set dma %d to %lld\n", dev_dbg(&dev->dev, " set dma %d to %lld\n",
index, (unsigned long long) res->start); tmp, (unsigned long long) res->start);
isapnp_write_byte(ISAPNP_CFG_DMA + index, res->start); isapnp_write_byte(ISAPNP_CFG_DMA + tmp, res->start);
} }
} }
for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) { for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) {
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_MEM, tmp); res = pnp_get_resource(dev, IORESOURCE_MEM, tmp);
if (!pnp_res) if (pnp_resource_enabled(res)) {
continue;
res = &pnp_res->res;
if (pnp_resource_valid(res)) {
index = pnp_res->index;
dev_dbg(&dev->dev, " set mem %d to %#llx\n", dev_dbg(&dev->dev, " set mem %d to %#llx\n",
index, (unsigned long long) res->start); tmp, (unsigned long long) res->start);
isapnp_write_word(ISAPNP_CFG_MEM + (index << 3), isapnp_write_word(ISAPNP_CFG_MEM + (tmp << 3),
(res->start >> 8) & 0xffff); (res->start >> 8) & 0xffff);
} }
} }
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
* *
* based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz> * based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz>
* Copyright 2003 Adam Belay <ambx1@neo.rr.com> * Copyright 2003 Adam Belay <ambx1@neo.rr.com>
* Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
* Bjorn Helgaas <bjorn.helgaas@hp.com>
*/ */
#include <linux/errno.h> #include <linux/errno.h>
...@@ -19,82 +21,64 @@ DEFINE_MUTEX(pnp_res_mutex); ...@@ -19,82 +21,64 @@ DEFINE_MUTEX(pnp_res_mutex);
static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
{ {
struct pnp_resource *pnp_res; struct resource *res, local_res;
struct resource *res;
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, idx);
if (!pnp_res) {
dev_err(&dev->dev, "too many I/O port resources\n");
/* pretend we were successful so at least the manager won't try again */
return 1;
}
res = &pnp_res->res;
/* check if this resource has been manually set, if so skip */ res = pnp_get_resource(dev, IORESOURCE_IO, idx);
if (!(res->flags & IORESOURCE_AUTO)) { if (res) {
dev_dbg(&dev->dev, " io %d already set to %#llx-%#llx " dev_dbg(&dev->dev, " io %d already set to %#llx-%#llx "
"flags %#lx\n", idx, (unsigned long long) res->start, "flags %#lx\n", idx, (unsigned long long) res->start,
(unsigned long long) res->end, res->flags); (unsigned long long) res->end, res->flags);
return 1; return 0;
} }
/* set the initial values */ res = &local_res;
pnp_res->index = idx; res->flags = rule->flags | IORESOURCE_AUTO;
res->flags |= rule->flags | IORESOURCE_IO; res->start = 0;
res->flags &= ~IORESOURCE_UNSET; res->end = 0;
if (!rule->size) { if (!rule->size) {
res->flags |= IORESOURCE_DISABLED; res->flags |= IORESOURCE_DISABLED;
dev_dbg(&dev->dev, " io %d disabled\n", idx); dev_dbg(&dev->dev, " io %d disabled\n", idx);
return 1; /* skip disabled resource requests */ goto __add;
} }
res->start = rule->min; res->start = rule->min;
res->end = res->start + rule->size - 1; res->end = res->start + rule->size - 1;
/* run through until pnp_check_port is happy */
while (!pnp_check_port(dev, res)) { while (!pnp_check_port(dev, res)) {
res->start += rule->align; res->start += rule->align;
res->end = res->start + rule->size - 1; res->end = res->start + rule->size - 1;
if (res->start > rule->max || !rule->align) { if (res->start > rule->max || !rule->align) {
dev_dbg(&dev->dev, " couldn't assign io %d\n", idx); dev_dbg(&dev->dev, " couldn't assign io %d "
return 0; "(min %#llx max %#llx)\n", idx,
(unsigned long long) rule->min,
(unsigned long long) rule->max);
return -EBUSY;
} }
} }
dev_dbg(&dev->dev, " assign io %d %#llx-%#llx\n", idx,
(unsigned long long) res->start, (unsigned long long) res->end); __add:
return 1; pnp_add_io_resource(dev, res->start, res->end, res->flags);
return 0;
} }
static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
{ {
struct pnp_resource *pnp_res; struct resource *res, local_res;
struct resource *res;
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_MEM, idx);
if (!pnp_res) {
dev_err(&dev->dev, "too many memory resources\n");
/* pretend we were successful so at least the manager won't try again */
return 1;
}
res = &pnp_res->res; res = pnp_get_resource(dev, IORESOURCE_MEM, idx);
if (res) {
/* check if this resource has been manually set, if so skip */
if (!(res->flags & IORESOURCE_AUTO)) {
dev_dbg(&dev->dev, " mem %d already set to %#llx-%#llx " dev_dbg(&dev->dev, " mem %d already set to %#llx-%#llx "
"flags %#lx\n", idx, (unsigned long long) res->start, "flags %#lx\n", idx, (unsigned long long) res->start,
(unsigned long long) res->end, res->flags); (unsigned long long) res->end, res->flags);
return 1; return 0;
} }
/* set the initial values */ res = &local_res;
pnp_res->index = idx; res->flags = rule->flags | IORESOURCE_AUTO;
res->flags |= rule->flags | IORESOURCE_MEM; res->start = 0;
res->flags &= ~IORESOURCE_UNSET; res->end = 0;
/* convert pnp flags to standard Linux flags */
if (!(rule->flags & IORESOURCE_MEM_WRITEABLE)) if (!(rule->flags & IORESOURCE_MEM_WRITEABLE))
res->flags |= IORESOURCE_READONLY; res->flags |= IORESOURCE_READONLY;
if (rule->flags & IORESOURCE_MEM_CACHEABLE) if (rule->flags & IORESOURCE_MEM_CACHEABLE)
...@@ -107,30 +91,32 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) ...@@ -107,30 +91,32 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
if (!rule->size) { if (!rule->size) {
res->flags |= IORESOURCE_DISABLED; res->flags |= IORESOURCE_DISABLED;
dev_dbg(&dev->dev, " mem %d disabled\n", idx); dev_dbg(&dev->dev, " mem %d disabled\n", idx);
return 1; /* skip disabled resource requests */ goto __add;
} }
res->start = rule->min; res->start = rule->min;
res->end = res->start + rule->size - 1; res->end = res->start + rule->size - 1;
/* run through until pnp_check_mem is happy */
while (!pnp_check_mem(dev, res)) { while (!pnp_check_mem(dev, res)) {
res->start += rule->align; res->start += rule->align;
res->end = res->start + rule->size - 1; res->end = res->start + rule->size - 1;
if (res->start > rule->max || !rule->align) { if (res->start > rule->max || !rule->align) {
dev_dbg(&dev->dev, " couldn't assign mem %d\n", idx); dev_dbg(&dev->dev, " couldn't assign mem %d "
return 0; "(min %#llx max %#llx)\n", idx,
(unsigned long long) rule->min,
(unsigned long long) rule->max);
return -EBUSY;
} }
} }
dev_dbg(&dev->dev, " assign mem %d %#llx-%#llx\n", idx,
(unsigned long long) res->start, (unsigned long long) res->end); __add:
return 1; pnp_add_mem_resource(dev, res->start, res->end, res->flags);
return 0;
} }
static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
{ {
struct pnp_resource *pnp_res; struct resource *res, local_res;
struct resource *res;
int i; int i;
/* IRQ priority: this table is good for i386 */ /* IRQ priority: this table is good for i386 */
...@@ -138,59 +124,57 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) ...@@ -138,59 +124,57 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2
}; };
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, idx); res = pnp_get_resource(dev, IORESOURCE_IRQ, idx);
if (!pnp_res) { if (res) {
dev_err(&dev->dev, "too many IRQ resources\n");
/* pretend we were successful so at least the manager won't try again */
return 1;
}
res = &pnp_res->res;
/* check if this resource has been manually set, if so skip */
if (!(res->flags & IORESOURCE_AUTO)) {
dev_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n", dev_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n",
idx, (int) res->start, res->flags); idx, (int) res->start, res->flags);
return 1; return 0;
} }
/* set the initial values */ res = &local_res;
pnp_res->index = idx; res->flags = rule->flags | IORESOURCE_AUTO;
res->flags |= rule->flags | IORESOURCE_IRQ; res->start = -1;
res->flags &= ~IORESOURCE_UNSET; res->end = -1;
if (bitmap_empty(rule->map, PNP_IRQ_NR)) { if (bitmap_empty(rule->map.bits, PNP_IRQ_NR)) {
res->flags |= IORESOURCE_DISABLED; res->flags |= IORESOURCE_DISABLED;
dev_dbg(&dev->dev, " irq %d disabled\n", idx); dev_dbg(&dev->dev, " irq %d disabled\n", idx);
return 1; /* skip disabled resource requests */ goto __add;
} }
/* TBD: need check for >16 IRQ */ /* TBD: need check for >16 IRQ */
res->start = find_next_bit(rule->map, PNP_IRQ_NR, 16); res->start = find_next_bit(rule->map.bits, PNP_IRQ_NR, 16);
if (res->start < PNP_IRQ_NR) { if (res->start < PNP_IRQ_NR) {
res->end = res->start; res->end = res->start;
dev_dbg(&dev->dev, " assign irq %d %d\n", idx, goto __add;
(int) res->start);
return 1;
} }
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
if (test_bit(xtab[i], rule->map)) { if (test_bit(xtab[i], rule->map.bits)) {
res->start = res->end = xtab[i]; res->start = res->end = xtab[i];
if (pnp_check_irq(dev, res)) { if (pnp_check_irq(dev, res))
dev_dbg(&dev->dev, " assign irq %d %d\n", idx, goto __add;
(int) res->start);
return 1;
}
} }
} }
if (rule->flags & IORESOURCE_IRQ_OPTIONAL) {
res->start = -1;
res->end = -1;
res->flags |= IORESOURCE_DISABLED;
dev_dbg(&dev->dev, " irq %d disabled (optional)\n", idx);
goto __add;
}
dev_dbg(&dev->dev, " couldn't assign irq %d\n", idx); dev_dbg(&dev->dev, " couldn't assign irq %d\n", idx);
return -EBUSY;
__add:
pnp_add_irq_resource(dev, res->start, res->flags);
return 0; return 0;
} }
static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
{ {
struct pnp_resource *pnp_res; struct resource *res, local_res;
struct resource *res;
int i; int i;
/* DMA priority: this table is good for i386 */ /* DMA priority: this table is good for i386 */
...@@ -198,231 +182,99 @@ static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) ...@@ -198,231 +182,99 @@ static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
1, 3, 5, 6, 7, 0, 2, 4 1, 3, 5, 6, 7, 0, 2, 4
}; };
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, idx); res = pnp_get_resource(dev, IORESOURCE_DMA, idx);
if (!pnp_res) { if (res) {
dev_err(&dev->dev, "too many DMA resources\n");
return;
}
res = &pnp_res->res;
/* check if this resource has been manually set, if so skip */
if (!(res->flags & IORESOURCE_AUTO)) {
dev_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n", dev_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n",
idx, (int) res->start, res->flags); idx, (int) res->start, res->flags);
return; return 0;
} }
/* set the initial values */ res = &local_res;
pnp_res->index = idx; res->flags = rule->flags | IORESOURCE_AUTO;
res->flags |= rule->flags | IORESOURCE_DMA; res->start = -1;
res->flags &= ~IORESOURCE_UNSET; res->end = -1;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
if (rule->map & (1 << xtab[i])) { if (rule->map & (1 << xtab[i])) {
res->start = res->end = xtab[i]; res->start = res->end = xtab[i];
if (pnp_check_dma(dev, res)) { if (pnp_check_dma(dev, res))
dev_dbg(&dev->dev, " assign dma %d %d\n", idx, goto __add;
(int) res->start);
return;
}
} }
} }
#ifdef MAX_DMA_CHANNELS #ifdef MAX_DMA_CHANNELS
res->start = res->end = MAX_DMA_CHANNELS; res->start = res->end = MAX_DMA_CHANNELS;
#endif #endif
res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED; res->flags |= IORESOURCE_DISABLED;
dev_dbg(&dev->dev, " disable dma %d\n", idx); dev_dbg(&dev->dev, " disable dma %d\n", idx);
}
void pnp_init_resource(struct resource *res)
{
unsigned long type;
type = res->flags & (IORESOURCE_IO | IORESOURCE_MEM |
IORESOURCE_IRQ | IORESOURCE_DMA);
res->name = NULL; __add:
res->flags = type | IORESOURCE_AUTO | IORESOURCE_UNSET; pnp_add_dma_resource(dev, res->start, res->flags);
if (type == IORESOURCE_IRQ || type == IORESOURCE_DMA) { return 0;
res->start = -1;
res->end = -1;
} else {
res->start = 0;
res->end = 0;
}
} }
/**
* pnp_init_resources - Resets a resource table to default values.
* @table: pointer to the desired resource table
*/
void pnp_init_resources(struct pnp_dev *dev) void pnp_init_resources(struct pnp_dev *dev)
{ {
struct resource *res; pnp_free_resources(dev);
int idx;
for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
res = &dev->res->irq[idx].res;
res->flags = IORESOURCE_IRQ;
pnp_init_resource(res);
}
for (idx = 0; idx < PNP_MAX_DMA; idx++) {
res = &dev->res->dma[idx].res;
res->flags = IORESOURCE_DMA;
pnp_init_resource(res);
}
for (idx = 0; idx < PNP_MAX_PORT; idx++) {
res = &dev->res->port[idx].res;
res->flags = IORESOURCE_IO;
pnp_init_resource(res);
}
for (idx = 0; idx < PNP_MAX_MEM; idx++) {
res = &dev->res->mem[idx].res;
res->flags = IORESOURCE_MEM;
pnp_init_resource(res);
}
} }
/**
* pnp_clean_resources - clears resources that were not manually set
* @res: the resources to clean
*/
static void pnp_clean_resource_table(struct pnp_dev *dev) static void pnp_clean_resource_table(struct pnp_dev *dev)
{ {
struct resource *res; struct pnp_resource *pnp_res, *tmp;
int idx;
list_for_each_entry_safe(pnp_res, tmp, &dev->resources, list) {
for (idx = 0; idx < PNP_MAX_IRQ; idx++) { if (pnp_res->res.flags & IORESOURCE_AUTO)
res = &dev->res->irq[idx].res; pnp_free_resource(pnp_res);
if (res->flags & IORESOURCE_AUTO) {
res->flags = IORESOURCE_IRQ;
pnp_init_resource(res);
}
}
for (idx = 0; idx < PNP_MAX_DMA; idx++) {
res = &dev->res->dma[idx].res;
if (res->flags & IORESOURCE_AUTO) {
res->flags = IORESOURCE_DMA;
pnp_init_resource(res);
}
}
for (idx = 0; idx < PNP_MAX_PORT; idx++) {
res = &dev->res->port[idx].res;
if (res->flags & IORESOURCE_AUTO) {
res->flags = IORESOURCE_IO;
pnp_init_resource(res);
}
}
for (idx = 0; idx < PNP_MAX_MEM; idx++) {
res = &dev->res->mem[idx].res;
if (res->flags & IORESOURCE_AUTO) {
res->flags = IORESOURCE_MEM;
pnp_init_resource(res);
}
} }
} }
/** /**
* pnp_assign_resources - assigns resources to the device based on the specified dependent number * pnp_assign_resources - assigns resources to the device based on the specified dependent number
* @dev: pointer to the desired device * @dev: pointer to the desired device
* @depnum: the dependent function number * @set: the dependent function number
*
* Only set depnum to 0 if the device does not have dependent options.
*/ */
static int pnp_assign_resources(struct pnp_dev *dev, int depnum) static int pnp_assign_resources(struct pnp_dev *dev, int set)
{ {
struct pnp_port *port; struct pnp_option *option;
struct pnp_mem *mem;
struct pnp_irq *irq;
struct pnp_dma *dma;
int nport = 0, nmem = 0, nirq = 0, ndma = 0; int nport = 0, nmem = 0, nirq = 0, ndma = 0;
int ret = 0;
if (!pnp_can_configure(dev)) dev_dbg(&dev->dev, "pnp_assign_resources, try dependent set %d\n", set);
return -ENODEV;
dbg_pnp_show_resources(dev, "before pnp_assign_resources");
mutex_lock(&pnp_res_mutex); mutex_lock(&pnp_res_mutex);
pnp_clean_resource_table(dev); pnp_clean_resource_table(dev);
if (dev->independent) {
dev_dbg(&dev->dev, "assigning independent options\n");
port = dev->independent->port;
mem = dev->independent->mem;
irq = dev->independent->irq;
dma = dev->independent->dma;
while (port) {
if (!pnp_assign_port(dev, port, nport))
goto fail;
nport++;
port = port->next;
}
while (mem) {
if (!pnp_assign_mem(dev, mem, nmem))
goto fail;
nmem++;
mem = mem->next;
}
while (irq) {
if (!pnp_assign_irq(dev, irq, nirq))
goto fail;
nirq++;
irq = irq->next;
}
while (dma) {
pnp_assign_dma(dev, dma, ndma);
ndma++;
dma = dma->next;
}
}
if (depnum) { list_for_each_entry(option, &dev->options, list) {
struct pnp_option *dep; if (pnp_option_is_dependent(option) &&
int i; pnp_option_set(option) != set)
continue;
dev_dbg(&dev->dev, "assigning dependent option %d\n", depnum);
for (i = 1, dep = dev->dependent; i < depnum; switch (option->type) {
i++, dep = dep->next) case IORESOURCE_IO:
if (!dep) ret = pnp_assign_port(dev, &option->u.port, nport++);
goto fail; break;
port = dep->port; case IORESOURCE_MEM:
mem = dep->mem; ret = pnp_assign_mem(dev, &option->u.mem, nmem++);
irq = dep->irq; break;
dma = dep->dma; case IORESOURCE_IRQ:
while (port) { ret = pnp_assign_irq(dev, &option->u.irq, nirq++);
if (!pnp_assign_port(dev, port, nport)) break;
goto fail; case IORESOURCE_DMA:
nport++; ret = pnp_assign_dma(dev, &option->u.dma, ndma++);
port = port->next; break;
} default:
while (mem) { ret = -EINVAL;
if (!pnp_assign_mem(dev, mem, nmem)) break;
goto fail;
nmem++;
mem = mem->next;
}
while (irq) {
if (!pnp_assign_irq(dev, irq, nirq))
goto fail;
nirq++;
irq = irq->next;
} }
while (dma) { if (ret < 0)
pnp_assign_dma(dev, dma, ndma); break;
ndma++; }
dma = dma->next;
}
} else if (dev->dependent)
goto fail;
mutex_unlock(&pnp_res_mutex);
dbg_pnp_show_resources(dev, "after pnp_assign_resources");
return 1;
fail:
pnp_clean_resource_table(dev);
mutex_unlock(&pnp_res_mutex); mutex_unlock(&pnp_res_mutex);
dbg_pnp_show_resources(dev, "after pnp_assign_resources (failed)"); if (ret < 0) {
return 0; dev_dbg(&dev->dev, "pnp_assign_resources failed (%d)\n", ret);
pnp_clean_resource_table(dev);
} else
dbg_pnp_show_resources(dev, "pnp_assign_resources succeeded");
return ret;
} }
/** /**
...@@ -431,29 +283,25 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum) ...@@ -431,29 +283,25 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
*/ */
int pnp_auto_config_dev(struct pnp_dev *dev) int pnp_auto_config_dev(struct pnp_dev *dev)
{ {
struct pnp_option *dep; int i, ret;
int i = 1;
if (!pnp_can_configure(dev)) { if (!pnp_can_configure(dev)) {
dev_dbg(&dev->dev, "configuration not supported\n"); dev_dbg(&dev->dev, "configuration not supported\n");
return -ENODEV; return -ENODEV;
} }
if (!dev->dependent) { ret = pnp_assign_resources(dev, 0);
if (pnp_assign_resources(dev, 0)) if (ret == 0)
return 0;
for (i = 1; i < dev->num_dependent_sets; i++) {
ret = pnp_assign_resources(dev, i);
if (ret == 0)
return 0; return 0;
} else {
dep = dev->dependent;
do {
if (pnp_assign_resources(dev, i))
return 0;
dep = dep->next;
i++;
} while (dep);
} }
dev_err(&dev->dev, "unable to assign resources\n"); dev_err(&dev->dev, "unable to assign resources\n");
return -EBUSY; return ret;
} }
/** /**
......
...@@ -117,9 +117,7 @@ static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state) ...@@ -117,9 +117,7 @@ static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state)
{ {
int power_state; int power_state;
power_state = acpi_pm_device_sleep_state(&dev->dev, power_state = acpi_pm_device_sleep_state(&dev->dev, NULL);
device_may_wakeup(&dev->dev),
NULL);
if (power_state < 0) if (power_state < 0)
power_state = (state.event == PM_EVENT_ON) ? power_state = (state.event == PM_EVENT_ON) ?
ACPI_STATE_D0 : ACPI_STATE_D3; ACPI_STATE_D0 : ACPI_STATE_D3;
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
* *
* Copyright (c) 2004 Matthieu Castet <castet.matthieu@free.fr> * Copyright (c) 2004 Matthieu Castet <castet.matthieu@free.fr>
* Copyright (c) 2004 Li Shaohua <shaohua.li@intel.com> * Copyright (c) 2004 Li Shaohua <shaohua.li@intel.com>
* Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
* Bjorn Helgaas <bjorn.helgaas@hp.com>
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the * under the terms of the GNU General Public License as published by the
...@@ -98,8 +100,10 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev, ...@@ -98,8 +100,10 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev,
int irq, flags; int irq, flags;
int p, t; int p, t;
if (!valid_IRQ(gsi)) if (!valid_IRQ(gsi)) {
pnp_add_irq_resource(dev, gsi, IORESOURCE_DISABLED);
return; return;
}
/* /*
* in IO-APIC mode, use overrided attribute. Two reasons: * in IO-APIC mode, use overrided attribute. Two reasons:
...@@ -178,13 +182,68 @@ static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start, ...@@ -178,13 +182,68 @@ static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start,
u64 end = start + len - 1; u64 end = start + len - 1;
if (io_decode == ACPI_DECODE_16) if (io_decode == ACPI_DECODE_16)
flags |= PNP_PORT_FLAG_16BITADDR; flags |= IORESOURCE_IO_16BIT_ADDR;
if (len == 0 || end >= 0x10003) if (len == 0 || end >= 0x10003)
flags |= IORESOURCE_DISABLED; flags |= IORESOURCE_DISABLED;
pnp_add_io_resource(dev, start, end, flags); pnp_add_io_resource(dev, start, end, flags);
} }
/*
* Device CSRs that do not appear in PCI config space should be described
* via ACPI. This would normally be done with Address Space Descriptors
* marked as "consumer-only," but old versions of Windows and Linux ignore
* the producer/consumer flag, so HP invented a vendor-defined resource to
* describe the location and size of CSR space.
*/
static struct acpi_vendor_uuid hp_ccsr_uuid = {
.subtype = 2,
.data = { 0xf9, 0xad, 0xe9, 0x69, 0x4f, 0x92, 0x5f, 0xab, 0xf6, 0x4a,
0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad },
};
static int vendor_resource_matches(struct pnp_dev *dev,
struct acpi_resource_vendor_typed *vendor,
struct acpi_vendor_uuid *match,
int expected_len)
{
int uuid_len = sizeof(vendor->uuid);
u8 uuid_subtype = vendor->uuid_subtype;
u8 *uuid = vendor->uuid;
int actual_len;
/* byte_length includes uuid_subtype and uuid */
actual_len = vendor->byte_length - uuid_len - 1;
if (uuid_subtype == match->subtype &&
uuid_len == sizeof(match->data) &&
memcmp(uuid, match->data, uuid_len) == 0) {
if (expected_len && expected_len != actual_len) {
dev_err(&dev->dev, "wrong vendor descriptor size; "
"expected %d, found %d bytes\n",
expected_len, actual_len);
return 0;
}
return 1;
}
return 0;
}
static void pnpacpi_parse_allocated_vendor(struct pnp_dev *dev,
struct acpi_resource_vendor_typed *vendor)
{
if (vendor_resource_matches(dev, vendor, &hp_ccsr_uuid, 16)) {
u64 start, length;
memcpy(&start, vendor->byte_data, sizeof(start));
memcpy(&length, vendor->byte_data + 8, sizeof(length));
pnp_add_mem_resource(dev, start, start + length - 1, 0);
}
}
static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev, static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev,
u64 start, u64 len, u64 start, u64 len,
int write_protect) int write_protect)
...@@ -235,6 +294,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, ...@@ -235,6 +294,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
struct acpi_resource_dma *dma; struct acpi_resource_dma *dma;
struct acpi_resource_io *io; struct acpi_resource_io *io;
struct acpi_resource_fixed_io *fixed_io; struct acpi_resource_fixed_io *fixed_io;
struct acpi_resource_vendor_typed *vendor_typed;
struct acpi_resource_memory24 *memory24; struct acpi_resource_memory24 *memory24;
struct acpi_resource_memory32 *memory32; struct acpi_resource_memory32 *memory32;
struct acpi_resource_fixed_memory32 *fixed_memory32; struct acpi_resource_fixed_memory32 *fixed_memory32;
...@@ -248,24 +308,39 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, ...@@ -248,24 +308,39 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
* _CRS, but some firmware violates this, so parse them all. * _CRS, but some firmware violates this, so parse them all.
*/ */
irq = &res->data.irq; irq = &res->data.irq;
for (i = 0; i < irq->interrupt_count; i++) { if (irq->interrupt_count == 0)
pnpacpi_parse_allocated_irqresource(dev, pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
irq->interrupts[i], else {
irq->triggering, for (i = 0; i < irq->interrupt_count; i++) {
irq->polarity, pnpacpi_parse_allocated_irqresource(dev,
irq->sharable); irq->interrupts[i],
irq->triggering,
irq->polarity,
irq->sharable);
}
/*
* The IRQ encoder puts a single interrupt in each
* descriptor, so if a _CRS descriptor has more than
* one interrupt, we won't be able to re-encode it.
*/
if (pnp_can_write(dev) && irq->interrupt_count > 1) {
dev_warn(&dev->dev, "multiple interrupts in "
"_CRS descriptor; configuration can't "
"be changed\n");
dev->capabilities &= ~PNP_WRITE;
}
} }
break; break;
case ACPI_RESOURCE_TYPE_DMA: case ACPI_RESOURCE_TYPE_DMA:
dma = &res->data.dma; dma = &res->data.dma;
if (dma->channel_count > 0) { if (dma->channel_count > 0 && dma->channels[0] != (u8) -1)
flags = dma_flags(dma->type, dma->bus_master, flags = dma_flags(dma->type, dma->bus_master,
dma->transfer); dma->transfer);
if (dma->channels[0] == (u8) -1) else
flags |= IORESOURCE_DISABLED; flags = IORESOURCE_DISABLED;
pnp_add_dma_resource(dev, dma->channels[0], flags); pnp_add_dma_resource(dev, dma->channels[0], flags);
}
break; break;
case ACPI_RESOURCE_TYPE_IO: case ACPI_RESOURCE_TYPE_IO:
...@@ -289,6 +364,8 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, ...@@ -289,6 +364,8 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
break; break;
case ACPI_RESOURCE_TYPE_VENDOR: case ACPI_RESOURCE_TYPE_VENDOR:
vendor_typed = &res->data.vendor_typed;
pnpacpi_parse_allocated_vendor(dev, vendor_typed);
break; break;
case ACPI_RESOURCE_TYPE_END_TAG: case ACPI_RESOURCE_TYPE_END_TAG:
...@@ -331,12 +408,29 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, ...@@ -331,12 +408,29 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
if (extended_irq->producer_consumer == ACPI_PRODUCER) if (extended_irq->producer_consumer == ACPI_PRODUCER)
return AE_OK; return AE_OK;
for (i = 0; i < extended_irq->interrupt_count; i++) { if (extended_irq->interrupt_count == 0)
pnpacpi_parse_allocated_irqresource(dev, pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
extended_irq->interrupts[i], else {
extended_irq->triggering, for (i = 0; i < extended_irq->interrupt_count; i++) {
extended_irq->polarity, pnpacpi_parse_allocated_irqresource(dev,
extended_irq->sharable); extended_irq->interrupts[i],
extended_irq->triggering,
extended_irq->polarity,
extended_irq->sharable);
}
/*
* The IRQ encoder puts a single interrupt in each
* descriptor, so if a _CRS descriptor has more than
* one interrupt, we won't be able to re-encode it.
*/
if (pnp_can_write(dev) &&
extended_irq->interrupt_count > 1) {
dev_warn(&dev->dev, "multiple interrupts in "
"_CRS descriptor; configuration can't "
"be changed\n");
dev->capabilities &= ~PNP_WRITE;
}
} }
break; break;
...@@ -373,179 +467,147 @@ int pnpacpi_parse_allocated_resource(struct pnp_dev *dev) ...@@ -373,179 +467,147 @@ int pnpacpi_parse_allocated_resource(struct pnp_dev *dev)
} }
static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev, static __init void pnpacpi_parse_dma_option(struct pnp_dev *dev,
struct pnp_option *option, unsigned int option_flags,
struct acpi_resource_dma *p) struct acpi_resource_dma *p)
{ {
int i; int i;
struct pnp_dma *dma; unsigned char map = 0, flags;
if (p->channel_count == 0) if (p->channel_count == 0)
return; return;
dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
if (!dma)
return;
for (i = 0; i < p->channel_count; i++) for (i = 0; i < p->channel_count; i++)
dma->map |= 1 << p->channels[i]; map |= 1 << p->channels[i];
dma->flags = dma_flags(p->type, p->bus_master, p->transfer);
pnp_register_dma_resource(dev, option, dma); flags = dma_flags(p->type, p->bus_master, p->transfer);
pnp_register_dma_resource(dev, option_flags, map, flags);
} }
static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev, static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev,
struct pnp_option *option, unsigned int option_flags,
struct acpi_resource_irq *p) struct acpi_resource_irq *p)
{ {
int i; int i;
struct pnp_irq *irq; pnp_irq_mask_t map;
unsigned char flags;
if (p->interrupt_count == 0) if (p->interrupt_count == 0)
return; return;
irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
if (!irq)
return;
bitmap_zero(map.bits, PNP_IRQ_NR);
for (i = 0; i < p->interrupt_count; i++) for (i = 0; i < p->interrupt_count; i++)
if (p->interrupts[i]) if (p->interrupts[i])
__set_bit(p->interrupts[i], irq->map); __set_bit(p->interrupts[i], map.bits);
irq->flags = irq_flags(p->triggering, p->polarity, p->sharable);
pnp_register_irq_resource(dev, option, irq); flags = irq_flags(p->triggering, p->polarity, p->sharable);
pnp_register_irq_resource(dev, option_flags, &map, flags);
} }
static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev, static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev,
struct pnp_option *option, unsigned int option_flags,
struct acpi_resource_extended_irq *p) struct acpi_resource_extended_irq *p)
{ {
int i; int i;
struct pnp_irq *irq; pnp_irq_mask_t map;
unsigned char flags;
if (p->interrupt_count == 0) if (p->interrupt_count == 0)
return; return;
irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
if (!irq)
return;
for (i = 0; i < p->interrupt_count; i++) bitmap_zero(map.bits, PNP_IRQ_NR);
if (p->interrupts[i]) for (i = 0; i < p->interrupt_count; i++) {
__set_bit(p->interrupts[i], irq->map); if (p->interrupts[i]) {
irq->flags = irq_flags(p->triggering, p->polarity, p->sharable); if (p->interrupts[i] < PNP_IRQ_NR)
__set_bit(p->interrupts[i], map.bits);
else
dev_err(&dev->dev, "ignoring IRQ %d option "
"(too large for %d entry bitmap)\n",
p->interrupts[i], PNP_IRQ_NR);
}
}
pnp_register_irq_resource(dev, option, irq); flags = irq_flags(p->triggering, p->polarity, p->sharable);
pnp_register_irq_resource(dev, option_flags, &map, flags);
} }
static __init void pnpacpi_parse_port_option(struct pnp_dev *dev, static __init void pnpacpi_parse_port_option(struct pnp_dev *dev,
struct pnp_option *option, unsigned int option_flags,
struct acpi_resource_io *io) struct acpi_resource_io *io)
{ {
struct pnp_port *port; unsigned char flags = 0;
if (io->address_length == 0) if (io->address_length == 0)
return; return;
port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
if (!port) if (io->io_decode == ACPI_DECODE_16)
return; flags = IORESOURCE_IO_16BIT_ADDR;
port->min = io->minimum; pnp_register_port_resource(dev, option_flags, io->minimum, io->maximum,
port->max = io->maximum; io->alignment, io->address_length, flags);
port->align = io->alignment;
port->size = io->address_length;
port->flags = ACPI_DECODE_16 == io->io_decode ?
PNP_PORT_FLAG_16BITADDR : 0;
pnp_register_port_resource(dev, option, port);
} }
static __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev, static __init void pnpacpi_parse_fixed_port_option(struct pnp_dev *dev,
struct pnp_option *option, unsigned int option_flags,
struct acpi_resource_fixed_io *io) struct acpi_resource_fixed_io *io)
{ {
struct pnp_port *port;
if (io->address_length == 0) if (io->address_length == 0)
return; return;
port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
if (!port) pnp_register_port_resource(dev, option_flags, io->address, io->address,
return; 0, io->address_length, IORESOURCE_IO_FIXED);
port->min = port->max = io->address;
port->size = io->address_length;
port->align = 0;
port->flags = PNP_PORT_FLAG_FIXED;
pnp_register_port_resource(dev, option, port);
} }
static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev, static __init void pnpacpi_parse_mem24_option(struct pnp_dev *dev,
struct pnp_option *option, unsigned int option_flags,
struct acpi_resource_memory24 *p) struct acpi_resource_memory24 *p)
{ {
struct pnp_mem *mem; unsigned char flags = 0;
if (p->address_length == 0) if (p->address_length == 0)
return; return;
mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
if (!mem)
return;
mem->min = p->minimum;
mem->max = p->maximum;
mem->align = p->alignment;
mem->size = p->address_length;
mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
IORESOURCE_MEM_WRITEABLE : 0;
pnp_register_mem_resource(dev, option, mem); if (p->write_protect == ACPI_READ_WRITE_MEMORY)
flags = IORESOURCE_MEM_WRITEABLE;
pnp_register_mem_resource(dev, option_flags, p->minimum, p->maximum,
p->alignment, p->address_length, flags);
} }
static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev, static __init void pnpacpi_parse_mem32_option(struct pnp_dev *dev,
struct pnp_option *option, unsigned int option_flags,
struct acpi_resource_memory32 *p) struct acpi_resource_memory32 *p)
{ {
struct pnp_mem *mem; unsigned char flags = 0;
if (p->address_length == 0) if (p->address_length == 0)
return; return;
mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
if (!mem)
return;
mem->min = p->minimum;
mem->max = p->maximum;
mem->align = p->alignment;
mem->size = p->address_length;
mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
IORESOURCE_MEM_WRITEABLE : 0;
pnp_register_mem_resource(dev, option, mem); if (p->write_protect == ACPI_READ_WRITE_MEMORY)
flags = IORESOURCE_MEM_WRITEABLE;
pnp_register_mem_resource(dev, option_flags, p->minimum, p->maximum,
p->alignment, p->address_length, flags);
} }
static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev, static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_dev *dev,
struct pnp_option *option, unsigned int option_flags,
struct acpi_resource_fixed_memory32 *p) struct acpi_resource_fixed_memory32 *p)
{ {
struct pnp_mem *mem; unsigned char flags = 0;
if (p->address_length == 0) if (p->address_length == 0)
return; return;
mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
if (!mem)
return;
mem->min = mem->max = p->address;
mem->size = p->address_length;
mem->align = 0;
mem->flags = (ACPI_READ_WRITE_MEMORY == p->write_protect) ?
IORESOURCE_MEM_WRITEABLE : 0;
pnp_register_mem_resource(dev, option, mem); if (p->write_protect == ACPI_READ_WRITE_MEMORY)
flags = IORESOURCE_MEM_WRITEABLE;
pnp_register_mem_resource(dev, option_flags, p->address, p->address,
0, p->address_length, flags);
} }
static __init void pnpacpi_parse_address_option(struct pnp_dev *dev, static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
struct pnp_option *option, unsigned int option_flags,
struct acpi_resource *r) struct acpi_resource *r)
{ {
struct acpi_resource_address64 addr, *p = &addr; struct acpi_resource_address64 addr, *p = &addr;
acpi_status status; acpi_status status;
struct pnp_mem *mem; unsigned char flags = 0;
struct pnp_port *port;
status = acpi_resource_to_address64(r, p); status = acpi_resource_to_address64(r, p);
if (!ACPI_SUCCESS(status)) { if (!ACPI_SUCCESS(status)) {
...@@ -558,49 +620,37 @@ static __init void pnpacpi_parse_address_option(struct pnp_dev *dev, ...@@ -558,49 +620,37 @@ static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
return; return;
if (p->resource_type == ACPI_MEMORY_RANGE) { if (p->resource_type == ACPI_MEMORY_RANGE) {
mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY)
if (!mem) flags = IORESOURCE_MEM_WRITEABLE;
return; pnp_register_mem_resource(dev, option_flags, p->minimum,
mem->min = mem->max = p->minimum; p->minimum, 0, p->address_length,
mem->size = p->address_length; flags);
mem->align = 0; } else if (p->resource_type == ACPI_IO_RANGE)
mem->flags = (p->info.mem.write_protect == pnp_register_port_resource(dev, option_flags, p->minimum,
ACPI_READ_WRITE_MEMORY) ? IORESOURCE_MEM_WRITEABLE p->minimum, 0, p->address_length,
: 0; IORESOURCE_IO_FIXED);
pnp_register_mem_resource(dev, option, mem);
} else if (p->resource_type == ACPI_IO_RANGE) {
port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
if (!port)
return;
port->min = port->max = p->minimum;
port->size = p->address_length;
port->align = 0;
port->flags = PNP_PORT_FLAG_FIXED;
pnp_register_port_resource(dev, option, port);
}
} }
struct acpipnp_parse_option_s { struct acpipnp_parse_option_s {
struct pnp_option *option;
struct pnp_option *option_independent;
struct pnp_dev *dev; struct pnp_dev *dev;
unsigned int option_flags;
}; };
static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res, static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
void *data) void *data)
{ {
int priority = 0; int priority;
struct acpipnp_parse_option_s *parse_data = data; struct acpipnp_parse_option_s *parse_data = data;
struct pnp_dev *dev = parse_data->dev; struct pnp_dev *dev = parse_data->dev;
struct pnp_option *option = parse_data->option; unsigned int option_flags = parse_data->option_flags;
switch (res->type) { switch (res->type) {
case ACPI_RESOURCE_TYPE_IRQ: case ACPI_RESOURCE_TYPE_IRQ:
pnpacpi_parse_irq_option(dev, option, &res->data.irq); pnpacpi_parse_irq_option(dev, option_flags, &res->data.irq);
break; break;
case ACPI_RESOURCE_TYPE_DMA: case ACPI_RESOURCE_TYPE_DMA:
pnpacpi_parse_dma_option(dev, option, &res->data.dma); pnpacpi_parse_dma_option(dev, option_flags, &res->data.dma);
break; break;
case ACPI_RESOURCE_TYPE_START_DEPENDENT: case ACPI_RESOURCE_TYPE_START_DEPENDENT:
...@@ -620,31 +670,19 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res, ...@@ -620,31 +670,19 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
priority = PNP_RES_PRIORITY_INVALID; priority = PNP_RES_PRIORITY_INVALID;
break; break;
} }
/* TBD: Consider performance/robustness bits */ parse_data->option_flags = pnp_new_dependent_set(dev, priority);
option = pnp_register_dependent_option(dev, priority);
if (!option)
return AE_ERROR;
parse_data->option = option;
break; break;
case ACPI_RESOURCE_TYPE_END_DEPENDENT: case ACPI_RESOURCE_TYPE_END_DEPENDENT:
/*only one EndDependentFn is allowed */ parse_data->option_flags = 0;
if (!parse_data->option_independent) {
dev_warn(&dev->dev, "more than one EndDependentFn "
"in _PRS\n");
return AE_ERROR;
}
parse_data->option = parse_data->option_independent;
parse_data->option_independent = NULL;
dev_dbg(&dev->dev, "end dependent options\n");
break; break;
case ACPI_RESOURCE_TYPE_IO: case ACPI_RESOURCE_TYPE_IO:
pnpacpi_parse_port_option(dev, option, &res->data.io); pnpacpi_parse_port_option(dev, option_flags, &res->data.io);
break; break;
case ACPI_RESOURCE_TYPE_FIXED_IO: case ACPI_RESOURCE_TYPE_FIXED_IO:
pnpacpi_parse_fixed_port_option(dev, option, pnpacpi_parse_fixed_port_option(dev, option_flags,
&res->data.fixed_io); &res->data.fixed_io);
break; break;
...@@ -653,29 +691,31 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res, ...@@ -653,29 +691,31 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
break; break;
case ACPI_RESOURCE_TYPE_MEMORY24: case ACPI_RESOURCE_TYPE_MEMORY24:
pnpacpi_parse_mem24_option(dev, option, &res->data.memory24); pnpacpi_parse_mem24_option(dev, option_flags,
&res->data.memory24);
break; break;
case ACPI_RESOURCE_TYPE_MEMORY32: case ACPI_RESOURCE_TYPE_MEMORY32:
pnpacpi_parse_mem32_option(dev, option, &res->data.memory32); pnpacpi_parse_mem32_option(dev, option_flags,
&res->data.memory32);
break; break;
case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
pnpacpi_parse_fixed_mem32_option(dev, option, pnpacpi_parse_fixed_mem32_option(dev, option_flags,
&res->data.fixed_memory32); &res->data.fixed_memory32);
break; break;
case ACPI_RESOURCE_TYPE_ADDRESS16: case ACPI_RESOURCE_TYPE_ADDRESS16:
case ACPI_RESOURCE_TYPE_ADDRESS32: case ACPI_RESOURCE_TYPE_ADDRESS32:
case ACPI_RESOURCE_TYPE_ADDRESS64: case ACPI_RESOURCE_TYPE_ADDRESS64:
pnpacpi_parse_address_option(dev, option, res); pnpacpi_parse_address_option(dev, option_flags, res);
break; break;
case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
break; break;
case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
pnpacpi_parse_ext_irq_option(dev, option, pnpacpi_parse_ext_irq_option(dev, option_flags,
&res->data.extended_irq); &res->data.extended_irq);
break; break;
...@@ -699,12 +739,9 @@ int __init pnpacpi_parse_resource_option_data(struct pnp_dev *dev) ...@@ -699,12 +739,9 @@ int __init pnpacpi_parse_resource_option_data(struct pnp_dev *dev)
dev_dbg(&dev->dev, "parse resource options\n"); dev_dbg(&dev->dev, "parse resource options\n");
parse_data.option = pnp_register_independent_option(dev);
if (!parse_data.option)
return -ENOMEM;
parse_data.option_independent = parse_data.option;
parse_data.dev = dev; parse_data.dev = dev;
parse_data.option_flags = 0;
status = acpi_walk_resources(handle, METHOD_NAME__PRS, status = acpi_walk_resources(handle, METHOD_NAME__PRS,
pnpacpi_option_resource, &parse_data); pnpacpi_option_resource, &parse_data);
...@@ -806,6 +843,13 @@ static void pnpacpi_encode_irq(struct pnp_dev *dev, ...@@ -806,6 +843,13 @@ static void pnpacpi_encode_irq(struct pnp_dev *dev,
struct acpi_resource_irq *irq = &resource->data.irq; struct acpi_resource_irq *irq = &resource->data.irq;
int triggering, polarity, shareable; int triggering, polarity, shareable;
if (!pnp_resource_enabled(p)) {
irq->interrupt_count = 0;
dev_dbg(&dev->dev, " encode irq (%s)\n",
p ? "disabled" : "missing");
return;
}
decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable); decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable);
irq->triggering = triggering; irq->triggering = triggering;
irq->polarity = polarity; irq->polarity = polarity;
...@@ -828,6 +872,13 @@ static void pnpacpi_encode_ext_irq(struct pnp_dev *dev, ...@@ -828,6 +872,13 @@ static void pnpacpi_encode_ext_irq(struct pnp_dev *dev,
struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq; struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq;
int triggering, polarity, shareable; int triggering, polarity, shareable;
if (!pnp_resource_enabled(p)) {
extended_irq->interrupt_count = 0;
dev_dbg(&dev->dev, " encode extended irq (%s)\n",
p ? "disabled" : "missing");
return;
}
decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable); decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable);
extended_irq->producer_consumer = ACPI_CONSUMER; extended_irq->producer_consumer = ACPI_CONSUMER;
extended_irq->triggering = triggering; extended_irq->triggering = triggering;
...@@ -848,6 +899,13 @@ static void pnpacpi_encode_dma(struct pnp_dev *dev, ...@@ -848,6 +899,13 @@ static void pnpacpi_encode_dma(struct pnp_dev *dev,
{ {
struct acpi_resource_dma *dma = &resource->data.dma; struct acpi_resource_dma *dma = &resource->data.dma;
if (!pnp_resource_enabled(p)) {
dma->channel_count = 0;
dev_dbg(&dev->dev, " encode dma (%s)\n",
p ? "disabled" : "missing");
return;
}
/* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */ /* Note: pnp_assign_dma will copy pnp_dma->flags into p->flags */
switch (p->flags & IORESOURCE_DMA_SPEED_MASK) { switch (p->flags & IORESOURCE_DMA_SPEED_MASK) {
case IORESOURCE_DMA_TYPEA: case IORESOURCE_DMA_TYPEA:
...@@ -889,17 +947,21 @@ static void pnpacpi_encode_io(struct pnp_dev *dev, ...@@ -889,17 +947,21 @@ static void pnpacpi_encode_io(struct pnp_dev *dev,
{ {
struct acpi_resource_io *io = &resource->data.io; struct acpi_resource_io *io = &resource->data.io;
/* Note: pnp_assign_port will copy pnp_port->flags into p->flags */ if (pnp_resource_enabled(p)) {
io->io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR) ? /* Note: pnp_assign_port copies pnp_port->flags into p->flags */
ACPI_DECODE_16 : ACPI_DECODE_10; io->io_decode = (p->flags & IORESOURCE_IO_16BIT_ADDR) ?
io->minimum = p->start; ACPI_DECODE_16 : ACPI_DECODE_10;
io->maximum = p->end; io->minimum = p->start;
io->alignment = 0; /* Correct? */ io->maximum = p->end;
io->address_length = p->end - p->start + 1; io->alignment = 0; /* Correct? */
io->address_length = p->end - p->start + 1;
dev_dbg(&dev->dev, " encode io %#llx-%#llx decode %#x\n", } else {
(unsigned long long) p->start, (unsigned long long) p->end, io->minimum = 0;
io->io_decode); io->address_length = 0;
}
dev_dbg(&dev->dev, " encode io %#x-%#x decode %#x\n", io->minimum,
io->minimum + io->address_length - 1, io->io_decode);
} }
static void pnpacpi_encode_fixed_io(struct pnp_dev *dev, static void pnpacpi_encode_fixed_io(struct pnp_dev *dev,
...@@ -908,11 +970,16 @@ static void pnpacpi_encode_fixed_io(struct pnp_dev *dev, ...@@ -908,11 +970,16 @@ static void pnpacpi_encode_fixed_io(struct pnp_dev *dev,
{ {
struct acpi_resource_fixed_io *fixed_io = &resource->data.fixed_io; struct acpi_resource_fixed_io *fixed_io = &resource->data.fixed_io;
fixed_io->address = p->start; if (pnp_resource_enabled(p)) {
fixed_io->address_length = p->end - p->start + 1; fixed_io->address = p->start;
fixed_io->address_length = p->end - p->start + 1;
} else {
fixed_io->address = 0;
fixed_io->address_length = 0;
}
dev_dbg(&dev->dev, " encode fixed_io %#llx-%#llx\n", dev_dbg(&dev->dev, " encode fixed_io %#x-%#x\n", fixed_io->address,
(unsigned long long) p->start, (unsigned long long) p->end); fixed_io->address + fixed_io->address_length - 1);
} }
static void pnpacpi_encode_mem24(struct pnp_dev *dev, static void pnpacpi_encode_mem24(struct pnp_dev *dev,
...@@ -921,17 +988,22 @@ static void pnpacpi_encode_mem24(struct pnp_dev *dev, ...@@ -921,17 +988,22 @@ static void pnpacpi_encode_mem24(struct pnp_dev *dev,
{ {
struct acpi_resource_memory24 *memory24 = &resource->data.memory24; struct acpi_resource_memory24 *memory24 = &resource->data.memory24;
/* Note: pnp_assign_mem will copy pnp_mem->flags into p->flags */ if (pnp_resource_enabled(p)) {
memory24->write_protect = /* Note: pnp_assign_mem copies pnp_mem->flags into p->flags */
(p->flags & IORESOURCE_MEM_WRITEABLE) ? memory24->write_protect = p->flags & IORESOURCE_MEM_WRITEABLE ?
ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
memory24->minimum = p->start; memory24->minimum = p->start;
memory24->maximum = p->end; memory24->maximum = p->end;
memory24->alignment = 0; memory24->alignment = 0;
memory24->address_length = p->end - p->start + 1; memory24->address_length = p->end - p->start + 1;
} else {
dev_dbg(&dev->dev, " encode mem24 %#llx-%#llx write_protect %#x\n", memory24->minimum = 0;
(unsigned long long) p->start, (unsigned long long) p->end, memory24->address_length = 0;
}
dev_dbg(&dev->dev, " encode mem24 %#x-%#x write_protect %#x\n",
memory24->minimum,
memory24->minimum + memory24->address_length - 1,
memory24->write_protect); memory24->write_protect);
} }
...@@ -941,16 +1013,21 @@ static void pnpacpi_encode_mem32(struct pnp_dev *dev, ...@@ -941,16 +1013,21 @@ static void pnpacpi_encode_mem32(struct pnp_dev *dev,
{ {
struct acpi_resource_memory32 *memory32 = &resource->data.memory32; struct acpi_resource_memory32 *memory32 = &resource->data.memory32;
memory32->write_protect = if (pnp_resource_enabled(p)) {
(p->flags & IORESOURCE_MEM_WRITEABLE) ? memory32->write_protect = p->flags & IORESOURCE_MEM_WRITEABLE ?
ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
memory32->minimum = p->start; memory32->minimum = p->start;
memory32->maximum = p->end; memory32->maximum = p->end;
memory32->alignment = 0; memory32->alignment = 0;
memory32->address_length = p->end - p->start + 1; memory32->address_length = p->end - p->start + 1;
} else {
memory32->minimum = 0;
memory32->alignment = 0;
}
dev_dbg(&dev->dev, " encode mem32 %#llx-%#llx write_protect %#x\n", dev_dbg(&dev->dev, " encode mem32 %#x-%#x write_protect %#x\n",
(unsigned long long) p->start, (unsigned long long) p->end, memory32->minimum,
memory32->minimum + memory32->address_length - 1,
memory32->write_protect); memory32->write_protect);
} }
...@@ -960,15 +1037,20 @@ static void pnpacpi_encode_fixed_mem32(struct pnp_dev *dev, ...@@ -960,15 +1037,20 @@ static void pnpacpi_encode_fixed_mem32(struct pnp_dev *dev,
{ {
struct acpi_resource_fixed_memory32 *fixed_memory32 = &resource->data.fixed_memory32; struct acpi_resource_fixed_memory32 *fixed_memory32 = &resource->data.fixed_memory32;
fixed_memory32->write_protect = if (pnp_resource_enabled(p)) {
(p->flags & IORESOURCE_MEM_WRITEABLE) ? fixed_memory32->write_protect =
ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY; p->flags & IORESOURCE_MEM_WRITEABLE ?
fixed_memory32->address = p->start; ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
fixed_memory32->address_length = p->end - p->start + 1; fixed_memory32->address = p->start;
fixed_memory32->address_length = p->end - p->start + 1;
} else {
fixed_memory32->address = 0;
fixed_memory32->address_length = 0;
}
dev_dbg(&dev->dev, " encode fixed_mem32 %#llx-%#llx " dev_dbg(&dev->dev, " encode fixed_mem32 %#x-%#x write_protect %#x\n",
"write_protect %#x\n", fixed_memory32->address,
(unsigned long long) p->start, (unsigned long long) p->end, fixed_memory32->address + fixed_memory32->address_length - 1,
fixed_memory32->write_protect); fixed_memory32->write_protect);
} }
......
...@@ -216,137 +216,116 @@ static unsigned char *pnpbios_parse_allocated_resource_data(struct pnp_dev *dev, ...@@ -216,137 +216,116 @@ static unsigned char *pnpbios_parse_allocated_resource_data(struct pnp_dev *dev,
static __init void pnpbios_parse_mem_option(struct pnp_dev *dev, static __init void pnpbios_parse_mem_option(struct pnp_dev *dev,
unsigned char *p, int size, unsigned char *p, int size,
struct pnp_option *option) unsigned int option_flags)
{ {
struct pnp_mem *mem; resource_size_t min, max, align, len;
unsigned char flags;
mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
if (!mem) min = ((p[5] << 8) | p[4]) << 8;
return; max = ((p[7] << 8) | p[6]) << 8;
mem->min = ((p[5] << 8) | p[4]) << 8; align = (p[9] << 8) | p[8];
mem->max = ((p[7] << 8) | p[6]) << 8; len = ((p[11] << 8) | p[10]) << 8;
mem->align = (p[9] << 8) | p[8]; flags = p[3];
mem->size = ((p[11] << 8) | p[10]) << 8; pnp_register_mem_resource(dev, option_flags, min, max, align, len,
mem->flags = p[3]; flags);
pnp_register_mem_resource(dev, option, mem);
} }
static __init void pnpbios_parse_mem32_option(struct pnp_dev *dev, static __init void pnpbios_parse_mem32_option(struct pnp_dev *dev,
unsigned char *p, int size, unsigned char *p, int size,
struct pnp_option *option) unsigned int option_flags)
{ {
struct pnp_mem *mem; resource_size_t min, max, align, len;
unsigned char flags;
mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
if (!mem) min = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
return; max = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
mem->min = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4]; align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12];
mem->max = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8]; len = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16];
mem->align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12]; flags = p[3];
mem->size = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16]; pnp_register_mem_resource(dev, option_flags, min, max, align, len,
mem->flags = p[3]; flags);
pnp_register_mem_resource(dev, option, mem);
} }
static __init void pnpbios_parse_fixed_mem32_option(struct pnp_dev *dev, static __init void pnpbios_parse_fixed_mem32_option(struct pnp_dev *dev,
unsigned char *p, int size, unsigned char *p, int size,
struct pnp_option *option) unsigned int option_flags)
{ {
struct pnp_mem *mem; resource_size_t base, len;
unsigned char flags;
mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
if (!mem) base = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
return; len = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
mem->min = mem->max = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4]; flags = p[3];
mem->size = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8]; pnp_register_mem_resource(dev, option_flags, base, base, 0, len, flags);
mem->align = 0;
mem->flags = p[3];
pnp_register_mem_resource(dev, option, mem);
} }
static __init void pnpbios_parse_irq_option(struct pnp_dev *dev, static __init void pnpbios_parse_irq_option(struct pnp_dev *dev,
unsigned char *p, int size, unsigned char *p, int size,
struct pnp_option *option) unsigned int option_flags)
{ {
struct pnp_irq *irq;
unsigned long bits; unsigned long bits;
pnp_irq_mask_t map;
unsigned char flags = IORESOURCE_IRQ_HIGHEDGE;
irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
if (!irq)
return;
bits = (p[2] << 8) | p[1]; bits = (p[2] << 8) | p[1];
bitmap_copy(irq->map, &bits, 16);
bitmap_zero(map.bits, PNP_IRQ_NR);
bitmap_copy(map.bits, &bits, 16);
if (size > 2) if (size > 2)
irq->flags = p[3]; flags = p[3];
else
irq->flags = IORESOURCE_IRQ_HIGHEDGE; pnp_register_irq_resource(dev, option_flags, &map, flags);
pnp_register_irq_resource(dev, option, irq);
} }
static __init void pnpbios_parse_dma_option(struct pnp_dev *dev, static __init void pnpbios_parse_dma_option(struct pnp_dev *dev,
unsigned char *p, int size, unsigned char *p, int size,
struct pnp_option *option) unsigned int option_flags)
{ {
struct pnp_dma *dma; pnp_register_dma_resource(dev, option_flags, p[1], p[2]);
dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
if (!dma)
return;
dma->map = p[1];
dma->flags = p[2];
pnp_register_dma_resource(dev, option, dma);
} }
static __init void pnpbios_parse_port_option(struct pnp_dev *dev, static __init void pnpbios_parse_port_option(struct pnp_dev *dev,
unsigned char *p, int size, unsigned char *p, int size,
struct pnp_option *option) unsigned int option_flags)
{ {
struct pnp_port *port; resource_size_t min, max, align, len;
unsigned char flags;
port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
if (!port) min = (p[3] << 8) | p[2];
return; max = (p[5] << 8) | p[4];
port->min = (p[3] << 8) | p[2]; align = p[6];
port->max = (p[5] << 8) | p[4]; len = p[7];
port->align = p[6]; flags = p[1] ? IORESOURCE_IO_16BIT_ADDR : 0;
port->size = p[7]; pnp_register_port_resource(dev, option_flags, min, max, align, len,
port->flags = p[1] ? PNP_PORT_FLAG_16BITADDR : 0; flags);
pnp_register_port_resource(dev, option, port);
} }
static __init void pnpbios_parse_fixed_port_option(struct pnp_dev *dev, static __init void pnpbios_parse_fixed_port_option(struct pnp_dev *dev,
unsigned char *p, int size, unsigned char *p, int size,
struct pnp_option *option) unsigned int option_flags)
{ {
struct pnp_port *port; resource_size_t base, len;
port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL); base = (p[2] << 8) | p[1];
if (!port) len = p[3];
return; pnp_register_port_resource(dev, option_flags, base, base, 0, len,
port->min = port->max = (p[2] << 8) | p[1]; IORESOURCE_IO_FIXED);
port->size = p[3];
port->align = 0;
port->flags = PNP_PORT_FLAG_FIXED;
pnp_register_port_resource(dev, option, port);
} }
static __init unsigned char * static __init unsigned char *
pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end, pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
struct pnp_dev *dev) struct pnp_dev *dev)
{ {
unsigned int len, tag; unsigned int len, tag;
int priority = 0; int priority;
struct pnp_option *option, *option_independent; unsigned int option_flags;
if (!p) if (!p)
return NULL; return NULL;
dev_dbg(&dev->dev, "parse resource options\n"); dev_dbg(&dev->dev, "parse resource options\n");
option_flags = 0;
option_independent = option = pnp_register_independent_option(dev);
if (!option)
return NULL;
while ((char *)p < (char *)end) { while ((char *)p < (char *)end) {
/* determine the type of tag */ /* determine the type of tag */
...@@ -363,37 +342,38 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end, ...@@ -363,37 +342,38 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
case LARGE_TAG_MEM: case LARGE_TAG_MEM:
if (len != 9) if (len != 9)
goto len_err; goto len_err;
pnpbios_parse_mem_option(dev, p, len, option); pnpbios_parse_mem_option(dev, p, len, option_flags);
break; break;
case LARGE_TAG_MEM32: case LARGE_TAG_MEM32:
if (len != 17) if (len != 17)
goto len_err; goto len_err;
pnpbios_parse_mem32_option(dev, p, len, option); pnpbios_parse_mem32_option(dev, p, len, option_flags);
break; break;
case LARGE_TAG_FIXEDMEM32: case LARGE_TAG_FIXEDMEM32:
if (len != 9) if (len != 9)
goto len_err; goto len_err;
pnpbios_parse_fixed_mem32_option(dev, p, len, option); pnpbios_parse_fixed_mem32_option(dev, p, len,
option_flags);
break; break;
case SMALL_TAG_IRQ: case SMALL_TAG_IRQ:
if (len < 2 || len > 3) if (len < 2 || len > 3)
goto len_err; goto len_err;
pnpbios_parse_irq_option(dev, p, len, option); pnpbios_parse_irq_option(dev, p, len, option_flags);
break; break;
case SMALL_TAG_DMA: case SMALL_TAG_DMA:
if (len != 2) if (len != 2)
goto len_err; goto len_err;
pnpbios_parse_dma_option(dev, p, len, option); pnpbios_parse_dma_option(dev, p, len, option_flags);
break; break;
case SMALL_TAG_PORT: case SMALL_TAG_PORT:
if (len != 7) if (len != 7)
goto len_err; goto len_err;
pnpbios_parse_port_option(dev, p, len, option); pnpbios_parse_port_option(dev, p, len, option_flags);
break; break;
case SMALL_TAG_VENDOR: case SMALL_TAG_VENDOR:
...@@ -403,28 +383,23 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end, ...@@ -403,28 +383,23 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
case SMALL_TAG_FIXEDPORT: case SMALL_TAG_FIXEDPORT:
if (len != 3) if (len != 3)
goto len_err; goto len_err;
pnpbios_parse_fixed_port_option(dev, p, len, option); pnpbios_parse_fixed_port_option(dev, p, len,
option_flags);
break; break;
case SMALL_TAG_STARTDEP: case SMALL_TAG_STARTDEP:
if (len > 1) if (len > 1)
goto len_err; goto len_err;
priority = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE; priority = PNP_RES_PRIORITY_ACCEPTABLE;
if (len > 0) if (len > 0)
priority = 0x100 | p[1]; priority = p[1];
option = pnp_register_dependent_option(dev, priority); option_flags = pnp_new_dependent_set(dev, priority);
if (!option)
return NULL;
break; break;
case SMALL_TAG_ENDDEP: case SMALL_TAG_ENDDEP:
if (len != 0) if (len != 0)
goto len_err; goto len_err;
if (option_independent == option) option_flags = 0;
dev_warn(&dev->dev, "missing "
"SMALL_TAG_STARTDEP tag\n");
option = option_independent;
dev_dbg(&dev->dev, "end dependent options\n");
break; break;
case SMALL_TAG_END: case SMALL_TAG_END:
...@@ -526,8 +501,16 @@ static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p, ...@@ -526,8 +501,16 @@ static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p,
static void pnpbios_encode_mem(struct pnp_dev *dev, unsigned char *p, static void pnpbios_encode_mem(struct pnp_dev *dev, unsigned char *p,
struct resource *res) struct resource *res)
{ {
unsigned long base = res->start; unsigned long base;
unsigned long len = res->end - res->start + 1; unsigned long len;
if (pnp_resource_enabled(res)) {
base = res->start;
len = res->end - res->start + 1;
} else {
base = 0;
len = 0;
}
p[4] = (base >> 8) & 0xff; p[4] = (base >> 8) & 0xff;
p[5] = ((base >> 8) >> 8) & 0xff; p[5] = ((base >> 8) >> 8) & 0xff;
...@@ -536,15 +519,22 @@ static void pnpbios_encode_mem(struct pnp_dev *dev, unsigned char *p, ...@@ -536,15 +519,22 @@ static void pnpbios_encode_mem(struct pnp_dev *dev, unsigned char *p,
p[10] = (len >> 8) & 0xff; p[10] = (len >> 8) & 0xff;
p[11] = ((len >> 8) >> 8) & 0xff; p[11] = ((len >> 8) >> 8) & 0xff;
dev_dbg(&dev->dev, " encode mem %#llx-%#llx\n", dev_dbg(&dev->dev, " encode mem %#lx-%#lx\n", base, base + len - 1);
(unsigned long long) res->start, (unsigned long long) res->end);
} }
static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p, static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p,
struct resource *res) struct resource *res)
{ {
unsigned long base = res->start; unsigned long base;
unsigned long len = res->end - res->start + 1; unsigned long len;
if (pnp_resource_enabled(res)) {
base = res->start;
len = res->end - res->start + 1;
} else {
base = 0;
len = 0;
}
p[4] = base & 0xff; p[4] = base & 0xff;
p[5] = (base >> 8) & 0xff; p[5] = (base >> 8) & 0xff;
...@@ -559,15 +549,22 @@ static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p, ...@@ -559,15 +549,22 @@ static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p,
p[18] = (len >> 16) & 0xff; p[18] = (len >> 16) & 0xff;
p[19] = (len >> 24) & 0xff; p[19] = (len >> 24) & 0xff;
dev_dbg(&dev->dev, " encode mem32 %#llx-%#llx\n", dev_dbg(&dev->dev, " encode mem32 %#lx-%#lx\n", base, base + len - 1);
(unsigned long long) res->start, (unsigned long long) res->end);
} }
static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p, static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p,
struct resource *res) struct resource *res)
{ {
unsigned long base = res->start; unsigned long base;
unsigned long len = res->end - res->start + 1; unsigned long len;
if (pnp_resource_enabled(res)) {
base = res->start;
len = res->end - res->start + 1;
} else {
base = 0;
len = 0;
}
p[4] = base & 0xff; p[4] = base & 0xff;
p[5] = (base >> 8) & 0xff; p[5] = (base >> 8) & 0xff;
...@@ -578,40 +575,54 @@ static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p, ...@@ -578,40 +575,54 @@ static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p,
p[10] = (len >> 16) & 0xff; p[10] = (len >> 16) & 0xff;
p[11] = (len >> 24) & 0xff; p[11] = (len >> 24) & 0xff;
dev_dbg(&dev->dev, " encode fixed_mem32 %#llx-%#llx\n", dev_dbg(&dev->dev, " encode fixed_mem32 %#lx-%#lx\n", base,
(unsigned long long) res->start, (unsigned long long) res->end); base + len - 1);
} }
static void pnpbios_encode_irq(struct pnp_dev *dev, unsigned char *p, static void pnpbios_encode_irq(struct pnp_dev *dev, unsigned char *p,
struct resource *res) struct resource *res)
{ {
unsigned long map = 0; unsigned long map;
if (pnp_resource_enabled(res))
map = 1 << res->start;
else
map = 0;
map = 1 << res->start;
p[1] = map & 0xff; p[1] = map & 0xff;
p[2] = (map >> 8) & 0xff; p[2] = (map >> 8) & 0xff;
dev_dbg(&dev->dev, " encode irq %llu\n", dev_dbg(&dev->dev, " encode irq mask %#lx\n", map);
(unsigned long long)res->start);
} }
static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p, static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p,
struct resource *res) struct resource *res)
{ {
unsigned long map = 0; unsigned long map;
if (pnp_resource_enabled(res))
map = 1 << res->start;
else
map = 0;
map = 1 << res->start;
p[1] = map & 0xff; p[1] = map & 0xff;
dev_dbg(&dev->dev, " encode dma %llu\n", dev_dbg(&dev->dev, " encode dma mask %#lx\n", map);
(unsigned long long)res->start);
} }
static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p, static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p,
struct resource *res) struct resource *res)
{ {
unsigned long base = res->start; unsigned long base;
unsigned long len = res->end - res->start + 1; unsigned long len;
if (pnp_resource_enabled(res)) {
base = res->start;
len = res->end - res->start + 1;
} else {
base = 0;
len = 0;
}
p[2] = base & 0xff; p[2] = base & 0xff;
p[3] = (base >> 8) & 0xff; p[3] = (base >> 8) & 0xff;
...@@ -619,8 +630,7 @@ static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p, ...@@ -619,8 +630,7 @@ static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p,
p[5] = (base >> 8) & 0xff; p[5] = (base >> 8) & 0xff;
p[7] = len & 0xff; p[7] = len & 0xff;
dev_dbg(&dev->dev, " encode io %#llx-%#llx\n", dev_dbg(&dev->dev, " encode io %#lx-%#lx\n", base, base + len - 1);
(unsigned long long) res->start, (unsigned long long) res->end);
} }
static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p, static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p,
...@@ -629,12 +639,20 @@ static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p, ...@@ -629,12 +639,20 @@ static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p,
unsigned long base = res->start; unsigned long base = res->start;
unsigned long len = res->end - res->start + 1; unsigned long len = res->end - res->start + 1;
if (pnp_resource_enabled(res)) {
base = res->start;
len = res->end - res->start + 1;
} else {
base = 0;
len = 0;
}
p[1] = base & 0xff; p[1] = base & 0xff;
p[2] = (base >> 8) & 0xff; p[2] = (base >> 8) & 0xff;
p[3] = len & 0xff; p[3] = len & 0xff;
dev_dbg(&dev->dev, " encode fixed_io %#llx-%#llx\n", dev_dbg(&dev->dev, " encode fixed_io %#lx-%#lx\n", base,
(unsigned long long) res->start, (unsigned long long) res->end); base + len - 1);
} }
static unsigned char *pnpbios_encode_allocated_resource_data(struct pnp_dev static unsigned char *pnpbios_encode_allocated_resource_data(struct pnp_dev
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
* when building up the resource structure for the first time. * when building up the resource structure for the first time.
* *
* Copyright (c) 2000 Peter Denison <peterd@pnd-pc.demon.co.uk> * Copyright (c) 2000 Peter Denison <peterd@pnd-pc.demon.co.uk>
* Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
* Bjorn Helgaas <bjorn.helgaas@hp.com>
* *
* Heavily based on PCI quirks handling which is * Heavily based on PCI quirks handling which is
* *
...@@ -20,203 +22,207 @@ ...@@ -20,203 +22,207 @@
#include <linux/kallsyms.h> #include <linux/kallsyms.h>
#include "base.h" #include "base.h"
static void quirk_awe32_add_ports(struct pnp_dev *dev,
struct pnp_option *option,
unsigned int offset)
{
struct pnp_option *new_option;
new_option = kmalloc(sizeof(struct pnp_option), GFP_KERNEL);
if (!new_option) {
dev_err(&dev->dev, "couldn't add ioport region to option set "
"%d\n", pnp_option_set(option));
return;
}
*new_option = *option;
new_option->u.port.min += offset;
new_option->u.port.max += offset;
list_add(&new_option->list, &option->list);
dev_info(&dev->dev, "added ioport region %#llx-%#llx to set %d\n",
(unsigned long long) new_option->u.port.min,
(unsigned long long) new_option->u.port.max,
pnp_option_set(option));
}
static void quirk_awe32_resources(struct pnp_dev *dev) static void quirk_awe32_resources(struct pnp_dev *dev)
{ {
struct pnp_port *port, *port2, *port3; struct pnp_option *option;
struct pnp_option *res = dev->dependent; unsigned int set = ~0;
/* /*
* Unfortunately the isapnp_add_port_resource is too tightly bound * Add two extra ioport regions (at offset 0x400 and 0x800 from the
* into the PnP discovery sequence, and cannot be used. Link in the * one given) to every dependent option set.
* two extra ports (at offset 0x400 and 0x800 from the one given) by
* hand.
*/ */
for (; res; res = res->next) { list_for_each_entry(option, &dev->options, list) {
port2 = pnp_alloc(sizeof(struct pnp_port)); if (pnp_option_is_dependent(option) &&
if (!port2) pnp_option_set(option) != set) {
return; set = pnp_option_set(option);
port3 = pnp_alloc(sizeof(struct pnp_port)); quirk_awe32_add_ports(dev, option, 0x800);
if (!port3) { quirk_awe32_add_ports(dev, option, 0x400);
kfree(port2);
return;
} }
port = res->port;
memcpy(port2, port, sizeof(struct pnp_port));
memcpy(port3, port, sizeof(struct pnp_port));
port->next = port2;
port2->next = port3;
port2->min += 0x400;
port2->max += 0x400;
port3->min += 0x800;
port3->max += 0x800;
dev_info(&dev->dev,
"AWE32 quirk - added ioports 0x%lx and 0x%lx\n",
(unsigned long)port2->min,
(unsigned long)port3->min);
} }
} }
static void quirk_cmi8330_resources(struct pnp_dev *dev) static void quirk_cmi8330_resources(struct pnp_dev *dev)
{ {
struct pnp_option *res = dev->dependent; struct pnp_option *option;
unsigned long tmp; struct pnp_irq *irq;
struct pnp_dma *dma;
for (; res; res = res->next) {
struct pnp_irq *irq;
struct pnp_dma *dma;
for (irq = res->irq; irq; irq = irq->next) { // Valid irqs are 5, 7, 10 list_for_each_entry(option, &dev->options, list) {
tmp = 0x04A0; if (!pnp_option_is_dependent(option))
bitmap_copy(irq->map, &tmp, 16); // 0000 0100 1010 0000 continue;
}
for (dma = res->dma; dma; dma = dma->next) // Valid 8bit dma channels are 1,3 if (option->type == IORESOURCE_IRQ) {
irq = &option->u.irq;
bitmap_zero(irq->map.bits, PNP_IRQ_NR);
__set_bit(5, irq->map.bits);
__set_bit(7, irq->map.bits);
__set_bit(10, irq->map.bits);
dev_info(&dev->dev, "set possible IRQs in "
"option set %d to 5, 7, 10\n",
pnp_option_set(option));
} else if (option->type == IORESOURCE_DMA) {
dma = &option->u.dma;
if ((dma->flags & IORESOURCE_DMA_TYPE_MASK) == if ((dma->flags & IORESOURCE_DMA_TYPE_MASK) ==
IORESOURCE_DMA_8BIT) IORESOURCE_DMA_8BIT &&
dma->map = 0x000A; dma->map != 0x0A) {
dev_info(&dev->dev, "changing possible "
"DMA channel mask in option set %d "
"from %#02x to 0x0A (1, 3)\n",
pnp_option_set(option), dma->map);
dma->map = 0x0A;
}
}
} }
dev_info(&dev->dev, "CMI8330 quirk - forced possible IRQs to 5, 7, 10 "
"and DMA channels to 1, 3\n");
} }
static void quirk_sb16audio_resources(struct pnp_dev *dev) static void quirk_sb16audio_resources(struct pnp_dev *dev)
{ {
struct pnp_option *option;
unsigned int prev_option_flags = ~0, n = 0;
struct pnp_port *port; struct pnp_port *port;
struct pnp_option *res = dev->dependent;
int changed = 0;
/* /*
* The default range on the mpu port for these devices is 0x388-0x388. * The default range on the OPL port for these devices is 0x388-0x388.
* Here we increase that range so that two such cards can be * Here we increase that range so that two such cards can be
* auto-configured. * auto-configured.
*/ */
list_for_each_entry(option, &dev->options, list) {
if (prev_option_flags != option->flags) {
prev_option_flags = option->flags;
n = 0;
}
for (; res; res = res->next) { if (pnp_option_is_dependent(option) &&
port = res->port; option->type == IORESOURCE_IO) {
if (!port) n++;
continue; port = &option->u.port;
port = port->next; if (n == 3 && port->min == port->max) {
if (!port) port->max += 0x70;
continue; dev_info(&dev->dev, "increased option port "
port = port->next; "range from %#llx-%#llx to "
if (!port) "%#llx-%#llx\n",
continue; (unsigned long long) port->min,
if (port->min != port->max) (unsigned long long) port->min,
continue; (unsigned long long) port->min,
port->max += 0x70; (unsigned long long) port->max);
changed = 1; }
}
} }
if (changed)
dev_info(&dev->dev, "SB audio device quirk - increased port range\n");
} }
static struct pnp_option *quirk_isapnp_mpu_options(struct pnp_dev *dev) static struct pnp_option *pnp_clone_dependent_set(struct pnp_dev *dev,
unsigned int set)
{ {
struct pnp_option *head = NULL; struct pnp_option *tail = NULL, *first_new_option = NULL;
struct pnp_option *prev = NULL; struct pnp_option *option, *new_option;
struct pnp_option *res; unsigned int flags;
/*
* Build a functional IRQ-less variant of each MPU option.
*/
for (res = dev->dependent; res; res = res->next) {
struct pnp_option *curr;
struct pnp_port *port;
struct pnp_port *copy;
port = res->port; list_for_each_entry(option, &dev->options, list) {
if (!port || !res->irq) if (pnp_option_is_dependent(option))
continue; tail = option;
}
if (!tail) {
dev_err(&dev->dev, "no dependent option sets\n");
return NULL;
}
copy = pnp_alloc(sizeof *copy); flags = pnp_new_dependent_set(dev, PNP_RES_PRIORITY_FUNCTIONAL);
if (!copy) list_for_each_entry(option, &dev->options, list) {
break; if (pnp_option_is_dependent(option) &&
pnp_option_set(option) == set) {
new_option = kmalloc(sizeof(struct pnp_option),
GFP_KERNEL);
if (!new_option) {
dev_err(&dev->dev, "couldn't clone dependent "
"set %d\n", set);
return NULL;
}
copy->min = port->min; *new_option = *option;
copy->max = port->max; new_option->flags = flags;
copy->align = port->align; if (!first_new_option)
copy->size = port->size; first_new_option = new_option;
copy->flags = port->flags;
curr = pnp_build_option(PNP_RES_PRIORITY_FUNCTIONAL); list_add(&new_option->list, &tail->list);
if (!curr) { tail = new_option;
kfree(copy);
break;
} }
curr->port = copy;
if (prev)
prev->next = curr;
else
head = curr;
prev = curr;
} }
if (head)
dev_info(&dev->dev, "adding IRQ-less MPU options\n");
return head; return first_new_option;
} }
static void quirk_ad1815_mpu_resources(struct pnp_dev *dev)
static void quirk_add_irq_optional_dependent_sets(struct pnp_dev *dev)
{ {
struct pnp_option *res; struct pnp_option *new_option;
unsigned int num_sets, i, set;
struct pnp_irq *irq; struct pnp_irq *irq;
/* num_sets = dev->num_dependent_sets;
* Distribute the independent IRQ over the dependent options for (i = 0; i < num_sets; i++) {
*/ new_option = pnp_clone_dependent_set(dev, i);
if (!new_option)
res = dev->independent; return;
if (!res)
return;
irq = res->irq;
if (!irq || irq->next)
return;
res = dev->dependent;
if (!res)
return;
while (1) {
struct pnp_irq *copy;
copy = pnp_alloc(sizeof *copy);
if (!copy)
break;
memcpy(copy->map, irq->map, sizeof copy->map);
copy->flags = irq->flags;
copy->next = res->irq; /* Yes, this is NULL */ set = pnp_option_set(new_option);
res->irq = copy; while (new_option && pnp_option_set(new_option) == set) {
if (new_option->type == IORESOURCE_IRQ) {
irq = &new_option->u.irq;
irq->flags |= IORESOURCE_IRQ_OPTIONAL;
}
dbg_pnp_show_option(dev, new_option);
new_option = list_entry(new_option->list.next,
struct pnp_option, list);
}
if (!res->next) dev_info(&dev->dev, "added dependent option set %d (same as "
break; "set %d except IRQ optional)\n", set, i);
res = res->next;
} }
kfree(irq);
res->next = quirk_isapnp_mpu_options(dev);
res = dev->independent;
res->irq = NULL;
} }
static void quirk_isapnp_mpu_resources(struct pnp_dev *dev) static void quirk_ad1815_mpu_resources(struct pnp_dev *dev)
{ {
struct pnp_option *res; struct pnp_option *option;
struct pnp_irq *irq = NULL;
unsigned int independent_irqs = 0;
list_for_each_entry(option, &dev->options, list) {
if (option->type == IORESOURCE_IRQ &&
!pnp_option_is_dependent(option)) {
independent_irqs++;
irq = &option->u.irq;
}
}
res = dev->dependent; if (independent_irqs != 1)
if (!res)
return; return;
while (res->next) irq->flags |= IORESOURCE_IRQ_OPTIONAL;
res = res->next; dev_info(&dev->dev, "made independent IRQ optional\n");
res->next = quirk_isapnp_mpu_options(dev);
} }
#include <linux/pci.h> #include <linux/pci.h>
...@@ -248,8 +254,7 @@ static void quirk_system_pci_resources(struct pnp_dev *dev) ...@@ -248,8 +254,7 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
for (j = 0; for (j = 0;
(res = pnp_get_resource(dev, IORESOURCE_MEM, j)); (res = pnp_get_resource(dev, IORESOURCE_MEM, j));
j++) { j++) {
if (res->flags & IORESOURCE_UNSET || if (res->start == 0 && res->end == 0)
(res->start == 0 && res->end == 0))
continue; continue;
pnp_start = res->start; pnp_start = res->start;
...@@ -312,10 +317,10 @@ static struct pnp_fixup pnp_fixups[] = { ...@@ -312,10 +317,10 @@ static struct pnp_fixup pnp_fixups[] = {
{"CTL0043", quirk_sb16audio_resources}, {"CTL0043", quirk_sb16audio_resources},
{"CTL0044", quirk_sb16audio_resources}, {"CTL0044", quirk_sb16audio_resources},
{"CTL0045", quirk_sb16audio_resources}, {"CTL0045", quirk_sb16audio_resources},
/* Add IRQ-less MPU options */ /* Add IRQ-optional MPU options */
{"ADS7151", quirk_ad1815_mpu_resources}, {"ADS7151", quirk_ad1815_mpu_resources},
{"ADS7181", quirk_isapnp_mpu_resources}, {"ADS7181", quirk_add_irq_optional_dependent_sets},
{"AZT0002", quirk_isapnp_mpu_resources}, {"AZT0002", quirk_add_irq_optional_dependent_sets},
/* PnP resources that might overlap PCI BARs */ /* PnP resources that might overlap PCI BARs */
{"PNP0c01", quirk_system_pci_resources}, {"PNP0c01", quirk_system_pci_resources},
{"PNP0c02", quirk_system_pci_resources}, {"PNP0c02", quirk_system_pci_resources},
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
* *
* based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz> * based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz>
* Copyright 2003 Adam Belay <ambx1@neo.rr.com> * Copyright 2003 Adam Belay <ambx1@neo.rr.com>
* Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
* Bjorn Helgaas <bjorn.helgaas@hp.com>
*/ */
#include <linux/module.h> #include <linux/module.h>
...@@ -28,201 +30,121 @@ static int pnp_reserve_mem[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some ...@@ -28,201 +30,121 @@ static int pnp_reserve_mem[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some
* option registration * option registration
*/ */
struct pnp_option *pnp_build_option(int priority) struct pnp_option *pnp_build_option(struct pnp_dev *dev, unsigned long type,
unsigned int option_flags)
{ {
struct pnp_option *option = pnp_alloc(sizeof(struct pnp_option)); struct pnp_option *option;
option = kzalloc(sizeof(struct pnp_option), GFP_KERNEL);
if (!option) if (!option)
return NULL; return NULL;
option->priority = priority & 0xff; option->flags = option_flags;
/* make sure the priority is valid */ option->type = type;
if (option->priority > PNP_RES_PRIORITY_FUNCTIONAL)
option->priority = PNP_RES_PRIORITY_INVALID;
return option;
}
struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev)
{
struct pnp_option *option;
option = pnp_build_option(PNP_RES_PRIORITY_PREFERRED);
/* this should never happen but if it does we'll try to continue */
if (dev->independent)
dev_err(&dev->dev, "independent resource already registered\n");
dev->independent = option;
dev_dbg(&dev->dev, "new independent option\n"); list_add_tail(&option->list, &dev->options);
return option; return option;
} }
struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev, int pnp_register_irq_resource(struct pnp_dev *dev, unsigned int option_flags,
int priority) pnp_irq_mask_t *map, unsigned char flags)
{ {
struct pnp_option *option; struct pnp_option *option;
struct pnp_irq *irq;
option = pnp_build_option(priority); option = pnp_build_option(dev, IORESOURCE_IRQ, option_flags);
if (!option)
if (dev->dependent) { return -ENOMEM;
struct pnp_option *parent = dev->dependent;
while (parent->next)
parent = parent->next;
parent->next = option;
} else
dev->dependent = option;
dev_dbg(&dev->dev, "new dependent option (priority %#x)\n", priority);
return option;
}
int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option,
struct pnp_irq *data)
{
struct pnp_irq *ptr;
#ifdef DEBUG
char buf[PNP_IRQ_NR]; /* hex-encoded, so this is overkill but safe */
#endif
ptr = option->irq; irq = &option->u.irq;
while (ptr && ptr->next) irq->map = *map;
ptr = ptr->next; irq->flags = flags;
if (ptr)
ptr->next = data;
else
option->irq = data;
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
{ {
int i; int i;
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
if (test_bit(i, data->map)) if (test_bit(i, irq->map.bits))
pcibios_penalize_isa_irq(i, 0); pcibios_penalize_isa_irq(i, 0);
} }
#endif #endif
#ifdef DEBUG dbg_pnp_show_option(dev, option);
bitmap_scnprintf(buf, sizeof(buf), data->map, PNP_IRQ_NR);
dev_dbg(&dev->dev, " irq bitmask %s flags %#x\n", buf,
data->flags);
#endif
return 0; return 0;
} }
int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option, int pnp_register_dma_resource(struct pnp_dev *dev, unsigned int option_flags,
struct pnp_dma *data) unsigned char map, unsigned char flags)
{ {
struct pnp_dma *ptr; struct pnp_option *option;
struct pnp_dma *dma;
ptr = option->dma;
while (ptr && ptr->next)
ptr = ptr->next;
if (ptr)
ptr->next = data;
else
option->dma = data;
dev_dbg(&dev->dev, " dma bitmask %#x flags %#x\n", data->map,
data->flags);
return 0;
}
int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option, option = pnp_build_option(dev, IORESOURCE_DMA, option_flags);
struct pnp_port *data) if (!option)
{ return -ENOMEM;
struct pnp_port *ptr;
ptr = option->port;
while (ptr && ptr->next)
ptr = ptr->next;
if (ptr)
ptr->next = data;
else
option->port = data;
dev_dbg(&dev->dev, " io "
"min %#x max %#x align %d size %d flags %#x\n",
data->min, data->max, data->align, data->size, data->flags);
return 0;
}
int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option, dma = &option->u.dma;
struct pnp_mem *data) dma->map = map;
{ dma->flags = flags;
struct pnp_mem *ptr;
dbg_pnp_show_option(dev, option);
ptr = option->mem;
while (ptr && ptr->next)
ptr = ptr->next;
if (ptr)
ptr->next = data;
else
option->mem = data;
dev_dbg(&dev->dev, " mem "
"min %#x max %#x align %d size %d flags %#x\n",
data->min, data->max, data->align, data->size, data->flags);
return 0; return 0;
} }
static void pnp_free_port(struct pnp_port *port) int pnp_register_port_resource(struct pnp_dev *dev, unsigned int option_flags,
resource_size_t min, resource_size_t max,
resource_size_t align, resource_size_t size,
unsigned char flags)
{ {
struct pnp_port *next; struct pnp_option *option;
struct pnp_port *port;
while (port) { option = pnp_build_option(dev, IORESOURCE_IO, option_flags);
next = port->next; if (!option)
kfree(port); return -ENOMEM;
port = next;
}
}
static void pnp_free_irq(struct pnp_irq *irq) port = &option->u.port;
{ port->min = min;
struct pnp_irq *next; port->max = max;
port->align = align;
port->size = size;
port->flags = flags;
while (irq) { dbg_pnp_show_option(dev, option);
next = irq->next; return 0;
kfree(irq);
irq = next;
}
} }
static void pnp_free_dma(struct pnp_dma *dma) int pnp_register_mem_resource(struct pnp_dev *dev, unsigned int option_flags,
resource_size_t min, resource_size_t max,
resource_size_t align, resource_size_t size,
unsigned char flags)
{ {
struct pnp_dma *next; struct pnp_option *option;
struct pnp_mem *mem;
while (dma) { option = pnp_build_option(dev, IORESOURCE_MEM, option_flags);
next = dma->next; if (!option)
kfree(dma); return -ENOMEM;
dma = next;
}
}
static void pnp_free_mem(struct pnp_mem *mem) mem = &option->u.mem;
{ mem->min = min;
struct pnp_mem *next; mem->max = max;
mem->align = align;
mem->size = size;
mem->flags = flags;
while (mem) { dbg_pnp_show_option(dev, option);
next = mem->next; return 0;
kfree(mem);
mem = next;
}
} }
void pnp_free_option(struct pnp_option *option) void pnp_free_options(struct pnp_dev *dev)
{ {
struct pnp_option *next; struct pnp_option *option, *tmp;
while (option) { list_for_each_entry_safe(option, tmp, &dev->options, list) {
next = option->next; list_del(&option->list);
pnp_free_port(option->port);
pnp_free_irq(option->irq);
pnp_free_dma(option->dma);
pnp_free_mem(option->mem);
kfree(option); kfree(option);
option = next;
} }
} }
...@@ -237,7 +159,7 @@ void pnp_free_option(struct pnp_option *option) ...@@ -237,7 +159,7 @@ void pnp_free_option(struct pnp_option *option)
!((*(enda) < *(startb)) || (*(endb) < *(starta))) !((*(enda) < *(startb)) || (*(endb) < *(starta)))
#define cannot_compare(flags) \ #define cannot_compare(flags) \
((flags) & (IORESOURCE_UNSET | IORESOURCE_DISABLED)) ((flags) & IORESOURCE_DISABLED)
int pnp_check_port(struct pnp_dev *dev, struct resource *res) int pnp_check_port(struct pnp_dev *dev, struct resource *res)
{ {
...@@ -364,6 +286,61 @@ static irqreturn_t pnp_test_handler(int irq, void *dev_id) ...@@ -364,6 +286,61 @@ static irqreturn_t pnp_test_handler(int irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
#ifdef CONFIG_PCI
static int pci_dev_uses_irq(struct pnp_dev *pnp, struct pci_dev *pci,
unsigned int irq)
{
u32 class;
u8 progif;
if (pci->irq == irq) {
dev_dbg(&pnp->dev, "device %s using irq %d\n",
pci_name(pci), irq);
return 1;
}
/*
* See pci_setup_device() and ata_pci_sff_activate_host() for
* similar IDE legacy detection.
*/
pci_read_config_dword(pci, PCI_CLASS_REVISION, &class);
class >>= 8; /* discard revision ID */
progif = class & 0xff;
class >>= 8;
if (class == PCI_CLASS_STORAGE_IDE) {
/*
* Unless both channels are native-PCI mode only,
* treat the compatibility IRQs as busy.
*/
if ((progif & 0x5) != 0x5)
if (pci_get_legacy_ide_irq(pci, 0) == irq ||
pci_get_legacy_ide_irq(pci, 1) == irq) {
dev_dbg(&pnp->dev, "legacy IDE device %s "
"using irq %d\n", pci_name(pci), irq);
return 1;
}
}
return 0;
}
#endif
static int pci_uses_irq(struct pnp_dev *pnp, unsigned int irq)
{
#ifdef CONFIG_PCI
struct pci_dev *pci = NULL;
for_each_pci_dev(pci) {
if (pci_dev_uses_irq(pnp, pci, irq)) {
pci_dev_put(pci);
return 1;
}
}
#endif
return 0;
}
int pnp_check_irq(struct pnp_dev *dev, struct resource *res) int pnp_check_irq(struct pnp_dev *dev, struct resource *res)
{ {
int i; int i;
...@@ -395,18 +372,9 @@ int pnp_check_irq(struct pnp_dev *dev, struct resource *res) ...@@ -395,18 +372,9 @@ int pnp_check_irq(struct pnp_dev *dev, struct resource *res)
} }
} }
#ifdef CONFIG_PCI
/* check if the resource is being used by a pci device */ /* check if the resource is being used by a pci device */
{ if (pci_uses_irq(dev, *irq))
struct pci_dev *pci = NULL; return 0;
for_each_pci_dev(pci) {
if (pci->irq == *irq) {
pci_dev_put(pci);
return 0;
}
}
}
#endif
/* check if the resource is already in use, skip if the /* check if the resource is already in use, skip if the
* device is active because it itself may be in use */ * device is active because it itself may be in use */
...@@ -499,81 +467,37 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res) ...@@ -499,81 +467,37 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res)
#endif #endif
} }
struct pnp_resource *pnp_get_pnp_resource(struct pnp_dev *dev, int pnp_resource_type(struct resource *res)
unsigned int type, unsigned int num)
{ {
struct pnp_resource_table *res = dev->res; return res->flags & (IORESOURCE_IO | IORESOURCE_MEM |
IORESOURCE_IRQ | IORESOURCE_DMA);
switch (type) {
case IORESOURCE_IO:
if (num >= PNP_MAX_PORT)
return NULL;
return &res->port[num];
case IORESOURCE_MEM:
if (num >= PNP_MAX_MEM)
return NULL;
return &res->mem[num];
case IORESOURCE_IRQ:
if (num >= PNP_MAX_IRQ)
return NULL;
return &res->irq[num];
case IORESOURCE_DMA:
if (num >= PNP_MAX_DMA)
return NULL;
return &res->dma[num];
}
return NULL;
} }
struct resource *pnp_get_resource(struct pnp_dev *dev, struct resource *pnp_get_resource(struct pnp_dev *dev,
unsigned int type, unsigned int num) unsigned int type, unsigned int num)
{ {
struct pnp_resource *pnp_res; struct pnp_resource *pnp_res;
struct resource *res;
pnp_res = pnp_get_pnp_resource(dev, type, num); list_for_each_entry(pnp_res, &dev->resources, list) {
if (pnp_res) res = &pnp_res->res;
return &pnp_res->res; if (pnp_resource_type(res) == type && num-- == 0)
return res;
}
return NULL; return NULL;
} }
EXPORT_SYMBOL(pnp_get_resource); EXPORT_SYMBOL(pnp_get_resource);
static struct pnp_resource *pnp_new_resource(struct pnp_dev *dev, int type) static struct pnp_resource *pnp_new_resource(struct pnp_dev *dev)
{ {
struct pnp_resource *pnp_res; struct pnp_resource *pnp_res;
int i;
switch (type) { pnp_res = kzalloc(sizeof(struct pnp_resource), GFP_KERNEL);
case IORESOURCE_IO: if (!pnp_res)
for (i = 0; i < PNP_MAX_PORT; i++) { return NULL;
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, i);
if (pnp_res && !pnp_resource_valid(&pnp_res->res)) list_add_tail(&pnp_res->list, &dev->resources);
return pnp_res; return pnp_res;
}
break;
case IORESOURCE_MEM:
for (i = 0; i < PNP_MAX_MEM; i++) {
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_MEM, i);
if (pnp_res && !pnp_resource_valid(&pnp_res->res))
return pnp_res;
}
break;
case IORESOURCE_IRQ:
for (i = 0; i < PNP_MAX_IRQ; i++) {
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, i);
if (pnp_res && !pnp_resource_valid(&pnp_res->res))
return pnp_res;
}
break;
case IORESOURCE_DMA:
for (i = 0; i < PNP_MAX_DMA; i++) {
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, i);
if (pnp_res && !pnp_resource_valid(&pnp_res->res))
return pnp_res;
}
break;
}
return NULL;
} }
struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
...@@ -581,15 +505,10 @@ struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, ...@@ -581,15 +505,10 @@ struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
{ {
struct pnp_resource *pnp_res; struct pnp_resource *pnp_res;
struct resource *res; struct resource *res;
static unsigned char warned;
pnp_res = pnp_new_resource(dev, IORESOURCE_IRQ); pnp_res = pnp_new_resource(dev);
if (!pnp_res) { if (!pnp_res) {
if (!warned) { dev_err(&dev->dev, "can't add resource for IRQ %d\n", irq);
dev_err(&dev->dev, "can't add resource for IRQ %d\n",
irq);
warned = 1;
}
return NULL; return NULL;
} }
...@@ -607,15 +526,10 @@ struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma, ...@@ -607,15 +526,10 @@ struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma,
{ {
struct pnp_resource *pnp_res; struct pnp_resource *pnp_res;
struct resource *res; struct resource *res;
static unsigned char warned;
pnp_res = pnp_new_resource(dev, IORESOURCE_DMA); pnp_res = pnp_new_resource(dev);
if (!pnp_res) { if (!pnp_res) {
if (!warned) { dev_err(&dev->dev, "can't add resource for DMA %d\n", dma);
dev_err(&dev->dev, "can't add resource for DMA %d\n",
dma);
warned = 1;
}
return NULL; return NULL;
} }
...@@ -634,16 +548,12 @@ struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev, ...@@ -634,16 +548,12 @@ struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev,
{ {
struct pnp_resource *pnp_res; struct pnp_resource *pnp_res;
struct resource *res; struct resource *res;
static unsigned char warned;
pnp_res = pnp_new_resource(dev, IORESOURCE_IO); pnp_res = pnp_new_resource(dev);
if (!pnp_res) { if (!pnp_res) {
if (!warned) { dev_err(&dev->dev, "can't add resource for IO %#llx-%#llx\n",
dev_err(&dev->dev, "can't add resource for IO " (unsigned long long) start,
"%#llx-%#llx\n",(unsigned long long) start, (unsigned long long) end);
(unsigned long long) end);
warned = 1;
}
return NULL; return NULL;
} }
...@@ -663,16 +573,12 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, ...@@ -663,16 +573,12 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
{ {
struct pnp_resource *pnp_res; struct pnp_resource *pnp_res;
struct resource *res; struct resource *res;
static unsigned char warned;
pnp_res = pnp_new_resource(dev, IORESOURCE_MEM); pnp_res = pnp_new_resource(dev);
if (!pnp_res) { if (!pnp_res) {
if (!warned) { dev_err(&dev->dev, "can't add resource for MEM %#llx-%#llx\n",
dev_err(&dev->dev, "can't add resource for MEM " (unsigned long long) start,
"%#llx-%#llx\n",(unsigned long long) start, (unsigned long long) end);
(unsigned long long) end);
warned = 1;
}
return NULL; return NULL;
} }
...@@ -686,6 +592,52 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, ...@@ -686,6 +592,52 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
return pnp_res; return pnp_res;
} }
/*
* Determine whether the specified resource is a possible configuration
* for this device.
*/
int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t start,
resource_size_t size)
{
struct pnp_option *option;
struct pnp_port *port;
struct pnp_mem *mem;
struct pnp_irq *irq;
struct pnp_dma *dma;
list_for_each_entry(option, &dev->options, list) {
if (option->type != type)
continue;
switch (option->type) {
case IORESOURCE_IO:
port = &option->u.port;
if (port->min == start && port->size == size)
return 1;
break;
case IORESOURCE_MEM:
mem = &option->u.mem;
if (mem->min == start && mem->size == size)
return 1;
break;
case IORESOURCE_IRQ:
irq = &option->u.irq;
if (start < PNP_IRQ_NR &&
test_bit(start, irq->map.bits))
return 1;
break;
case IORESOURCE_DMA:
dma = &option->u.dma;
if (dma->map & (1 << start))
return 1;
break;
}
}
return 0;
}
EXPORT_SYMBOL(pnp_possible_config);
/* format is: pnp_reserve_irq=irq1[,irq2] .... */ /* format is: pnp_reserve_irq=irq1[,irq2] .... */
static int __init pnp_setup_reserve_irq(char *str) static int __init pnp_setup_reserve_irq(char *str)
{ {
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
* support.c - standard functions for the use of pnp protocol drivers * support.c - standard functions for the use of pnp protocol drivers
* *
* Copyright 2003 Adam Belay <ambx1@neo.rr.com> * Copyright 2003 Adam Belay <ambx1@neo.rr.com>
* Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
* Bjorn Helgaas <bjorn.helgaas@hp.com>
*/ */
#include <linux/module.h> #include <linux/module.h>
...@@ -16,6 +18,10 @@ ...@@ -16,6 +18,10 @@
*/ */
int pnp_is_active(struct pnp_dev *dev) int pnp_is_active(struct pnp_dev *dev)
{ {
/*
* I don't think this is very reliable because pnp_disable_dev()
* only clears out auto-assigned resources.
*/
if (!pnp_port_start(dev, 0) && pnp_port_len(dev, 0) <= 1 && if (!pnp_port_start(dev, 0) && pnp_port_len(dev, 0) <= 1 &&
!pnp_mem_start(dev, 0) && pnp_mem_len(dev, 0) <= 1 && !pnp_mem_start(dev, 0) && pnp_mem_len(dev, 0) <= 1 &&
pnp_irq(dev, 0) == -1 && pnp_dma(dev, 0) == -1) pnp_irq(dev, 0) == -1 && pnp_dma(dev, 0) == -1)
...@@ -52,39 +58,154 @@ void pnp_eisa_id_to_string(u32 id, char *str) ...@@ -52,39 +58,154 @@ void pnp_eisa_id_to_string(u32 id, char *str)
str[7] = '\0'; str[7] = '\0';
} }
char *pnp_resource_type_name(struct resource *res)
{
switch (pnp_resource_type(res)) {
case IORESOURCE_IO:
return "io";
case IORESOURCE_MEM:
return "mem";
case IORESOURCE_IRQ:
return "irq";
case IORESOURCE_DMA:
return "dma";
}
return NULL;
}
void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc) void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc)
{ {
#ifdef DEBUG #ifdef DEBUG
char buf[128];
int len = 0;
struct pnp_resource *pnp_res;
struct resource *res; struct resource *res;
int i;
dev_dbg(&dev->dev, "current resources: %s\n", desc); if (list_empty(&dev->resources)) {
dev_dbg(&dev->dev, "%s: no current resources\n", desc);
for (i = 0; i < PNP_MAX_IRQ; i++) { return;
res = pnp_get_resource(dev, IORESOURCE_IRQ, i);
if (res && !(res->flags & IORESOURCE_UNSET))
dev_dbg(&dev->dev, " irq %lld flags %#lx\n",
(unsigned long long) res->start, res->flags);
} }
for (i = 0; i < PNP_MAX_DMA; i++) {
res = pnp_get_resource(dev, IORESOURCE_DMA, i); dev_dbg(&dev->dev, "%s: current resources:\n", desc);
if (res && !(res->flags & IORESOURCE_UNSET)) list_for_each_entry(pnp_res, &dev->resources, list) {
dev_dbg(&dev->dev, " dma %lld flags %#lx\n", res = &pnp_res->res;
(unsigned long long) res->start, res->flags);
len += snprintf(buf + len, sizeof(buf) - len, " %-3s ",
pnp_resource_type_name(res));
if (res->flags & IORESOURCE_DISABLED) {
dev_dbg(&dev->dev, "%sdisabled\n", buf);
continue;
}
switch (pnp_resource_type(res)) {
case IORESOURCE_IO:
case IORESOURCE_MEM:
len += snprintf(buf + len, sizeof(buf) - len,
"%#llx-%#llx flags %#lx",
(unsigned long long) res->start,
(unsigned long long) res->end,
res->flags);
break;
case IORESOURCE_IRQ:
case IORESOURCE_DMA:
len += snprintf(buf + len, sizeof(buf) - len,
"%lld flags %#lx",
(unsigned long long) res->start,
res->flags);
break;
}
dev_dbg(&dev->dev, "%s\n", buf);
} }
for (i = 0; i < PNP_MAX_PORT; i++) { #endif
res = pnp_get_resource(dev, IORESOURCE_IO, i); }
if (res && !(res->flags & IORESOURCE_UNSET))
dev_dbg(&dev->dev, " io %#llx-%#llx flags %#lx\n", char *pnp_option_priority_name(struct pnp_option *option)
(unsigned long long) res->start, {
(unsigned long long) res->end, res->flags); switch (pnp_option_priority(option)) {
case PNP_RES_PRIORITY_PREFERRED:
return "preferred";
case PNP_RES_PRIORITY_ACCEPTABLE:
return "acceptable";
case PNP_RES_PRIORITY_FUNCTIONAL:
return "functional";
} }
for (i = 0; i < PNP_MAX_MEM; i++) { return "invalid";
res = pnp_get_resource(dev, IORESOURCE_MEM, i); }
if (res && !(res->flags & IORESOURCE_UNSET))
dev_dbg(&dev->dev, " mem %#llx-%#llx flags %#lx\n", void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option)
(unsigned long long) res->start, {
(unsigned long long) res->end, res->flags); #ifdef DEBUG
char buf[128];
int len = 0, i;
struct pnp_port *port;
struct pnp_mem *mem;
struct pnp_irq *irq;
struct pnp_dma *dma;
if (pnp_option_is_dependent(option))
len += snprintf(buf + len, sizeof(buf) - len,
" dependent set %d (%s) ",
pnp_option_set(option),
pnp_option_priority_name(option));
else
len += snprintf(buf + len, sizeof(buf) - len, " independent ");
switch (option->type) {
case IORESOURCE_IO:
port = &option->u.port;
len += snprintf(buf + len, sizeof(buf) - len, "io min %#llx "
"max %#llx align %lld size %lld flags %#x",
(unsigned long long) port->min,
(unsigned long long) port->max,
(unsigned long long) port->align,
(unsigned long long) port->size, port->flags);
break;
case IORESOURCE_MEM:
mem = &option->u.mem;
len += snprintf(buf + len, sizeof(buf) - len, "mem min %#llx "
"max %#llx align %lld size %lld flags %#x",
(unsigned long long) mem->min,
(unsigned long long) mem->max,
(unsigned long long) mem->align,
(unsigned long long) mem->size, mem->flags);
break;
case IORESOURCE_IRQ:
irq = &option->u.irq;
len += snprintf(buf + len, sizeof(buf) - len, "irq");
if (bitmap_empty(irq->map.bits, PNP_IRQ_NR))
len += snprintf(buf + len, sizeof(buf) - len,
" <none>");
else {
for (i = 0; i < PNP_IRQ_NR; i++)
if (test_bit(i, irq->map.bits))
len += snprintf(buf + len,
sizeof(buf) - len,
" %d", i);
}
len += snprintf(buf + len, sizeof(buf) - len, " flags %#x",
irq->flags);
if (irq->flags & IORESOURCE_IRQ_OPTIONAL)
len += snprintf(buf + len, sizeof(buf) - len,
" (optional)");
break;
case IORESOURCE_DMA:
dma = &option->u.dma;
len += snprintf(buf + len, sizeof(buf) - len, "dma");
if (!dma->map)
len += snprintf(buf + len, sizeof(buf) - len,
" <none>");
else {
for (i = 0; i < 8; i++)
if (dma->map & (1 << i))
len += snprintf(buf + len,
sizeof(buf) - len,
" %d", i);
}
len += snprintf(buf + len, sizeof(buf) - len, " (bitmask %#x) "
"flags %#x", dma->map, dma->flags);
break;
} }
dev_dbg(&dev->dev, "%s\n", buf);
#endif #endif
} }
...@@ -60,7 +60,7 @@ static void reserve_resources_of_dev(struct pnp_dev *dev) ...@@ -60,7 +60,7 @@ static void reserve_resources_of_dev(struct pnp_dev *dev)
int i; int i;
for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) { for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) {
if (res->flags & IORESOURCE_UNSET) if (res->flags & IORESOURCE_DISABLED)
continue; continue;
if (res->start == 0) if (res->start == 0)
continue; /* disabled */ continue; /* disabled */
...@@ -81,7 +81,7 @@ static void reserve_resources_of_dev(struct pnp_dev *dev) ...@@ -81,7 +81,7 @@ static void reserve_resources_of_dev(struct pnp_dev *dev)
} }
for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) { for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
if (res->flags & (IORESOURCE_UNSET | IORESOURCE_DISABLED)) if (res->flags & IORESOURCE_DISABLED)
continue; continue;
reserve_range(dev, res->start, res->end, 0); reserve_range(dev, res->start, res->end, 0);
......
...@@ -383,21 +383,14 @@ static int __devinit check_name(char *name) ...@@ -383,21 +383,14 @@ static int __devinit check_name(char *name)
return 0; return 0;
} }
static int __devinit check_resources(struct pnp_option *option) static int __devinit check_resources(struct pnp_dev *dev)
{ {
struct pnp_option *tmp; resource_size_t base[] = {0x2f8, 0x3f8, 0x2e8, 0x3e8};
if (!option) int i;
return 0;
for (tmp = option; tmp; tmp = tmp->next) { for (i = 0; i < ARRAY_SIZE(base); i++) {
struct pnp_port *port; if (pnp_possible_config(dev, IORESOURCE_IO, base[i], 8))
for (port = tmp->port; port; port = port->next) return 1;
if ((port->size == 8) &&
((port->min == 0x2f8) ||
(port->min == 0x3f8) ||
(port->min == 0x2e8) ||
(port->min == 0x3e8)))
return 1;
} }
return 0; return 0;
...@@ -420,10 +413,7 @@ static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags) ...@@ -420,10 +413,7 @@ static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags)
(dev->card && check_name(dev->card->name)))) (dev->card && check_name(dev->card->name))))
return -ENODEV; return -ENODEV;
if (check_resources(dev->independent)) if (check_resources(dev))
return 0;
if (check_resources(dev->dependent))
return 0; return 0;
return -ENODEV; return -ENODEV;
......
...@@ -63,7 +63,7 @@ ...@@ -63,7 +63,7 @@
/* Current ACPICA subsystem version in YYYYMMDD format */ /* Current ACPICA subsystem version in YYYYMMDD format */
#define ACPI_CA_VERSION 0x20080321 #define ACPI_CA_VERSION 0x20080609
/* /*
* OS name, used for the _OS object. The _OS object is essentially obsolete, * OS name, used for the _OS object. The _OS object is essentially obsolete,
......
...@@ -162,6 +162,7 @@ extern struct acpi_dmtable_info acpi_dm_table_info_dmar_hdr[]; ...@@ -162,6 +162,7 @@ extern struct acpi_dmtable_info acpi_dm_table_info_dmar_hdr[];
extern struct acpi_dmtable_info acpi_dm_table_info_dmar_scope[]; extern struct acpi_dmtable_info acpi_dm_table_info_dmar_scope[];
extern struct acpi_dmtable_info acpi_dm_table_info_dmar0[]; extern struct acpi_dmtable_info acpi_dm_table_info_dmar0[];
extern struct acpi_dmtable_info acpi_dm_table_info_dmar1[]; extern struct acpi_dmtable_info acpi_dm_table_info_dmar1[];
extern struct acpi_dmtable_info acpi_dm_table_info_dmar2[];
extern struct acpi_dmtable_info acpi_dm_table_info_ecdt[]; extern struct acpi_dmtable_info acpi_dm_table_info_ecdt[];
extern struct acpi_dmtable_info acpi_dm_table_info_einj[]; extern struct acpi_dmtable_info acpi_dm_table_info_einj[];
extern struct acpi_dmtable_info acpi_dm_table_info_einj0[]; extern struct acpi_dmtable_info acpi_dm_table_info_einj0[];
......
...@@ -221,7 +221,7 @@ acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state); ...@@ -221,7 +221,7 @@ acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state);
* dsinit * dsinit
*/ */
acpi_status acpi_status
acpi_ds_initialize_objects(acpi_native_uint table_index, acpi_ds_initialize_objects(u32 table_index,
struct acpi_namespace_node *start_node); struct acpi_namespace_node *start_node);
/* /*
......
...@@ -108,8 +108,9 @@ ...@@ -108,8 +108,9 @@
#define AE_BAD_HEX_CONSTANT (acpi_status) (0x0007 | AE_CODE_PROGRAMMER) #define AE_BAD_HEX_CONSTANT (acpi_status) (0x0007 | AE_CODE_PROGRAMMER)
#define AE_BAD_OCTAL_CONSTANT (acpi_status) (0x0008 | AE_CODE_PROGRAMMER) #define AE_BAD_OCTAL_CONSTANT (acpi_status) (0x0008 | AE_CODE_PROGRAMMER)
#define AE_BAD_DECIMAL_CONSTANT (acpi_status) (0x0009 | AE_CODE_PROGRAMMER) #define AE_BAD_DECIMAL_CONSTANT (acpi_status) (0x0009 | AE_CODE_PROGRAMMER)
#define AE_MISSING_ARGUMENTS (acpi_status) (0x000A | AE_CODE_PROGRAMMER)
#define AE_CODE_PGM_MAX 0x0009 #define AE_CODE_PGM_MAX 0x000A
/* /*
* Acpi table exceptions * Acpi table exceptions
...@@ -225,6 +226,7 @@ char const *acpi_gbl_exception_names_env[] = { ...@@ -225,6 +226,7 @@ char const *acpi_gbl_exception_names_env[] = {
}; };
char const *acpi_gbl_exception_names_pgm[] = { char const *acpi_gbl_exception_names_pgm[] = {
NULL,
"AE_BAD_PARAMETER", "AE_BAD_PARAMETER",
"AE_BAD_CHARACTER", "AE_BAD_CHARACTER",
"AE_BAD_PATHNAME", "AE_BAD_PATHNAME",
...@@ -233,10 +235,12 @@ char const *acpi_gbl_exception_names_pgm[] = { ...@@ -233,10 +235,12 @@ char const *acpi_gbl_exception_names_pgm[] = {
"AE_ALIGNMENT", "AE_ALIGNMENT",
"AE_BAD_HEX_CONSTANT", "AE_BAD_HEX_CONSTANT",
"AE_BAD_OCTAL_CONSTANT", "AE_BAD_OCTAL_CONSTANT",
"AE_BAD_DECIMAL_CONSTANT" "AE_BAD_DECIMAL_CONSTANT",
"AE_MISSING_ARGUMENTS"
}; };
char const *acpi_gbl_exception_names_tbl[] = { char const *acpi_gbl_exception_names_tbl[] = {
NULL,
"AE_BAD_SIGNATURE", "AE_BAD_SIGNATURE",
"AE_BAD_HEADER", "AE_BAD_HEADER",
"AE_BAD_CHECKSUM", "AE_BAD_CHECKSUM",
...@@ -246,6 +250,7 @@ char const *acpi_gbl_exception_names_tbl[] = { ...@@ -246,6 +250,7 @@ char const *acpi_gbl_exception_names_tbl[] = {
}; };
char const *acpi_gbl_exception_names_aml[] = { char const *acpi_gbl_exception_names_aml[] = {
NULL,
"AE_AML_ERROR", "AE_AML_ERROR",
"AE_AML_PARSE", "AE_AML_PARSE",
"AE_AML_BAD_OPCODE", "AE_AML_BAD_OPCODE",
...@@ -283,6 +288,7 @@ char const *acpi_gbl_exception_names_aml[] = { ...@@ -283,6 +288,7 @@ char const *acpi_gbl_exception_names_aml[] = {
}; };
char const *acpi_gbl_exception_names_ctrl[] = { char const *acpi_gbl_exception_names_ctrl[] = {
NULL,
"AE_CTRL_RETURN_VALUE", "AE_CTRL_RETURN_VALUE",
"AE_CTRL_PENDING", "AE_CTRL_PENDING",
"AE_CTRL_TERMINATE", "AE_CTRL_TERMINATE",
......
...@@ -140,7 +140,7 @@ ACPI_EXTERN u32 acpi_gbl_trace_flags; ...@@ -140,7 +140,7 @@ ACPI_EXTERN u32 acpi_gbl_trace_flags;
*/ */
ACPI_EXTERN struct acpi_internal_rsdt acpi_gbl_root_table_list; ACPI_EXTERN struct acpi_internal_rsdt acpi_gbl_root_table_list;
ACPI_EXTERN struct acpi_table_fadt acpi_gbl_FADT; ACPI_EXTERN struct acpi_table_fadt acpi_gbl_FADT;
extern acpi_native_uint acpi_gbl_permanent_mmap; extern u8 acpi_gbl_permanent_mmap;
/* These addresses are calculated from FADT address values */ /* These addresses are calculated from FADT address values */
......
...@@ -87,6 +87,8 @@ acpi_status acpi_hw_clear_acpi_status(void); ...@@ -87,6 +87,8 @@ acpi_status acpi_hw_clear_acpi_status(void);
/* /*
* hwgpe - GPE support * hwgpe - GPE support
*/ */
acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info);
acpi_status acpi_status
acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info *gpe_event_info); acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info *gpe_event_info);
...@@ -100,11 +102,9 @@ acpi_status ...@@ -100,11 +102,9 @@ acpi_status
acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
struct acpi_gpe_block_info *gpe_block); struct acpi_gpe_block_info *gpe_block);
#ifdef ACPI_FUTURE_USAGE
acpi_status acpi_status
acpi_hw_get_gpe_status(struct acpi_gpe_event_info *gpe_event_info, acpi_hw_get_gpe_status(struct acpi_gpe_event_info *gpe_event_info,
acpi_event_status * event_status); acpi_event_status * event_status);
#endif /* ACPI_FUTURE_USAGE */
acpi_status acpi_hw_disable_all_gpes(void); acpi_status acpi_hw_disable_all_gpes(void);
......
...@@ -366,10 +366,7 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth); ...@@ -366,10 +366,7 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth);
void void
acpi_ex_dump_operands(union acpi_operand_object **operands, acpi_ex_dump_operands(union acpi_operand_object **operands,
acpi_interpreter_mode interpreter_mode, const char *opcode_name, u32 num_opcodes);
char *ident,
u32 num_levels,
char *note, char *module_name, u32 line_number);
#ifdef ACPI_FUTURE_USAGE #ifdef ACPI_FUTURE_USAGE
void void
......
...@@ -98,8 +98,8 @@ union acpi_parse_object; ...@@ -98,8 +98,8 @@ union acpi_parse_object;
static char *acpi_gbl_mutex_names[ACPI_NUM_MUTEX] = { static char *acpi_gbl_mutex_names[ACPI_NUM_MUTEX] = {
"ACPI_MTX_Interpreter", "ACPI_MTX_Interpreter",
"ACPI_MTX_Tables",
"ACPI_MTX_Namespace", "ACPI_MTX_Namespace",
"ACPI_MTX_Tables",
"ACPI_MTX_Events", "ACPI_MTX_Events",
"ACPI_MTX_Caches", "ACPI_MTX_Caches",
"ACPI_MTX_Memory", "ACPI_MTX_Memory",
...@@ -282,8 +282,8 @@ struct acpi_predefined_names { ...@@ -282,8 +282,8 @@ struct acpi_predefined_names {
/* Info structure used to convert external<->internal namestrings */ /* Info structure used to convert external<->internal namestrings */
struct acpi_namestring_info { struct acpi_namestring_info {
char *external_name; const char *external_name;
char *next_external_char; const char *next_external_char;
char *internal_name; char *internal_name;
u32 length; u32 length;
u32 num_segments; u32 num_segments;
......
...@@ -80,12 +80,12 @@ ...@@ -80,12 +80,12 @@
*/ */
#define ACPI_CAST_PTR(t, p) ((t *) (acpi_uintptr_t) (p)) #define ACPI_CAST_PTR(t, p) ((t *) (acpi_uintptr_t) (p))
#define ACPI_CAST_INDIRECT_PTR(t, p) ((t **) (acpi_uintptr_t) (p)) #define ACPI_CAST_INDIRECT_PTR(t, p) ((t **) (acpi_uintptr_t) (p))
#define ACPI_ADD_PTR(t,a,b) ACPI_CAST_PTR (t, (ACPI_CAST_PTR (u8,(a)) + (acpi_native_uint)(b))) #define ACPI_ADD_PTR(t, a, b) ACPI_CAST_PTR (t, (ACPI_CAST_PTR (u8,(a)) + (acpi_size)(b)))
#define ACPI_PTR_DIFF(a,b) (acpi_native_uint) (ACPI_CAST_PTR (u8,(a)) - ACPI_CAST_PTR (u8,(b))) #define ACPI_PTR_DIFF(a, b) (acpi_size) (ACPI_CAST_PTR (u8,(a)) - ACPI_CAST_PTR (u8,(b)))
/* Pointer/Integer type conversions */ /* Pointer/Integer type conversions */
#define ACPI_TO_POINTER(i) ACPI_ADD_PTR (void,(void *) NULL,(acpi_native_uint) i) #define ACPI_TO_POINTER(i) ACPI_ADD_PTR (void, (void *) NULL, (acpi_size) i)
#define ACPI_TO_INTEGER(p) ACPI_PTR_DIFF (p,(void *) NULL) #define ACPI_TO_INTEGER(p) ACPI_PTR_DIFF (p,(void *) NULL)
#define ACPI_OFFSET(d,f) (acpi_size) ACPI_PTR_DIFF (&(((d *)0)->f),(void *) NULL) #define ACPI_OFFSET(d,f) (acpi_size) ACPI_PTR_DIFF (&(((d *)0)->f),(void *) NULL)
#define ACPI_PHYSADDR_TO_PTR(i) ACPI_TO_POINTER(i) #define ACPI_PHYSADDR_TO_PTR(i) ACPI_TO_POINTER(i)
...@@ -296,22 +296,22 @@ struct acpi_integer_overlay { ...@@ -296,22 +296,22 @@ struct acpi_integer_overlay {
/* /*
* Rounding macros (Power of two boundaries only) * Rounding macros (Power of two boundaries only)
*/ */
#define ACPI_ROUND_DOWN(value,boundary) (((acpi_native_uint)(value)) & \ #define ACPI_ROUND_DOWN(value, boundary) (((acpi_size)(value)) & \
(~(((acpi_native_uint) boundary)-1))) (~(((acpi_size) boundary)-1)))
#define ACPI_ROUND_UP(value,boundary) ((((acpi_native_uint)(value)) + \ #define ACPI_ROUND_UP(value, boundary) ((((acpi_size)(value)) + \
(((acpi_native_uint) boundary)-1)) & \ (((acpi_size) boundary)-1)) & \
(~(((acpi_native_uint) boundary)-1))) (~(((acpi_size) boundary)-1)))
/* Note: sizeof(acpi_native_uint) evaluates to either 2, 4, or 8 */ /* Note: sizeof(acpi_size) evaluates to either 4 or 8 (32- vs 64-bit mode) */
#define ACPI_ROUND_DOWN_TO_32BIT(a) ACPI_ROUND_DOWN(a,4) #define ACPI_ROUND_DOWN_TO_32BIT(a) ACPI_ROUND_DOWN(a,4)
#define ACPI_ROUND_DOWN_TO_64BIT(a) ACPI_ROUND_DOWN(a,8) #define ACPI_ROUND_DOWN_TO_64BIT(a) ACPI_ROUND_DOWN(a,8)
#define ACPI_ROUND_DOWN_TO_NATIVE_WORD(a) ACPI_ROUND_DOWN(a,sizeof(acpi_native_uint)) #define ACPI_ROUND_DOWN_TO_NATIVE_WORD(a) ACPI_ROUND_DOWN(a,sizeof(acpi_size))
#define ACPI_ROUND_UP_TO_32BIT(a) ACPI_ROUND_UP(a,4) #define ACPI_ROUND_UP_TO_32BIT(a) ACPI_ROUND_UP(a,4)
#define ACPI_ROUND_UP_TO_64BIT(a) ACPI_ROUND_UP(a,8) #define ACPI_ROUND_UP_TO_64BIT(a) ACPI_ROUND_UP(a,8)
#define ACPI_ROUND_UP_TO_NATIVE_WORD(a) ACPI_ROUND_UP(a,sizeof(acpi_native_uint)) #define ACPI_ROUND_UP_TO_NATIVE_WORD(a) ACPI_ROUND_UP(a,sizeof(acpi_size))
#define ACPI_ROUND_BITS_UP_TO_BYTES(a) ACPI_DIV_8((a) + 7) #define ACPI_ROUND_BITS_UP_TO_BYTES(a) ACPI_DIV_8((a) + 7)
#define ACPI_ROUND_BITS_DOWN_TO_BYTES(a) ACPI_DIV_8((a)) #define ACPI_ROUND_BITS_DOWN_TO_BYTES(a) ACPI_DIV_8((a))
...@@ -322,7 +322,7 @@ struct acpi_integer_overlay { ...@@ -322,7 +322,7 @@ struct acpi_integer_overlay {
#define ACPI_ROUND_UP_TO(value,boundary) (((value) + ((boundary)-1)) / (boundary)) #define ACPI_ROUND_UP_TO(value,boundary) (((value) + ((boundary)-1)) / (boundary))
#define ACPI_IS_MISALIGNED(value) (((acpi_native_uint)value) & (sizeof(acpi_native_uint)-1)) #define ACPI_IS_MISALIGNED(value) (((acpi_size)value) & (sizeof(acpi_size)-1))
/* /*
* Bitmask creation * Bitmask creation
...@@ -414,7 +414,7 @@ struct acpi_integer_overlay { ...@@ -414,7 +414,7 @@ struct acpi_integer_overlay {
* error messages. The __FILE__ macro is not very useful for this, because it * error messages. The __FILE__ macro is not very useful for this, because it
* often includes the entire pathname to the module * often includes the entire pathname to the module
*/ */
#define ACPI_MODULE_NAME(name) static char ACPI_UNUSED_VAR *_acpi_module_name = name; #define ACPI_MODULE_NAME(name) static const char ACPI_UNUSED_VAR _acpi_module_name[] = name;
#else #else
#define ACPI_MODULE_NAME(name) #define ACPI_MODULE_NAME(name)
#endif #endif
...@@ -467,19 +467,17 @@ struct acpi_integer_overlay { ...@@ -467,19 +467,17 @@ struct acpi_integer_overlay {
/* /*
* If ACPI_GET_FUNCTION_NAME was not defined in the compiler-dependent header, * If ACPI_GET_FUNCTION_NAME was not defined in the compiler-dependent header,
* define it now. This is the case where there the compiler does not support * define it now. This is the case where there the compiler does not support
* a __FUNCTION__ macro or equivalent. We save the function name on the * a __FUNCTION__ macro or equivalent.
* local stack.
*/ */
#ifndef ACPI_GET_FUNCTION_NAME #ifndef ACPI_GET_FUNCTION_NAME
#define ACPI_GET_FUNCTION_NAME _acpi_function_name #define ACPI_GET_FUNCTION_NAME _acpi_function_name
/* /*
* The Name parameter should be the procedure name as a quoted string. * The Name parameter should be the procedure name as a quoted string.
* This is declared as a local string ("MyFunctionName") so that it can * The function name is also used by the function exit macros below.
* be also used by the function exit macros below.
* Note: (const char) is used to be compatible with the debug interfaces * Note: (const char) is used to be compatible with the debug interfaces
* and macros such as __FUNCTION__. * and macros such as __FUNCTION__.
*/ */
#define ACPI_FUNCTION_NAME(name) const char *_acpi_function_name = #name; #define ACPI_FUNCTION_NAME(name) static const char _acpi_function_name[] = #name;
#else #else
/* Compiler supports __FUNCTION__ (or equivalent) -- Ignore this macro */ /* Compiler supports __FUNCTION__ (or equivalent) -- Ignore this macro */
...@@ -599,7 +597,7 @@ struct acpi_integer_overlay { ...@@ -599,7 +597,7 @@ struct acpi_integer_overlay {
/* Stack and buffer dumping */ /* Stack and buffer dumping */
#define ACPI_DUMP_STACK_ENTRY(a) acpi_ex_dump_operand((a),0) #define ACPI_DUMP_STACK_ENTRY(a) acpi_ex_dump_operand((a),0)
#define ACPI_DUMP_OPERANDS(a,b,c,d,e) acpi_ex_dump_operands(a,b,c,d,e,_acpi_module_name,__LINE__) #define ACPI_DUMP_OPERANDS(a,b,c) acpi_ex_dump_operands(a,b,c)
#define ACPI_DUMP_ENTRY(a,b) acpi_ns_dump_entry (a,b) #define ACPI_DUMP_ENTRY(a,b) acpi_ns_dump_entry (a,b)
#define ACPI_DUMP_PATHNAME(a,b,c,d) acpi_ns_dump_pathname(a,b,c,d) #define ACPI_DUMP_PATHNAME(a,b,c,d) acpi_ns_dump_pathname(a,b,c,d)
...@@ -635,7 +633,7 @@ struct acpi_integer_overlay { ...@@ -635,7 +633,7 @@ struct acpi_integer_overlay {
#define ACPI_FUNCTION_VALUE_EXIT(s) do { } while(0) #define ACPI_FUNCTION_VALUE_EXIT(s) do { } while(0)
#define ACPI_FUNCTION_ENTRY() do { } while(0) #define ACPI_FUNCTION_ENTRY() do { } while(0)
#define ACPI_DUMP_STACK_ENTRY(a) do { } while(0) #define ACPI_DUMP_STACK_ENTRY(a) do { } while(0)
#define ACPI_DUMP_OPERANDS(a,b,c,d,e) do { } while(0) #define ACPI_DUMP_OPERANDS(a,b,c) do { } while(0)
#define ACPI_DUMP_ENTRY(a,b) do { } while(0) #define ACPI_DUMP_ENTRY(a,b) do { } while(0)
#define ACPI_DUMP_TABLES(a,b) do { } while(0) #define ACPI_DUMP_TABLES(a,b) do { } while(0)
#define ACPI_DUMP_PATHNAME(a,b,c,d) do { } while(0) #define ACPI_DUMP_PATHNAME(a,b,c,d) do { } while(0)
......
...@@ -86,8 +86,7 @@ acpi_status acpi_ns_initialize_devices(void); ...@@ -86,8 +86,7 @@ acpi_status acpi_ns_initialize_devices(void);
acpi_status acpi_ns_load_namespace(void); acpi_status acpi_ns_load_namespace(void);
acpi_status acpi_status
acpi_ns_load_table(acpi_native_uint table_index, acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node);
struct acpi_namespace_node *node);
/* /*
* nswalk - walk the namespace * nswalk - walk the namespace
...@@ -108,12 +107,11 @@ struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, struct ...@@ -108,12 +107,11 @@ struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, struct
* nsparse - table parsing * nsparse - table parsing
*/ */
acpi_status acpi_status
acpi_ns_parse_table(acpi_native_uint table_index, acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node);
struct acpi_namespace_node *start_node);
acpi_status acpi_status
acpi_ns_one_complete_parse(acpi_native_uint pass_number, acpi_ns_one_complete_parse(u32 pass_number,
acpi_native_uint table_index, u32 table_index,
struct acpi_namespace_node *start_node); struct acpi_namespace_node *start_node);
/* /*
...@@ -201,7 +199,7 @@ acpi_ns_pattern_match(struct acpi_namespace_node *obj_node, char *search_for); ...@@ -201,7 +199,7 @@ acpi_ns_pattern_match(struct acpi_namespace_node *obj_node, char *search_for);
acpi_status acpi_status
acpi_ns_get_node(struct acpi_namespace_node *prefix_node, acpi_ns_get_node(struct acpi_namespace_node *prefix_node,
char *external_pathname, const char *external_pathname,
u32 flags, struct acpi_namespace_node **out_node); u32 flags, struct acpi_namespace_node **out_node);
acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node); acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node);
...@@ -265,28 +263,30 @@ acpi_object_type acpi_ns_get_type(struct acpi_namespace_node *node); ...@@ -265,28 +263,30 @@ acpi_object_type acpi_ns_get_type(struct acpi_namespace_node *node);
u32 acpi_ns_local(acpi_object_type type); u32 acpi_ns_local(acpi_object_type type);
void void
acpi_ns_report_error(char *module_name, acpi_ns_report_error(const char *module_name,
u32 line_number, u32 line_number,
char *internal_name, acpi_status lookup_status); const char *internal_name, acpi_status lookup_status);
void void
acpi_ns_report_method_error(char *module_name, acpi_ns_report_method_error(const char *module_name,
u32 line_number, u32 line_number,
char *message, const char *message,
struct acpi_namespace_node *node, struct acpi_namespace_node *node,
char *path, acpi_status lookup_status); const char *path, acpi_status lookup_status);
void acpi_ns_print_node_pathname(struct acpi_namespace_node *node, char *msg); void
acpi_ns_print_node_pathname(struct acpi_namespace_node *node, const char *msg);
acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info); acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info);
void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info); void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info);
acpi_status acpi_ns_internalize_name(char *dotted_name, char **converted_name); acpi_status
acpi_ns_internalize_name(const char *dotted_name, char **converted_name);
acpi_status acpi_status
acpi_ns_externalize_name(u32 internal_name_length, acpi_ns_externalize_name(u32 internal_name_length,
char *internal_name, const char *internal_name,
u32 * converted_name_length, char **converted_name); u32 * converted_name_length, char **converted_name);
struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle); struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle);
......
...@@ -376,9 +376,9 @@ acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int); ...@@ -376,9 +376,9 @@ acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int);
#define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->archdata.acpi_handle)) #define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->archdata.acpi_handle))
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
int acpi_pm_device_sleep_state(struct device *, int, int *); int acpi_pm_device_sleep_state(struct device *, int *);
#else /* !CONFIG_PM_SLEEP */ #else /* !CONFIG_PM_SLEEP */
static inline int acpi_pm_device_sleep_state(struct device *d, int w, int *p) static inline int acpi_pm_device_sleep_state(struct device *d, int *p)
{ {
if (p) if (p)
*p = ACPI_STATE_D0; *p = ACPI_STATE_D0;
......
...@@ -144,7 +144,7 @@ void acpi_os_release_mutex(acpi_mutex handle); ...@@ -144,7 +144,7 @@ void acpi_os_release_mutex(acpi_mutex handle);
void *acpi_os_allocate(acpi_size size); void *acpi_os_allocate(acpi_size size);
void __iomem *acpi_os_map_memory(acpi_physical_address where, void __iomem *acpi_os_map_memory(acpi_physical_address where,
acpi_native_uint length); acpi_size length);
void acpi_os_unmap_memory(void __iomem * logical_address, acpi_size size); void acpi_os_unmap_memory(void __iomem * logical_address, acpi_size size);
......
...@@ -98,7 +98,7 @@ void acpi_free(void *address); ...@@ -98,7 +98,7 @@ void acpi_free(void *address);
*/ */
acpi_status acpi_reallocate_root_table(void); acpi_status acpi_reallocate_root_table(void);
acpi_status acpi_find_root_pointer(acpi_native_uint * rsdp_address); acpi_status acpi_find_root_pointer(acpi_size *rsdp_address);
acpi_status acpi_load_tables(void); acpi_status acpi_load_tables(void);
...@@ -108,15 +108,15 @@ acpi_status acpi_unload_table_id(acpi_owner_id id); ...@@ -108,15 +108,15 @@ acpi_status acpi_unload_table_id(acpi_owner_id id);
acpi_status acpi_status
acpi_get_table_header(acpi_string signature, acpi_get_table_header(acpi_string signature,
acpi_native_uint instance, u32 instance,
struct acpi_table_header *out_table_header); struct acpi_table_header *out_table_header);
acpi_status acpi_status
acpi_get_table(acpi_string signature, acpi_get_table(acpi_string signature,
acpi_native_uint instance, struct acpi_table_header **out_table); u32 instance, struct acpi_table_header **out_table);
acpi_status acpi_status
acpi_get_table_by_index(acpi_native_uint table_index, acpi_get_table_by_index(u32 table_index,
struct acpi_table_header **out_table); struct acpi_table_header **out_table);
acpi_status acpi_status
...@@ -248,9 +248,7 @@ acpi_status acpi_disable_event(u32 event, u32 flags); ...@@ -248,9 +248,7 @@ acpi_status acpi_disable_event(u32 event, u32 flags);
acpi_status acpi_clear_event(u32 event); acpi_status acpi_clear_event(u32 event);
#ifdef ACPI_FUTURE_USAGE
acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status); acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status);
#endif /* ACPI_FUTURE_USAGE */
acpi_status acpi_set_gpe_type(acpi_handle gpe_device, u32 gpe_number, u8 type); acpi_status acpi_set_gpe_type(acpi_handle gpe_device, u32 gpe_number, u8 type);
...@@ -260,12 +258,10 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags); ...@@ -260,12 +258,10 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags);
acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags); acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags);
#ifdef ACPI_FUTURE_USAGE
acpi_status acpi_status
acpi_get_gpe_status(acpi_handle gpe_device, acpi_get_gpe_status(acpi_handle gpe_device,
u32 gpe_number, u32 gpe_number,
u32 flags, acpi_event_status * event_status); u32 flags, acpi_event_status * event_status);
#endif /* ACPI_FUTURE_USAGE */
acpi_status acpi_status
acpi_install_gpe_block(acpi_handle gpe_device, acpi_install_gpe_block(acpi_handle gpe_device,
......
...@@ -108,7 +108,6 @@ struct acpi_walk_state { ...@@ -108,7 +108,6 @@ struct acpi_walk_state {
union acpi_operand_object **caller_return_desc; union acpi_operand_object **caller_return_desc;
union acpi_generic_state *control_state; /* List of control states (nested IFs) */ union acpi_generic_state *control_state; /* List of control states (nested IFs) */
struct acpi_namespace_node *deferred_node; /* Used when executing deferred opcodes */ struct acpi_namespace_node *deferred_node; /* Used when executing deferred opcodes */
struct acpi_gpe_event_info *gpe_event_info; /* Info for GPE (_Lxx/_Exx methods only */
union acpi_operand_object *implicit_return_obj; union acpi_operand_object *implicit_return_obj;
struct acpi_namespace_node *method_call_node; /* Called method Node */ struct acpi_namespace_node *method_call_node; /* Called method Node */
union acpi_parse_object *method_call_op; /* method_call Op if running a method */ union acpi_parse_object *method_call_op; /* method_call Op if running a method */
...@@ -143,7 +142,7 @@ struct acpi_init_walk_info { ...@@ -143,7 +142,7 @@ struct acpi_init_walk_info {
u16 package_init; u16 package_init;
u16 object_count; u16 object_count;
acpi_owner_id owner_id; acpi_owner_id owner_id;
acpi_native_uint table_index; u32 table_index;
}; };
struct acpi_get_devices_info { struct acpi_get_devices_info {
...@@ -189,17 +188,12 @@ struct acpi_evaluate_info { ...@@ -189,17 +188,12 @@ struct acpi_evaluate_info {
union acpi_operand_object **parameters; union acpi_operand_object **parameters;
struct acpi_namespace_node *resolved_node; struct acpi_namespace_node *resolved_node;
union acpi_operand_object *return_object; union acpi_operand_object *return_object;
u8 param_count;
u8 pass_number; u8 pass_number;
u8 parameter_type;
u8 return_object_type; u8 return_object_type;
u8 flags; u8 flags;
}; };
/* Types for parameter_type above */
#define ACPI_PARAM_ARGS 0
#define ACPI_PARAM_GPE 1
/* Values for Flags above */ /* Values for Flags above */
#define ACPI_IGNORE_RETURN_VALUE 1 #define ACPI_IGNORE_RETURN_VALUE 1
......
...@@ -49,7 +49,7 @@ acpi_status acpi_allocate_root_table(u32 initial_table_count); ...@@ -49,7 +49,7 @@ acpi_status acpi_allocate_root_table(u32 initial_table_count);
/* /*
* tbfadt - FADT parse/convert/validate * tbfadt - FADT parse/convert/validate
*/ */
void acpi_tb_parse_fadt(acpi_native_uint table_index, u8 flags); void acpi_tb_parse_fadt(u32 table_index, u8 flags);
void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length); void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length);
...@@ -58,8 +58,7 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length); ...@@ -58,8 +58,7 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length);
*/ */
acpi_status acpi_status
acpi_tb_find_table(char *signature, acpi_tb_find_table(char *signature,
char *oem_id, char *oem_id, char *oem_table_id, u32 *table_index);
char *oem_table_id, acpi_native_uint * table_index);
/* /*
* tbinstal - Table removal and deletion * tbinstal - Table removal and deletion
...@@ -69,30 +68,28 @@ acpi_status acpi_tb_resize_root_table_list(void); ...@@ -69,30 +68,28 @@ acpi_status acpi_tb_resize_root_table_list(void);
acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc); acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc);
acpi_status acpi_status
acpi_tb_add_table(struct acpi_table_desc *table_desc, acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index);
acpi_native_uint * table_index);
acpi_status acpi_status
acpi_tb_store_table(acpi_physical_address address, acpi_tb_store_table(acpi_physical_address address,
struct acpi_table_header *table, struct acpi_table_header *table,
u32 length, u8 flags, acpi_native_uint * table_index); u32 length, u8 flags, u32 *table_index);
void acpi_tb_delete_table(struct acpi_table_desc *table_desc); void acpi_tb_delete_table(struct acpi_table_desc *table_desc);
void acpi_tb_terminate(void); void acpi_tb_terminate(void);
void acpi_tb_delete_namespace_by_owner(acpi_native_uint table_index); void acpi_tb_delete_namespace_by_owner(u32 table_index);
acpi_status acpi_tb_allocate_owner_id(acpi_native_uint table_index); acpi_status acpi_tb_allocate_owner_id(u32 table_index);
acpi_status acpi_tb_release_owner_id(acpi_native_uint table_index); acpi_status acpi_tb_release_owner_id(u32 table_index);
acpi_status acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id);
acpi_tb_get_owner_id(acpi_native_uint table_index, acpi_owner_id * owner_id);
u8 acpi_tb_is_table_loaded(acpi_native_uint table_index); u8 acpi_tb_is_table_loaded(u32 table_index);
void acpi_tb_set_table_loaded_flag(acpi_native_uint table_index, u8 is_loaded); void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded);
/* /*
* tbutils - table manager utilities * tbutils - table manager utilities
...@@ -103,14 +100,14 @@ void ...@@ -103,14 +100,14 @@ void
acpi_tb_print_table_header(acpi_physical_address address, acpi_tb_print_table_header(acpi_physical_address address,
struct acpi_table_header *header); struct acpi_table_header *header);
u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length); u8 acpi_tb_checksum(u8 *buffer, u32 length);
acpi_status acpi_status
acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length); acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length);
void void
acpi_tb_install_table(acpi_physical_address address, acpi_tb_install_table(acpi_physical_address address,
u8 flags, char *signature, acpi_native_uint table_index); u8 flags, char *signature, u32 table_index);
acpi_status acpi_status
acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags); acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags);
......
...@@ -300,6 +300,7 @@ struct acpi_table_dbgp { ...@@ -300,6 +300,7 @@ struct acpi_table_dbgp {
/******************************************************************************* /*******************************************************************************
* *
* DMAR - DMA Remapping table * DMAR - DMA Remapping table
* From "Intel Virtualization Technology for Directed I/O", Sept. 2007
* *
******************************************************************************/ ******************************************************************************/
...@@ -310,6 +311,10 @@ struct acpi_table_dmar { ...@@ -310,6 +311,10 @@ struct acpi_table_dmar {
u8 reserved[10]; u8 reserved[10];
}; };
/* Flags */
#define ACPI_DMAR_INTR_REMAP (1)
/* DMAR subtable header */ /* DMAR subtable header */
struct acpi_dmar_header { struct acpi_dmar_header {
...@@ -382,6 +387,20 @@ struct acpi_dmar_reserved_memory { ...@@ -382,6 +387,20 @@ struct acpi_dmar_reserved_memory {
#define ACPI_DMAR_ALLOW_ALL (1) #define ACPI_DMAR_ALLOW_ALL (1)
/* 2: Root Port ATS Capability Reporting Structure */
struct acpi_dmar_atsr {
struct acpi_dmar_header header;
u8 flags;
u8 reserved;
u16 segment;
};
/* Flags */
#define ACPI_DMAR_ALL_PORTS (1)
/******************************************************************************* /*******************************************************************************
* *
* ECDT - Embedded Controller Boot Resources Table * ECDT - Embedded Controller Boot Resources Table
...@@ -1156,9 +1175,9 @@ struct acpi_srat_mem_affinity { ...@@ -1156,9 +1175,9 @@ struct acpi_srat_mem_affinity {
u16 reserved; /* Reserved, must be zero */ u16 reserved; /* Reserved, must be zero */
u64 base_address; u64 base_address;
u64 length; u64 length;
u32 memory_type; /* See acpi_address_range_id */ u32 reserved1;
u32 flags; u32 flags;
u64 reserved1; /* Reserved, must be zero */ u64 reserved2; /* Reserved, must be zero */
}; };
/* Flags */ /* Flags */
......
...@@ -110,10 +110,10 @@ ...@@ -110,10 +110,10 @@
* usually used for memory allocation, efficient loop counters, and array * usually used for memory allocation, efficient loop counters, and array
* indexes. The types are similar to the size_t type in the C library and are * indexes. The types are similar to the size_t type in the C library and are
* required because there is no C type that consistently represents the native * required because there is no C type that consistently represents the native
* data width. * data width. ACPI_SIZE is needed because there is no guarantee that a
* kernel-level C library is present.
* *
* ACPI_SIZE 16/32/64-bit unsigned value * ACPI_SIZE 16/32/64-bit unsigned value
* ACPI_NATIVE_UINT 16/32/64-bit unsigned value
* ACPI_NATIVE_INT 16/32/64-bit signed value * ACPI_NATIVE_INT 16/32/64-bit signed value
* *
*/ */
...@@ -147,9 +147,9 @@ typedef int INT32; ...@@ -147,9 +147,9 @@ typedef int INT32;
/*! [End] no source code translation !*/ /*! [End] no source code translation !*/
typedef u64 acpi_native_uint;
typedef s64 acpi_native_int; typedef s64 acpi_native_int;
typedef u64 acpi_size;
typedef u64 acpi_io_address; typedef u64 acpi_io_address;
typedef u64 acpi_physical_address; typedef u64 acpi_physical_address;
...@@ -186,9 +186,9 @@ typedef int INT32; ...@@ -186,9 +186,9 @@ typedef int INT32;
/*! [End] no source code translation !*/ /*! [End] no source code translation !*/
typedef u32 acpi_native_uint;
typedef s32 acpi_native_int; typedef s32 acpi_native_int;
typedef u32 acpi_size;
typedef u32 acpi_io_address; typedef u32 acpi_io_address;
typedef u32 acpi_physical_address; typedef u32 acpi_physical_address;
...@@ -202,10 +202,6 @@ typedef u32 acpi_physical_address; ...@@ -202,10 +202,6 @@ typedef u32 acpi_physical_address;
#error unknown ACPI_MACHINE_WIDTH #error unknown ACPI_MACHINE_WIDTH
#endif #endif
/* Variable-width type, used instead of clib size_t */
typedef acpi_native_uint acpi_size;
/******************************************************************************* /*******************************************************************************
* *
* OS-dependent and compiler-dependent types * OS-dependent and compiler-dependent types
...@@ -219,7 +215,7 @@ typedef acpi_native_uint acpi_size; ...@@ -219,7 +215,7 @@ typedef acpi_native_uint acpi_size;
/* Value returned by acpi_os_get_thread_id */ /* Value returned by acpi_os_get_thread_id */
#ifndef acpi_thread_id #ifndef acpi_thread_id
#define acpi_thread_id acpi_native_uint #define acpi_thread_id acpi_size
#endif #endif
/* Object returned from acpi_os_create_lock */ /* Object returned from acpi_os_create_lock */
...@@ -231,7 +227,7 @@ typedef acpi_native_uint acpi_size; ...@@ -231,7 +227,7 @@ typedef acpi_native_uint acpi_size;
/* Flags for acpi_os_acquire_lock/acpi_os_release_lock */ /* Flags for acpi_os_acquire_lock/acpi_os_release_lock */
#ifndef acpi_cpu_flags #ifndef acpi_cpu_flags
#define acpi_cpu_flags acpi_native_uint #define acpi_cpu_flags acpi_size
#endif #endif
/* Object returned from acpi_os_create_cache */ /* Object returned from acpi_os_create_cache */
......
...@@ -172,7 +172,7 @@ char *acpi_ut_strstr(char *string1, char *string2); ...@@ -172,7 +172,7 @@ char *acpi_ut_strstr(char *string1, char *string2);
void *acpi_ut_memcpy(void *dest, const void *src, acpi_size count); void *acpi_ut_memcpy(void *dest, const void *src, acpi_size count);
void *acpi_ut_memset(void *dest, acpi_native_uint value, acpi_size count); void *acpi_ut_memset(void *dest, u8 value, acpi_size count);
int acpi_ut_to_upper(int c); int acpi_ut_to_upper(int c);
...@@ -245,41 +245,45 @@ void acpi_ut_track_stack_ptr(void); ...@@ -245,41 +245,45 @@ void acpi_ut_track_stack_ptr(void);
void void
acpi_ut_trace(u32 line_number, acpi_ut_trace(u32 line_number,
const char *function_name, char *module_name, u32 component_id); const char *function_name,
const char *module_name, u32 component_id);
void void
acpi_ut_trace_ptr(u32 line_number, acpi_ut_trace_ptr(u32 line_number,
const char *function_name, const char *function_name,
char *module_name, u32 component_id, void *pointer); const char *module_name, u32 component_id, void *pointer);
void void
acpi_ut_trace_u32(u32 line_number, acpi_ut_trace_u32(u32 line_number,
const char *function_name, const char *function_name,
char *module_name, u32 component_id, u32 integer); const char *module_name, u32 component_id, u32 integer);
void void
acpi_ut_trace_str(u32 line_number, acpi_ut_trace_str(u32 line_number,
const char *function_name, const char *function_name,
char *module_name, u32 component_id, char *string); const char *module_name, u32 component_id, char *string);
void void
acpi_ut_exit(u32 line_number, acpi_ut_exit(u32 line_number,
const char *function_name, char *module_name, u32 component_id); const char *function_name,
const char *module_name, u32 component_id);
void void
acpi_ut_status_exit(u32 line_number, acpi_ut_status_exit(u32 line_number,
const char *function_name, const char *function_name,
char *module_name, u32 component_id, acpi_status status); const char *module_name,
u32 component_id, acpi_status status);
void void
acpi_ut_value_exit(u32 line_number, acpi_ut_value_exit(u32 line_number,
const char *function_name, const char *function_name,
char *module_name, u32 component_id, acpi_integer value); const char *module_name,
u32 component_id, acpi_integer value);
void void
acpi_ut_ptr_exit(u32 line_number, acpi_ut_ptr_exit(u32 line_number,
const char *function_name, const char *function_name,
char *module_name, u32 component_id, u8 * ptr); const char *module_name, u32 component_id, u8 *ptr);
void acpi_ut_dump_buffer(u8 * buffer, u32 count, u32 display, u32 component_id); void acpi_ut_dump_buffer(u8 * buffer, u32 count, u32 display, u32 component_id);
...@@ -297,33 +301,35 @@ void ACPI_INTERNAL_VAR_XFACE ...@@ -297,33 +301,35 @@ void ACPI_INTERNAL_VAR_XFACE
acpi_ut_debug_print(u32 requested_debug_level, acpi_ut_debug_print(u32 requested_debug_level,
u32 line_number, u32 line_number,
const char *function_name, const char *function_name,
char *module_name, const char *module_name,
u32 component_id, char *format, ...) ACPI_PRINTF_LIKE(6); u32 component_id,
const char *format, ...) ACPI_PRINTF_LIKE(6);
void ACPI_INTERNAL_VAR_XFACE void ACPI_INTERNAL_VAR_XFACE
acpi_ut_debug_print_raw(u32 requested_debug_level, acpi_ut_debug_print_raw(u32 requested_debug_level,
u32 line_number, u32 line_number,
const char *function_name, const char *function_name,
char *module_name, const char *module_name,
u32 component_id, u32 component_id,
char *format, ...) ACPI_PRINTF_LIKE(6); const char *format, ...) ACPI_PRINTF_LIKE(6);
void ACPI_INTERNAL_VAR_XFACE void ACPI_INTERNAL_VAR_XFACE
acpi_ut_error(char *module_name, acpi_ut_error(const char *module_name,
u32 line_number, char *format, ...) ACPI_PRINTF_LIKE(3); u32 line_number, const char *format, ...) ACPI_PRINTF_LIKE(3);
void ACPI_INTERNAL_VAR_XFACE void ACPI_INTERNAL_VAR_XFACE
acpi_ut_exception(char *module_name, acpi_ut_exception(const char *module_name,
u32 line_number, u32 line_number,
acpi_status status, char *format, ...) ACPI_PRINTF_LIKE(4); acpi_status status,
const char *format, ...) ACPI_PRINTF_LIKE(4);
void ACPI_INTERNAL_VAR_XFACE void ACPI_INTERNAL_VAR_XFACE
acpi_ut_warning(char *module_name, acpi_ut_warning(const char *module_name,
u32 line_number, char *format, ...) ACPI_PRINTF_LIKE(3); u32 line_number, const char *format, ...) ACPI_PRINTF_LIKE(3);
void ACPI_INTERNAL_VAR_XFACE void ACPI_INTERNAL_VAR_XFACE
acpi_ut_info(char *module_name, acpi_ut_info(const char *module_name,
u32 line_number, char *format, ...) ACPI_PRINTF_LIKE(3); u32 line_number, const char *format, ...) ACPI_PRINTF_LIKE(3);
/* /*
* utdelete - Object deletion and reference counts * utdelete - Object deletion and reference counts
...@@ -376,13 +382,14 @@ acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest); ...@@ -376,13 +382,14 @@ acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest);
/* /*
* utobject - internal object create/delete/cache routines * utobject - internal object create/delete/cache routines
*/ */
union acpi_operand_object *acpi_ut_create_internal_object_dbg(char *module_name, union acpi_operand_object *acpi_ut_create_internal_object_dbg(const char
*module_name,
u32 line_number, u32 line_number,
u32 component_id, u32 component_id,
acpi_object_type acpi_object_type
type); type);
void *acpi_ut_allocate_object_desc_dbg(char *module_name, void *acpi_ut_allocate_object_desc_dbg(const char *module_name,
u32 line_number, u32 component_id); u32 line_number, u32 component_id);
#define acpi_ut_create_internal_object(t) acpi_ut_create_internal_object_dbg (_acpi_module_name,__LINE__,_COMPONENT,t) #define acpi_ut_create_internal_object(t) acpi_ut_create_internal_object_dbg (_acpi_module_name,__LINE__,_COMPONENT,t)
...@@ -476,7 +483,7 @@ u8 acpi_ut_valid_acpi_name(u32 name); ...@@ -476,7 +483,7 @@ u8 acpi_ut_valid_acpi_name(u32 name);
acpi_name acpi_ut_repair_name(char *name); acpi_name acpi_ut_repair_name(char *name);
u8 acpi_ut_valid_acpi_char(char character, acpi_native_uint position); u8 acpi_ut_valid_acpi_char(char character, u32 position);
acpi_status acpi_status
acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer); acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer);
...@@ -543,26 +550,29 @@ acpi_status ...@@ -543,26 +550,29 @@ acpi_status
acpi_ut_initialize_buffer(struct acpi_buffer *buffer, acpi_ut_initialize_buffer(struct acpi_buffer *buffer,
acpi_size required_length); acpi_size required_length);
void *acpi_ut_allocate(acpi_size size, u32 component, char *module, u32 line); void *acpi_ut_allocate(acpi_size size,
u32 component, const char *module, u32 line);
void *acpi_ut_allocate_zeroed(acpi_size size, void *acpi_ut_allocate_zeroed(acpi_size size,
u32 component, char *module, u32 line); u32 component, const char *module, u32 line);
#ifdef ACPI_DBG_TRACK_ALLOCATIONS #ifdef ACPI_DBG_TRACK_ALLOCATIONS
void *acpi_ut_allocate_and_track(acpi_size size, void *acpi_ut_allocate_and_track(acpi_size size,
u32 component, char *module, u32 line); u32 component, const char *module, u32 line);
void *acpi_ut_allocate_zeroed_and_track(acpi_size size, void *acpi_ut_allocate_zeroed_and_track(acpi_size size,
u32 component, char *module, u32 line); u32 component,
const char *module, u32 line);
void void
acpi_ut_free_and_track(void *address, u32 component, char *module, u32 line); acpi_ut_free_and_track(void *address,
u32 component, const char *module, u32 line);
#ifdef ACPI_FUTURE_USAGE #ifdef ACPI_FUTURE_USAGE
void acpi_ut_dump_allocation_info(void); void acpi_ut_dump_allocation_info(void);
#endif /* ACPI_FUTURE_USAGE */ #endif /* ACPI_FUTURE_USAGE */
void acpi_ut_dump_allocations(u32 component, char *module); void acpi_ut_dump_allocations(u32 component, const char *module);
acpi_status acpi_status
acpi_ut_create_list(char *list_name, acpi_ut_create_list(char *list_name,
......
...@@ -255,7 +255,7 @@ extern void acpi_processor_unregister_performance(struct ...@@ -255,7 +255,7 @@ extern void acpi_processor_unregister_performance(struct
int acpi_processor_notify_smm(struct module *calling_module); int acpi_processor_notify_smm(struct module *calling_module);
/* for communication between multiple parts of the processor kernel module */ /* for communication between multiple parts of the processor kernel module */
extern struct acpi_processor *processors[NR_CPUS]; DECLARE_PER_CPU(struct acpi_processor *, processors);
extern struct acpi_processor_errata errata; extern struct acpi_processor_errata errata;
void arch_acpi_processor_init_pdc(struct acpi_processor *pr); void arch_acpi_processor_init_pdc(struct acpi_processor *pr);
......
#ifndef __ACPI_REBOOT_H
#define __ACPI_REBOOT_H
#ifdef CONFIG_ACPI
extern void acpi_reboot(void);
#else
static inline void acpi_reboot(void) { }
#endif
/*
* Dummy placeholder to make the EFI patches apply to the x86 tree.
* Andrew/Len, please just kill this file if you encounter it.
*/
#ifndef acpi_reboot
# define acpi_reboot() do { } while (0)
#endif #endif
...@@ -763,6 +763,8 @@ prefetchw (const void *x) ...@@ -763,6 +763,8 @@ prefetchw (const void *x)
#define spin_lock_prefetch(x) prefetchw(x) #define spin_lock_prefetch(x) prefetchw(x)
extern unsigned long boot_option_idle_override; extern unsigned long boot_option_idle_override;
extern unsigned long idle_halt;
extern unsigned long idle_nomwait;
#endif /* !__ASSEMBLY__ */ #endif /* !__ASSEMBLY__ */
......
...@@ -727,6 +727,8 @@ extern int force_mwait; ...@@ -727,6 +727,8 @@ extern int force_mwait;
extern void select_idle_routine(const struct cpuinfo_x86 *c); extern void select_idle_routine(const struct cpuinfo_x86 *c);
extern unsigned long boot_option_idle_override; extern unsigned long boot_option_idle_override;
extern unsigned long idle_halt;
extern unsigned long idle_nomwait;
extern void enable_sep_cpu(void); extern void enable_sep_cpu(void);
extern int sysenter_setup(void); extern int sysenter_setup(void);
......
...@@ -127,6 +127,15 @@ static inline void set_freezable(void) ...@@ -127,6 +127,15 @@ static inline void set_freezable(void)
current->flags &= ~PF_NOFREEZE; current->flags &= ~PF_NOFREEZE;
} }
/*
* Tell the freezer that the current task should be frozen by it and that it
* should send a fake signal to the task to freeze it.
*/
static inline void set_freezable_with_signal(void)
{
current->flags &= ~(PF_NOFREEZE | PF_FREEZER_NOSIG);
}
/* /*
* Freezer-friendly wrappers around wait_event_interruptible() and * Freezer-friendly wrappers around wait_event_interruptible() and
* wait_event_interruptible_timeout(), originally defined in <linux/wait.h> * wait_event_interruptible_timeout(), originally defined in <linux/wait.h>
...@@ -174,6 +183,7 @@ static inline void freezer_do_not_count(void) {} ...@@ -174,6 +183,7 @@ static inline void freezer_do_not_count(void) {}
static inline void freezer_count(void) {} static inline void freezer_count(void) {}
static inline int freezer_should_skip(struct task_struct *p) { return 0; } static inline int freezer_should_skip(struct task_struct *p) { return 0; }
static inline void set_freezable(void) {} static inline void set_freezable(void) {}
static inline void set_freezable_with_signal(void) {}
#define wait_event_freezable(wq, condition) \ #define wait_event_freezable(wq, condition) \
wait_event_interruptible(wq, condition) wait_event_interruptible(wq, condition)
......
...@@ -59,6 +59,7 @@ struct resource_list { ...@@ -59,6 +59,7 @@ struct resource_list {
#define IORESOURCE_IRQ_HIGHLEVEL (1<<2) #define IORESOURCE_IRQ_HIGHLEVEL (1<<2)
#define IORESOURCE_IRQ_LOWLEVEL (1<<3) #define IORESOURCE_IRQ_LOWLEVEL (1<<3)
#define IORESOURCE_IRQ_SHAREABLE (1<<4) #define IORESOURCE_IRQ_SHAREABLE (1<<4)
#define IORESOURCE_IRQ_OPTIONAL (1<<5)
/* PnP DMA specific bits (IORESOURCE_BITS) */ /* PnP DMA specific bits (IORESOURCE_BITS) */
#define IORESOURCE_DMA_TYPE_MASK (3<<0) #define IORESOURCE_DMA_TYPE_MASK (3<<0)
...@@ -88,6 +89,10 @@ struct resource_list { ...@@ -88,6 +89,10 @@ struct resource_list {
#define IORESOURCE_MEM_SHADOWABLE (1<<5) /* dup: IORESOURCE_SHADOWABLE */ #define IORESOURCE_MEM_SHADOWABLE (1<<5) /* dup: IORESOURCE_SHADOWABLE */
#define IORESOURCE_MEM_EXPANSIONROM (1<<6) #define IORESOURCE_MEM_EXPANSIONROM (1<<6)
/* PnP I/O specific bits (IORESOURCE_BITS) */
#define IORESOURCE_IO_16BIT_ADDR (1<<0)
#define IORESOURCE_IO_FIXED (1<<1)
/* PCI ROM control bits (IORESOURCE_BITS) */ /* PCI ROM control bits (IORESOURCE_BITS) */
#define IORESOURCE_ROM_ENABLE (1<<0) /* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */ #define IORESOURCE_ROM_ENABLE (1<<0) /* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */
#define IORESOURCE_ROM_SHADOW (1<<1) /* ROM is copy at C000:0 */ #define IORESOURCE_ROM_SHADOW (1<<1) /* ROM is copy at C000:0 */
......
/* /*
* Linux Plug and Play Support * Linux Plug and Play Support
* Copyright by Adam Belay <ambx1@neo.rr.com> * Copyright by Adam Belay <ambx1@neo.rr.com>
* Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
* Bjorn Helgaas <bjorn.helgaas@hp.com>
*/ */
#ifndef _LINUX_PNP_H #ifndef _LINUX_PNP_H
...@@ -15,7 +17,6 @@ ...@@ -15,7 +17,6 @@
struct pnp_protocol; struct pnp_protocol;
struct pnp_dev; struct pnp_dev;
struct pnp_resource_table;
/* /*
* Resource Management * Resource Management
...@@ -24,7 +25,14 @@ struct resource *pnp_get_resource(struct pnp_dev *, unsigned int, unsigned int); ...@@ -24,7 +25,14 @@ struct resource *pnp_get_resource(struct pnp_dev *, unsigned int, unsigned int);
static inline int pnp_resource_valid(struct resource *res) static inline int pnp_resource_valid(struct resource *res)
{ {
if (res && !(res->flags & IORESOURCE_UNSET)) if (res)
return 1;
return 0;
}
static inline int pnp_resource_enabled(struct resource *res)
{
if (res && !(res->flags & IORESOURCE_DISABLED))
return 1; return 1;
return 0; return 0;
} }
...@@ -40,19 +48,31 @@ static inline resource_size_t pnp_resource_len(struct resource *res) ...@@ -40,19 +48,31 @@ static inline resource_size_t pnp_resource_len(struct resource *res)
static inline resource_size_t pnp_port_start(struct pnp_dev *dev, static inline resource_size_t pnp_port_start(struct pnp_dev *dev,
unsigned int bar) unsigned int bar)
{ {
return pnp_get_resource(dev, IORESOURCE_IO, bar)->start; struct resource *res = pnp_get_resource(dev, IORESOURCE_IO, bar);
if (pnp_resource_valid(res))
return res->start;
return 0;
} }
static inline resource_size_t pnp_port_end(struct pnp_dev *dev, static inline resource_size_t pnp_port_end(struct pnp_dev *dev,
unsigned int bar) unsigned int bar)
{ {
return pnp_get_resource(dev, IORESOURCE_IO, bar)->end; struct resource *res = pnp_get_resource(dev, IORESOURCE_IO, bar);
if (pnp_resource_valid(res))
return res->end;
return 0;
} }
static inline unsigned long pnp_port_flags(struct pnp_dev *dev, static inline unsigned long pnp_port_flags(struct pnp_dev *dev,
unsigned int bar) unsigned int bar)
{ {
return pnp_get_resource(dev, IORESOURCE_IO, bar)->flags; struct resource *res = pnp_get_resource(dev, IORESOURCE_IO, bar);
if (pnp_resource_valid(res))
return res->flags;
return IORESOURCE_IO | IORESOURCE_AUTO;
} }
static inline int pnp_port_valid(struct pnp_dev *dev, unsigned int bar) static inline int pnp_port_valid(struct pnp_dev *dev, unsigned int bar)
...@@ -63,25 +83,41 @@ static inline int pnp_port_valid(struct pnp_dev *dev, unsigned int bar) ...@@ -63,25 +83,41 @@ static inline int pnp_port_valid(struct pnp_dev *dev, unsigned int bar)
static inline resource_size_t pnp_port_len(struct pnp_dev *dev, static inline resource_size_t pnp_port_len(struct pnp_dev *dev,
unsigned int bar) unsigned int bar)
{ {
return pnp_resource_len(pnp_get_resource(dev, IORESOURCE_IO, bar)); struct resource *res = pnp_get_resource(dev, IORESOURCE_IO, bar);
if (pnp_resource_valid(res))
return pnp_resource_len(res);
return 0;
} }
static inline resource_size_t pnp_mem_start(struct pnp_dev *dev, static inline resource_size_t pnp_mem_start(struct pnp_dev *dev,
unsigned int bar) unsigned int bar)
{ {
return pnp_get_resource(dev, IORESOURCE_MEM, bar)->start; struct resource *res = pnp_get_resource(dev, IORESOURCE_MEM, bar);
if (pnp_resource_valid(res))
return res->start;
return 0;
} }
static inline resource_size_t pnp_mem_end(struct pnp_dev *dev, static inline resource_size_t pnp_mem_end(struct pnp_dev *dev,
unsigned int bar) unsigned int bar)
{ {
return pnp_get_resource(dev, IORESOURCE_MEM, bar)->end; struct resource *res = pnp_get_resource(dev, IORESOURCE_MEM, bar);
if (pnp_resource_valid(res))
return res->end;
return 0;
} }
static inline unsigned long pnp_mem_flags(struct pnp_dev *dev, unsigned int bar) static inline unsigned long pnp_mem_flags(struct pnp_dev *dev, unsigned int bar)
{ {
return pnp_get_resource(dev, IORESOURCE_MEM, bar)->flags; struct resource *res = pnp_get_resource(dev, IORESOURCE_MEM, bar);
if (pnp_resource_valid(res))
return res->flags;
return IORESOURCE_MEM | IORESOURCE_AUTO;
} }
static inline int pnp_mem_valid(struct pnp_dev *dev, unsigned int bar) static inline int pnp_mem_valid(struct pnp_dev *dev, unsigned int bar)
...@@ -92,18 +128,30 @@ static inline int pnp_mem_valid(struct pnp_dev *dev, unsigned int bar) ...@@ -92,18 +128,30 @@ static inline int pnp_mem_valid(struct pnp_dev *dev, unsigned int bar)
static inline resource_size_t pnp_mem_len(struct pnp_dev *dev, static inline resource_size_t pnp_mem_len(struct pnp_dev *dev,
unsigned int bar) unsigned int bar)
{ {
return pnp_resource_len(pnp_get_resource(dev, IORESOURCE_MEM, bar)); struct resource *res = pnp_get_resource(dev, IORESOURCE_MEM, bar);
if (pnp_resource_valid(res))
return pnp_resource_len(res);
return 0;
} }
static inline resource_size_t pnp_irq(struct pnp_dev *dev, unsigned int bar) static inline resource_size_t pnp_irq(struct pnp_dev *dev, unsigned int bar)
{ {
return pnp_get_resource(dev, IORESOURCE_IRQ, bar)->start; struct resource *res = pnp_get_resource(dev, IORESOURCE_IRQ, bar);
if (pnp_resource_valid(res))
return res->start;
return -1;
} }
static inline unsigned long pnp_irq_flags(struct pnp_dev *dev, unsigned int bar) static inline unsigned long pnp_irq_flags(struct pnp_dev *dev, unsigned int bar)
{ {
return pnp_get_resource(dev, IORESOURCE_IRQ, bar)->flags; struct resource *res = pnp_get_resource(dev, IORESOURCE_IRQ, bar);
if (pnp_resource_valid(res))
return res->flags;
return IORESOURCE_IRQ | IORESOURCE_AUTO;
} }
static inline int pnp_irq_valid(struct pnp_dev *dev, unsigned int bar) static inline int pnp_irq_valid(struct pnp_dev *dev, unsigned int bar)
...@@ -114,12 +162,20 @@ static inline int pnp_irq_valid(struct pnp_dev *dev, unsigned int bar) ...@@ -114,12 +162,20 @@ static inline int pnp_irq_valid(struct pnp_dev *dev, unsigned int bar)
static inline resource_size_t pnp_dma(struct pnp_dev *dev, unsigned int bar) static inline resource_size_t pnp_dma(struct pnp_dev *dev, unsigned int bar)
{ {
return pnp_get_resource(dev, IORESOURCE_DMA, bar)->start; struct resource *res = pnp_get_resource(dev, IORESOURCE_DMA, bar);
if (pnp_resource_valid(res))
return res->start;
return -1;
} }
static inline unsigned long pnp_dma_flags(struct pnp_dev *dev, unsigned int bar) static inline unsigned long pnp_dma_flags(struct pnp_dev *dev, unsigned int bar)
{ {
return pnp_get_resource(dev, IORESOURCE_DMA, bar)->flags; struct resource *res = pnp_get_resource(dev, IORESOURCE_DMA, bar);
if (pnp_resource_valid(res))
return res->flags;
return IORESOURCE_DMA | IORESOURCE_AUTO;
} }
static inline int pnp_dma_valid(struct pnp_dev *dev, unsigned int bar) static inline int pnp_dma_valid(struct pnp_dev *dev, unsigned int bar)
...@@ -128,57 +184,6 @@ static inline int pnp_dma_valid(struct pnp_dev *dev, unsigned int bar) ...@@ -128,57 +184,6 @@ static inline int pnp_dma_valid(struct pnp_dev *dev, unsigned int bar)
} }
#define PNP_PORT_FLAG_16BITADDR (1<<0)
#define PNP_PORT_FLAG_FIXED (1<<1)
struct pnp_port {
unsigned short min; /* min base number */
unsigned short max; /* max base number */
unsigned char align; /* align boundary */
unsigned char size; /* size of range */
unsigned char flags; /* port flags */
unsigned char pad; /* pad */
struct pnp_port *next; /* next port */
};
#define PNP_IRQ_NR 256
struct pnp_irq {
DECLARE_BITMAP(map, PNP_IRQ_NR); /* bitmask for IRQ lines */
unsigned char flags; /* IRQ flags */
unsigned char pad; /* pad */
struct pnp_irq *next; /* next IRQ */
};
struct pnp_dma {
unsigned char map; /* bitmask for DMA channels */
unsigned char flags; /* DMA flags */
struct pnp_dma *next; /* next port */
};
struct pnp_mem {
unsigned int min; /* min base number */
unsigned int max; /* max base number */
unsigned int align; /* align boundary */
unsigned int size; /* size of range */
unsigned char flags; /* memory flags */
unsigned char pad; /* pad */
struct pnp_mem *next; /* next memory resource */
};
#define PNP_RES_PRIORITY_PREFERRED 0
#define PNP_RES_PRIORITY_ACCEPTABLE 1
#define PNP_RES_PRIORITY_FUNCTIONAL 2
#define PNP_RES_PRIORITY_INVALID 65535
struct pnp_option {
unsigned short priority; /* priority */
struct pnp_port *port; /* first port */
struct pnp_irq *irq; /* first IRQ */
struct pnp_dma *dma; /* first DMA */
struct pnp_mem *mem; /* first memory resource */
struct pnp_option *next; /* used to chain dependent resources */
};
/* /*
* Device Management * Device Management
*/ */
...@@ -246,9 +251,9 @@ struct pnp_dev { ...@@ -246,9 +251,9 @@ struct pnp_dev {
int active; int active;
int capabilities; int capabilities;
struct pnp_option *independent; unsigned int num_dependent_sets;
struct pnp_option *dependent; struct list_head resources;
struct pnp_resource_table *res; struct list_head options;
char name[PNP_NAME_LEN]; /* contains a human-readable name */ char name[PNP_NAME_LEN]; /* contains a human-readable name */
int flags; /* used by protocols */ int flags; /* used by protocols */
...@@ -425,6 +430,8 @@ void pnp_unregister_card_driver(struct pnp_card_driver *drv); ...@@ -425,6 +430,8 @@ void pnp_unregister_card_driver(struct pnp_card_driver *drv);
extern struct list_head pnp_cards; extern struct list_head pnp_cards;
/* resource management */ /* resource management */
int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t base,
resource_size_t size);
int pnp_auto_config_dev(struct pnp_dev *dev); int pnp_auto_config_dev(struct pnp_dev *dev);
int pnp_start_dev(struct pnp_dev *dev); int pnp_start_dev(struct pnp_dev *dev);
int pnp_stop_dev(struct pnp_dev *dev); int pnp_stop_dev(struct pnp_dev *dev);
...@@ -452,6 +459,9 @@ static inline int pnp_register_card_driver(struct pnp_card_driver *drv) { return ...@@ -452,6 +459,9 @@ static inline int pnp_register_card_driver(struct pnp_card_driver *drv) { return
static inline void pnp_unregister_card_driver(struct pnp_card_driver *drv) { } static inline void pnp_unregister_card_driver(struct pnp_card_driver *drv) { }
/* resource management */ /* resource management */
static inline int pnp_possible_config(struct pnp_dev *dev, int type,
resource_size_t base,
resource_size_t size) { return 0; }
static inline int pnp_auto_config_dev(struct pnp_dev *dev) { return -ENODEV; } static inline int pnp_auto_config_dev(struct pnp_dev *dev) { return -ENODEV; }
static inline int pnp_start_dev(struct pnp_dev *dev) { return -ENODEV; } static inline int pnp_start_dev(struct pnp_dev *dev) { return -ENODEV; }
static inline int pnp_stop_dev(struct pnp_dev *dev) { return -ENODEV; } static inline int pnp_stop_dev(struct pnp_dev *dev) { return -ENODEV; }
......
...@@ -1494,6 +1494,7 @@ static inline void put_task_struct(struct task_struct *t) ...@@ -1494,6 +1494,7 @@ static inline void put_task_struct(struct task_struct *t)
#define PF_MEMPOLICY 0x10000000 /* Non-default NUMA mempolicy */ #define PF_MEMPOLICY 0x10000000 /* Non-default NUMA mempolicy */
#define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex tester */ #define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex tester */
#define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezeable */ #define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezeable */
#define PF_FREEZER_NOSIG 0x80000000 /* Freezer won't send signals to it */
/* /*
* Only the _current_ task can read/write to tsk->flags, but other * Only the _current_ task can read/write to tsk->flags, but other
......
...@@ -299,6 +299,7 @@ int __ref cpu_down(unsigned int cpu) ...@@ -299,6 +299,7 @@ int __ref cpu_down(unsigned int cpu)
cpu_maps_update_done(); cpu_maps_update_done();
return err; return err;
} }
EXPORT_SYMBOL(cpu_down);
#endif /*CONFIG_HOTPLUG_CPU*/ #endif /*CONFIG_HOTPLUG_CPU*/
/* Requires cpu_add_remove_lock to be held */ /* Requires cpu_add_remove_lock to be held */
......
...@@ -235,7 +235,7 @@ int kthreadd(void *unused) ...@@ -235,7 +235,7 @@ int kthreadd(void *unused)
set_user_nice(tsk, KTHREAD_NICE_LEVEL); set_user_nice(tsk, KTHREAD_NICE_LEVEL);
set_cpus_allowed(tsk, CPU_MASK_ALL); set_cpus_allowed(tsk, CPU_MASK_ALL);
current->flags |= PF_NOFREEZE; current->flags |= PF_NOFREEZE | PF_FREEZER_NOSIG;
for (;;) { for (;;) {
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
......
...@@ -19,9 +19,6 @@ ...@@ -19,9 +19,6 @@
*/ */
#define TIMEOUT (20 * HZ) #define TIMEOUT (20 * HZ)
#define FREEZER_KERNEL_THREADS 0
#define FREEZER_USER_SPACE 1
static inline int freezeable(struct task_struct * p) static inline int freezeable(struct task_struct * p)
{ {
if ((p == current) || if ((p == current) ||
...@@ -84,63 +81,53 @@ static void fake_signal_wake_up(struct task_struct *p) ...@@ -84,63 +81,53 @@ static void fake_signal_wake_up(struct task_struct *p)
spin_unlock_irqrestore(&p->sighand->siglock, flags); spin_unlock_irqrestore(&p->sighand->siglock, flags);
} }
static int has_mm(struct task_struct *p) static inline bool should_send_signal(struct task_struct *p)
{ {
return (p->mm && !(p->flags & PF_BORROWED_MM)); return !(p->flags & PF_FREEZER_NOSIG);
} }
/** /**
* freeze_task - send a freeze request to given task * freeze_task - send a freeze request to given task
* @p: task to send the request to * @p: task to send the request to
* @with_mm_only: if set, the request will only be sent if the task has its * @sig_only: if set, the request will only be sent if the task has the
* own mm * PF_FREEZER_NOSIG flag unset
* Return value: 0, if @with_mm_only is set and the task has no mm of its * Return value: 'false', if @sig_only is set and the task has
* own or the task is frozen, 1, otherwise * PF_FREEZER_NOSIG set or the task is frozen, 'true', otherwise
* *
* The freeze request is sent by seting the tasks's TIF_FREEZE flag and * The freeze request is sent by setting the tasks's TIF_FREEZE flag and
* either sending a fake signal to it or waking it up, depending on whether * either sending a fake signal to it or waking it up, depending on whether
* or not it has its own mm (ie. it is a user land task). If @with_mm_only * or not it has PF_FREEZER_NOSIG set. If @sig_only is set and the task
* is set and the task has no mm of its own (ie. it is a kernel thread), * has PF_FREEZER_NOSIG set (ie. it is a typical kernel thread), its
* its TIF_FREEZE flag should not be set. * TIF_FREEZE flag will not be set.
*
* The task_lock() is necessary to prevent races with exit_mm() or
* use_mm()/unuse_mm() from occuring.
*/ */
static int freeze_task(struct task_struct *p, int with_mm_only) static bool freeze_task(struct task_struct *p, bool sig_only)
{ {
int ret = 1; /*
* We first check if the task is freezing and next if it has already
* been frozen to avoid the race with frozen_process() which first marks
* the task as frozen and next clears its TIF_FREEZE.
*/
if (!freezing(p)) {
rmb();
if (frozen(p))
return false;
task_lock(p); if (!sig_only || should_send_signal(p))
if (freezing(p)) { set_freeze_flag(p);
if (has_mm(p)) { else
if (!signal_pending(p)) return false;
fake_signal_wake_up(p); }
} else {
if (with_mm_only) if (should_send_signal(p)) {
ret = 0; if (!signal_pending(p))
else fake_signal_wake_up(p);
wake_up_state(p, TASK_INTERRUPTIBLE); } else if (sig_only) {
} return false;
} else { } else {
rmb(); wake_up_state(p, TASK_INTERRUPTIBLE);
if (frozen(p)) {
ret = 0;
} else {
if (has_mm(p)) {
set_freeze_flag(p);
fake_signal_wake_up(p);
} else {
if (with_mm_only) {
ret = 0;
} else {
set_freeze_flag(p);
wake_up_state(p, TASK_INTERRUPTIBLE);
}
}
}
} }
task_unlock(p);
return ret; return true;
} }
static void cancel_freezing(struct task_struct *p) static void cancel_freezing(struct task_struct *p)
...@@ -156,7 +143,7 @@ static void cancel_freezing(struct task_struct *p) ...@@ -156,7 +143,7 @@ static void cancel_freezing(struct task_struct *p)
} }
} }
static int try_to_freeze_tasks(int freeze_user_space) static int try_to_freeze_tasks(bool sig_only)
{ {
struct task_struct *g, *p; struct task_struct *g, *p;
unsigned long end_time; unsigned long end_time;
...@@ -175,7 +162,7 @@ static int try_to_freeze_tasks(int freeze_user_space) ...@@ -175,7 +162,7 @@ static int try_to_freeze_tasks(int freeze_user_space)
if (frozen(p) || !freezeable(p)) if (frozen(p) || !freezeable(p))
continue; continue;
if (!freeze_task(p, freeze_user_space)) if (!freeze_task(p, sig_only))
continue; continue;
/* /*
...@@ -235,13 +222,13 @@ int freeze_processes(void) ...@@ -235,13 +222,13 @@ int freeze_processes(void)
int error; int error;
printk("Freezing user space processes ... "); printk("Freezing user space processes ... ");
error = try_to_freeze_tasks(FREEZER_USER_SPACE); error = try_to_freeze_tasks(true);
if (error) if (error)
goto Exit; goto Exit;
printk("done.\n"); printk("done.\n");
printk("Freezing remaining freezable tasks ... "); printk("Freezing remaining freezable tasks ... ");
error = try_to_freeze_tasks(FREEZER_KERNEL_THREADS); error = try_to_freeze_tasks(false);
if (error) if (error)
goto Exit; goto Exit;
printk("done."); printk("done.");
...@@ -251,7 +238,7 @@ int freeze_processes(void) ...@@ -251,7 +238,7 @@ int freeze_processes(void)
return error; return error;
} }
static void thaw_tasks(int thaw_user_space) static void thaw_tasks(bool nosig_only)
{ {
struct task_struct *g, *p; struct task_struct *g, *p;
...@@ -260,7 +247,7 @@ static void thaw_tasks(int thaw_user_space) ...@@ -260,7 +247,7 @@ static void thaw_tasks(int thaw_user_space)
if (!freezeable(p)) if (!freezeable(p))
continue; continue;
if (!p->mm == thaw_user_space) if (nosig_only && should_send_signal(p))
continue; continue;
thaw_process(p); thaw_process(p);
...@@ -271,8 +258,8 @@ static void thaw_tasks(int thaw_user_space) ...@@ -271,8 +258,8 @@ static void thaw_tasks(int thaw_user_space)
void thaw_processes(void) void thaw_processes(void)
{ {
printk("Restarting tasks ... "); printk("Restarting tasks ... ");
thaw_tasks(FREEZER_KERNEL_THREADS); thaw_tasks(true);
thaw_tasks(FREEZER_USER_SPACE); thaw_tasks(false);
schedule(); schedule();
printk("done.\n"); printk("done.\n");
} }
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/console.h> #include <linux/console.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/freezer.h> #include <linux/freezer.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -69,16 +70,22 @@ static int snapshot_open(struct inode *inode, struct file *filp) ...@@ -69,16 +70,22 @@ static int snapshot_open(struct inode *inode, struct file *filp)
struct snapshot_data *data; struct snapshot_data *data;
int error; int error;
if (!atomic_add_unless(&snapshot_device_available, -1, 0)) mutex_lock(&pm_mutex);
return -EBUSY;
if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
error = -EBUSY;
goto Unlock;
}
if ((filp->f_flags & O_ACCMODE) == O_RDWR) { if ((filp->f_flags & O_ACCMODE) == O_RDWR) {
atomic_inc(&snapshot_device_available); atomic_inc(&snapshot_device_available);
return -ENOSYS; error = -ENOSYS;
goto Unlock;
} }
if(create_basic_memory_bitmaps()) { if(create_basic_memory_bitmaps()) {
atomic_inc(&snapshot_device_available); atomic_inc(&snapshot_device_available);
return -ENOMEM; error = -ENOMEM;
goto Unlock;
} }
nonseekable_open(inode, filp); nonseekable_open(inode, filp);
data = &snapshot_state; data = &snapshot_state;
...@@ -98,33 +105,36 @@ static int snapshot_open(struct inode *inode, struct file *filp) ...@@ -98,33 +105,36 @@ static int snapshot_open(struct inode *inode, struct file *filp)
if (error) if (error)
pm_notifier_call_chain(PM_POST_HIBERNATION); pm_notifier_call_chain(PM_POST_HIBERNATION);
} }
if (error) { if (error)
atomic_inc(&snapshot_device_available); atomic_inc(&snapshot_device_available);
return error;
}
data->frozen = 0; data->frozen = 0;
data->ready = 0; data->ready = 0;
data->platform_support = 0; data->platform_support = 0;
return 0; Unlock:
mutex_unlock(&pm_mutex);
return error;
} }
static int snapshot_release(struct inode *inode, struct file *filp) static int snapshot_release(struct inode *inode, struct file *filp)
{ {
struct snapshot_data *data; struct snapshot_data *data;
mutex_lock(&pm_mutex);
swsusp_free(); swsusp_free();
free_basic_memory_bitmaps(); free_basic_memory_bitmaps();
data = filp->private_data; data = filp->private_data;
free_all_swap_pages(data->swap); free_all_swap_pages(data->swap);
if (data->frozen) { if (data->frozen)
mutex_lock(&pm_mutex);
thaw_processes(); thaw_processes();
mutex_unlock(&pm_mutex);
}
pm_notifier_call_chain(data->mode == O_WRONLY ? pm_notifier_call_chain(data->mode == O_WRONLY ?
PM_POST_HIBERNATION : PM_POST_RESTORE); PM_POST_HIBERNATION : PM_POST_RESTORE);
atomic_inc(&snapshot_device_available); atomic_inc(&snapshot_device_available);
mutex_unlock(&pm_mutex);
return 0; return 0;
} }
...@@ -134,9 +144,13 @@ static ssize_t snapshot_read(struct file *filp, char __user *buf, ...@@ -134,9 +144,13 @@ static ssize_t snapshot_read(struct file *filp, char __user *buf,
struct snapshot_data *data; struct snapshot_data *data;
ssize_t res; ssize_t res;
mutex_lock(&pm_mutex);
data = filp->private_data; data = filp->private_data;
if (!data->ready) if (!data->ready) {
return -ENODATA; res = -ENODATA;
goto Unlock;
}
res = snapshot_read_next(&data->handle, count); res = snapshot_read_next(&data->handle, count);
if (res > 0) { if (res > 0) {
if (copy_to_user(buf, data_of(data->handle), res)) if (copy_to_user(buf, data_of(data->handle), res))
...@@ -144,6 +158,10 @@ static ssize_t snapshot_read(struct file *filp, char __user *buf, ...@@ -144,6 +158,10 @@ static ssize_t snapshot_read(struct file *filp, char __user *buf,
else else
*offp = data->handle.offset; *offp = data->handle.offset;
} }
Unlock:
mutex_unlock(&pm_mutex);
return res; return res;
} }
...@@ -153,6 +171,8 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf, ...@@ -153,6 +171,8 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf,
struct snapshot_data *data; struct snapshot_data *data;
ssize_t res; ssize_t res;
mutex_lock(&pm_mutex);
data = filp->private_data; data = filp->private_data;
res = snapshot_write_next(&data->handle, count); res = snapshot_write_next(&data->handle, count);
if (res > 0) { if (res > 0) {
...@@ -161,11 +181,14 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf, ...@@ -161,11 +181,14 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf,
else else
*offp = data->handle.offset; *offp = data->handle.offset;
} }
mutex_unlock(&pm_mutex);
return res; return res;
} }
static int snapshot_ioctl(struct inode *inode, struct file *filp, static long snapshot_ioctl(struct file *filp, unsigned int cmd,
unsigned int cmd, unsigned long arg) unsigned long arg)
{ {
int error = 0; int error = 0;
struct snapshot_data *data; struct snapshot_data *data;
...@@ -179,6 +202,9 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, ...@@ -179,6 +202,9 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
if (!mutex_trylock(&pm_mutex))
return -EBUSY;
data = filp->private_data; data = filp->private_data;
switch (cmd) { switch (cmd) {
...@@ -186,7 +212,6 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, ...@@ -186,7 +212,6 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
case SNAPSHOT_FREEZE: case SNAPSHOT_FREEZE:
if (data->frozen) if (data->frozen)
break; break;
mutex_lock(&pm_mutex);
printk("Syncing filesystems ... "); printk("Syncing filesystems ... ");
sys_sync(); sys_sync();
printk("done.\n"); printk("done.\n");
...@@ -194,7 +219,6 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, ...@@ -194,7 +219,6 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
error = freeze_processes(); error = freeze_processes();
if (error) if (error)
thaw_processes(); thaw_processes();
mutex_unlock(&pm_mutex);
if (!error) if (!error)
data->frozen = 1; data->frozen = 1;
break; break;
...@@ -202,9 +226,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, ...@@ -202,9 +226,7 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
case SNAPSHOT_UNFREEZE: case SNAPSHOT_UNFREEZE:
if (!data->frozen || data->ready) if (!data->frozen || data->ready)
break; break;
mutex_lock(&pm_mutex);
thaw_processes(); thaw_processes();
mutex_unlock(&pm_mutex);
data->frozen = 0; data->frozen = 0;
break; break;
...@@ -307,16 +329,11 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, ...@@ -307,16 +329,11 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
error = -EPERM; error = -EPERM;
break; break;
} }
if (!mutex_trylock(&pm_mutex)) {
error = -EBUSY;
break;
}
/* /*
* Tasks are frozen and the notifiers have been called with * Tasks are frozen and the notifiers have been called with
* PM_HIBERNATION_PREPARE * PM_HIBERNATION_PREPARE
*/ */
error = suspend_devices_and_enter(PM_SUSPEND_MEM); error = suspend_devices_and_enter(PM_SUSPEND_MEM);
mutex_unlock(&pm_mutex);
break; break;
case SNAPSHOT_PLATFORM_SUPPORT: case SNAPSHOT_PLATFORM_SUPPORT:
...@@ -390,6 +407,8 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, ...@@ -390,6 +407,8 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp,
} }
mutex_unlock(&pm_mutex);
return error; return error;
} }
...@@ -399,7 +418,7 @@ static const struct file_operations snapshot_fops = { ...@@ -399,7 +418,7 @@ static const struct file_operations snapshot_fops = {
.read = snapshot_read, .read = snapshot_read,
.write = snapshot_write, .write = snapshot_write,
.llseek = no_llseek, .llseek = no_llseek,
.ioctl = snapshot_ioctl, .unlocked_ioctl = snapshot_ioctl,
}; };
static struct miscdevice snapshot_device = { static struct miscdevice snapshot_device = {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册