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
  ...
This commit is contained in:
Linus Torvalds 2008-07-16 14:52:12 -07:00
commit 4314652bb4
128 changed files with 4333 additions and 2452 deletions

View File

@ -29,46 +29,46 @@ Description:
$ cd /sys/firmware/acpi/interrupts
$ grep . *
error:0
ff_gbl_lock:0
ff_pmtimer:0
ff_pwr_btn:0
ff_rt_clk:0
ff_slp_btn:0
gpe00:0
gpe01:0
gpe02:0
gpe03:0
gpe04:0
gpe05:0
gpe06:0
gpe07:0
gpe08:0
gpe09:174
gpe0A:0
gpe0B:0
gpe0C:0
gpe0D:0
gpe0E:0
gpe0F:0
gpe10:0
gpe11:60
gpe12:0
gpe13:0
gpe14:0
gpe15:0
gpe16:0
gpe17:0
gpe18:0
gpe19:7
gpe1A:0
gpe1B:0
gpe1C:0
gpe1D:0
gpe1E:0
gpe1F:0
gpe_all:241
sci:241
error: 0
ff_gbl_lock: 0 enable
ff_pmtimer: 0 invalid
ff_pwr_btn: 0 enable
ff_rt_clk: 2 disable
ff_slp_btn: 0 invalid
gpe00: 0 invalid
gpe01: 0 enable
gpe02: 108 enable
gpe03: 0 invalid
gpe04: 0 invalid
gpe05: 0 invalid
gpe06: 0 enable
gpe07: 0 enable
gpe08: 0 invalid
gpe09: 0 invalid
gpe0A: 0 invalid
gpe0B: 0 invalid
gpe0C: 0 invalid
gpe0D: 0 invalid
gpe0E: 0 invalid
gpe0F: 0 invalid
gpe10: 0 invalid
gpe11: 0 invalid
gpe12: 0 invalid
gpe13: 0 invalid
gpe14: 0 invalid
gpe15: 0 invalid
gpe16: 0 invalid
gpe17: 1084 enable
gpe18: 0 enable
gpe19: 0 invalid
gpe1A: 0 invalid
gpe1B: 0 invalid
gpe1C: 0 invalid
gpe1D: 0 invalid
gpe1E: 0 invalid
gpe1F: 0 invalid
gpe_all: 1192
sci: 1194
sci - The total number of times the ACPI SCI
has claimed an interrupt.
@ -89,6 +89,13 @@ Description:
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.
# echo 0 > gpe11
@ -97,3 +104,43 @@ Description:
None of these counters has an effect on the function
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

View File

@ -818,7 +818,7 @@ and is between 256 and 4096 characters. It is defined in the file
See Documentation/ide/ide.txt.
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
of waking up a idle CPU, but will use a lot of power and make the system
run hot. Not recommended.
@ -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
loop use the MONITOR/MWAIT idle loop anyways. Performance should be the same
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
Claim all unknown PCI IDE storage controllers.

View File

@ -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
be registered.
If you have a mail LED that is not green, please report this to me.
Backlight
*********

View File

@ -216,8 +216,8 @@ W: http://code.google.com/p/aceracpi
S: Maintained
ACPI
P: Len Brown
M: len.brown@intel.com
P: Andi Kleen
M: ak@linux.intel.com
M: lenb@kernel.org
L: linux-acpi@vger.kernel.org
W: http://www.lesswatts.org/projects/acpi/
@ -239,8 +239,8 @@ W: http://www.lesswatts.org/projects/acpi/
S: Supported
ACPI FAN DRIVER
P: Len Brown
M: len.brown@intel.com
P: Zhang Rui
M: rui.zhang@intel.com
L: linux-acpi@vger.kernel.org
W: http://www.lesswatts.org/projects/acpi/
S: Supported
@ -252,14 +252,14 @@ L: pcihpd-discuss@lists.sourceforge.net
S: Supported
ACPI THERMAL DRIVER
P: Len Brown
M: len.brown@intel.com
P: Zhang Rui
M: rui.zhang@intel.com
L: linux-acpi@vger.kernel.org
W: http://www.lesswatts.org/projects/acpi/
S: Supported
ACPI VIDEO DRIVER
P: Rui Zhang
P: Zhang Rui
M: rui.zhang@intel.com
L: linux-acpi@vger.kernel.org
W: http://www.lesswatts.org/projects/acpi/
@ -1160,6 +1160,11 @@ M: scott@spiteful.org
L: pcihpd-discuss@lists.sourceforge.net
S: Supported
COMPAL LAPTOP SUPPORT
P: Cezary Jackiewicz
M: cezary.jackiewicz@gmail.com
S: Maintained
COMPUTONE INTELLIPORT MULTIPORT CARD
P: Michael H. Warfield
M: mhw@wittsend.com
@ -1787,6 +1792,12 @@ P: David Howells
M: dhowells@redhat.com
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
P: Miklos Szeredi
M: miklos@szeredi.hu

View File

@ -55,6 +55,10 @@ void (*ia64_mark_idle)(int);
unsigned long boot_option_idle_override = 0;
EXPORT_SYMBOL(boot_option_idle_override);
unsigned long idle_halt;
EXPORT_SYMBOL(idle_halt);
unsigned long idle_nomwait;
EXPORT_SYMBOL(idle_nomwait);
void
ia64_do_show_stack (struct unw_frame_info *info, void *arg)

View File

@ -56,6 +56,12 @@ static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c)
if (cpu_has(c, X86_FEATURE_ACPI))
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->buffer.length = 12;
obj->buffer.pointer = (u8 *) buf;

View File

@ -7,6 +7,12 @@
#include <linux/module.h>
#include <linux/pm.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;
@ -325,7 +331,27 @@ static int __init idle_setup(char *str)
pm_idle = poll_idle;
} else if (!strcmp(str, "mwait"))
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;
boot_option_idle_override = 1;

View File

@ -156,10 +156,9 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *memory_affinity)
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",
start_pfn, end_pfn,
memory_affinity->memory_type,
pxm,
((memory_affinity->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) ?
"enabled and removable" : "enabled" ) );

View File

@ -21,7 +21,7 @@ obj-$(CONFIG_X86) += blacklist.o
#
# ACPI Core Subsystem (Interpreter)
#
obj-y += osl.o utils.o \
obj-y += osl.o utils.o reboot.o\
dispatcher/ events/ executer/ hardware/ \
namespace/ parser/ resources/ tables/ \
utilities/

View File

@ -377,6 +377,9 @@ static int __init bay_init(void)
INIT_LIST_HEAD(&drive_bays);
if (acpi_disabled)
return -ENODEV;
if (acpi_disabled)
return -ENODEV;

View File

@ -612,7 +612,7 @@ static int __init acpi_bus_init_irq(void)
return 0;
}
acpi_native_uint acpi_gbl_permanent_mmap;
u8 acpi_gbl_permanent_mmap;
void __init acpi_early_init(void)

View File

@ -151,7 +151,7 @@ acpi_ds_init_one_object(acpi_handle obj_handle,
******************************************************************************/
acpi_status
acpi_ds_initialize_objects(acpi_native_uint table_index,
acpi_ds_initialize_objects(u32 table_index,
struct acpi_namespace_node * start_node)
{
acpi_status status;

View File

@ -377,7 +377,6 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
}
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,
obj_desc->method.aml_start,

View File

@ -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,
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)) {
ACPI_ERROR((AE_INFO, "(%s) bad operand(s) (%X)",
acpi_ps_get_opcode_name(op->common.aml_opcode),
@ -785,10 +779,6 @@ acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state,
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);
if (!obj_desc) {
return_ACPI_STATUS(AE_NOT_EXIST);
@ -848,7 +838,7 @@ acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state,
union acpi_operand_object **operand;
struct acpi_namespace_node *node;
union acpi_parse_object *next_op;
acpi_native_uint table_index;
u32 table_index;
struct acpi_table_header *table;
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,
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];
/* Find the ACPI table */
@ -1091,10 +1077,8 @@ acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state,
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");
ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS,
acpi_ps_get_opcode_name(op->common.aml_opcode), 1);
/*
* Get the bank_value operand and save it
* (at Top of stack)

View File

@ -408,14 +408,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
[walk_state->
num_operands - 1]),
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)) {

View File

@ -70,7 +70,7 @@ acpi_status
acpi_ds_result_pop(union acpi_operand_object **object,
struct acpi_walk_state *walk_state)
{
acpi_native_uint index;
u32 index;
union acpi_generic_state *state;
acpi_status status;
@ -122,7 +122,7 @@ acpi_ds_result_pop(union acpi_operand_object **object,
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"Obj=%p [%s] Index=%X State=%p Num=%X\n", *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);
}
@ -146,7 +146,7 @@ acpi_ds_result_push(union acpi_operand_object * object,
{
union acpi_generic_state *state;
acpi_status status;
acpi_native_uint index;
u32 index;
ACPI_FUNCTION_NAME(ds_result_push);
@ -400,7 +400,7 @@ void
acpi_ds_obj_stack_pop_and_delete(u32 pop_count,
struct acpi_walk_state *walk_state)
{
acpi_native_int i;
s32 i;
union acpi_operand_object *obj_desc;
ACPI_FUNCTION_NAME(ds_obj_stack_pop_and_delete);
@ -409,7 +409,7 @@ acpi_ds_obj_stack_pop_and_delete(u32 pop_count,
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) {
return;
}
@ -615,14 +615,8 @@ acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state,
walk_state->pass_number = pass_number;
if (info) {
if (info->parameter_type == ACPI_PARAM_GPE) {
walk_state->gpe_event_info =
ACPI_CAST_PTR(struct acpi_gpe_event_info,
info->parameters);
} else {
walk_state->params = info->parameters;
walk_state->caller_return_desc = &info->return_object;
}
walk_state->params = info->parameters;
walk_state->caller_return_desc = &info->return_object;
}
status = acpi_ps_init_scope(&walk_state->parser_state, op);

View File

@ -917,6 +917,9 @@ static int __init dock_init(void)
dock_station = NULL;
if (acpi_disabled)
return 0;
if (acpi_disabled)
return 0;

View File

@ -188,7 +188,7 @@ acpi_status acpi_ev_install_xrupt_handlers(void)
static acpi_status acpi_ev_fixed_event_initialize(void)
{
acpi_native_uint i;
u32 i;
acpi_status status;
/*
@ -231,7 +231,7 @@ u32 acpi_ev_fixed_event_detect(void)
u32 int_status = ACPI_INTERRUPT_NOT_HANDLED;
u32 fixed_status;
u32 fixed_enable;
acpi_native_uint i;
u32 i;
ACPI_FUNCTION_NAME(ev_fixed_event_detect);
@ -260,7 +260,7 @@ u32 acpi_ev_fixed_event_detect(void)
/* Found an active (signalled) event */
acpi_os_fixed_event_count(i);
int_status |= acpi_ev_fixed_event_dispatch((u32) i);
int_status |= acpi_ev_fixed_event_dispatch(i);
}
}

View File

@ -256,7 +256,7 @@ acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
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) {
case ACPI_GPE_TYPE_WAKE:
@ -273,13 +273,23 @@ acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
/* Disable the requested runtime GPE */
ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_RUN_ENABLED);
/* fallthrough */
break;
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);
}
@ -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;
struct acpi_gpe_block_info *gpe_block;
acpi_native_uint i;
u32 i;
ACPI_FUNCTION_ENTRY();
@ -379,8 +389,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
u32 status_reg;
u32 enable_reg;
acpi_cpu_flags flags;
acpi_native_uint i;
acpi_native_uint j;
u32 i;
u32 j;
ACPI_FUNCTION_NAME(ev_gpe_detect);
@ -462,13 +472,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
*/
int_status |=
acpi_ev_gpe_dispatch(&gpe_block->
event_info[(i *
ACPI_GPE_REGISTER_WIDTH)
+
j],
(u32) j +
gpe_register_info->
base_gpe_number);
event_info[((acpi_size) i * ACPI_GPE_REGISTER_WIDTH) + j], j + gpe_register_info->base_gpe_number);
}
}
}
@ -555,10 +559,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
*/
info->prefix_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;
status = acpi_ns_evaluate(info);

View File

@ -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_event_info *gpe_event_info;
acpi_native_uint i;
acpi_native_uint j;
u32 i;
u32 j;
ACPI_FUNCTION_TRACE(ev_delete_gpe_handlers);
@ -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++) {
gpe_event_info =
&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) ==
ACPI_GPE_DISPATCH_HANDLER) {
@ -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 *this_event;
struct acpi_gpe_register_info *this_register;
acpi_native_uint i;
acpi_native_uint j;
u32 i;
u32 j;
acpi_status status;
ACPI_FUNCTION_TRACE(ev_create_gpe_info_blocks);
@ -983,8 +984,8 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
struct acpi_gpe_walk_info gpe_info;
u32 wake_gpe_count;
u32 gpe_enabled_count;
acpi_native_uint i;
acpi_native_uint j;
u32 i;
u32 j;
ACPI_FUNCTION_TRACE(ev_initialize_gpe_block);
@ -1033,7 +1034,8 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
gpe_event_info =
&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) ==
ACPI_GPE_DISPATCH_METHOD)

View File

@ -575,7 +575,7 @@ acpi_status acpi_ev_release_global_lock(void)
void acpi_ev_terminate(void)
{
acpi_native_uint i;
u32 i;
acpi_status status;
ACPI_FUNCTION_TRACE(ev_terminate);
@ -589,7 +589,7 @@ void acpi_ev_terminate(void)
/* Disable all fixed events */
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)) {
ACPI_ERROR((AE_INFO,
"Could not disable fixed event %d",

View File

@ -81,7 +81,7 @@ acpi_ev_install_handler(acpi_handle obj_handle,
acpi_status acpi_ev_install_region_handlers(void)
{
acpi_status status;
acpi_native_uint i;
u32 i;
ACPI_FUNCTION_TRACE(ev_install_region_handlers);
@ -151,7 +151,7 @@ acpi_status acpi_ev_install_region_handlers(void)
acpi_status acpi_ev_initialize_op_regions(void)
{
acpi_status status;
acpi_native_uint i;
u32 i;
ACPI_FUNCTION_TRACE(ev_initialize_op_regions);
@ -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->pathname = NULL;
info->parameters = args;
info->parameter_type = ACPI_PARAM_ARGS;
info->flags = ACPI_IGNORE_RETURN_VALUE;
/*

View File

@ -380,7 +380,7 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
acpi_status status;
struct acpica_device_id hid;
struct acpi_compatible_id_list *cid;
acpi_native_uint i;
u32 i;
/*
* Get the _HID and check for a PCI Root Bridge

View File

@ -472,7 +472,6 @@ acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
}
ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
#ifdef ACPI_FUTURE_USAGE
/*******************************************************************************
*
* FUNCTION: acpi_get_event_status
@ -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 status = AE_OK;
u32 value;
ACPI_FUNCTION_TRACE(acpi_get_event_status);
@ -506,7 +506,20 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
status =
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);
}
@ -566,7 +579,6 @@ acpi_get_gpe_status(acpi_handle gpe_device,
}
ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
#endif /* ACPI_FUTURE_USAGE */
/*******************************************************************************
*
* FUNCTION: acpi_install_gpe_block

View File

@ -53,7 +53,7 @@ ACPI_MODULE_NAME("exconfig")
/* Local prototypes */
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,
union acpi_operand_object **ddb_handle);
@ -73,7 +73,7 @@ acpi_ex_add_table(acpi_native_uint table_index,
******************************************************************************/
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,
union acpi_operand_object **ddb_handle)
{
@ -96,7 +96,8 @@ acpi_ex_add_table(acpi_native_uint table_index,
/* 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 */
@ -128,12 +129,12 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
{
acpi_status status;
union acpi_operand_object **operand = &walk_state->operands[0];
acpi_native_uint table_index;
struct acpi_namespace_node *parent_node;
struct acpi_namespace_node *start_node;
struct acpi_namespace_node *parameter_node = NULL;
union acpi_operand_object *ddb_handle;
struct acpi_table_header *table;
u32 table_index;
ACPI_FUNCTION_TRACE(ex_load_table_op);
@ -280,7 +281,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
{
union acpi_operand_object *ddb_handle;
struct acpi_table_desc table_desc;
acpi_native_uint table_index;
u32 table_index;
acpi_status status;
u32 length;
@ -437,7 +438,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
{
acpi_status status = AE_OK;
union acpi_operand_object *table_desc = ddb_handle;
acpi_native_uint table_index;
u32 table_index;
struct acpi_table_header *table;
ACPI_FUNCTION_TRACE(ex_unload_table);
@ -454,9 +455,9 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
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 */

View File

@ -288,11 +288,11 @@ acpi_ex_convert_to_ascii(acpi_integer integer,
u16 base, u8 * string, u8 data_width)
{
acpi_integer digit;
acpi_native_uint i;
acpi_native_uint j;
acpi_native_uint k = 0;
acpi_native_uint hex_length;
acpi_native_uint decimal_length;
u32 i;
u32 j;
u32 k = 0;
u32 hex_length;
u32 decimal_length;
u32 remainder;
u8 supress_zeros;
@ -348,7 +348,7 @@ acpi_ex_convert_to_ascii(acpi_integer integer,
/* 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--) {
/* Get one hex digit, most significant digits first */

View File

@ -45,8 +45,6 @@
#include <acpi/acinterp.h>
#include <acpi/amlcode.h>
#include <acpi/acnamesp.h>
#include <acpi/acevents.h>
#include <acpi/actables.h>
#define _COMPONENT ACPI_EXECUTER
ACPI_MODULE_NAME("excreate")

View File

@ -580,25 +580,22 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
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.pointer);
length = obj_desc->buffer.length;
if (length > 64) {
length = 64;
}
/* Debug only -- dump the buffer contents */
if (obj_desc->buffer.pointer) {
acpi_os_printf("Buffer Contents: ");
for (index = 0; index < length; index++) {
acpi_os_printf(" %02x",
obj_desc->buffer.pointer[index]);
length = obj_desc->buffer.length;
if (length > 128) {
length = 128;
}
acpi_os_printf("\n");
acpi_os_printf
("Buffer Contents: (displaying length 0x%.2X)\n",
length);
ACPI_DUMP_BUFFER(obj_desc->buffer.pointer, length);
}
break;
@ -756,54 +753,42 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
*
* FUNCTION: acpi_ex_dump_operands
*
* PARAMETERS: Operands - Operand list
* interpreter_mode - Load or Exec
* Ident - Identification
* 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
* PARAMETERS: Operands - A list of Operand objects
* opcode_name - AML opcode name
* num_operands - Operand count for this opcode
*
* DESCRIPTION: Dump the object stack
* DESCRIPTION: Dump the operands associated with the opcode
*
******************************************************************************/
void
acpi_ex_dump_operands(union acpi_operand_object **operands,
acpi_interpreter_mode interpreter_mode,
char *ident,
u32 num_levels,
char *note, char *module_name, u32 line_number)
const char *opcode_name, u32 num_operands)
{
acpi_native_uint i;
ACPI_FUNCTION_NAME(ex_dump_operands);
if (!ident) {
ident = "?";
}
if (!note) {
note = "?";
if (!opcode_name) {
opcode_name = "UNKNOWN";
}
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"************* Operand Stack Contents (Opcode [%s], %d Operands)\n",
ident, num_levels));
"**** Start operand dump for opcode [%s], %d operands\n",
opcode_name, num_operands));
if (num_levels == 0) {
num_levels = 1;
if (num_operands == 0) {
num_operands = 1;
}
/* Dump the operand stack starting at the top */
/* Dump the individual operands */
for (i = 0; num_levels > 0; i--, num_levels--) {
acpi_ex_dump_operand(operands[i], 0);
while (num_operands) {
acpi_ex_dump_operand(*operands, 0);
operands++;
num_operands--;
}
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"************* Operand Stack dump from %s(%d), %s\n",
module_name, line_number, note));
"**** End operand dump for [%s]\n", opcode_name));
return;
}

View File

@ -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
* 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,
obj_desc->common_field.
access_byte_width) >=
(obj_desc->common_field.base_byte_offset +
(acpi_native_uint) obj_desc->common_field.
access_byte_width + field_datum_byte_offset)) {
((acpi_size) obj_desc->common_field.
base_byte_offset +
obj_desc->common_field.access_byte_width +
field_datum_byte_offset)) {
return_ACPI_STATUS(AE_OK);
}
}

View File

@ -329,8 +329,8 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
/* Result of two Strings is a String */
return_desc = acpi_ut_create_string_object((acpi_size)
(operand0->string.
return_desc = acpi_ut_create_string_object(((acpi_size)
operand0->string.
length +
local_operand1->
string.length));
@ -352,8 +352,8 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
/* Result of two Buffers is a Buffer */
return_desc = acpi_ut_create_buffer_object((acpi_size)
(operand0->buffer.
return_desc = acpi_ut_create_buffer_object(((acpi_size)
operand0->buffer.
length +
local_operand1->
buffer.length));

View File

@ -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->extra.aml_start =
((union acpi_parse_object *)(info->data_register_node))->
named.data;
ACPI_CAST_PTR(union acpi_parse_object,
info->data_register_node)->named.data;
second_desc->extra.aml_length =
((union acpi_parse_object *)(info->data_register_node))->
named.length;
ACPI_CAST_PTR(union acpi_parse_object,
info->data_register_node)->named.length;
break;

View File

@ -156,7 +156,7 @@ acpi_ex_system_memory_space_handler(u32 function,
/* Create a new mapping starting at the address given */
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) {
ACPI_ERROR((AE_INFO,
"Could not map memory at %8.8X%8.8X, size %X",

View File

@ -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);
}

View File

@ -343,12 +343,6 @@ acpi_ex_store(union acpi_operand_object *source_desc,
acpi_ut_get_object_type_name(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);
}

View File

@ -148,7 +148,7 @@ acpi_fan_write_state(struct file *file, const char __user * buffer,
int result = 0;
struct seq_file *m = file->private_data;
struct acpi_device *device = m->private;
char state_string[12] = { '\0' };
char state_string[3] = { '\0' };
if (count > sizeof(state_string) - 1)
return -EINVAL;
@ -157,6 +157,12 @@ acpi_fan_write_state(struct file *file, const char __user * buffer,
return -EFAULT;
state_string[count] = '\0';
if ((state_string[0] < '0') || (state_string[0] > '3'))
return -EINVAL;
if (state_string[1] == '\n')
state_string[1] = '\0';
if (state_string[1] != '\0')
return -EINVAL;
result = acpi_bus_set_power(device->handle,
simple_strtoul(state_string, NULL, 0));

View File

@ -333,6 +333,9 @@ static int __init acpi_rtc_init(void)
{
struct device *dev = get_rtc_dev();
if (acpi_disabled)
return 0;
if (acpi_disabled)
return 0;

View File

@ -53,6 +53,54 @@ static acpi_status
acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
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
@ -68,7 +116,7 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
******************************************************************************/
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;
acpi_status status;
@ -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_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info,
acpi_event_status * event_status)
@ -198,7 +245,6 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info,
unlock_and_exit:
return (status);
}
#endif /* ACPI_FUTURE_USAGE */
/******************************************************************************
*

View File

@ -73,7 +73,7 @@ acpi_ns_dump_one_device(acpi_handle obj_handle,
void acpi_ns_print_pathname(u32 num_segments, char *pathname)
{
acpi_native_uint i;
u32 i;
ACPI_FUNCTION_NAME(ns_print_pathname);
@ -515,12 +515,12 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
if (obj_type > ACPI_TYPE_LOCAL_MAX) {
acpi_os_printf
("(Ptr to ACPI Object type %X [UNKNOWN])\n",
("(Pointer to ACPI Object type %.2X [UNKNOWN])\n",
obj_type);
bytes_to_dump = 32;
} else {
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));
bytes_to_dump =
sizeof(union acpi_operand_object);

View File

@ -138,6 +138,41 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info)
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_LV_INFO, _COMPONENT);

View File

@ -542,7 +542,6 @@ acpi_ns_init_one_device(acpi_handle obj_handle,
info->prefix_node = device_node;
info->pathname = METHOD_NAME__INI;
info->parameters = NULL;
info->parameter_type = ACPI_PARAM_ARGS;
info->flags = ACPI_IGNORE_RETURN_VALUE;
/*

View File

@ -71,8 +71,7 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle);
******************************************************************************/
acpi_status
acpi_ns_load_table(acpi_native_uint table_index,
struct acpi_namespace_node *node)
acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node)
{
acpi_status status;

View File

@ -63,13 +63,13 @@ ACPI_MODULE_NAME("nsparse")
*
******************************************************************************/
acpi_status
acpi_ns_one_complete_parse(acpi_native_uint pass_number,
acpi_native_uint table_index,
struct acpi_namespace_node * start_node)
acpi_ns_one_complete_parse(u32 pass_number,
u32 table_index,
struct acpi_namespace_node *start_node)
{
union acpi_parse_object *parse_root;
acpi_status status;
acpi_native_uint aml_length;
u32 aml_length;
u8 *aml_start;
struct acpi_walk_state *walk_state;
struct acpi_table_header *table;
@ -112,8 +112,8 @@ acpi_ns_one_complete_parse(acpi_native_uint pass_number,
aml_start = (u8 *) table + 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,
aml_start, (u32) aml_length,
NULL, (u8) pass_number);
aml_start, aml_length, NULL,
(u8) pass_number);
}
if (ACPI_FAILURE(status)) {
@ -158,8 +158,7 @@ acpi_ns_one_complete_parse(acpi_native_uint pass_number,
******************************************************************************/
acpi_status
acpi_ns_parse_table(acpi_native_uint table_index,
struct acpi_namespace_node *start_node)
acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node)
{
acpi_status status;

View File

@ -73,9 +73,9 @@ acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node *node_to_search);
******************************************************************************/
void
acpi_ns_report_error(char *module_name,
acpi_ns_report_error(const char *module_name,
u32 line_number,
char *internal_name, acpi_status lookup_status)
const char *internal_name, acpi_status lookup_status)
{
acpi_status status;
u32 bad_name;
@ -130,11 +130,11 @@ acpi_ns_report_error(char *module_name,
******************************************************************************/
void
acpi_ns_report_method_error(char *module_name,
acpi_ns_report_method_error(const char *module_name,
u32 line_number,
char *message,
const char *message,
struct acpi_namespace_node *prefix_node,
char *path, acpi_status method_status)
const char *path, acpi_status method_status)
{
acpi_status status;
struct acpi_namespace_node *node = prefix_node;
@ -167,7 +167,8 @@ acpi_ns_report_method_error(char *module_name,
******************************************************************************/
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;
acpi_status status;
@ -296,7 +297,7 @@ u32 acpi_ns_local(acpi_object_type type)
void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info)
{
char *next_external_char;
const char *next_external_char;
u32 i;
ACPI_FUNCTION_ENTRY();
@ -363,9 +364,9 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info)
{
u32 num_segments = info->num_segments;
char *internal_name = info->internal_name;
char *external_name = info->next_external_char;
const char *external_name = info->next_external_char;
char *result = NULL;
acpi_native_uint i;
u32 i;
ACPI_FUNCTION_TRACE(ns_build_internal_name);
@ -400,12 +401,11 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info)
result = &internal_name[i];
} else if (num_segments == 2) {
internal_name[i] = AML_DUAL_NAME_PREFIX;
result = &internal_name[(acpi_native_uint) (i + 1)];
result = &internal_name[(acpi_size) i + 1];
} else {
internal_name[i] = AML_MULTI_NAME_PREFIX_OP;
internal_name[(acpi_native_uint) (i + 1)] =
(char)num_segments;
result = &internal_name[(acpi_native_uint) (i + 2)];
internal_name[(acpi_size) i + 1] = (char)num_segments;
result = &internal_name[(acpi_size) i + 2];
}
}
@ -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;
struct acpi_namestring_info info;
@ -528,15 +529,15 @@ acpi_status acpi_ns_internalize_name(char *external_name, char **converted_name)
acpi_status
acpi_ns_externalize_name(u32 internal_name_length,
char *internal_name,
const char *internal_name,
u32 * converted_name_length, char **converted_name)
{
acpi_native_uint names_index = 0;
acpi_native_uint num_segments = 0;
acpi_native_uint required_length;
acpi_native_uint prefix_length = 0;
acpi_native_uint i = 0;
acpi_native_uint j = 0;
u32 names_index = 0;
u32 num_segments = 0;
u32 required_length;
u32 prefix_length = 0;
u32 i = 0;
u32 j = 0;
ACPI_FUNCTION_TRACE(ns_externalize_name);
@ -582,9 +583,8 @@ acpi_ns_externalize_name(u32 internal_name_length,
/* <count> 4-byte names */
names_index = prefix_length + 2;
num_segments = (acpi_native_uint) (u8)
internal_name[(acpi_native_uint)
(prefix_length + 1)];
num_segments = (u8)
internal_name[(acpi_size) prefix_length + 1];
break;
case AML_DUAL_NAME_PREFIX:
@ -823,7 +823,7 @@ u32 acpi_ns_opens_scope(acpi_object_type type)
acpi_status
acpi_ns_get_node(struct acpi_namespace_node *prefix_node,
char *pathname,
const char *pathname,
u32 flags, struct acpi_namespace_node **return_node)
{
union acpi_generic_state scope_info;

View File

@ -182,7 +182,6 @@ acpi_evaluate_object(acpi_handle handle,
}
info->pathname = pathname;
info->parameter_type = ACPI_PARAM_ARGS;
/* Convert and validate the device handle */
@ -442,7 +441,7 @@ acpi_ns_get_device_callback(acpi_handle obj_handle,
u32 flags;
struct acpica_device_id hid;
struct acpi_compatible_id_list *cid;
acpi_native_uint i;
u32 i;
int found;
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);

View File

@ -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 *)header;
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->length,
p->memory_type, p->proximity_domain,
p->proximity_domain,
(p->flags & ACPI_SRAT_MEM_ENABLED)?
"enabled" : "disabled",
(p->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)?

View File

@ -76,7 +76,7 @@ acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state)
{
u8 *aml = parser_state->aml;
u32 package_length = 0;
acpi_native_uint byte_count;
u32 byte_count;
u8 byte_zero_mask = 0x3F; /* Default [0:5] */
ACPI_FUNCTION_TRACE(ps_get_next_package_length);
@ -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
*/
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 */

View File

@ -333,9 +333,9 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
static void
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 */

View File

@ -162,7 +162,7 @@ do_prt_fixups(struct acpi_prt_entry *entry, struct acpi_pci_routing_table *prt)
!strcmp(prt->source, quirk->source) &&
strlen(prt->source) >= strlen(quirk->actual_source)) {
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",
entry->id.segment, entry->id.bus,
entry->id.device, 'A' + entry->pin,
@ -429,7 +429,7 @@ acpi_pci_irq_derive(struct pci_dev *dev,
{
struct pci_dev *bridge = dev;
int irq = -1;
u8 bridge_pin = 0;
u8 bridge_pin = 0, orig_pin = pin;
if (!dev)
@ -463,8 +463,8 @@ acpi_pci_irq_derive(struct pci_dev *dev,
}
if (irq < 0) {
printk(KERN_WARNING PREFIX "Unable to derive IRQ for device %s\n",
pci_name(dev));
dev_warn(&dev->dev, "can't derive routing for PCI INT %c\n",
'A' + orig_pin);
return -1;
}
@ -487,6 +487,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
int triggering = ACPI_LEVEL_SENSITIVE;
int polarity = ACPI_ACTIVE_LOW;
char *link = NULL;
char link_desc[16];
int rc;
@ -503,7 +504,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
pin--;
if (!dev->bus) {
printk(KERN_ERR PREFIX "Invalid (NULL) 'bus' field\n");
dev_err(&dev->dev, "invalid (NULL) 'bus' field\n");
return -ENODEV;
}
@ -538,8 +539,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
* driver reported one, then use it. Exit in any case.
*/
if (irq < 0) {
printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: no GSI",
pci_name(dev), ('A' + pin));
dev_warn(&dev->dev, "PCI INT %c: no GSI", 'A' + pin);
/* Interrupt Line values above 0xF are forbidden */
if (dev->irq > 0 && (dev->irq <= 0xF)) {
printk(" - using IRQ %d\n", dev->irq);
@ -554,21 +554,21 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
rc = acpi_register_gsi(irq, triggering, polarity);
if (rc < 0) {
printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: failed "
"to register GSI\n", pci_name(dev), ('A' + pin));
dev_warn(&dev->dev, "PCI INT %c: failed to register GSI\n",
'A' + pin);
return rc;
}
dev->irq = rc;
printk(KERN_INFO PREFIX "PCI Interrupt %s[%c] -> ",
pci_name(dev), 'A' + pin);
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,
(triggering == ACPI_LEVEL_SENSITIVE) ? "level" : "edge",
(polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq);
dev_info(&dev->dev, "PCI INT %c%s -> GSI %u (%s, %s) -> IRQ %d\n",
'A' + pin, link_desc, irq,
(triggering == ACPI_LEVEL_SENSITIVE) ? "level" : "edge",
(polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq);
return 0;
}
@ -616,10 +616,6 @@ void acpi_pci_irq_disable(struct pci_dev *dev)
* (e.g. PCI_UNDEFINED_IRQ).
*/
printk(KERN_INFO PREFIX "PCI interrupt for device %s disabled\n",
pci_name(dev));
dev_info(&dev->dev, "PCI INT %c disabled\n", 'A' + pin);
acpi_unregister_gsi(gsi);
return;
}

View File

@ -118,8 +118,31 @@ static const struct file_operations acpi_processor_info_fops = {
.release = single_release,
};
struct acpi_processor *processors[NR_CPUS];
DEFINE_PER_CPU(struct acpi_processor *, processors);
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
@ -265,7 +288,20 @@ static int acpi_processor_set_pdc(struct acpi_processor *pr)
if (!pdc_in)
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);
if (ACPI_FAILURE(status))
@ -614,14 +650,14 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid)
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)
{
int result = 0;
acpi_status status = AE_OK;
struct acpi_processor *pr;
struct sys_device *sysdev;
pr = acpi_driver_data(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.
* Don't trust it blindly
*/
if (processor_device_array[pr->id] != NULL &&
processor_device_array[pr->id] != device) {
if (per_cpu(processor_device_array, pr->id) != NULL &&
per_cpu(processor_device_array, pr->id) != device) {
printk(KERN_WARNING "BIOS reported wrong ACPI id "
"for the processor\n");
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);
if (result)
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,
acpi_processor_notify, pr);
@ -749,7 +789,7 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb,
unsigned long action, void *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) {
acpi_processor_ppc_has_changed(pr);
@ -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,
acpi_processor_notify);
sysfs_remove_link(&device->dev.kobj, "sysdev");
acpi_processor_remove_fs(device);
if (pr->cdev) {
@ -819,8 +861,8 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
pr->cdev = NULL;
}
processors[pr->id] = NULL;
processor_device_array[pr->id] = NULL;
per_cpu(processors, pr->id) = NULL;
per_cpu(processor_device_array, pr->id) = NULL;
kfree(pr);
return 0;
@ -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)
{
if (cpu_online(pr->id)) {
return (-EINVAL);
}
if (cpu_online(pr->id))
cpu_down(pr->id);
arch_unregister_cpu(pr->id);
acpi_unmap_lsapic(pr->id);
return (0);
@ -1068,8 +1110,6 @@ static int __init acpi_processor_init(void)
{
int result = 0;
memset(&processors, 0, sizeof(processors));
memset(&errata, 0, sizeof(errata));
#ifdef CONFIG_SMP
@ -1083,6 +1123,11 @@ static int __init acpi_processor_init(void)
return -ENOMEM;
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);
if (result < 0)
goto out_proc;

View File

@ -41,6 +41,7 @@
#include <linux/pm_qos_params.h>
#include <linux/clockchips.h>
#include <linux/cpuidle.h>
#include <linux/cpuidle.h>
/*
* Include the apic definitions for x86 to have the APIC timer related defines
@ -57,6 +58,7 @@
#include <acpi/acpi_bus.h>
#include <acpi/processor.h>
#include <asm/processor.h>
#define ACPI_PROCESSOR_COMPONENT 0x01000000
#define ACPI_PROCESSOR_CLASS "processor"
@ -401,7 +403,7 @@ static void acpi_processor_idle(void)
*/
local_irq_disable();
pr = processors[smp_processor_id()];
pr = __get_cpu_var(processors);
if (!pr) {
local_irq_enable();
return;
@ -955,6 +957,21 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
} else {
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 {
snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI IOPORT 0x%x",
cx.address);
@ -1431,7 +1448,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
struct acpi_processor *pr;
struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
pr = processors[smp_processor_id()];
pr = __get_cpu_var(processors);
if (unlikely(!pr))
return 0;
@ -1471,7 +1488,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
u32 t1, t2;
int sleep_ticks = 0;
pr = processors[smp_processor_id()];
pr = __get_cpu_var(processors);
if (unlikely(!pr))
return 0;
@ -1549,7 +1566,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
u32 t1, t2;
int sleep_ticks = 0;
pr = processors[smp_processor_id()];
pr = __get_cpu_var(processors);
if (unlikely(!pr))
return 0;
@ -1780,6 +1797,15 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
return 0;
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);
max_cstate = acpi_processor_cstate_check(max_cstate);
if (max_cstate < ACPI_C_STATES_MAX)

View File

@ -89,7 +89,7 @@ static int acpi_processor_ppc_notifier(struct notifier_block *nb,
if (event != CPUFREQ_INCOMPATIBLE)
goto out;
pr = processors[policy->cpu];
pr = per_cpu(processors, policy->cpu);
if (!pr || !pr->performance)
goto out;
@ -572,7 +572,7 @@ int acpi_processor_preregister_performance(
/* Call _PSD for all CPUs */
for_each_possible_cpu(i) {
pr = processors[i];
pr = per_cpu(processors, i);
if (!pr) {
/* Look only at processors in ACPI namespace */
continue;
@ -603,7 +603,7 @@ int acpi_processor_preregister_performance(
* domain info.
*/
for_each_possible_cpu(i) {
pr = processors[i];
pr = per_cpu(processors, i);
if (!pr)
continue;
@ -624,7 +624,7 @@ int acpi_processor_preregister_performance(
cpus_clear(covered_cpus);
for_each_possible_cpu(i) {
pr = processors[i];
pr = per_cpu(processors, i);
if (!pr)
continue;
@ -651,7 +651,7 @@ int acpi_processor_preregister_performance(
if (i == j)
continue;
match_pr = processors[j];
match_pr = per_cpu(processors, j);
if (!match_pr)
continue;
@ -680,7 +680,7 @@ int acpi_processor_preregister_performance(
if (i == j)
continue;
match_pr = processors[j];
match_pr = per_cpu(processors, j);
if (!match_pr)
continue;
@ -697,7 +697,7 @@ int acpi_processor_preregister_performance(
err_ret:
for_each_possible_cpu(i) {
pr = processors[i];
pr = per_cpu(processors, i);
if (!pr || !pr->performance)
continue;
@ -728,7 +728,7 @@ acpi_processor_register_performance(struct acpi_processor_performance
mutex_lock(&performance_mutex);
pr = processors[cpu];
pr = per_cpu(processors, cpu);
if (!pr) {
mutex_unlock(&performance_mutex);
return -ENODEV;
@ -766,7 +766,7 @@ acpi_processor_unregister_performance(struct acpi_processor_performance
mutex_lock(&performance_mutex);
pr = processors[cpu];
pr = per_cpu(processors, cpu);
if (!pr) {
mutex_unlock(&performance_mutex);
return;

View File

@ -71,7 +71,7 @@ static int acpi_processor_update_tsd_coord(void)
* coordination between all CPUs.
*/
for_each_possible_cpu(i) {
pr = processors[i];
pr = per_cpu(processors, i);
if (!pr)
continue;
@ -93,7 +93,7 @@ static int acpi_processor_update_tsd_coord(void)
cpus_clear(covered_cpus);
for_each_possible_cpu(i) {
pr = processors[i];
pr = per_cpu(processors, i);
if (!pr)
continue;
@ -119,7 +119,7 @@ static int acpi_processor_update_tsd_coord(void)
if (i == j)
continue;
match_pr = processors[j];
match_pr = per_cpu(processors, j);
if (!match_pr)
continue;
@ -152,7 +152,7 @@ static int acpi_processor_update_tsd_coord(void)
if (i == j)
continue;
match_pr = processors[j];
match_pr = per_cpu(processors, j);
if (!match_pr)
continue;
@ -172,7 +172,7 @@ static int acpi_processor_update_tsd_coord(void)
err_ret:
for_each_possible_cpu(i) {
pr = processors[i];
pr = per_cpu(processors, i);
if (!pr)
continue;
@ -214,7 +214,7 @@ static int acpi_processor_throttling_notifier(unsigned long event, void *data)
struct acpi_processor_throttling *p_throttling;
cpu = p_tstate->cpu;
pr = processors[cpu];
pr = per_cpu(processors, cpu);
if (!pr) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid pr pointer\n"));
return 0;
@ -1035,7 +1035,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
* 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
* error message and continue.
@ -1232,7 +1232,10 @@ static ssize_t acpi_processor_write_throttling(struct file *file,
int result = 0;
struct seq_file *m = file->private_data;
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))
return -EINVAL;
@ -1241,10 +1244,23 @@ static ssize_t acpi_processor_write_throttling(struct file *file,
return -EFAULT;
state_string[count] = '\0';
if ((count > 0) && (state_string[count-1] == '\n'))
state_string[count-1] = '\0';
result = acpi_processor_set_throttling(pr,
simple_strtoul(state_string,
NULL, 0));
charp = state_string;
if ((state_string[0] == 't') || (state_string[0] == 'T'))
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)
return result;

50
drivers/acpi/reboot.c Normal file
View File

@ -0,0 +1,50 @@
#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);
}

View File

@ -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)
{
acpi_native_uint bits_set;
u8 bits_set;
ACPI_FUNCTION_ENTRY();
@ -84,7 +84,7 @@ static u8 acpi_rs_count_set_bits(u16 bit_field)
bit_field &= (u16) (bit_field - 1);
}
return ((u8) bits_set);
return bits_set;
}
/*******************************************************************************

View File

@ -181,9 +181,9 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
}
/*
* Loop through the ACPI_INTERNAL_OBJECTS - Each object
* should be a package that in turn contains an
* acpi_integer Address, a u8 Pin, a Name and a u8 source_index.
* Loop through the ACPI_INTERNAL_OBJECTS - Each object should be a
* package that in turn contains an acpi_integer Address, a u8 Pin,
* a Name, and a u8 source_index.
*/
top_object_list = package_object->package.elements;
number_of_elements = package_object->package.count;
@ -240,9 +240,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
/* 1) First subobject: Dereference the PRT.Address */
obj_desc = sub_object_list[0];
if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
user_prt->address = obj_desc->integer.value;
} else {
if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
ACPI_ERROR((AE_INFO,
"(PRT[%X].Address) Need Integer, found %s",
index,
@ -250,12 +248,12 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
return_ACPI_STATUS(AE_BAD_DATA);
}
user_prt->address = obj_desc->integer.value;
/* 2) Second subobject: Dereference the PRT.Pin */
obj_desc = sub_object_list[1];
if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
user_prt->pin = (u32) obj_desc->integer.value;
} else {
if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
ACPI_ERROR((AE_INFO,
"(PRT[%X].Pin) Need Integer, found %s",
index,
@ -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
* 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,
/* 4) Fourth subobject: Dereference the PRT.source_index */
obj_desc = sub_object_list[source_index_index];
if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
user_prt->source_index = (u32) obj_desc->integer.value;
} else {
if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
ACPI_ERROR((AE_INFO,
"(PRT[%X].SourceIndex) Need Integer, found %s",
index,
@ -374,6 +389,8 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
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 */
top_object_list++;

View File

@ -82,7 +82,7 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *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 */

View File

@ -62,7 +62,7 @@ ACPI_MODULE_NAME("rsutils")
******************************************************************************/
u8 acpi_rs_decode_bitmask(u16 mask, u8 * list)
{
acpi_native_uint i;
u8 i;
u8 bit_count;
ACPI_FUNCTION_ENTRY();
@ -71,7 +71,7 @@ u8 acpi_rs_decode_bitmask(u16 mask, u8 * list)
for (i = 0, bit_count = 0; mask; i++) {
if (mask & 0x0001) {
list[bit_count] = (u8) i;
list[bit_count] = i;
bit_count++;
}
@ -96,8 +96,8 @@ u8 acpi_rs_decode_bitmask(u16 mask, u8 * list)
u16 acpi_rs_encode_bitmask(u8 * list, u8 count)
{
acpi_native_uint i;
acpi_native_uint mask;
u32 i;
u16 mask;
ACPI_FUNCTION_ENTRY();
@ -107,7 +107,7 @@ u16 acpi_rs_encode_bitmask(u8 * list, u8 count)
mask |= (0x1 << list[i]);
}
return ((u16) mask);
return mask;
}
/*******************************************************************************
@ -130,7 +130,7 @@ u16 acpi_rs_encode_bitmask(u8 * list, u8 count)
void
acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type)
{
acpi_native_uint i;
u32 i;
ACPI_FUNCTION_ENTRY();
@ -679,7 +679,6 @@ acpi_rs_set_srs_method_data(struct acpi_namespace_node *node,
info->prefix_node = node;
info->pathname = METHOD_NAME__SRS;
info->parameters = args;
info->parameter_type = ACPI_PARAM_ARGS;
info->flags = ACPI_IGNORE_RETURN_VALUE;
/*

View File

@ -6,6 +6,8 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/acpi.h>
#include <linux/signal.h>
#include <linux/kthread.h>
#include <acpi/acpi_drivers.h>
#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
}
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;
union acpi_object arg;
acpi_status status = AE_OK;
/*
* TBD: evaluate _PS3?
*/
if (acpi_bus_get_device(handle, &device))
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.pointer = &arg;
arg.type = ACPI_TYPE_INTEGER;
@ -118,26 +140,22 @@ static int acpi_eject_operation(acpi_handle handle, int lockable)
/*
* TBD: _EJD support.
*/
status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL);
if (ACPI_FAILURE(status)) {
return (-ENODEV);
}
if (ACPI_FAILURE(status))
return -ENODEV;
return (0);
return 0;
}
static ssize_t
acpi_eject_store(struct device *d, struct device_attribute *attr,
const char *buf, size_t count)
{
int result;
int ret = count;
int islockable;
acpi_status status;
acpi_handle handle;
acpi_object_type type = 0;
struct acpi_device *acpi_device = to_acpi_device(d);
struct task_struct *task;
if ((!count) || (buf[0] != '1')) {
return -EINVAL;
@ -154,18 +172,12 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
goto err;
}
islockable = acpi_device->flags.lockable;
handle = acpi_device->handle;
result = acpi_bus_trim(acpi_device, 1);
if (!result)
result = acpi_eject_operation(handle, islockable);
if (result) {
ret = -EBUSY;
}
err:
/* remove the device in another thread to fix the deadlock issue */
task = kthread_run(acpi_bus_hot_remove_device,
acpi_device->handle, "acpi_hot_remove_device");
if (IS_ERR(task))
ret = PTR_ERR(task);
err:
return ret;
}

View File

@ -61,8 +61,6 @@ static u32 acpi_suspend_states[] = {
[PM_SUSPEND_MAX] = ACPI_STATE_S5
};
static int init_8259A_after_S1;
/**
* acpi_suspend_begin - Set the target system sleep state to the state
* associated with given @pm_state, if supported.
@ -185,13 +183,6 @@ static void acpi_suspend_finish(void)
acpi_set_firmware_waking_vector((acpi_physical_address) 0);
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 = {
.finish = acpi_suspend_finish,
.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 */
#ifdef CONFIG_HIBERNATION
@ -368,8 +339,8 @@ int acpi_suspend(u32 acpi_state)
/**
* acpi_pm_device_sleep_state - return preferred power state of ACPI device
* in the system sleep state given by %acpi_target_sleep_state
* @dev: device to examine
* @wake: if set, the device should be able to wake up the system
* @dev: device to examine; its driver model wakeup flags control
* whether it should be able to wake up the system
* @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
* failure (ie. if there's no 'struct acpi_device' for @dev)
@ -387,7 +358,7 @@ int acpi_suspend(u32 acpi_state)
* 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);
struct acpi_device *adev;
@ -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.
*/
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)) {
acpi_status status;
@ -472,8 +443,6 @@ int __init acpi_sleep_init(void)
u8 type_a, type_b;
#ifdef CONFIG_SUSPEND
int i = 0;
dmi_check_system(acpisleep_dmi_table);
#endif
if (acpi_disabled)

View File

@ -167,7 +167,13 @@ static int acpi_system_sysfs_init(void)
#define COUNT_ERROR 2 /* other */
#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_counters;
static struct attribute **all_attrs;
@ -202,9 +208,44 @@ static int count_num_gpes(void)
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)
{
u32 *tmp = all_counters;
struct event_counter *tmp = all_counters;
all_counters = NULL;
kfree(tmp);
@ -230,9 +271,10 @@ void acpi_os_gpe_count(u32 gpe_number)
return;
if (gpe_number < num_gpes)
all_counters[gpe_number]++;
all_counters[gpe_number].count++;
else
all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR]++;
all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR].
count++;
return;
}
@ -243,44 +285,144 @@ void acpi_os_fixed_event_count(u32 event_number)
return;
if (event_number < ACPI_NUM_FIXED_EVENTS)
all_counters[num_gpes + event_number]++;
all_counters[num_gpes + event_number].count++;
else
all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR]++;
all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR].
count++;
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,
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;
all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE] =
all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_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.
* 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,
struct kobj_attribute *attr, const char *buf, size_t size)
{
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) {
int i;
for (i = 0; i < num_counters; ++i)
all_counters[i] = 0;
all_counters[i].count = 0;
acpi_gpe_count = 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
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)
@ -298,7 +440,8 @@ void acpi_irq_stats_init(void)
if (all_attrs == NULL)
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)
goto fail;

View File

@ -124,7 +124,7 @@ static struct acpi_fadt_info fadt_info_table[] = {
static void inline
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,
/* All other fields are byte-wide */
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->access_width = 0;
}
@ -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;
struct acpi_table_header *table;
@ -280,7 +280,7 @@ static void acpi_tb_convert_fadt(void)
{
u8 pm1_register_length;
struct acpi_generic_address *target;
acpi_native_uint i;
u32 i;
/* Update the local FADT table header length */
@ -343,9 +343,11 @@ static void acpi_tb_convert_fadt(void)
*
* The PM event blocks are split into two register blocks, first is the
* 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 */
@ -360,14 +362,17 @@ static void acpi_tb_convert_fadt(void)
/* The PM1B register block is optional, ignore if not present */
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,
pm1_register_length,
(acpi_gbl_FADT.xpm1b_event_block.
address + pm1_register_length));
/* Don't forget to copy space_id of the GAS */
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)
u32 *address32;
struct acpi_generic_address *address64;
u8 length;
acpi_native_uint i;
u32 i;
/* Examine all of the 64-bit extended address fields (X fields) */

View File

@ -65,10 +65,9 @@ ACPI_MODULE_NAME("tbfind")
******************************************************************************/
acpi_status
acpi_tb_find_table(char *signature,
char *oem_id,
char *oem_table_id, acpi_native_uint * table_index)
char *oem_id, char *oem_table_id, u32 *table_index)
{
acpi_native_uint i;
u32 i;
acpi_status status;
struct acpi_table_header header;

View File

@ -107,11 +107,10 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc)
******************************************************************************/
acpi_status
acpi_tb_add_table(struct acpi_table_desc *table_desc,
acpi_native_uint * table_index)
acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
{
acpi_native_uint i;
acpi_native_uint length;
u32 i;
u32 length;
acpi_status status = AE_OK;
ACPI_FUNCTION_TRACE(tb_add_table);
@ -207,8 +206,8 @@ acpi_status acpi_tb_resize_root_table_list(void)
/* Increase the Table Array size */
tables = ACPI_ALLOCATE_ZEROED((acpi_gbl_root_table_list.size +
ACPI_ROOT_TABLE_SIZE_INCREMENT)
tables = ACPI_ALLOCATE_ZEROED(((acpi_size) acpi_gbl_root_table_list.
size + ACPI_ROOT_TABLE_SIZE_INCREMENT)
* sizeof(struct acpi_table_desc));
if (!tables) {
ACPI_ERROR((AE_INFO,
@ -220,7 +219,7 @@ acpi_status acpi_tb_resize_root_table_list(void)
if (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));
if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
@ -253,7 +252,7 @@ acpi_status acpi_tb_resize_root_table_list(void)
acpi_status
acpi_tb_store_table(acpi_physical_address address,
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;
@ -334,7 +333,7 @@ void acpi_tb_delete_table(struct acpi_table_desc *table_desc)
void acpi_tb_terminate(void)
{
acpi_native_uint i;
u32 i;
ACPI_FUNCTION_TRACE(tb_terminate);
@ -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;
@ -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;
@ -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;
@ -462,8 +461,7 @@ acpi_status acpi_tb_release_owner_id(acpi_native_uint table_index)
*
******************************************************************************/
acpi_status
acpi_tb_get_owner_id(acpi_native_uint table_index, acpi_owner_id * owner_id)
acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id)
{
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)
*
******************************************************************************/
u8 acpi_tb_is_table_loaded(acpi_native_uint table_index)
u8 acpi_tb_is_table_loaded(u32 table_index)
{
u8 is_loaded = FALSE;
@ -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);

View File

@ -49,8 +49,8 @@ ACPI_MODULE_NAME("tbutils")
/* Local prototypes */
static acpi_physical_address
acpi_tb_get_root_table_entry(u8 * table_entry,
acpi_native_uint table_entry_size);
acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size);
/*******************************************************************************
*
* FUNCTION: acpi_tb_check_xsdt
@ -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 *end = buffer + length;
@ -268,7 +268,7 @@ u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length)
void
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;
@ -336,8 +336,7 @@ acpi_tb_install_table(acpi_physical_address address,
******************************************************************************/
static acpi_physical_address
acpi_tb_get_root_table_entry(u8 * table_entry,
acpi_native_uint table_entry_size)
acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size)
{
u64 address64;
@ -395,8 +394,8 @@ acpi_status __init
acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
{
struct acpi_table_rsdp *rsdp;
acpi_native_uint table_entry_size;
acpi_native_uint i;
u32 table_entry_size;
u32 i;
u32 table_count;
struct acpi_table_header *table;
acpi_physical_address address;

View File

@ -125,7 +125,7 @@ acpi_initialize_tables(struct acpi_table_desc * initial_table_array,
/* Root Table Array has been statically allocated by the host */
ACPI_MEMSET(initial_table_array, 0,
initial_table_count *
(acpi_size) initial_table_count *
sizeof(struct acpi_table_desc));
acpi_gbl_root_table_list.tables = initial_table_array;
@ -183,9 +183,9 @@ acpi_status acpi_reallocate_root_table(void)
return_ACPI_STATUS(AE_SUPPORT);
}
new_size =
(acpi_gbl_root_table_list.count +
ACPI_ROOT_TABLE_SIZE_INCREMENT) * sizeof(struct acpi_table_desc);
new_size = ((acpi_size) acpi_gbl_root_table_list.count +
ACPI_ROOT_TABLE_SIZE_INCREMENT) *
sizeof(struct acpi_table_desc);
/* Create new array and copy the old array */
@ -222,7 +222,7 @@ acpi_status acpi_reallocate_root_table(void)
acpi_status acpi_load_table(struct acpi_table_header *table_ptr)
{
acpi_status status;
acpi_native_uint table_index;
u32 table_index;
struct acpi_table_desc table_desc;
if (!table_ptr)
@ -264,11 +264,10 @@ ACPI_EXPORT_SYMBOL(acpi_load_table)
*****************************************************************************/
acpi_status
acpi_get_table_header(char *signature,
acpi_native_uint instance,
struct acpi_table_header * out_table_header)
u32 instance, struct acpi_table_header *out_table_header)
{
acpi_native_uint i;
acpi_native_uint j;
u32 i;
u32 j;
struct acpi_table_header *header;
/* Parameter validation */
@ -378,10 +377,10 @@ ACPI_EXPORT_SYMBOL(acpi_unload_table_id)
*****************************************************************************/
acpi_status
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;
acpi_native_uint j;
u32 i;
u32 j;
acpi_status status;
/* Parameter validation */
@ -435,8 +434,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_table)
*
******************************************************************************/
acpi_status
acpi_get_table_by_index(acpi_native_uint table_index,
struct acpi_table_header ** table)
acpi_get_table_by_index(u32 table_index, struct acpi_table_header **table)
{
acpi_status status;
@ -493,7 +491,7 @@ static acpi_status acpi_tb_load_namespace(void)
{
acpi_status status;
struct acpi_table_header *table;
acpi_native_uint i;
u32 i;
ACPI_FUNCTION_TRACE(tb_load_namespace);

View File

@ -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 *mem_rover;
@ -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
* 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,
ACPI_EBDA_WINDOW_SIZE);
if (!table_ptr) {

View File

@ -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;
@ -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,
u32 component, char *module, u32 line)
u32 component, const char *module, u32 line)
{
void *allocation;

View File

@ -572,7 +572,7 @@ acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,
acpi_status status = AE_OK;
union acpi_operand_object *package_object;
union acpi_operand_object **package_elements;
acpi_native_uint i;
u32 i;
ACPI_FUNCTION_TRACE(ut_copy_epackage_to_ipackage);
@ -599,7 +599,7 @@ acpi_ut_copy_epackage_to_ipackage(union acpi_object *external_object,
/* Truncate package and delete it */
package_object->package.count = (u32) i;
package_object->package.count = i;
package_elements[i] = NULL;
acpi_ut_remove_reference(package_object);
return_ACPI_STATUS(status);

View File

@ -157,7 +157,8 @@ void ACPI_INTERNAL_VAR_XFACE
acpi_ut_debug_print(u32 requested_debug_level,
u32 line_number,
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;
va_list args;
@ -228,7 +229,8 @@ void ACPI_INTERNAL_VAR_XFACE
acpi_ut_debug_print_raw(u32 requested_debug_level,
u32 line_number,
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;
@ -261,7 +263,8 @@ ACPI_EXPORT_SYMBOL(acpi_ut_debug_print_raw)
******************************************************************************/
void
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++;
@ -293,7 +296,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_trace)
void
acpi_ut_trace_ptr(u32 line_number,
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_ut_track_stack_ptr();
@ -324,7 +327,7 @@ acpi_ut_trace_ptr(u32 line_number,
void
acpi_ut_trace_str(u32 line_number,
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++;
@ -356,7 +359,7 @@ acpi_ut_trace_str(u32 line_number,
void
acpi_ut_trace_u32(u32 line_number,
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++;
@ -386,7 +389,8 @@ acpi_ut_trace_u32(u32 line_number,
void
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,
@ -417,7 +421,8 @@ ACPI_EXPORT_SYMBOL(acpi_ut_exit)
void
acpi_ut_status_exit(u32 line_number,
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)) {
@ -458,7 +463,8 @@ ACPI_EXPORT_SYMBOL(acpi_ut_status_exit)
void
acpi_ut_value_exit(u32 line_number,
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,
@ -490,7 +496,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_value_exit)
void
acpi_ut_ptr_exit(u32 line_number,
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,
@ -519,8 +525,8 @@ acpi_ut_ptr_exit(u32 line_number,
void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display)
{
acpi_native_uint i = 0;
acpi_native_uint j;
u32 i = 0;
u32 j;
u32 temp32;
u8 buf_char;
@ -539,7 +545,7 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display)
/* Print current offset */
acpi_os_printf("%6.4X: ", (u32) i);
acpi_os_printf("%6.4X: ", i);
/* Print 16 hex chars */
@ -549,7 +555,7 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display)
/* Dump fill spaces */
acpi_os_printf("%*s", ((display * 2) + 1), " ");
j += (acpi_native_uint) display;
j += display;
continue;
}
@ -557,32 +563,38 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display)
case DB_BYTE_DISPLAY:
default: /* Default is BYTE display */
acpi_os_printf("%02X ", buffer[i + j]);
acpi_os_printf("%02X ",
buffer[(acpi_size) i + j]);
break;
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);
break;
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);
break;
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_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);
break;
}
j += (acpi_native_uint) display;
j += display;
}
/*
@ -596,7 +608,7 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display)
return;
}
buf_char = buffer[i + j];
buf_char = buffer[(acpi_size) i + j];
if (ACPI_IS_PRINT(buf_char)) {
acpi_os_printf("%c", buf_char);
} else {

View File

@ -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_operand_object *next_object = NULL;
union acpi_generic_state *state;
acpi_native_uint i;
u32 i;
ACPI_FUNCTION_TRACE_PTR(ut_update_object_reference, object);

View File

@ -97,7 +97,7 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
acpi_status status;
union acpi_operand_object *string_desc;
union acpi_operand_object *return_desc;
acpi_native_uint i;
u32 i;
ACPI_FUNCTION_TRACE(ut_osi_implementation);
@ -217,7 +217,6 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
info->prefix_node = prefix_node;
info->pathname = path;
info->parameter_type = ACPI_PARAM_ARGS;
/* Evaluate the object/method */
@ -514,7 +513,7 @@ acpi_ut_execute_CID(struct acpi_namespace_node * device_node,
u32 count;
u32 size;
struct acpi_compatible_id_list *cid_list;
acpi_native_uint i;
u32 i;
ACPI_FUNCTION_TRACE(ut_execute_CID);

View File

@ -64,7 +64,7 @@ ACPI_MODULE_NAME("utmisc")
******************************************************************************/
const char *acpi_ut_validate_exception(acpi_status status)
{
acpi_status sub_status;
u32 sub_status;
const char *exception = NULL;
ACPI_FUNCTION_ENTRY();
@ -85,32 +85,28 @@ const char *acpi_ut_validate_exception(acpi_status status)
case AE_CODE_PROGRAMMER:
if (sub_status <= AE_CODE_PGM_MAX) {
exception =
acpi_gbl_exception_names_pgm[sub_status - 1];
exception = acpi_gbl_exception_names_pgm[sub_status];
}
break;
case AE_CODE_ACPI_TABLES:
if (sub_status <= AE_CODE_TBL_MAX) {
exception =
acpi_gbl_exception_names_tbl[sub_status - 1];
exception = acpi_gbl_exception_names_tbl[sub_status];
}
break;
case AE_CODE_AML:
if (sub_status <= AE_CODE_AML_MAX) {
exception =
acpi_gbl_exception_names_aml[sub_status - 1];
exception = acpi_gbl_exception_names_aml[sub_status];
}
break;
case AE_CODE_CONTROL:
if (sub_status <= AE_CODE_CTRL_MAX) {
exception =
acpi_gbl_exception_names_ctrl[sub_status - 1];
exception = acpi_gbl_exception_names_ctrl[sub_status];
}
break;
@ -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_native_uint i;
acpi_native_uint j;
acpi_native_uint k;
u32 i;
u32 j;
u32 k;
acpi_status status;
ACPI_FUNCTION_TRACE(ut_allocate_owner_id);
@ -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_status status;
acpi_native_uint index;
u32 index;
u32 bit;
ACPI_FUNCTION_TRACE_U32(ut_release_owner_id, owner_id);
@ -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') ||
@ -628,7 +624,7 @@ u8 acpi_ut_valid_acpi_char(char character, acpi_native_uint position)
u8 acpi_ut_valid_acpi_name(u32 name)
{
acpi_native_uint i;
u32 i;
ACPI_FUNCTION_ENTRY();
@ -657,7 +653,7 @@ u8 acpi_ut_valid_acpi_name(u32 name)
acpi_name acpi_ut_repair_name(char *name)
{
acpi_native_uint i;
u32 i;
char new_name[ACPI_NAME_SIZE];
for (i = 0; i < ACPI_NAME_SIZE; i++) {
@ -1024,7 +1020,7 @@ acpi_ut_walk_package_tree(union acpi_operand_object * source_object,
******************************************************************************/
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;
@ -1037,8 +1033,8 @@ acpi_ut_error(char *module_name, u32 line_number, char *format, ...)
}
void ACPI_INTERNAL_VAR_XFACE
acpi_ut_exception(char *module_name,
u32 line_number, acpi_status status, char *format, ...)
acpi_ut_exception(const char *module_name,
u32 line_number, acpi_status status, const char *format, ...)
{
va_list args;
@ -1054,7 +1050,8 @@ acpi_ut_exception(char *module_name,
EXPORT_SYMBOL(acpi_ut_exception);
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;
@ -1067,7 +1064,7 @@ acpi_ut_warning(char *module_name, u32 line_number, char *format, ...)
}
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;

View File

@ -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 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 (i == mutex_id) {
ACPI_ERROR((AE_INFO,
@ -315,7 +315,7 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id)
* ordering rule. This indicates a coding error somewhere in
* 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 (i == mutex_id) {
continue;

View File

@ -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 component_id,
acpi_object_type
@ -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
* terminated.
*/
package_elements = ACPI_ALLOCATE_ZEROED((acpi_size)
(count + 1) * sizeof(void *));
package_elements = ACPI_ALLOCATE_ZEROED(((acpi_size) count +
1) * sizeof(void *));
if (!package_elements) {
acpi_ut_remove_reference(package_desc);
return_PTR(NULL);
@ -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)
{
union acpi_operand_object *object;

View File

@ -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, ..)
*
* 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
*
* 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)
static void acpi_video_device_find_cap(struct acpi_video_device *device)
{
acpi_handle h_dummy1;
int i;
u32 max_level = 0;
union acpi_object *obj = NULL;
struct acpi_video_device_brightness *br = NULL;
memset(&device->cap, 0, sizeof(device->cap));
@ -672,53 +739,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
device->cap._DSS = 1;
}
if (ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
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);
max_level = acpi_video_init_brightness(device);
if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){
int result;
@ -1695,6 +1716,8 @@ static void
acpi_video_switch_brightness(struct acpi_video_device *device, int event)
{
unsigned long level_current, level_next;
if (!device->brightness)
return;
acpi_video_device_lcd_get_level_current(device, &level_current);
level_next = acpi_video_get_next_level(device, level_current, event);
acpi_video_device_lcd_set_level(device, level_next);

View File

@ -58,6 +58,55 @@ struct apm_queue {
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
*/
@ -69,13 +118,7 @@ struct apm_user {
unsigned int reader: 1;
int suspend_result;
unsigned int 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 */
enum apm_suspend_state suspend_state;
struct apm_queue queue;
};
@ -83,7 +126,8 @@ struct apm_user {
/*
* 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 struct task_struct *kapmd_tsk;
@ -166,78 +210,6 @@ static void queue_event(apm_event_t event)
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)
{
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)
as->suspend_result = -EINTR;
if (as->suspend_state == SUSPEND_READ) {
int pending;
switch (as->suspend_state) {
case SUSPEND_READ:
/*
* If we read a suspend command from /dev/apm_bios,
* then the corresponding APM_IOC_SUSPEND ioctl is
* interpreted as an acknowledge.
*/
as->suspend_state = SUSPEND_ACKED;
suspends_pending--;
pending = suspends_pending == 0;
atomic_dec(&suspend_acks_pending);
mutex_unlock(&state_lock);
/*
* If there are no further acknowledges required,
* suspend the system.
* suspend_acks_pending changed, the notifier needs to
* be woken up for this
*/
if (pending)
apm_suspend();
wake_up(&apm_suspend_waitqueue);
/*
* 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)
* try_to_freeze() in freezer_count() will not trigger
*/
freezer_count();
} else {
break;
case SUSPEND_ACKTO:
as->suspend_result = -ETIMEDOUT;
mutex_unlock(&state_lock);
break;
default:
as->suspend_state = SUSPEND_WAIT;
mutex_unlock(&state_lock);
/*
* Otherwise it is a request to suspend the system.
* Queue an event for all readers, and expect an
* acknowledge from all writers who haven't already
* acknowledged.
* Just invoke pm_suspend(), we'll handle it from
* there via the notifier.
*/
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_state == SUSPEND_DONE);
as->suspend_result = pm_suspend(PM_SUSPEND_MEM);
}
mutex_lock(&state_lock);
@ -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)
{
struct apm_user *as = filp->private_data;
int pending = 0;
filp->private_data = NULL;
@ -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
* events are concerned, we no longer exist. However, we
* need to balance suspends_pending, which means the
* possibility of sleeping.
* events are concerned, we no longer exist.
*/
mutex_lock(&state_lock);
if (as->suspend_state != SUSPEND_NONE) {
suspends_pending -= 1;
pending = suspends_pending == 0;
}
if (as->suspend_state == SUSPEND_PENDING ||
as->suspend_state == SUSPEND_READ)
atomic_dec(&suspend_acks_pending);
mutex_unlock(&state_lock);
if (pending)
apm_suspend();
wake_up(&apm_suspend_waitqueue);
kfree(as);
return 0;
@ -545,7 +496,6 @@ static int kapmd(void *arg)
{
do {
apm_event_t event;
int ret;
wait_event_interruptible(kapmd_wait,
!queue_empty(&kapmd_queue) || kthread_should_stop());
@ -570,20 +520,13 @@ static int kapmd(void *arg)
case APM_USER_SUSPEND:
case APM_SYS_SUSPEND:
ret = queue_suspend_event(event, NULL);
if (ret < 0) {
/*
* We were busy. Try again in 50ms.
*/
queue_add_event(&kapmd_queue, event);
msleep(50);
}
if (ret > 0)
apm_suspend();
pm_suspend(PM_SUSPEND_MEM);
break;
case APM_CRITICAL_SUSPEND:
apm_suspend();
atomic_inc(&userspace_notification_inhibit);
pm_suspend(PM_SUSPEND_MEM);
atomic_dec(&userspace_notification_inhibit);
break;
}
} while (1);
@ -591,6 +534,120 @@ static int kapmd(void *arg)
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)
{
int ret;
@ -604,7 +661,7 @@ static int __init apm_init(void)
if (IS_ERR(kapmd_tsk)) {
ret = PTR_ERR(kapmd_tsk);
kapmd_tsk = NULL;
return ret;
goto out;
}
wake_up_process(kapmd_tsk);
@ -613,16 +670,27 @@ static int __init apm_init(void)
#endif
ret = misc_register(&apm_device);
if (ret != 0) {
remove_proc_entry("apm", NULL);
kthread_stop(kapmd_tsk);
}
if (ret)
goto out_stop;
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;
}
static void __exit apm_exit(void)
{
unregister_pm_notifier(&apm_notif_block);
misc_deregister(&apm_device);
remove_proc_entry("apm", NULL);

View File

@ -179,17 +179,29 @@ config FUJITSU_LAPTOP
tristate "Fujitsu Laptop Extras"
depends on X86
depends on ACPI
depends on INPUT
depends on BACKLIGHT_CLASS_DEVICE
---help---
This is a driver for laptops built by Fujitsu:
* P2xxx/P5xxx/S6xxx/S7xxx series Lifebooks
* 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.
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
tristate "HP Compaq TC1100 Tablet WMI Extras (EXPERIMENTAL)"
depends on X86 && !X86_64
@ -219,6 +231,23 @@ config MSI_LAPTOP
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
tristate "Sony Laptop Extras"
depends on X86 && ACPI

View File

@ -5,10 +5,11 @@ obj- := misc.o # Dummy rule to force built-in.o to be made
obj-$(CONFIG_IBM_ASM) += ibmasm/
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_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_SSC) += atmel-ssc.o
obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o

View File

@ -22,18 +22,18 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define ACER_WMI_VERSION "0.1"
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/dmi.h>
#include <linux/fb.h>
#include <linux/backlight.h>
#include <linux/leds.h>
#include <linux/platform_device.h>
#include <linux/acpi.h>
#include <linux/i8042.h>
#include <linux/debugfs.h>
#include <acpi/acpi_drivers.h>
@ -87,6 +87,7 @@ struct acer_quirks {
* Acer ACPI method GUIDs
*/
#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_GUID2 "95764E09-FB56-4e83-B31A-37761F60994A"
@ -150,6 +151,12 @@ struct acer_data {
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 */
struct wmi_interface {
/* The WMI device type */
@ -160,6 +167,9 @@ struct wmi_interface {
/* Private data for the current interface */
struct acer_data data;
/* debugfs entries associated with this interface */
struct acer_debug debug;
};
/* The static interface pointer, points to the currently detected interface */
@ -174,7 +184,7 @@ static struct wmi_interface *interface;
struct quirk_entry {
u8 wireless;
u8 mailled;
u8 brightness;
s8 brightness;
u8 bluetooth;
};
@ -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_acer_aspire_1520 = {
.brightness = -1,
};
static struct quirk_entry quirk_acer_travelmate_2490 = {
.mailled = 1,
};
@ -207,7 +221,29 @@ static struct quirk_entry quirk_medion_md_98300 = {
.wireless = 1,
};
static struct quirk_entry quirk_fujitsu_amilo_li_1718 = {
.wireless = 2,
};
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,
.ident = "Acer Aspire 3100",
@ -298,6 +334,15 @@ static struct dmi_system_id acer_quirks[] = {
},
.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,
.ident = "Medion MD 98300",
@ -393,6 +438,12 @@ struct wmi_interface *iface)
return AE_ERROR;
*value = result & 0x1;
return AE_OK;
case 2:
err = ec_read(0x71, &result);
if (err)
return AE_ERROR;
*value = result & 0x1;
return AE_OK;
default:
err = ec_read(0xA, &result);
if (err)
@ -506,6 +557,15 @@ static acpi_status AMW0_set_capabilities(void)
struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
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.ecx = args.edx = 0;
@ -552,7 +612,8 @@ static acpi_status AMW0_set_capabilities(void)
* appear to use the same EC register for brightness, even if they
* differ for wireless, etc
*/
interface->capability |= ACER_CAP_BRIGHTNESS;
if (quirks->brightness >= 0)
interface->capability |= ACER_CAP_BRIGHTNESS;
return AE_OK;
}
@ -807,7 +868,15 @@ static int read_brightness(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;
}
@ -829,8 +898,9 @@ static int __devinit acer_backlight_init(struct device *dev)
acer_backlight_device = bd;
bd->props.power = FB_BLANK_UNBLANK;
bd->props.brightness = max_brightness;
bd->props.max_brightness = max_brightness;
bd->props.brightness = read_brightness(NULL);
backlight_update_status(bd);
return 0;
}
@ -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,
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
*/
@ -1052,12 +1144,40 @@ static int create_sysfs(void)
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)
{
int err;
printk(ACER_INFO "Acer Laptop ACPI-WMI Extras version %s\n",
ACER_WMI_VERSION);
printk(ACER_INFO "Acer Laptop ACPI-WMI Extras\n");
find_quirks();
/*
* Detect which ACPI-WMI interface we're using.
@ -1092,8 +1212,6 @@ static int __init acer_wmi_init(void)
if (wmi_has_guid(AMW0_GUID1))
AMW0_find_mailled();
find_quirks();
if (!interface) {
printk(ACER_ERR "No or unsupported WMI interface, unable to "
"load\n");
@ -1111,6 +1229,13 @@ static int __init acer_wmi_init(void)
if (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 */
acer_commandline_init();

View File

@ -0,0 +1,404 @@
/*-*-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:*");

View File

@ -87,7 +87,7 @@ enum {
CM_ASL_LID
};
const char *cm_getv[] = {
static const char *cm_getv[] = {
"WLDG", NULL, NULL, NULL,
"CAMG", NULL, NULL, NULL,
NULL, "PBLG", NULL, NULL,
@ -96,7 +96,7 @@ const char *cm_getv[] = {
"CRDG", "LIDG"
};
const char *cm_setv[] = {
static const char *cm_setv[] = {
"WLDS", NULL, NULL, NULL,
"CAMS", NULL, NULL, NULL,
"SDSP", "PBLS", "HDPS", NULL,

File diff suppressed because it is too large Load Diff

View File

@ -293,13 +293,11 @@ EXPORT_SYMBOL(pci_osc_control_set);
* choose highest power _SxD or any lower power
*/
static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev,
pm_message_t state)
static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev)
{
int acpi_state;
acpi_state = acpi_pm_device_sleep_state(&pdev->dev,
device_may_wakeup(&pdev->dev), NULL);
acpi_state = acpi_pm_device_sleep_state(&pdev->dev, NULL);
if (acpi_state < 0)
return PCI_POWER_ERROR;

View File

@ -508,7 +508,7 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
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
@ -528,7 +528,7 @@ pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state)
return PCI_D0;
if (platform_pci_choose_state) {
ret = platform_pci_choose_state(dev, state);
ret = platform_pci_choose_state(dev);
if (ret != PCI_POWER_ERROR)
return ret;
}

View File

@ -6,8 +6,7 @@ extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
extern void pci_cleanup_rom(struct pci_dev *dev);
/* Firmware callbacks */
extern pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev,
pm_message_t state);
extern pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev);
extern int (*platform_pci_set_power_state)(struct pci_dev *dev,
pci_power_t state);

View File

@ -1,3 +1,8 @@
/*
* Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
* Bjorn Helgaas <bjorn.helgaas@hp.com>
*/
extern spinlock_t pnp_lock;
void *pnp_alloc(long size);
@ -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);
void pnp_remove_card_device(struct pnp_dev *dev);
struct pnp_option *pnp_build_option(int priority);
struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev);
struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev,
int priority);
int pnp_register_irq_resource(struct pnp_dev *dev, struct pnp_option *option,
struct pnp_irq *data);
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,
struct pnp_port *data);
int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option,
struct pnp_mem *data);
struct pnp_port {
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; /* port flags */
};
#define PNP_IRQ_NR 256
typedef struct { DECLARE_BITMAP(bits, PNP_IRQ_NR); } pnp_irq_mask_t;
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_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);
void __pnp_remove_device(struct pnp_dev *dev);
@ -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_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 pnp_init_resource(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
void pnp_free_resources(struct pnp_dev *dev);
int pnp_resource_type(struct resource *res);
struct pnp_resource {
struct list_head list;
struct resource res;
unsigned int index; /* ISAPNP config register index */
};
struct pnp_resource_table {
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];
};
void pnp_free_resource(struct pnp_resource *pnp_res);
struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
int flags);

View File

@ -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)
{
struct pnp_dev *dev = to_pnp_dev(dmdev);
pnp_free_option(dev->independent);
pnp_free_option(dev->dependent);
pnp_free_ids(dev);
kfree(dev->res);
pnp_free_resources(dev);
pnp_free_options(dev);
kfree(dev);
}
@ -119,12 +133,8 @@ struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, char *pnpid
if (!dev)
return NULL;
dev->res = kzalloc(sizeof(struct pnp_resource_table), GFP_KERNEL);
if (!dev->res) {
kfree(dev);
return NULL;
}
INIT_LIST_HEAD(&dev->resources);
INIT_LIST_HEAD(&dev->options);
dev->protocol = protocol;
dev->number = id;
dev->dma_mask = DMA_24BIT_MASK;
@ -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);
if (!dev_id) {
kfree(dev->res);
kfree(dev);
return NULL;
}

View File

@ -3,6 +3,8 @@
*
* 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 (C) 2008 Hewlett-Packard Development Company, L.P.
* Bjorn Helgaas <bjorn.helgaas@hp.com>
*/
#include <linux/pnp.h>
@ -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,
struct pnp_port *port)
{
pnp_printf(buffer,
"%sport 0x%x-0x%x, align 0x%x, size 0x%x, %i-bit address decoding\n",
space, port->min, port->max,
port->align ? (port->align - 1) : 0, port->size,
port->flags & PNP_PORT_FLAG_16BITADDR ? 16 : 10);
pnp_printf(buffer, "%sport %#llx-%#llx, align %#llx, size %#llx, "
"%i-bit address decoding\n", space,
(unsigned long long) port->min,
(unsigned long long) port->max,
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,
@ -67,7 +71,7 @@ static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space,
pnp_printf(buffer, "%sirq ", space);
for (i = 0; i < PNP_IRQ_NR; i++)
if (test_bit(i, irq->map)) {
if (test_bit(i, irq->map.bits)) {
if (!first) {
pnp_printf(buffer, ",");
} else {
@ -78,7 +82,7 @@ static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space,
else
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>");
if (irq->flags & IORESOURCE_IRQ_HIGHEDGE)
pnp_printf(buffer, " High-Edge");
@ -88,6 +92,8 @@ static void pnp_print_irq(pnp_info_buffer_t * buffer, char *space,
pnp_printf(buffer, " High-Level");
if (irq->flags & IORESOURCE_IRQ_LOWLEVEL)
pnp_printf(buffer, " Low-Level");
if (irq->flags & IORESOURCE_IRQ_OPTIONAL)
pnp_printf(buffer, " (optional)");
pnp_printf(buffer, "\n");
}
@ -148,8 +154,11 @@ static void pnp_print_mem(pnp_info_buffer_t * buffer, char *space,
{
char *s;
pnp_printf(buffer, "%sMemory 0x%x-0x%x, align 0x%x, size 0x%x",
space, mem->min, mem->max, mem->align, mem->size);
pnp_printf(buffer, "%sMemory %#llx-%#llx, align %#llx, size %#llx",
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)
pnp_printf(buffer, ", writeable");
if (mem->flags & IORESOURCE_MEM_CACHEABLE)
@ -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,
struct pnp_option *option, int dep)
struct pnp_option *option)
{
char *s;
struct pnp_port *port;
struct pnp_irq *irq;
struct pnp_dma *dma;
struct pnp_mem *mem;
if (dep) {
switch (option->priority) {
case PNP_RES_PRIORITY_PREFERRED:
s = "preferred";
break;
case PNP_RES_PRIORITY_ACCEPTABLE:
s = "acceptable";
break;
case PNP_RES_PRIORITY_FUNCTIONAL:
s = "functional";
break;
default:
s = "invalid";
}
pnp_printf(buffer, "Dependent: %02i - Priority %s\n", dep, s);
switch (option->type) {
case IORESOURCE_IO:
pnp_print_port(buffer, space, &option->u.port);
break;
case IORESOURCE_MEM:
pnp_print_mem(buffer, space, &option->u.mem);
break;
case IORESOURCE_IRQ:
pnp_print_irq(buffer, space, &option->u.irq);
break;
case IORESOURCE_DMA:
pnp_print_dma(buffer, space, &option->u.dma);
break;
}
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,
struct device_attribute *attr, char *buf)
{
struct pnp_dev *dev = to_pnp_dev(dmdev);
struct pnp_option *independent = dev->independent;
struct pnp_option *dependent = dev->dependent;
int ret, dep = 1;
pnp_info_buffer_t *buffer;
struct pnp_option *option;
int ret, dep = 0, set = 0;
char *indent;
pnp_info_buffer_t *buffer = (pnp_info_buffer_t *)
pnp_alloc(sizeof(pnp_info_buffer_t));
buffer = pnp_alloc(sizeof(pnp_info_buffer_t));
if (!buffer)
return -ENOMEM;
buffer->len = PAGE_SIZE;
buffer->buffer = buf;
buffer->curr = buffer->buffer;
if (independent)
pnp_print_option(buffer, "", independent, 0);
while (dependent) {
pnp_print_option(buffer, " ", dependent, dep);
dependent = dependent->next;
dep++;
list_for_each_entry(option, &dev->options, list) {
if (pnp_option_is_dependent(option)) {
indent = " ";
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);
kfree(buffer);
return ret;
@ -248,79 +250,59 @@ static ssize_t pnp_show_current_resources(struct device *dmdev,
char *buf)
{
struct pnp_dev *dev = to_pnp_dev(dmdev);
struct resource *res;
int i, ret;
pnp_info_buffer_t *buffer;
struct pnp_resource *pnp_res;
struct resource *res;
int ret;
if (!dev)
return -EINVAL;
buffer = (pnp_info_buffer_t *) pnp_alloc(sizeof(pnp_info_buffer_t));
buffer = pnp_alloc(sizeof(pnp_info_buffer_t));
if (!buffer)
return -ENOMEM;
buffer->len = PAGE_SIZE;
buffer->buffer = buf;
buffer->curr = buffer->buffer;
pnp_printf(buffer, "state = ");
if (dev->active)
pnp_printf(buffer, "active\n");
else
pnp_printf(buffer, "disabled\n");
pnp_printf(buffer, "state = %s\n", dev->active ? "active" : "disabled");
for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) {
if (pnp_resource_valid(res)) {
pnp_printf(buffer, "io");
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_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++) {
if (pnp_resource_valid(res)) {
pnp_printf(buffer, "dma");
if (res->flags & IORESOURCE_DISABLED)
pnp_printf(buffer, " disabled\n");
else
pnp_printf(buffer, " %lld\n",
(unsigned long long) res->start);
list_for_each_entry(pnp_res, &dev->resources, list) {
res = &pnp_res->res;
pnp_printf(buffer, pnp_resource_type_name(res));
if (res->flags & IORESOURCE_DISABLED) {
pnp_printf(buffer, " disabled\n");
continue;
}
switch (pnp_resource_type(res)) {
case IORESOURCE_IO:
case IORESOURCE_MEM:
pnp_printf(buffer, " %#llx-%#llx\n",
(unsigned long long) res->start,
(unsigned long long) res->end);
break;
case IORESOURCE_IRQ:
case IORESOURCE_DMA:
pnp_printf(buffer, " %lld\n",
(unsigned long long) res->start);
break;
}
}
ret = (buffer->curr - buf);
kfree(buffer);
return ret;
}
static ssize_t
pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
const char *ubuf, size_t count)
static ssize_t pnp_set_current_resources(struct device *dmdev,
struct device_attribute *attr,
const char *ubuf, size_t count)
{
struct pnp_dev *dev = to_pnp_dev(dmdev);
struct pnp_resource *pnp_res;
char *buf = (void *)ubuf;
int retval = 0;
resource_size_t start, end;
@ -368,7 +350,6 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
goto done;
}
if (!strnicmp(buf, "set", 3)) {
int nport = 0, nmem = 0, nirq = 0, ndma = 0;
if (dev->active)
goto done;
buf += 3;
@ -391,10 +372,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
end = simple_strtoul(buf, &buf, 0);
} else
end = start;
pnp_res = pnp_add_io_resource(dev, start, end,
0);
if (pnp_res)
pnp_res->index = nport++;
pnp_add_io_resource(dev, start, end, 0);
continue;
}
if (!strnicmp(buf, "mem", 3)) {
@ -411,10 +389,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
end = simple_strtoul(buf, &buf, 0);
} else
end = start;
pnp_res = pnp_add_mem_resource(dev, start, end,
0);
if (pnp_res)
pnp_res->index = nmem++;
pnp_add_mem_resource(dev, start, end, 0);
continue;
}
if (!strnicmp(buf, "irq", 3)) {
@ -422,9 +397,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
while (isspace(*buf))
++buf;
start = simple_strtoul(buf, &buf, 0);
pnp_res = pnp_add_irq_resource(dev, start, 0);
if (pnp_res)
pnp_res->index = nirq++;
pnp_add_irq_resource(dev, start, 0);
continue;
}
if (!strnicmp(buf, "dma", 3)) {
@ -432,9 +405,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr,
while (isspace(*buf))
++buf;
start = simple_strtoul(buf, &buf, 0);
pnp_res = pnp_add_dma_resource(dev, start, 0);
if (pnp_res)
pnp_res->index = ndma++;
pnp_add_dma_resource(dev, start, 0);
continue;
}
break;

View File

@ -429,154 +429,135 @@ static struct pnp_dev *__init isapnp_parse_device(struct pnp_card *card,
* Add IRQ resource to resources list.
*/
static void __init isapnp_parse_irq_resource(struct pnp_dev *dev,
struct pnp_option *option,
unsigned int option_flags,
int size)
{
unsigned char tmp[3];
struct pnp_irq *irq;
unsigned long bits;
pnp_irq_mask_t map;
unsigned char flags = IORESOURCE_IRQ_HIGHEDGE;
isapnp_peek(tmp, size);
irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
if (!irq)
return;
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)
irq->flags = tmp[2];
else
irq->flags = IORESOURCE_IRQ_HIGHEDGE;
pnp_register_irq_resource(dev, option, irq);
flags = tmp[2];
pnp_register_irq_resource(dev, option_flags, &map, flags);
}
/*
* Add DMA resource to resources list.
*/
static void __init isapnp_parse_dma_resource(struct pnp_dev *dev,
struct pnp_option *option,
unsigned int option_flags,
int size)
{
unsigned char tmp[2];
struct pnp_dma *dma;
isapnp_peek(tmp, size);
dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
if (!dma)
return;
dma->map = tmp[0];
dma->flags = tmp[1];
pnp_register_dma_resource(dev, option, dma);
pnp_register_dma_resource(dev, option_flags, tmp[0], tmp[1]);
}
/*
* Add port resource to resources list.
*/
static void __init isapnp_parse_port_resource(struct pnp_dev *dev,
struct pnp_option *option,
unsigned int option_flags,
int size)
{
unsigned char tmp[7];
struct pnp_port *port;
resource_size_t min, max, align, len;
unsigned char flags;
isapnp_peek(tmp, size);
port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
if (!port)
return;
port->min = (tmp[2] << 8) | tmp[1];
port->max = (tmp[4] << 8) | tmp[3];
port->align = tmp[5];
port->size = tmp[6];
port->flags = tmp[0] ? PNP_PORT_FLAG_16BITADDR : 0;
pnp_register_port_resource(dev, option, port);
min = (tmp[2] << 8) | tmp[1];
max = (tmp[4] << 8) | tmp[3];
align = tmp[5];
len = tmp[6];
flags = tmp[0] ? IORESOURCE_IO_16BIT_ADDR : 0;
pnp_register_port_resource(dev, option_flags,
min, max, align, len, flags);
}
/*
* Add fixed port resource to resources list.
*/
static void __init isapnp_parse_fixed_port_resource(struct pnp_dev *dev,
struct pnp_option *option,
unsigned int option_flags,
int size)
{
unsigned char tmp[3];
struct pnp_port *port;
resource_size_t base, len;
isapnp_peek(tmp, size);
port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
if (!port)
return;
port->min = port->max = (tmp[1] << 8) | tmp[0];
port->size = tmp[2];
port->align = 0;
port->flags = PNP_PORT_FLAG_FIXED;
pnp_register_port_resource(dev, option, port);
base = (tmp[1] << 8) | tmp[0];
len = tmp[2];
pnp_register_port_resource(dev, option_flags, base, base, 0, len,
IORESOURCE_IO_FIXED);
}
/*
* Add memory resource to resources list.
*/
static void __init isapnp_parse_mem_resource(struct pnp_dev *dev,
struct pnp_option *option,
unsigned int option_flags,
int size)
{
unsigned char tmp[9];
struct pnp_mem *mem;
resource_size_t min, max, align, len;
unsigned char flags;
isapnp_peek(tmp, size);
mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
if (!mem)
return;
mem->min = ((tmp[2] << 8) | tmp[1]) << 8;
mem->max = ((tmp[4] << 8) | tmp[3]) << 8;
mem->align = (tmp[6] << 8) | tmp[5];
mem->size = ((tmp[8] << 8) | tmp[7]) << 8;
mem->flags = tmp[0];
pnp_register_mem_resource(dev, option, mem);
min = ((tmp[2] << 8) | tmp[1]) << 8;
max = ((tmp[4] << 8) | tmp[3]) << 8;
align = (tmp[6] << 8) | tmp[5];
len = ((tmp[8] << 8) | tmp[7]) << 8;
flags = tmp[0];
pnp_register_mem_resource(dev, option_flags,
min, max, align, len, flags);
}
/*
* Add 32-bit memory resource to resources list.
*/
static void __init isapnp_parse_mem32_resource(struct pnp_dev *dev,
struct pnp_option *option,
unsigned int option_flags,
int size)
{
unsigned char tmp[17];
struct pnp_mem *mem;
resource_size_t min, max, align, len;
unsigned char flags;
isapnp_peek(tmp, size);
mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
if (!mem)
return;
mem->min = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
mem->max = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
mem->align =
(tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9];
mem->size =
(tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13];
mem->flags = tmp[0];
pnp_register_mem_resource(dev, option, mem);
min = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
max = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
align = (tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9];
len = (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13];
flags = tmp[0];
pnp_register_mem_resource(dev, option_flags,
min, max, align, len, flags);
}
/*
* Add 32-bit fixed memory resource to resources list.
*/
static void __init isapnp_parse_fixed_mem32_resource(struct pnp_dev *dev,
struct pnp_option *option,
unsigned int option_flags,
int size)
{
unsigned char tmp[9];
struct pnp_mem *mem;
resource_size_t base, len;
unsigned char flags;
isapnp_peek(tmp, size);
mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
if (!mem)
return;
mem->min = mem->max =
(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);
base = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
len = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
flags = tmp[0];
pnp_register_mem_resource(dev, option_flags, base, base, 0, len, flags);
}
/*
@ -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,
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];
struct pnp_option *option;
unsigned int option_flags;
struct pnp_dev *dev;
u32 eisa_id;
char id[8];
if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
return 1;
option = pnp_register_independent_option(dev);
if (!option) {
kfree(dev);
return 1;
}
option_flags = 0;
pnp_add_card_device(card, dev);
while (1) {
@ -634,16 +611,11 @@ static int __init isapnp_create_device(struct pnp_card *card,
return 1;
size = 0;
skip = 0;
option = pnp_register_independent_option(dev);
if (!option) {
kfree(dev);
return 1;
}
option_flags = 0;
pnp_add_card_device(card, dev);
} else {
skip = 1;
}
priority = 0;
compat = 0;
break;
case _STAG_COMPATDEVID:
@ -660,44 +632,42 @@ static int __init isapnp_create_device(struct pnp_card *card,
case _STAG_IRQ:
if (size < 2 || size > 3)
goto __skip;
isapnp_parse_irq_resource(dev, option, size);
isapnp_parse_irq_resource(dev, option_flags, size);
size = 0;
break;
case _STAG_DMA:
if (size != 2)
goto __skip;
isapnp_parse_dma_resource(dev, option, size);
isapnp_parse_dma_resource(dev, option_flags, size);
size = 0;
break;
case _STAG_STARTDEP:
if (size > 1)
goto __skip;
priority = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE;
priority = PNP_RES_PRIORITY_ACCEPTABLE;
if (size > 0) {
isapnp_peek(tmp, size);
priority = 0x100 | tmp[0];
priority = tmp[0];
size = 0;
}
option = pnp_register_dependent_option(dev, priority);
if (!option)
return 1;
option_flags = pnp_new_dependent_set(dev, priority);
break;
case _STAG_ENDDEP:
if (size != 0)
goto __skip;
priority = 0;
dev_dbg(&dev->dev, "end dependent options\n");
option_flags = 0;
break;
case _STAG_IOPORT:
if (size != 7)
goto __skip;
isapnp_parse_port_resource(dev, option, size);
isapnp_parse_port_resource(dev, option_flags, size);
size = 0;
break;
case _STAG_FIXEDIO:
if (size != 3)
goto __skip;
isapnp_parse_fixed_port_resource(dev, option, size);
isapnp_parse_fixed_port_resource(dev, option_flags,
size);
size = 0;
break;
case _STAG_VENDOR:
@ -705,7 +675,7 @@ static int __init isapnp_create_device(struct pnp_card *card,
case _LTAG_MEMRANGE:
if (size != 9)
goto __skip;
isapnp_parse_mem_resource(dev, option, size);
isapnp_parse_mem_resource(dev, option_flags, size);
size = 0;
break;
case _LTAG_ANSISTR:
@ -720,13 +690,14 @@ static int __init isapnp_create_device(struct pnp_card *card,
case _LTAG_MEM32RANGE:
if (size != 17)
goto __skip;
isapnp_parse_mem32_resource(dev, option, size);
isapnp_parse_mem32_resource(dev, option_flags, size);
size = 0;
break;
case _LTAG_FIXEDMEM32RANGE:
if (size != 9)
goto __skip;
isapnp_parse_fixed_mem32_resource(dev, option, size);
isapnp_parse_fixed_mem32_resource(dev, option_flags,
size);
size = 0;
break;
case _STAG_END:
@ -928,7 +899,6 @@ EXPORT_SYMBOL(isapnp_write_byte);
static int isapnp_get_resources(struct pnp_dev *dev)
{
struct pnp_resource *pnp_res;
int i, ret;
dev_dbg(&dev->dev, "get resources\n");
@ -940,35 +910,23 @@ static int isapnp_get_resources(struct pnp_dev *dev)
for (i = 0; i < ISAPNP_MAX_PORT; i++) {
ret = isapnp_read_word(ISAPNP_CFG_PORT + (i << 1));
if (ret) {
pnp_res = pnp_add_io_resource(dev, ret, ret, 0);
if (pnp_res)
pnp_res->index = i;
}
pnp_add_io_resource(dev, ret, ret,
ret == 0 ? IORESOURCE_DISABLED : 0);
}
for (i = 0; i < ISAPNP_MAX_MEM; i++) {
ret = isapnp_read_word(ISAPNP_CFG_MEM + (i << 3)) << 8;
if (ret) {
pnp_res = pnp_add_mem_resource(dev, ret, ret, 0);
if (pnp_res)
pnp_res->index = i;
}
pnp_add_mem_resource(dev, ret, ret,
ret == 0 ? IORESOURCE_DISABLED : 0);
}
for (i = 0; i < ISAPNP_MAX_IRQ; i++) {
ret = isapnp_read_word(ISAPNP_CFG_IRQ + (i << 1)) >> 8;
if (ret) {
pnp_res = pnp_add_irq_resource(dev, ret, 0);
if (pnp_res)
pnp_res->index = i;
}
pnp_add_irq_resource(dev, ret,
ret == 0 ? IORESOURCE_DISABLED : 0);
}
for (i = 0; i < ISAPNP_MAX_DMA; i++) {
ret = isapnp_read_byte(ISAPNP_CFG_DMA + i);
if (ret != 4) {
pnp_res = pnp_add_dma_resource(dev, ret, 0);
if (pnp_res)
pnp_res->index = i;
}
pnp_add_dma_resource(dev, ret,
ret == 4 ? IORESOURCE_DISABLED : 0);
}
__end:
@ -978,62 +936,45 @@ static int isapnp_get_resources(struct pnp_dev *dev)
static int isapnp_set_resources(struct pnp_dev *dev)
{
struct pnp_resource *pnp_res;
struct resource *res;
int tmp, index;
int tmp;
dev_dbg(&dev->dev, "set resources\n");
isapnp_cfg_begin(dev->card->number, dev->number);
dev->active = 1;
for (tmp = 0; tmp < ISAPNP_MAX_PORT; tmp++) {
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, tmp);
if (!pnp_res)
continue;
res = &pnp_res->res;
if (pnp_resource_valid(res)) {
index = pnp_res->index;
res = pnp_get_resource(dev, IORESOURCE_IO, tmp);
if (pnp_resource_enabled(res)) {
dev_dbg(&dev->dev, " set io %d to %#llx\n",
index, (unsigned long long) res->start);
isapnp_write_word(ISAPNP_CFG_PORT + (index << 1),
tmp, (unsigned long long) res->start);
isapnp_write_word(ISAPNP_CFG_PORT + (tmp << 1),
res->start);
}
}
for (tmp = 0; tmp < ISAPNP_MAX_IRQ; tmp++) {
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IRQ, tmp);
if (!pnp_res)
continue;
res = &pnp_res->res;
if (pnp_resource_valid(res)) {
res = pnp_get_resource(dev, IORESOURCE_IRQ, tmp);
if (pnp_resource_enabled(res)) {
int irq = res->start;
if (irq == 2)
irq = 9;
index = pnp_res->index;
dev_dbg(&dev->dev, " set irq %d to %d\n", index, irq);
isapnp_write_byte(ISAPNP_CFG_IRQ + (index << 1), irq);
dev_dbg(&dev->dev, " set irq %d to %d\n", tmp, irq);
isapnp_write_byte(ISAPNP_CFG_IRQ + (tmp << 1), irq);
}
}
for (tmp = 0; tmp < ISAPNP_MAX_DMA; tmp++) {
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, tmp);
if (!pnp_res)
continue;
res = &pnp_res->res;
if (pnp_resource_valid(res)) {
index = pnp_res->index;
res = pnp_get_resource(dev, IORESOURCE_DMA, tmp);
if (pnp_resource_enabled(res)) {
dev_dbg(&dev->dev, " set dma %d to %lld\n",
index, (unsigned long long) res->start);
isapnp_write_byte(ISAPNP_CFG_DMA + index, res->start);
tmp, (unsigned long long) res->start);
isapnp_write_byte(ISAPNP_CFG_DMA + tmp, res->start);
}
}
for (tmp = 0; tmp < ISAPNP_MAX_MEM; tmp++) {
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_MEM, tmp);
if (!pnp_res)
continue;
res = &pnp_res->res;
if (pnp_resource_valid(res)) {
index = pnp_res->index;
res = pnp_get_resource(dev, IORESOURCE_MEM, tmp);
if (pnp_resource_enabled(res)) {
dev_dbg(&dev->dev, " set mem %d to %#llx\n",
index, (unsigned long long) res->start);
isapnp_write_word(ISAPNP_CFG_MEM + (index << 3),
tmp, (unsigned long long) res->start);
isapnp_write_word(ISAPNP_CFG_MEM + (tmp << 3),
(res->start >> 8) & 0xffff);
}
}

View File

@ -3,6 +3,8 @@
*
* based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz>
* 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>
@ -19,82 +21,64 @@ DEFINE_MUTEX(pnp_res_mutex);
static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
{
struct pnp_resource *pnp_res;
struct resource *res;
struct resource *res, local_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 */
if (!(res->flags & IORESOURCE_AUTO)) {
res = pnp_get_resource(dev, IORESOURCE_IO, idx);
if (res) {
dev_dbg(&dev->dev, " io %d already set to %#llx-%#llx "
"flags %#lx\n", idx, (unsigned long long) res->start,
(unsigned long long) res->end, res->flags);
return 1;
return 0;
}
/* set the initial values */
pnp_res->index = idx;
res->flags |= rule->flags | IORESOURCE_IO;
res->flags &= ~IORESOURCE_UNSET;
res = &local_res;
res->flags = rule->flags | IORESOURCE_AUTO;
res->start = 0;
res->end = 0;
if (!rule->size) {
res->flags |= IORESOURCE_DISABLED;
dev_dbg(&dev->dev, " io %d disabled\n", idx);
return 1; /* skip disabled resource requests */
goto __add;
}
res->start = rule->min;
res->end = res->start + rule->size - 1;
/* run through until pnp_check_port is happy */
while (!pnp_check_port(dev, res)) {
res->start += rule->align;
res->end = res->start + rule->size - 1;
if (res->start > rule->max || !rule->align) {
dev_dbg(&dev->dev, " couldn't assign io %d\n", idx);
return 0;
dev_dbg(&dev->dev, " couldn't assign io %d "
"(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);
return 1;
__add:
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)
{
struct pnp_resource *pnp_res;
struct resource *res;
struct resource *res, local_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;
/* check if this resource has been manually set, if so skip */
if (!(res->flags & IORESOURCE_AUTO)) {
res = pnp_get_resource(dev, IORESOURCE_MEM, idx);
if (res) {
dev_dbg(&dev->dev, " mem %d already set to %#llx-%#llx "
"flags %#lx\n", idx, (unsigned long long) res->start,
(unsigned long long) res->end, res->flags);
return 1;
return 0;
}
/* set the initial values */
pnp_res->index = idx;
res->flags |= rule->flags | IORESOURCE_MEM;
res->flags &= ~IORESOURCE_UNSET;
res = &local_res;
res->flags = rule->flags | IORESOURCE_AUTO;
res->start = 0;
res->end = 0;
/* convert pnp flags to standard Linux flags */
if (!(rule->flags & IORESOURCE_MEM_WRITEABLE))
res->flags |= IORESOURCE_READONLY;
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)
if (!rule->size) {
res->flags |= IORESOURCE_DISABLED;
dev_dbg(&dev->dev, " mem %d disabled\n", idx);
return 1; /* skip disabled resource requests */
goto __add;
}
res->start = rule->min;
res->end = res->start + rule->size - 1;
/* run through until pnp_check_mem is happy */
while (!pnp_check_mem(dev, res)) {
res->start += rule->align;
res->end = res->start + rule->size - 1;
if (res->start > rule->max || !rule->align) {
dev_dbg(&dev->dev, " couldn't assign mem %d\n", idx);
return 0;
dev_dbg(&dev->dev, " couldn't assign mem %d "
"(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);
return 1;
__add:
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)
{
struct pnp_resource *pnp_res;
struct resource *res;
struct resource *res, local_res;
int i;
/* 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)
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);
if (!pnp_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)) {
res = pnp_get_resource(dev, IORESOURCE_IRQ, idx);
if (res) {
dev_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n",
idx, (int) res->start, res->flags);
return 1;
return 0;
}
/* set the initial values */
pnp_res->index = idx;
res->flags |= rule->flags | IORESOURCE_IRQ;
res->flags &= ~IORESOURCE_UNSET;
res = &local_res;
res->flags = rule->flags | IORESOURCE_AUTO;
res->start = -1;
res->end = -1;
if (bitmap_empty(rule->map, PNP_IRQ_NR)) {
if (bitmap_empty(rule->map.bits, PNP_IRQ_NR)) {
res->flags |= IORESOURCE_DISABLED;
dev_dbg(&dev->dev, " irq %d disabled\n", idx);
return 1; /* skip disabled resource requests */
goto __add;
}
/* 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) {
res->end = res->start;
dev_dbg(&dev->dev, " assign irq %d %d\n", idx,
(int) res->start);
return 1;
goto __add;
}
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];
if (pnp_check_irq(dev, res)) {
dev_dbg(&dev->dev, " assign irq %d %d\n", idx,
(int) res->start);
return 1;
}
if (pnp_check_irq(dev, res))
goto __add;
}
}
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);
return -EBUSY;
__add:
pnp_add_irq_resource(dev, res->start, res->flags);
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;
struct resource *res, local_res;
int i;
/* 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)
1, 3, 5, 6, 7, 0, 2, 4
};
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_DMA, idx);
if (!pnp_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)) {
res = pnp_get_resource(dev, IORESOURCE_DMA, idx);
if (res) {
dev_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n",
idx, (int) res->start, res->flags);
return;
return 0;
}
/* set the initial values */
pnp_res->index = idx;
res->flags |= rule->flags | IORESOURCE_DMA;
res->flags &= ~IORESOURCE_UNSET;
res = &local_res;
res->flags = rule->flags | IORESOURCE_AUTO;
res->start = -1;
res->end = -1;
for (i = 0; i < 8; i++) {
if (rule->map & (1 << xtab[i])) {
res->start = res->end = xtab[i];
if (pnp_check_dma(dev, res)) {
dev_dbg(&dev->dev, " assign dma %d %d\n", idx,
(int) res->start);
return;
}
if (pnp_check_dma(dev, res))
goto __add;
}
}
#ifdef MAX_DMA_CHANNELS
res->start = res->end = MAX_DMA_CHANNELS;
#endif
res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED;
res->flags |= IORESOURCE_DISABLED;
dev_dbg(&dev->dev, " disable dma %d\n", idx);
__add:
pnp_add_dma_resource(dev, res->start, res->flags);
return 0;
}
void pnp_init_resource(struct resource *res)
{
unsigned long type;
type = res->flags & (IORESOURCE_IO | IORESOURCE_MEM |
IORESOURCE_IRQ | IORESOURCE_DMA);
res->name = NULL;
res->flags = type | IORESOURCE_AUTO | IORESOURCE_UNSET;
if (type == IORESOURCE_IRQ || type == IORESOURCE_DMA) {
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)
{
struct resource *res;
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_free_resources(dev);
}
/**
* 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)
{
struct resource *res;
int idx;
struct pnp_resource *pnp_res, *tmp;
for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
res = &dev->res->irq[idx].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);
}
list_for_each_entry_safe(pnp_res, tmp, &dev->resources, list) {
if (pnp_res->res.flags & IORESOURCE_AUTO)
pnp_free_resource(pnp_res);
}
}
/**
* pnp_assign_resources - assigns resources to the device based on the specified dependent number
* @dev: pointer to the desired device
* @depnum: the dependent function number
*
* Only set depnum to 0 if the device does not have dependent options.
* @set: the dependent function number
*/
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_mem *mem;
struct pnp_irq *irq;
struct pnp_dma *dma;
struct pnp_option *option;
int nport = 0, nmem = 0, nirq = 0, ndma = 0;
int ret = 0;
if (!pnp_can_configure(dev))
return -ENODEV;
dbg_pnp_show_resources(dev, "before pnp_assign_resources");
dev_dbg(&dev->dev, "pnp_assign_resources, try dependent set %d\n", set);
mutex_lock(&pnp_res_mutex);
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;
list_for_each_entry(option, &dev->options, list) {
if (pnp_option_is_dependent(option) &&
pnp_option_set(option) != set)
continue;
switch (option->type) {
case IORESOURCE_IO:
ret = pnp_assign_port(dev, &option->u.port, nport++);
break;
case IORESOURCE_MEM:
ret = pnp_assign_mem(dev, &option->u.mem, nmem++);
break;
case IORESOURCE_IRQ:
ret = pnp_assign_irq(dev, &option->u.irq, nirq++);
break;
case IORESOURCE_DMA:
ret = pnp_assign_dma(dev, &option->u.dma, ndma++);
break;
default:
ret = -EINVAL;
break;
}
if (ret < 0)
break;
}
if (depnum) {
struct pnp_option *dep;
int i;
dev_dbg(&dev->dev, "assigning dependent option %d\n", depnum);
for (i = 1, dep = dev->dependent; i < depnum;
i++, dep = dep->next)
if (!dep)
goto fail;
port = dep->port;
mem = dep->mem;
irq = dep->irq;
dma = dep->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;
}
} 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);
dbg_pnp_show_resources(dev, "after pnp_assign_resources (failed)");
return 0;
if (ret < 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)
*/
int pnp_auto_config_dev(struct pnp_dev *dev)
{
struct pnp_option *dep;
int i = 1;
int i, ret;
if (!pnp_can_configure(dev)) {
dev_dbg(&dev->dev, "configuration not supported\n");
return -ENODEV;
}
if (!dev->dependent) {
if (pnp_assign_resources(dev, 0))
ret = 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;
} 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");
return -EBUSY;
return ret;
}
/**

View File

@ -117,9 +117,7 @@ static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state)
{
int power_state;
power_state = acpi_pm_device_sleep_state(&dev->dev,
device_may_wakeup(&dev->dev),
NULL);
power_state = acpi_pm_device_sleep_state(&dev->dev, NULL);
if (power_state < 0)
power_state = (state.event == PM_EVENT_ON) ?
ACPI_STATE_D0 : ACPI_STATE_D3;

View File

@ -3,6 +3,8 @@
*
* Copyright (c) 2004 Matthieu Castet <castet.matthieu@free.fr>
* 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
* 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,
int irq, flags;
int p, t;
if (!valid_IRQ(gsi))
if (!valid_IRQ(gsi)) {
pnp_add_irq_resource(dev, gsi, IORESOURCE_DISABLED);
return;
}
/*
* 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,
u64 end = start + len - 1;
if (io_decode == ACPI_DECODE_16)
flags |= PNP_PORT_FLAG_16BITADDR;
flags |= IORESOURCE_IO_16BIT_ADDR;
if (len == 0 || end >= 0x10003)
flags |= IORESOURCE_DISABLED;
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,
u64 start, u64 len,
int write_protect)
@ -235,6 +294,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
struct acpi_resource_dma *dma;
struct acpi_resource_io *io;
struct acpi_resource_fixed_io *fixed_io;
struct acpi_resource_vendor_typed *vendor_typed;
struct acpi_resource_memory24 *memory24;
struct acpi_resource_memory32 *memory32;
struct acpi_resource_fixed_memory32 *fixed_memory32;
@ -248,24 +308,39 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
* _CRS, but some firmware violates this, so parse them all.
*/
irq = &res->data.irq;
for (i = 0; i < irq->interrupt_count; i++) {
pnpacpi_parse_allocated_irqresource(dev,
irq->interrupts[i],
irq->triggering,
irq->polarity,
irq->sharable);
if (irq->interrupt_count == 0)
pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
else {
for (i = 0; i < irq->interrupt_count; i++) {
pnpacpi_parse_allocated_irqresource(dev,
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;
case ACPI_RESOURCE_TYPE_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,
dma->transfer);
if (dma->channels[0] == (u8) -1)
flags |= IORESOURCE_DISABLED;
pnp_add_dma_resource(dev, dma->channels[0], flags);
}
else
flags = IORESOURCE_DISABLED;
pnp_add_dma_resource(dev, dma->channels[0], flags);
break;
case ACPI_RESOURCE_TYPE_IO:
@ -289,6 +364,8 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
break;
case ACPI_RESOURCE_TYPE_VENDOR:
vendor_typed = &res->data.vendor_typed;
pnpacpi_parse_allocated_vendor(dev, vendor_typed);
break;
case ACPI_RESOURCE_TYPE_END_TAG:
@ -331,12 +408,29 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
if (extended_irq->producer_consumer == ACPI_PRODUCER)
return AE_OK;
for (i = 0; i < extended_irq->interrupt_count; i++) {
pnpacpi_parse_allocated_irqresource(dev,
extended_irq->interrupts[i],
extended_irq->triggering,
extended_irq->polarity,
extended_irq->sharable);
if (extended_irq->interrupt_count == 0)
pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
else {
for (i = 0; i < extended_irq->interrupt_count; i++) {
pnpacpi_parse_allocated_irqresource(dev,
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;
@ -373,179 +467,147 @@ int pnpacpi_parse_allocated_resource(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)
{
int i;
struct pnp_dma *dma;
unsigned char map = 0, flags;
if (p->channel_count == 0)
return;
dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
if (!dma)
return;
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,
struct pnp_option *option,
unsigned int option_flags,
struct acpi_resource_irq *p)
{
int i;
struct pnp_irq *irq;
pnp_irq_mask_t map;
unsigned char flags;
if (p->interrupt_count == 0)
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++)
if (p->interrupts[i])
__set_bit(p->interrupts[i], irq->map);
irq->flags = irq_flags(p->triggering, p->polarity, p->sharable);
__set_bit(p->interrupts[i], map.bits);
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,
struct pnp_option *option,
unsigned int option_flags,
struct acpi_resource_extended_irq *p)
{
int i;
struct pnp_irq *irq;
pnp_irq_mask_t map;
unsigned char flags;
if (p->interrupt_count == 0)
return;
irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
if (!irq)
return;
for (i = 0; i < p->interrupt_count; i++)
if (p->interrupts[i])
__set_bit(p->interrupts[i], irq->map);
irq->flags = irq_flags(p->triggering, p->polarity, p->sharable);
bitmap_zero(map.bits, PNP_IRQ_NR);
for (i = 0; i < p->interrupt_count; i++) {
if (p->interrupts[i]) {
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,
struct pnp_option *option,
unsigned int option_flags,
struct acpi_resource_io *io)
{
struct pnp_port *port;
unsigned char flags = 0;
if (io->address_length == 0)
return;
port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
if (!port)
return;
port->min = io->minimum;
port->max = io->maximum;
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);
if (io->io_decode == ACPI_DECODE_16)
flags = IORESOURCE_IO_16BIT_ADDR;
pnp_register_port_resource(dev, option_flags, io->minimum, io->maximum,
io->alignment, io->address_length, flags);
}
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 pnp_port *port;
if (io->address_length == 0)
return;
port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
if (!port)
return;
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);
pnp_register_port_resource(dev, option_flags, io->address, io->address,
0, io->address_length, IORESOURCE_IO_FIXED);
}
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 pnp_mem *mem;
unsigned char flags = 0;
if (p->address_length == 0)
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,
struct pnp_option *option,
unsigned int option_flags,
struct acpi_resource_memory32 *p)
{
struct pnp_mem *mem;
unsigned char flags = 0;
if (p->address_length == 0)
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,
struct pnp_option *option,
unsigned int option_flags,
struct acpi_resource_fixed_memory32 *p)
{
struct pnp_mem *mem;
unsigned char flags = 0;
if (p->address_length == 0)
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,
struct pnp_option *option,
unsigned int option_flags,
struct acpi_resource *r)
{
struct acpi_resource_address64 addr, *p = &addr;
acpi_status status;
struct pnp_mem *mem;
struct pnp_port *port;
unsigned char flags = 0;
status = acpi_resource_to_address64(r, p);
if (!ACPI_SUCCESS(status)) {
@ -558,49 +620,37 @@ static __init void pnpacpi_parse_address_option(struct pnp_dev *dev,
return;
if (p->resource_type == ACPI_MEMORY_RANGE) {
mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
if (!mem)
return;
mem->min = mem->max = p->minimum;
mem->size = p->address_length;
mem->align = 0;
mem->flags = (p->info.mem.write_protect ==
ACPI_READ_WRITE_MEMORY) ? IORESOURCE_MEM_WRITEABLE
: 0;
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);
}
if (p->info.mem.write_protect == ACPI_READ_WRITE_MEMORY)
flags = IORESOURCE_MEM_WRITEABLE;
pnp_register_mem_resource(dev, option_flags, p->minimum,
p->minimum, 0, p->address_length,
flags);
} else if (p->resource_type == ACPI_IO_RANGE)
pnp_register_port_resource(dev, option_flags, p->minimum,
p->minimum, 0, p->address_length,
IORESOURCE_IO_FIXED);
}
struct acpipnp_parse_option_s {
struct pnp_option *option;
struct pnp_option *option_independent;
struct pnp_dev *dev;
unsigned int option_flags;
};
static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
void *data)
{
int priority = 0;
int priority;
struct acpipnp_parse_option_s *parse_data = data;
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) {
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;
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;
case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@ -620,31 +670,19 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
priority = PNP_RES_PRIORITY_INVALID;
break;
}
/* TBD: Consider performance/robustness bits */
option = pnp_register_dependent_option(dev, priority);
if (!option)
return AE_ERROR;
parse_data->option = option;
parse_data->option_flags = pnp_new_dependent_set(dev, priority);
break;
case ACPI_RESOURCE_TYPE_END_DEPENDENT:
/*only one EndDependentFn is allowed */
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");
parse_data->option_flags = 0;
break;
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;
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);
break;
@ -653,29 +691,31 @@ static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res,
break;
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;
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;
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);
break;
case ACPI_RESOURCE_TYPE_ADDRESS16:
case ACPI_RESOURCE_TYPE_ADDRESS32:
case ACPI_RESOURCE_TYPE_ADDRESS64:
pnpacpi_parse_address_option(dev, option, res);
pnpacpi_parse_address_option(dev, option_flags, res);
break;
case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
break;
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);
break;
@ -699,12 +739,9 @@ int __init pnpacpi_parse_resource_option_data(struct pnp_dev *dev)
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.option_flags = 0;
status = acpi_walk_resources(handle, METHOD_NAME__PRS,
pnpacpi_option_resource, &parse_data);
@ -806,6 +843,13 @@ static void pnpacpi_encode_irq(struct pnp_dev *dev,
struct acpi_resource_irq *irq = &resource->data.irq;
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);
irq->triggering = triggering;
irq->polarity = polarity;
@ -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;
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);
extended_irq->producer_consumer = ACPI_CONSUMER;
extended_irq->triggering = triggering;
@ -848,6 +899,13 @@ static void pnpacpi_encode_dma(struct pnp_dev *dev,
{
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 */
switch (p->flags & IORESOURCE_DMA_SPEED_MASK) {
case IORESOURCE_DMA_TYPEA:
@ -889,17 +947,21 @@ static void pnpacpi_encode_io(struct pnp_dev *dev,
{
struct acpi_resource_io *io = &resource->data.io;
/* Note: pnp_assign_port will copy pnp_port->flags into p->flags */
io->io_decode = (p->flags & PNP_PORT_FLAG_16BITADDR) ?
ACPI_DECODE_16 : ACPI_DECODE_10;
io->minimum = p->start;
io->maximum = p->end;
io->alignment = 0; /* Correct? */
io->address_length = p->end - p->start + 1;
if (pnp_resource_enabled(p)) {
/* Note: pnp_assign_port copies pnp_port->flags into p->flags */
io->io_decode = (p->flags & IORESOURCE_IO_16BIT_ADDR) ?
ACPI_DECODE_16 : ACPI_DECODE_10;
io->minimum = p->start;
io->maximum = p->end;
io->alignment = 0; /* Correct? */
io->address_length = p->end - p->start + 1;
} else {
io->minimum = 0;
io->address_length = 0;
}
dev_dbg(&dev->dev, " encode io %#llx-%#llx decode %#x\n",
(unsigned long long) p->start, (unsigned long long) p->end,
io->io_decode);
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,
@ -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;
fixed_io->address = p->start;
fixed_io->address_length = p->end - p->start + 1;
if (pnp_resource_enabled(p)) {
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",
(unsigned long long) p->start, (unsigned long long) p->end);
dev_dbg(&dev->dev, " encode fixed_io %#x-%#x\n", fixed_io->address,
fixed_io->address + fixed_io->address_length - 1);
}
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;
/* Note: pnp_assign_mem will copy pnp_mem->flags into p->flags */
memory24->write_protect =
(p->flags & IORESOURCE_MEM_WRITEABLE) ?
ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
memory24->minimum = p->start;
memory24->maximum = p->end;
memory24->alignment = 0;
memory24->address_length = p->end - p->start + 1;
if (pnp_resource_enabled(p)) {
/* Note: pnp_assign_mem copies pnp_mem->flags into p->flags */
memory24->write_protect = p->flags & IORESOURCE_MEM_WRITEABLE ?
ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
memory24->minimum = p->start;
memory24->maximum = p->end;
memory24->alignment = 0;
memory24->address_length = p->end - p->start + 1;
} else {
memory24->minimum = 0;
memory24->address_length = 0;
}
dev_dbg(&dev->dev, " encode mem24 %#llx-%#llx write_protect %#x\n",
(unsigned long long) p->start, (unsigned long long) p->end,
dev_dbg(&dev->dev, " encode mem24 %#x-%#x write_protect %#x\n",
memory24->minimum,
memory24->minimum + memory24->address_length - 1,
memory24->write_protect);
}
@ -941,16 +1013,21 @@ static void pnpacpi_encode_mem32(struct pnp_dev *dev,
{
struct acpi_resource_memory32 *memory32 = &resource->data.memory32;
memory32->write_protect =
(p->flags & IORESOURCE_MEM_WRITEABLE) ?
ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
memory32->minimum = p->start;
memory32->maximum = p->end;
memory32->alignment = 0;
memory32->address_length = p->end - p->start + 1;
if (pnp_resource_enabled(p)) {
memory32->write_protect = p->flags & IORESOURCE_MEM_WRITEABLE ?
ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
memory32->minimum = p->start;
memory32->maximum = p->end;
memory32->alignment = 0;
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",
(unsigned long long) p->start, (unsigned long long) p->end,
dev_dbg(&dev->dev, " encode mem32 %#x-%#x write_protect %#x\n",
memory32->minimum,
memory32->minimum + memory32->address_length - 1,
memory32->write_protect);
}
@ -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;
fixed_memory32->write_protect =
(p->flags & IORESOURCE_MEM_WRITEABLE) ?
ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
fixed_memory32->address = p->start;
fixed_memory32->address_length = p->end - p->start + 1;
if (pnp_resource_enabled(p)) {
fixed_memory32->write_protect =
p->flags & IORESOURCE_MEM_WRITEABLE ?
ACPI_READ_WRITE_MEMORY : ACPI_READ_ONLY_MEMORY;
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 "
"write_protect %#x\n",
(unsigned long long) p->start, (unsigned long long) p->end,
dev_dbg(&dev->dev, " encode fixed_mem32 %#x-%#x write_protect %#x\n",
fixed_memory32->address,
fixed_memory32->address + fixed_memory32->address_length - 1,
fixed_memory32->write_protect);
}

View File

@ -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,
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)
return;
mem->min = ((p[5] << 8) | p[4]) << 8;
mem->max = ((p[7] << 8) | p[6]) << 8;
mem->align = (p[9] << 8) | p[8];
mem->size = ((p[11] << 8) | p[10]) << 8;
mem->flags = p[3];
pnp_register_mem_resource(dev, option, mem);
min = ((p[5] << 8) | p[4]) << 8;
max = ((p[7] << 8) | p[6]) << 8;
align = (p[9] << 8) | p[8];
len = ((p[11] << 8) | p[10]) << 8;
flags = p[3];
pnp_register_mem_resource(dev, option_flags, min, max, align, len,
flags);
}
static __init void pnpbios_parse_mem32_option(struct pnp_dev *dev,
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)
return;
mem->min = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
mem->max = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
mem->align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12];
mem->size = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16];
mem->flags = p[3];
pnp_register_mem_resource(dev, option, mem);
min = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
max = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12];
len = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16];
flags = p[3];
pnp_register_mem_resource(dev, option_flags, min, max, align, len,
flags);
}
static __init void pnpbios_parse_fixed_mem32_option(struct pnp_dev *dev,
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)
return;
mem->min = mem->max = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
mem->size = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
mem->align = 0;
mem->flags = p[3];
pnp_register_mem_resource(dev, option, mem);
base = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
len = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
flags = p[3];
pnp_register_mem_resource(dev, option_flags, base, base, 0, len, flags);
}
static __init void pnpbios_parse_irq_option(struct pnp_dev *dev,
unsigned char *p, int size,
struct pnp_option *option)
unsigned int option_flags)
{
struct pnp_irq *irq;
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];
bitmap_copy(irq->map, &bits, 16);
bitmap_zero(map.bits, PNP_IRQ_NR);
bitmap_copy(map.bits, &bits, 16);
if (size > 2)
irq->flags = p[3];
else
irq->flags = IORESOURCE_IRQ_HIGHEDGE;
pnp_register_irq_resource(dev, option, irq);
flags = p[3];
pnp_register_irq_resource(dev, option_flags, &map, flags);
}
static __init void pnpbios_parse_dma_option(struct pnp_dev *dev,
unsigned char *p, int size,
struct pnp_option *option)
unsigned int option_flags)
{
struct pnp_dma *dma;
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);
pnp_register_dma_resource(dev, option_flags, p[1], p[2]);
}
static __init void pnpbios_parse_port_option(struct pnp_dev *dev,
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)
return;
port->min = (p[3] << 8) | p[2];
port->max = (p[5] << 8) | p[4];
port->align = p[6];
port->size = p[7];
port->flags = p[1] ? PNP_PORT_FLAG_16BITADDR : 0;
pnp_register_port_resource(dev, option, port);
min = (p[3] << 8) | p[2];
max = (p[5] << 8) | p[4];
align = p[6];
len = p[7];
flags = p[1] ? IORESOURCE_IO_16BIT_ADDR : 0;
pnp_register_port_resource(dev, option_flags, min, max, align, len,
flags);
}
static __init void pnpbios_parse_fixed_port_option(struct pnp_dev *dev,
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);
if (!port)
return;
port->min = port->max = (p[2] << 8) | p[1];
port->size = p[3];
port->align = 0;
port->flags = PNP_PORT_FLAG_FIXED;
pnp_register_port_resource(dev, option, port);
base = (p[2] << 8) | p[1];
len = p[3];
pnp_register_port_resource(dev, option_flags, base, base, 0, len,
IORESOURCE_IO_FIXED);
}
static __init unsigned char *
pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
struct pnp_dev *dev)
struct pnp_dev *dev)
{
unsigned int len, tag;
int priority = 0;
struct pnp_option *option, *option_independent;
int priority;
unsigned int option_flags;
if (!p)
return NULL;
dev_dbg(&dev->dev, "parse resource options\n");
option_independent = option = pnp_register_independent_option(dev);
if (!option)
return NULL;
option_flags = 0;
while ((char *)p < (char *)end) {
/* determine the type of tag */
@ -363,37 +342,38 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
case LARGE_TAG_MEM:
if (len != 9)
goto len_err;
pnpbios_parse_mem_option(dev, p, len, option);
pnpbios_parse_mem_option(dev, p, len, option_flags);
break;
case LARGE_TAG_MEM32:
if (len != 17)
goto len_err;
pnpbios_parse_mem32_option(dev, p, len, option);
pnpbios_parse_mem32_option(dev, p, len, option_flags);
break;
case LARGE_TAG_FIXEDMEM32:
if (len != 9)
goto len_err;
pnpbios_parse_fixed_mem32_option(dev, p, len, option);
pnpbios_parse_fixed_mem32_option(dev, p, len,
option_flags);
break;
case SMALL_TAG_IRQ:
if (len < 2 || len > 3)
goto len_err;
pnpbios_parse_irq_option(dev, p, len, option);
pnpbios_parse_irq_option(dev, p, len, option_flags);
break;
case SMALL_TAG_DMA:
if (len != 2)
goto len_err;
pnpbios_parse_dma_option(dev, p, len, option);
pnpbios_parse_dma_option(dev, p, len, option_flags);
break;
case SMALL_TAG_PORT:
if (len != 7)
goto len_err;
pnpbios_parse_port_option(dev, p, len, option);
pnpbios_parse_port_option(dev, p, len, option_flags);
break;
case SMALL_TAG_VENDOR:
@ -403,28 +383,23 @@ pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
case SMALL_TAG_FIXEDPORT:
if (len != 3)
goto len_err;
pnpbios_parse_fixed_port_option(dev, p, len, option);
pnpbios_parse_fixed_port_option(dev, p, len,
option_flags);
break;
case SMALL_TAG_STARTDEP:
if (len > 1)
goto len_err;
priority = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE;
priority = PNP_RES_PRIORITY_ACCEPTABLE;
if (len > 0)
priority = 0x100 | p[1];
option = pnp_register_dependent_option(dev, priority);
if (!option)
return NULL;
priority = p[1];
option_flags = pnp_new_dependent_set(dev, priority);
break;
case SMALL_TAG_ENDDEP:
if (len != 0)
goto len_err;
if (option_independent == option)
dev_warn(&dev->dev, "missing "
"SMALL_TAG_STARTDEP tag\n");
option = option_independent;
dev_dbg(&dev->dev, "end dependent options\n");
option_flags = 0;
break;
case SMALL_TAG_END:
@ -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,
struct resource *res)
{
unsigned long base = res->start;
unsigned long len = res->end - res->start + 1;
unsigned long base;
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[5] = ((base >> 8) >> 8) & 0xff;
@ -536,15 +519,22 @@ static void pnpbios_encode_mem(struct pnp_dev *dev, unsigned char *p,
p[10] = (len >> 8) & 0xff;
p[11] = ((len >> 8) >> 8) & 0xff;
dev_dbg(&dev->dev, " encode mem %#llx-%#llx\n",
(unsigned long long) res->start, (unsigned long long) res->end);
dev_dbg(&dev->dev, " encode mem %#lx-%#lx\n", base, base + len - 1);
}
static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p,
struct resource *res)
{
unsigned long base = res->start;
unsigned long len = res->end - res->start + 1;
unsigned long base;
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[5] = (base >> 8) & 0xff;
@ -559,15 +549,22 @@ static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p,
p[18] = (len >> 16) & 0xff;
p[19] = (len >> 24) & 0xff;
dev_dbg(&dev->dev, " encode mem32 %#llx-%#llx\n",
(unsigned long long) res->start, (unsigned long long) res->end);
dev_dbg(&dev->dev, " encode mem32 %#lx-%#lx\n", base, base + len - 1);
}
static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p,
struct resource *res)
{
unsigned long base = res->start;
unsigned long len = res->end - res->start + 1;
unsigned long base;
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[5] = (base >> 8) & 0xff;
@ -578,40 +575,54 @@ static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p,
p[10] = (len >> 16) & 0xff;
p[11] = (len >> 24) & 0xff;
dev_dbg(&dev->dev, " encode fixed_mem32 %#llx-%#llx\n",
(unsigned long long) res->start, (unsigned long long) res->end);
dev_dbg(&dev->dev, " encode fixed_mem32 %#lx-%#lx\n", base,
base + len - 1);
}
static void pnpbios_encode_irq(struct pnp_dev *dev, unsigned char *p,
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[2] = (map >> 8) & 0xff;
dev_dbg(&dev->dev, " encode irq %llu\n",
(unsigned long long)res->start);
dev_dbg(&dev->dev, " encode irq mask %#lx\n", map);
}
static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p,
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;
dev_dbg(&dev->dev, " encode dma %llu\n",
(unsigned long long)res->start);
dev_dbg(&dev->dev, " encode dma mask %#lx\n", map);
}
static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p,
struct resource *res)
{
unsigned long base = res->start;
unsigned long len = res->end - res->start + 1;
unsigned long base;
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[3] = (base >> 8) & 0xff;
@ -619,8 +630,7 @@ static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p,
p[5] = (base >> 8) & 0xff;
p[7] = len & 0xff;
dev_dbg(&dev->dev, " encode io %#llx-%#llx\n",
(unsigned long long) res->start, (unsigned long long) res->end);
dev_dbg(&dev->dev, " encode io %#lx-%#lx\n", base, base + len - 1);
}
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 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[2] = (base >> 8) & 0xff;
p[3] = len & 0xff;
dev_dbg(&dev->dev, " encode fixed_io %#llx-%#llx\n",
(unsigned long long) res->start, (unsigned long long) res->end);
dev_dbg(&dev->dev, " encode fixed_io %#lx-%#lx\n", base,
base + len - 1);
}
static unsigned char *pnpbios_encode_allocated_resource_data(struct pnp_dev

View File

@ -5,6 +5,8 @@
* when building up the resource structure for the first time.
*
* 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
*
@ -20,203 +22,207 @@
#include <linux/kallsyms.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)
{
struct pnp_port *port, *port2, *port3;
struct pnp_option *res = dev->dependent;
struct pnp_option *option;
unsigned int set = ~0;
/*
* Unfortunately the isapnp_add_port_resource is too tightly bound
* into the PnP discovery sequence, and cannot be used. Link in the
* two extra ports (at offset 0x400 and 0x800 from the one given) by
* hand.
* Add two extra ioport regions (at offset 0x400 and 0x800 from the
* one given) to every dependent option set.
*/
for (; res; res = res->next) {
port2 = pnp_alloc(sizeof(struct pnp_port));
if (!port2)
return;
port3 = pnp_alloc(sizeof(struct pnp_port));
if (!port3) {
kfree(port2);
return;
list_for_each_entry(option, &dev->options, list) {
if (pnp_option_is_dependent(option) &&
pnp_option_set(option) != set) {
set = pnp_option_set(option);
quirk_awe32_add_ports(dev, option, 0x800);
quirk_awe32_add_ports(dev, option, 0x400);
}
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)
{
struct pnp_option *res = dev->dependent;
unsigned long tmp;
struct pnp_option *option;
struct pnp_irq *irq;
struct pnp_dma *dma;
for (; res; res = res->next) {
list_for_each_entry(option, &dev->options, list) {
if (!pnp_option_is_dependent(option))
continue;
struct pnp_irq *irq;
struct pnp_dma *dma;
for (irq = res->irq; irq; irq = irq->next) { // Valid irqs are 5, 7, 10
tmp = 0x04A0;
bitmap_copy(irq->map, &tmp, 16); // 0000 0100 1010 0000
}
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) ==
IORESOURCE_DMA_8BIT)
dma->map = 0x000A;
IORESOURCE_DMA_8BIT &&
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)
{
struct pnp_option *option;
unsigned int prev_option_flags = ~0, n = 0;
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
* 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) {
port = res->port;
if (!port)
continue;
port = port->next;
if (!port)
continue;
port = port->next;
if (!port)
continue;
if (port->min != port->max)
continue;
port->max += 0x70;
changed = 1;
if (pnp_option_is_dependent(option) &&
option->type == IORESOURCE_IO) {
n++;
port = &option->u.port;
if (n == 3 && port->min == port->max) {
port->max += 0x70;
dev_info(&dev->dev, "increased option port "
"range from %#llx-%#llx to "
"%#llx-%#llx\n",
(unsigned long long) port->min,
(unsigned long long) port->min,
(unsigned long long) port->min,
(unsigned long long) port->max);
}
}
}
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 *prev = NULL;
struct pnp_option *res;
struct pnp_option *tail = NULL, *first_new_option = NULL;
struct pnp_option *option, *new_option;
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;
if (!port || !res->irq)
continue;
copy = pnp_alloc(sizeof *copy);
if (!copy)
break;
copy->min = port->min;
copy->max = port->max;
copy->align = port->align;
copy->size = port->size;
copy->flags = port->flags;
curr = pnp_build_option(PNP_RES_PRIORITY_FUNCTIONAL);
if (!curr) {
kfree(copy);
break;
}
curr->port = copy;
if (prev)
prev->next = curr;
else
head = curr;
prev = curr;
list_for_each_entry(option, &dev->options, list) {
if (pnp_option_is_dependent(option))
tail = option;
}
if (!tail) {
dev_err(&dev->dev, "no dependent option sets\n");
return NULL;
}
if (head)
dev_info(&dev->dev, "adding IRQ-less MPU options\n");
return head;
flags = pnp_new_dependent_set(dev, PNP_RES_PRIORITY_FUNCTIONAL);
list_for_each_entry(option, &dev->options, list) {
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;
}
*new_option = *option;
new_option->flags = flags;
if (!first_new_option)
first_new_option = new_option;
list_add(&new_option->list, &tail->list);
tail = new_option;
}
}
return first_new_option;
}
static void quirk_add_irq_optional_dependent_sets(struct pnp_dev *dev)
{
struct pnp_option *new_option;
unsigned int num_sets, i, set;
struct pnp_irq *irq;
num_sets = dev->num_dependent_sets;
for (i = 0; i < num_sets; i++) {
new_option = pnp_clone_dependent_set(dev, i);
if (!new_option)
return;
set = pnp_option_set(new_option);
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);
}
dev_info(&dev->dev, "added dependent option set %d (same as "
"set %d except IRQ optional)\n", set, i);
}
}
static void quirk_ad1815_mpu_resources(struct pnp_dev *dev)
{
struct pnp_option *res;
struct pnp_irq *irq;
struct pnp_option *option;
struct pnp_irq *irq = NULL;
unsigned int independent_irqs = 0;
/*
* Distribute the independent IRQ over the dependent options
*/
res = dev->independent;
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 */
res->irq = copy;
if (!res->next)
break;
res = res->next;
list_for_each_entry(option, &dev->options, list) {
if (option->type == IORESOURCE_IRQ &&
!pnp_option_is_dependent(option)) {
independent_irqs++;
irq = &option->u.irq;
}
}
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)
{
struct pnp_option *res;
res = dev->dependent;
if (!res)
if (independent_irqs != 1)
return;
while (res->next)
res = res->next;
res->next = quirk_isapnp_mpu_options(dev);
irq->flags |= IORESOURCE_IRQ_OPTIONAL;
dev_info(&dev->dev, "made independent IRQ optional\n");
}
#include <linux/pci.h>
@ -248,8 +254,7 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
for (j = 0;
(res = pnp_get_resource(dev, IORESOURCE_MEM, j));
j++) {
if (res->flags & IORESOURCE_UNSET ||
(res->start == 0 && res->end == 0))
if (res->start == 0 && res->end == 0)
continue;
pnp_start = res->start;
@ -312,10 +317,10 @@ static struct pnp_fixup pnp_fixups[] = {
{"CTL0043", quirk_sb16audio_resources},
{"CTL0044", quirk_sb16audio_resources},
{"CTL0045", quirk_sb16audio_resources},
/* Add IRQ-less MPU options */
/* Add IRQ-optional MPU options */
{"ADS7151", quirk_ad1815_mpu_resources},
{"ADS7181", quirk_isapnp_mpu_resources},
{"AZT0002", quirk_isapnp_mpu_resources},
{"ADS7181", quirk_add_irq_optional_dependent_sets},
{"AZT0002", quirk_add_irq_optional_dependent_sets},
/* PnP resources that might overlap PCI BARs */
{"PNP0c01", quirk_system_pci_resources},
{"PNP0c02", quirk_system_pci_resources},

View File

@ -3,6 +3,8 @@
*
* based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz>
* 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>
@ -28,201 +30,121 @@ static int pnp_reserve_mem[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some
* 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)
return NULL;
option->priority = priority & 0xff;
/* make sure the priority is valid */
if (option->priority > PNP_RES_PRIORITY_FUNCTIONAL)
option->priority = PNP_RES_PRIORITY_INVALID;
option->flags = option_flags;
option->type = type;
list_add_tail(&option->list, &dev->options);
return option;
}
struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev)
int pnp_register_irq_resource(struct pnp_dev *dev, unsigned int option_flags,
pnp_irq_mask_t *map, unsigned char flags)
{
struct pnp_option *option;
struct pnp_irq *irq;
option = pnp_build_option(PNP_RES_PRIORITY_PREFERRED);
option = pnp_build_option(dev, IORESOURCE_IRQ, option_flags);
if (!option)
return -ENOMEM;
/* 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");
return option;
}
struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev,
int priority)
{
struct pnp_option *option;
option = pnp_build_option(priority);
if (dev->dependent) {
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;
while (ptr && ptr->next)
ptr = ptr->next;
if (ptr)
ptr->next = data;
else
option->irq = data;
irq = &option->u.irq;
irq->map = *map;
irq->flags = flags;
#ifdef CONFIG_PCI
{
int 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);
}
#endif
#ifdef DEBUG
bitmap_scnprintf(buf, sizeof(buf), data->map, PNP_IRQ_NR);
dev_dbg(&dev->dev, " irq bitmask %s flags %#x\n", buf,
data->flags);
#endif
dbg_pnp_show_option(dev, option);
return 0;
}
int pnp_register_dma_resource(struct pnp_dev *dev, struct pnp_option *option,
struct pnp_dma *data)
int pnp_register_dma_resource(struct pnp_dev *dev, unsigned int option_flags,
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;
option = pnp_build_option(dev, IORESOURCE_DMA, option_flags);
if (!option)
return -ENOMEM;
dev_dbg(&dev->dev, " dma bitmask %#x flags %#x\n", data->map,
data->flags);
dma = &option->u.dma;
dma->map = map;
dma->flags = flags;
dbg_pnp_show_option(dev, option);
return 0;
}
int pnp_register_port_resource(struct pnp_dev *dev, struct pnp_option *option,
struct pnp_port *data)
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 *ptr;
struct pnp_option *option;
struct pnp_port *port;
ptr = option->port;
while (ptr && ptr->next)
ptr = ptr->next;
if (ptr)
ptr->next = data;
else
option->port = data;
option = pnp_build_option(dev, IORESOURCE_IO, option_flags);
if (!option)
return -ENOMEM;
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);
port = &option->u.port;
port->min = min;
port->max = max;
port->align = align;
port->size = size;
port->flags = flags;
dbg_pnp_show_option(dev, option);
return 0;
}
int pnp_register_mem_resource(struct pnp_dev *dev, struct pnp_option *option,
struct pnp_mem *data)
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_mem *ptr;
struct pnp_option *option;
struct pnp_mem *mem;
ptr = option->mem;
while (ptr && ptr->next)
ptr = ptr->next;
if (ptr)
ptr->next = data;
else
option->mem = data;
option = pnp_build_option(dev, IORESOURCE_MEM, option_flags);
if (!option)
return -ENOMEM;
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);
mem = &option->u.mem;
mem->min = min;
mem->max = max;
mem->align = align;
mem->size = size;
mem->flags = flags;
dbg_pnp_show_option(dev, option);
return 0;
}
static void pnp_free_port(struct pnp_port *port)
void pnp_free_options(struct pnp_dev *dev)
{
struct pnp_port *next;
struct pnp_option *option, *tmp;
while (port) {
next = port->next;
kfree(port);
port = next;
}
}
static void pnp_free_irq(struct pnp_irq *irq)
{
struct pnp_irq *next;
while (irq) {
next = irq->next;
kfree(irq);
irq = next;
}
}
static void pnp_free_dma(struct pnp_dma *dma)
{
struct pnp_dma *next;
while (dma) {
next = dma->next;
kfree(dma);
dma = next;
}
}
static void pnp_free_mem(struct pnp_mem *mem)
{
struct pnp_mem *next;
while (mem) {
next = mem->next;
kfree(mem);
mem = next;
}
}
void pnp_free_option(struct pnp_option *option)
{
struct pnp_option *next;
while (option) {
next = option->next;
pnp_free_port(option->port);
pnp_free_irq(option->irq);
pnp_free_dma(option->dma);
pnp_free_mem(option->mem);
list_for_each_entry_safe(option, tmp, &dev->options, list) {
list_del(&option->list);
kfree(option);
option = next;
}
}
@ -237,7 +159,7 @@ void pnp_free_option(struct pnp_option *option)
!((*(enda) < *(startb)) || (*(endb) < *(starta)))
#define cannot_compare(flags) \
((flags) & (IORESOURCE_UNSET | IORESOURCE_DISABLED))
((flags) & IORESOURCE_DISABLED)
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)
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 i;
@ -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 */
{
struct pci_dev *pci = NULL;
for_each_pci_dev(pci) {
if (pci->irq == *irq) {
pci_dev_put(pci);
return 0;
}
}
}
#endif
if (pci_uses_irq(dev, *irq))
return 0;
/* check if the resource is already in use, skip if the
* 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)
#endif
}
struct pnp_resource *pnp_get_pnp_resource(struct pnp_dev *dev,
unsigned int type, unsigned int num)
int pnp_resource_type(struct resource *res)
{
struct pnp_resource_table *res = dev->res;
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;
return res->flags & (IORESOURCE_IO | IORESOURCE_MEM |
IORESOURCE_IRQ | IORESOURCE_DMA);
}
struct resource *pnp_get_resource(struct pnp_dev *dev,
unsigned int type, unsigned int num)
{
struct pnp_resource *pnp_res;
struct resource *res;
pnp_res = pnp_get_pnp_resource(dev, type, num);
if (pnp_res)
return &pnp_res->res;
list_for_each_entry(pnp_res, &dev->resources, list) {
res = &pnp_res->res;
if (pnp_resource_type(res) == type && num-- == 0)
return res;
}
return NULL;
}
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;
int i;
switch (type) {
case IORESOURCE_IO:
for (i = 0; i < PNP_MAX_PORT; i++) {
pnp_res = pnp_get_pnp_resource(dev, IORESOURCE_IO, i);
if (pnp_res && !pnp_resource_valid(&pnp_res->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;
pnp_res = kzalloc(sizeof(struct pnp_resource), GFP_KERNEL);
if (!pnp_res)
return NULL;
list_add_tail(&pnp_res->list, &dev->resources);
return pnp_res;
}
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 resource *res;
static unsigned char warned;
pnp_res = pnp_new_resource(dev, IORESOURCE_IRQ);
pnp_res = pnp_new_resource(dev);
if (!pnp_res) {
if (!warned) {
dev_err(&dev->dev, "can't add resource for IRQ %d\n",
irq);
warned = 1;
}
dev_err(&dev->dev, "can't add resource for IRQ %d\n", irq);
return NULL;
}
@ -607,15 +526,10 @@ struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma,
{
struct pnp_resource *pnp_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 (!warned) {
dev_err(&dev->dev, "can't add resource for DMA %d\n",
dma);
warned = 1;
}
dev_err(&dev->dev, "can't add resource for DMA %d\n", dma);
return NULL;
}
@ -634,16 +548,12 @@ struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev,
{
struct pnp_resource *pnp_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 (!warned) {
dev_err(&dev->dev, "can't add resource for IO "
"%#llx-%#llx\n",(unsigned long long) start,
(unsigned long long) end);
warned = 1;
}
dev_err(&dev->dev, "can't add resource for IO %#llx-%#llx\n",
(unsigned long long) start,
(unsigned long long) end);
return NULL;
}
@ -663,16 +573,12 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
{
struct pnp_resource *pnp_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 (!warned) {
dev_err(&dev->dev, "can't add resource for MEM "
"%#llx-%#llx\n",(unsigned long long) start,
(unsigned long long) end);
warned = 1;
}
dev_err(&dev->dev, "can't add resource for MEM %#llx-%#llx\n",
(unsigned long long) start,
(unsigned long long) end);
return NULL;
}
@ -686,6 +592,52 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
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] .... */
static int __init pnp_setup_reserve_irq(char *str)
{

View File

@ -2,6 +2,8 @@
* support.c - standard functions for the use of pnp protocol drivers
*
* 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>
@ -16,6 +18,10 @@
*/
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 &&
!pnp_mem_start(dev, 0) && pnp_mem_len(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)
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)
{
#ifdef DEBUG
char buf[128];
int len = 0;
struct pnp_resource *pnp_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);
return;
}
for (i = 0; i < PNP_MAX_IRQ; i++) {
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);
if (res && !(res->flags & IORESOURCE_UNSET))
dev_dbg(&dev->dev, " dma %lld flags %#lx\n",
(unsigned long long) res->start, res->flags);
}
for (i = 0; i < PNP_MAX_PORT; i++) {
res = pnp_get_resource(dev, IORESOURCE_IO, i);
if (res && !(res->flags & IORESOURCE_UNSET))
dev_dbg(&dev->dev, " io %#llx-%#llx flags %#lx\n",
(unsigned long long) res->start,
(unsigned long long) res->end, res->flags);
}
for (i = 0; i < PNP_MAX_MEM; i++) {
res = pnp_get_resource(dev, IORESOURCE_MEM, i);
if (res && !(res->flags & IORESOURCE_UNSET))
dev_dbg(&dev->dev, " mem %#llx-%#llx flags %#lx\n",
(unsigned long long) res->start,
(unsigned long long) res->end, res->flags);
dev_dbg(&dev->dev, "%s: current resources:\n", desc);
list_for_each_entry(pnp_res, &dev->resources, list) {
res = &pnp_res->res;
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);
}
#endif
}
char *pnp_option_priority_name(struct pnp_option *option)
{
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";
}
return "invalid";
}
void dbg_pnp_show_option(struct pnp_dev *dev, struct pnp_option *option)
{
#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
}

View File

@ -60,7 +60,7 @@ static void reserve_resources_of_dev(struct pnp_dev *dev)
int i;
for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) {
if (res->flags & IORESOURCE_UNSET)
if (res->flags & IORESOURCE_DISABLED)
continue;
if (res->start == 0)
continue; /* disabled */
@ -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++) {
if (res->flags & (IORESOURCE_UNSET | IORESOURCE_DISABLED))
if (res->flags & IORESOURCE_DISABLED)
continue;
reserve_range(dev, res->start, res->end, 0);

View File

@ -383,21 +383,14 @@ static int __devinit check_name(char *name)
return 0;
}
static int __devinit check_resources(struct pnp_option *option)
static int __devinit check_resources(struct pnp_dev *dev)
{
struct pnp_option *tmp;
if (!option)
return 0;
resource_size_t base[] = {0x2f8, 0x3f8, 0x2e8, 0x3e8};
int i;
for (tmp = option; tmp; tmp = tmp->next) {
struct pnp_port *port;
for (port = tmp->port; port; port = port->next)
if ((port->size == 8) &&
((port->min == 0x2f8) ||
(port->min == 0x3f8) ||
(port->min == 0x2e8) ||
(port->min == 0x3e8)))
return 1;
for (i = 0; i < ARRAY_SIZE(base); i++) {
if (pnp_possible_config(dev, IORESOURCE_IO, base[i], 8))
return 1;
}
return 0;
@ -420,10 +413,7 @@ static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags)
(dev->card && check_name(dev->card->name))))
return -ENODEV;
if (check_resources(dev->independent))
return 0;
if (check_resources(dev->dependent))
if (check_resources(dev))
return 0;
return -ENODEV;

View File

@ -63,7 +63,7 @@
/* 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,

View File

@ -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_dmar0[];
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_einj[];
extern struct acpi_dmtable_info acpi_dm_table_info_einj0[];

Some files were not shown because too many files have changed in this diff Show More