diff options
Diffstat (limited to 'drivers')
287 files changed, 3089 insertions, 2559 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 4770de5707b9..c205653e9644 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -43,19 +43,6 @@ config ACPI_SLEEP depends on SUSPEND || HIBERNATION default y -config ACPI_PROCFS - bool "Deprecated /proc/acpi files" - depends on PROC_FS - help - For backwards compatibility, this option allows - deprecated /proc/acpi/ files to exist, even when - they have been replaced by functions in /sys. - - This option has no effect on /proc/acpi/ files - and functions which do not yet exist in /sys. - - Say N to delete /proc/acpi/ files that have moved to /sys/ - config ACPI_EC_DEBUGFS tristate "EC read/write access through /sys/kernel/debug/ec" default n @@ -115,7 +102,7 @@ config ACPI_BUTTON config ACPI_VIDEO tristate "Video" - depends on X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL + depends on X86 && BACKLIGHT_CLASS_DEVICE depends on INPUT select THERMAL help @@ -343,6 +330,19 @@ config ACPI_BGRT data from the firmware boot splash. It will appear under /sys/firmware/acpi/bgrt/ . +config ACPI_REDUCED_HARDWARE_ONLY + bool "Hardware-reduced ACPI support only" if EXPERT + def_bool n + depends on ACPI + help + This config item changes the way the ACPI code is built. When this + option is selected, the kernel will use a specialized version of + ACPICA that ONLY supports the ACPI "reduced hardware" mode. The + resulting kernel will be smaller but it will also be restricted to + running in ACPI reduced hardware mode ONLY. + + If you are unsure what to do, do not enable this option. + source "drivers/acpi/apei/Kconfig" config ACPI_EXTLOG diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 6f190bc2b8b7..2c01c1da29ce 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -33,6 +33,7 @@ #include <linux/platform_device.h> #include <linux/power_supply.h> #include <linux/acpi.h> +#include "battery.h" #define PREFIX "ACPI: " @@ -57,6 +58,7 @@ struct acpi_ac { struct power_supply charger; struct platform_device *pdev; unsigned long long state; + struct notifier_block battery_nb; }; #define to_acpi_ac(x) container_of(x, struct acpi_ac, charger) @@ -152,6 +154,26 @@ static void acpi_ac_notify_handler(acpi_handle handle, u32 event, void *data) return; } +static int acpi_ac_battery_notify(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct acpi_ac *ac = container_of(nb, struct acpi_ac, battery_nb); + struct acpi_bus_event *event = (struct acpi_bus_event *)data; + + /* + * On HP Pavilion dv6-6179er AC status notifications aren't triggered + * when adapter is plugged/unplugged. However, battery status + * notifcations are triggered when battery starts charging or + * discharging. Re-reading AC status triggers lost AC notifications, + * if AC status has changed. + */ + if (strcmp(event->device_class, ACPI_BATTERY_CLASS) == 0 && + event->type == ACPI_BATTERY_NOTIFY_STATUS) + acpi_ac_get_state(ac); + + return NOTIFY_OK; +} + static int thinkpad_e530_quirk(const struct dmi_system_id *d) { ac_sleep_before_get_state_ms = 1000; @@ -215,6 +237,8 @@ static int acpi_ac_probe(struct platform_device *pdev) acpi_device_name(adev), acpi_device_bid(adev), ac->state ? "on-line" : "off-line"); + ac->battery_nb.notifier_call = acpi_ac_battery_notify; + register_acpi_notifier(&ac->battery_nb); end: if (result) kfree(ac); @@ -261,6 +285,7 @@ static int acpi_ac_remove(struct platform_device *pdev) ac = platform_get_drvdata(pdev); if (ac->charger.dev) power_supply_unregister(&ac->charger); + unregister_acpi_notifier(&ac->battery_nb); kfree(ac); diff --git a/drivers/acpi/acpi_cmos_rtc.c b/drivers/acpi/acpi_cmos_rtc.c index 84190ed89c04..961b45d18a5d 100644 --- a/drivers/acpi/acpi_cmos_rtc.c +++ b/drivers/acpi/acpi_cmos_rtc.c @@ -18,8 +18,6 @@ #include "internal.h" -#define PREFIX "ACPI: " - ACPI_MODULE_NAME("cmos rtc"); static const struct acpi_device_id acpi_cmos_rtc_ids[] = { diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index 6745fe137b9e..69e29f409d4c 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -33,6 +33,13 @@ ACPI_MODULE_NAME("acpi_lpss"); #define LPSS_GENERAL_UART_RTS_OVRD BIT(3) #define LPSS_SW_LTR 0x10 #define LPSS_AUTO_LTR 0x14 +#define LPSS_LTR_SNOOP_REQ BIT(15) +#define LPSS_LTR_SNOOP_MASK 0x0000FFFF +#define LPSS_LTR_SNOOP_LAT_1US 0x800 +#define LPSS_LTR_SNOOP_LAT_32US 0xC00 +#define LPSS_LTR_SNOOP_LAT_SHIFT 5 +#define LPSS_LTR_SNOOP_LAT_CUTOFF 3000 +#define LPSS_LTR_MAX_VAL 0x3FF #define LPSS_TX_INT 0x20 #define LPSS_TX_INT_MASK BIT(1) @@ -102,6 +109,16 @@ static struct lpss_device_desc lpt_sdio_dev_desc = { .ltr_required = true, }; +static struct lpss_shared_clock pwm_clock = { + .name = "pwm_clk", + .rate = 25000000, +}; + +static struct lpss_device_desc byt_pwm_dev_desc = { + .clk_required = true, + .shared_clock = &pwm_clock, +}; + static struct lpss_shared_clock uart_clock = { .name = "uart_clk", .rate = 44236800, @@ -157,6 +174,7 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = { { "INT33C7", }, /* BayTrail LPSS devices */ + { "80860F09", (unsigned long)&byt_pwm_dev_desc }, { "80860F0A", (unsigned long)&byt_uart_dev_desc }, { "80860F0E", (unsigned long)&byt_spi_dev_desc }, { "80860F14", (unsigned long)&byt_sdio_dev_desc }, @@ -315,6 +333,17 @@ static int acpi_lpss_create_device(struct acpi_device *adev, return ret; } +static u32 __lpss_reg_read(struct lpss_private_data *pdata, unsigned int reg) +{ + return readl(pdata->mmio_base + pdata->dev_desc->prv_offset + reg); +} + +static void __lpss_reg_write(u32 val, struct lpss_private_data *pdata, + unsigned int reg) +{ + writel(val, pdata->mmio_base + pdata->dev_desc->prv_offset + reg); +} + static int lpss_reg_read(struct device *dev, unsigned int reg, u32 *val) { struct acpi_device *adev; @@ -336,7 +365,7 @@ static int lpss_reg_read(struct device *dev, unsigned int reg, u32 *val) ret = -ENODEV; goto out; } - *val = readl(pdata->mmio_base + pdata->dev_desc->prv_offset + reg); + *val = __lpss_reg_read(pdata, reg); out: spin_unlock_irqrestore(&dev->power.lock, flags); @@ -389,6 +418,37 @@ static struct attribute_group lpss_attr_group = { .name = "lpss_ltr", }; +static void acpi_lpss_set_ltr(struct device *dev, s32 val) +{ + struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); + u32 ltr_mode, ltr_val; + + ltr_mode = __lpss_reg_read(pdata, LPSS_GENERAL); + if (val < 0) { + if (ltr_mode & LPSS_GENERAL_LTR_MODE_SW) { + ltr_mode &= ~LPSS_GENERAL_LTR_MODE_SW; + __lpss_reg_write(ltr_mode, pdata, LPSS_GENERAL); + } + return; + } + ltr_val = __lpss_reg_read(pdata, LPSS_SW_LTR) & ~LPSS_LTR_SNOOP_MASK; + if (val >= LPSS_LTR_SNOOP_LAT_CUTOFF) { + ltr_val |= LPSS_LTR_SNOOP_LAT_32US; + val = LPSS_LTR_MAX_VAL; + } else if (val > LPSS_LTR_MAX_VAL) { + ltr_val |= LPSS_LTR_SNOOP_LAT_32US | LPSS_LTR_SNOOP_REQ; + val >>= LPSS_LTR_SNOOP_LAT_SHIFT; + } else { + ltr_val |= LPSS_LTR_SNOOP_LAT_1US | LPSS_LTR_SNOOP_REQ; + } + ltr_val |= val; + __lpss_reg_write(ltr_val, pdata, LPSS_SW_LTR); + if (!(ltr_mode & LPSS_GENERAL_LTR_MODE_SW)) { + ltr_mode |= LPSS_GENERAL_LTR_MODE_SW; + __lpss_reg_write(ltr_mode, pdata, LPSS_GENERAL); + } +} + static int acpi_lpss_platform_notify(struct notifier_block *nb, unsigned long action, void *data) { @@ -426,9 +486,29 @@ static struct notifier_block acpi_lpss_nb = { .notifier_call = acpi_lpss_platform_notify, }; +static void acpi_lpss_bind(struct device *dev) +{ + struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); + + if (!pdata || !pdata->mmio_base || !pdata->dev_desc->ltr_required) + return; + + if (pdata->mmio_size >= pdata->dev_desc->prv_offset + LPSS_LTR_SIZE) + dev->power.set_latency_tolerance = acpi_lpss_set_ltr; + else + dev_err(dev, "MMIO size insufficient to access LTR\n"); +} + +static void acpi_lpss_unbind(struct device *dev) +{ + dev->power.set_latency_tolerance = NULL; +} + static struct acpi_scan_handler lpss_handler = { .ids = acpi_lpss_device_ids, .attach = acpi_lpss_create_device, + .bind = acpi_lpss_bind, + .unbind = acpi_lpss_unbind, }; void __init acpi_lpss_init(void) diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index df96a0fe4890..37d73024b82e 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -408,28 +408,14 @@ static int acpi_pad_pur(acpi_handle handle) return num; } -/* Notify firmware how many CPUs are idle */ -static void acpi_pad_ost(acpi_handle handle, int stat, - uint32_t idle_cpus) -{ - union acpi_object params[3] = { - {.type = ACPI_TYPE_INTEGER,}, - {.type = ACPI_TYPE_INTEGER,}, - {.type = ACPI_TYPE_BUFFER,}, - }; - struct acpi_object_list arg_list = {3, params}; - - params[0].integer.value = ACPI_PROCESSOR_AGGREGATOR_NOTIFY; - params[1].integer.value = stat; - params[2].buffer.length = 4; - params[2].buffer.pointer = (void *)&idle_cpus; - acpi_evaluate_object(handle, "_OST", &arg_list, NULL); -} - static void acpi_pad_handle_notify(acpi_handle handle) { int num_cpus; uint32_t idle_cpus; + struct acpi_buffer param = { + .length = 4, + .pointer = (void *)&idle_cpus, + }; mutex_lock(&isolated_cpus_lock); num_cpus = acpi_pad_pur(handle); @@ -439,7 +425,7 @@ static void acpi_pad_handle_notify(acpi_handle handle) } acpi_pad_idle_cpus(num_cpus); idle_cpus = acpi_pad_idle_cpus_num(); - acpi_pad_ost(handle, 0, idle_cpus); + acpi_evaluate_ost(handle, ACPI_PROCESSOR_AGGREGATOR_NOTIFY, 0, ¶m); mutex_unlock(&isolated_cpus_lock); } diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index 438304086ff1..b7ed86a20427 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile @@ -122,6 +122,8 @@ acpi-y += \ rsaddr.o \ rscalc.o \ rscreate.o \ + rsdump.o \ + rsdumpinfo.o \ rsinfo.o \ rsio.o \ rsirq.o \ @@ -132,8 +134,6 @@ acpi-y += \ rsutils.o \ rsxface.o -acpi-$(ACPI_FUTURE_USAGE) += rsdump.o rsdumpinfo.o - acpi-y += \ tbfadt.o \ tbfind.o \ diff --git a/drivers/acpi/acpica/accommon.h b/drivers/acpi/acpica/accommon.h index 8a6c4a0d22db..6f1c616910ac 100644 --- a/drivers/acpi/acpica/accommon.h +++ b/drivers/acpi/acpica/accommon.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index 2bf3ca2b8a7a..68a91eb0fa48 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -115,6 +115,8 @@ ACPI_HW_DEPENDENT_RETURN_VOID(void char *block_arg)) ACPI_HW_DEPENDENT_RETURN_VOID(void acpi_db_generate_sci(void)) +void acpi_db_execute_test(char *type_arg); + /* * dbconvert - miscellaneous conversion routines */ diff --git a/drivers/acpi/acpica/acdispat.h b/drivers/acpi/acpica/acdispat.h index 427db72a6302..d3e2cc395d7f 100644 --- a/drivers/acpi/acpica/acdispat.h +++ b/drivers/acpi/acpica/acdispat.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -139,20 +139,21 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, struct acpi_walk_state *walk_state); /* - * dsload - Parser/Interpreter interface, pass 1 namespace load callbacks + * dsload - Parser/Interpreter interface */ acpi_status acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number); +/* dsload - pass 1 namespace load callbacks */ + acpi_status acpi_ds_load1_begin_op(struct acpi_walk_state *walk_state, union acpi_parse_object **out_op); acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state); -/* - * dsload - Parser/Interpreter interface, pass 2 namespace load callbacks - */ +/* dsload - pass 2 namespace load callbacks */ + acpi_status acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, union acpi_parse_object **out_op); @@ -200,7 +201,9 @@ void acpi_ds_method_data_init(struct acpi_walk_state *walk_state); /* * dsmethod - Parser/Interpreter interface - control method parsing */ -acpi_status acpi_ds_parse_method(struct acpi_namespace_node *node); +acpi_status +acpi_ds_auto_serialize_method(struct acpi_namespace_node *node, + union acpi_operand_object *obj_desc); acpi_status acpi_ds_call_control_method(struct acpi_thread_state *thread, diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 0fb0adf435d6..68ec61fff188 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 4ed1aa384df2..49bbc71fad54 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -51,11 +51,19 @@ * to simplify maintenance of the code. */ #ifdef DEFINE_ACPI_GLOBALS -#define ACPI_EXTERN -#define ACPI_INIT_GLOBAL(a,b) a=b +#define ACPI_GLOBAL(type,name) \ + extern type name; \ + type name + +#define ACPI_INIT_GLOBAL(type,name,value) \ + type name=value + #else -#define ACPI_EXTERN extern -#define ACPI_INIT_GLOBAL(a,b) a +#define ACPI_GLOBAL(type,name) \ + extern type name + +#define ACPI_INIT_GLOBAL(type,name,value) \ + extern type name #endif #ifdef DEFINE_ACPI_GLOBALS @@ -82,33 +90,34 @@ * 5) Allow unresolved references (invalid target name) in package objects * 6) Enable warning messages for behavior that is not ACPI spec compliant */ -u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_interpreter_slack, FALSE); +ACPI_INIT_GLOBAL(u8, acpi_gbl_enable_interpreter_slack, FALSE); /* - * Automatically serialize ALL control methods? Default is FALSE, meaning - * to use the Serialized/not_serialized method flags on a per method basis. - * Only change this if the ASL code is poorly written and cannot handle - * reentrancy even though methods are marked "NotSerialized". + * Automatically serialize all methods that create named objects? Default + * is TRUE, meaning that all non_serialized methods are scanned once at + * table load time to determine those that create named objects. Methods + * that create named objects are marked Serialized in order to prevent + * possible run-time problems if they are entered by more than one thread. */ -u8 ACPI_INIT_GLOBAL(acpi_gbl_all_methods_serialized, FALSE); +ACPI_INIT_GLOBAL(u8, acpi_gbl_auto_serialize_methods, TRUE); /* * Create the predefined _OSI method in the namespace? Default is TRUE * because ACPI CA is fully compatible with other ACPI implementations. * Changing this will revert ACPI CA (and machine ASL) to pre-OSI behavior. */ -u8 ACPI_INIT_GLOBAL(acpi_gbl_create_osi_method, TRUE); +ACPI_INIT_GLOBAL(u8, acpi_gbl_create_osi_method, TRUE); /* * Optionally use default values for the ACPI register widths. Set this to * TRUE to use the defaults, if an FADT contains incorrect widths/lengths. */ -u8 ACPI_INIT_GLOBAL(acpi_gbl_use_default_register_widths, TRUE); +ACPI_INIT_GLOBAL(u8, acpi_gbl_use_default_register_widths, TRUE); /* * Optionally enable output from the AML Debug Object. */ -u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_aml_debug_object, FALSE); +ACPI_INIT_GLOBAL(u8, acpi_gbl_enable_aml_debug_object, FALSE); /* * Optionally copy the entire DSDT to local memory (instead of simply @@ -116,7 +125,7 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_aml_debug_object, FALSE); * DSDT, creating the need for this option. Default is FALSE, do not copy * the DSDT. */ -u8 ACPI_INIT_GLOBAL(acpi_gbl_copy_dsdt_locally, FALSE); +ACPI_INIT_GLOBAL(u8, acpi_gbl_copy_dsdt_locally, FALSE); /* * Optionally ignore an XSDT if present and use the RSDT instead. @@ -124,7 +133,7 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_copy_dsdt_locally, FALSE); * of the RSDT, the XSDT has been found to be corrupt or ill-formed on * some machines. Default behavior is to use the XSDT if present. */ -u8 ACPI_INIT_GLOBAL(acpi_gbl_do_not_use_xsdt, FALSE); +ACPI_INIT_GLOBAL(u8, acpi_gbl_do_not_use_xsdt, FALSE); /* * Optionally use 32-bit FADT addresses if and when there is a conflict @@ -134,7 +143,7 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_do_not_use_xsdt, FALSE); * some machines have been found to have a corrupted non-zero 64-bit * address. Default is FALSE, do not favor the 32-bit addresses. */ -u8 ACPI_INIT_GLOBAL(acpi_gbl_use32_bit_fadt_addresses, FALSE); +ACPI_INIT_GLOBAL(u8, acpi_gbl_use32_bit_fadt_addresses, FALSE); /* * Optionally truncate I/O addresses to 16 bits. Provides compatibility @@ -142,47 +151,28 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_use32_bit_fadt_addresses, FALSE); * this value is set to TRUE if any Windows OSI strings have been * requested by the BIOS. */ -u8 ACPI_INIT_GLOBAL(acpi_gbl_truncate_io_addresses, FALSE); +ACPI_INIT_GLOBAL(u8, acpi_gbl_truncate_io_addresses, FALSE); /* * Disable runtime checking and repair of values returned by control methods. * Use only if the repair is causing a problem on a particular machine. */ -u8 ACPI_INIT_GLOBAL(acpi_gbl_disable_auto_repair, FALSE); +ACPI_INIT_GLOBAL(u8, acpi_gbl_disable_auto_repair, FALSE); /* * Optionally do not load any SSDTs from the RSDT/XSDT during initialization. * This can be useful for debugging ACPI problems on some machines. */ -u8 ACPI_INIT_GLOBAL(acpi_gbl_disable_ssdt_table_load, FALSE); +ACPI_INIT_GLOBAL(u8, acpi_gbl_disable_ssdt_table_load, FALSE); /* * We keep track of the latest version of Windows that has been requested by * the BIOS. */ -u8 ACPI_INIT_GLOBAL(acpi_gbl_osi_data, 0); - -/* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */ - -struct acpi_table_fadt acpi_gbl_FADT; -u32 acpi_current_gpe_count; -u32 acpi_gbl_trace_flags; -acpi_name acpi_gbl_trace_method_name; -u8 acpi_gbl_system_awake_and_running; - -/* - * ACPI 5.0 introduces the concept of a "reduced hardware platform", meaning - * that the ACPI hardware is no longer required. A flag in the FADT indicates - * a reduced HW machine, and that flag is duplicated here for convenience. - */ -u8 acpi_gbl_reduced_hardware; +ACPI_INIT_GLOBAL(u8, acpi_gbl_osi_data, 0); #endif /* DEFINE_ACPI_GLOBALS */ -/* Do not disassemble buffers to resource descriptors */ - -ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_no_resource_disassembly, FALSE); - /***************************************************************************** * * ACPI Table globals @@ -190,37 +180,36 @@ ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_no_resource_disassembly, FALSE); ****************************************************************************/ /* - * acpi_gbl_root_table_list is the master list of ACPI tables that were - * found in the RSDT/XSDT. + * Master list of all ACPI tables that were found in the RSDT/XSDT. */ -ACPI_EXTERN struct acpi_table_list acpi_gbl_root_table_list; +ACPI_GLOBAL(struct acpi_table_list, acpi_gbl_root_table_list); + +/* DSDT information. Used to check for DSDT corruption */ + +ACPI_GLOBAL(struct acpi_table_header *, acpi_gbl_DSDT); +ACPI_GLOBAL(struct acpi_table_header, acpi_gbl_original_dsdt_header); #if (!ACPI_REDUCED_HARDWARE) -ACPI_EXTERN struct acpi_table_facs *acpi_gbl_FACS; +ACPI_GLOBAL(struct acpi_table_facs *, acpi_gbl_FACS); #endif /* !ACPI_REDUCED_HARDWARE */ /* These addresses are calculated from the FADT Event Block addresses */ -ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_status; -ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable; - -ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_status; -ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable; +ACPI_GLOBAL(struct acpi_generic_address, acpi_gbl_xpm1a_status); +ACPI_GLOBAL(struct acpi_generic_address, acpi_gbl_xpm1a_enable); -/* DSDT information. Used to check for DSDT corruption */ - -ACPI_EXTERN struct acpi_table_header *acpi_gbl_DSDT; -ACPI_EXTERN struct acpi_table_header acpi_gbl_original_dsdt_header; +ACPI_GLOBAL(struct acpi_generic_address, acpi_gbl_xpm1b_status); +ACPI_GLOBAL(struct acpi_generic_address, acpi_gbl_xpm1b_enable); /* - * Handle both ACPI 1.0 and ACPI 2.0 Integer widths. The integer width is + * Handle both ACPI 1.0 and ACPI 2.0+ Integer widths. The integer width is * determined by the revision of the DSDT: If the DSDT revision is less than * 2, use only the lower 32 bits of the internal 64-bit Integer. */ -ACPI_EXTERN u8 acpi_gbl_integer_bit_width; -ACPI_EXTERN u8 acpi_gbl_integer_byte_width; -ACPI_EXTERN u8 acpi_gbl_integer_nybble_width; +ACPI_GLOBAL(u8, acpi_gbl_integer_bit_width); +ACPI_GLOBAL(u8, acpi_gbl_integer_byte_width); +ACPI_GLOBAL(u8, acpi_gbl_integer_nybble_width); /***************************************************************************** * @@ -233,36 +222,36 @@ ACPI_EXTERN u8 acpi_gbl_integer_nybble_width; * actual OS mutex handles, indexed by the local ACPI_MUTEX_HANDLEs. * (The table maps local handles to the real OS handles) */ -ACPI_EXTERN struct acpi_mutex_info acpi_gbl_mutex_info[ACPI_NUM_MUTEX]; +ACPI_GLOBAL(struct acpi_mutex_info, acpi_gbl_mutex_info[ACPI_NUM_MUTEX]); /* * Global lock mutex is an actual AML mutex object * Global lock semaphore works in conjunction with the actual global lock * Global lock spinlock is used for "pending" handshake */ -ACPI_EXTERN union acpi_operand_object *acpi_gbl_global_lock_mutex; -ACPI_EXTERN acpi_semaphore acpi_gbl_global_lock_semaphore; -ACPI_EXTERN acpi_spinlock acpi_gbl_global_lock_pending_lock; -ACPI_EXTERN u16 acpi_gbl_global_lock_handle; -ACPI_EXTERN u8 acpi_gbl_global_lock_acquired; -ACPI_EXTERN u8 acpi_gbl_global_lock_present; -ACPI_EXTERN u8 acpi_gbl_global_lock_pending; +ACPI_GLOBAL(union acpi_operand_object *, acpi_gbl_global_lock_mutex); +ACPI_GLOBAL(acpi_semaphore, acpi_gbl_global_lock_semaphore); +ACPI_GLOBAL(acpi_spinlock, acpi_gbl_global_lock_pending_lock); +ACPI_GLOBAL(u16, acpi_gbl_global_lock_handle); +ACPI_GLOBAL(u8, acpi_gbl_global_lock_acquired); +ACPI_GLOBAL(u8, acpi_gbl_global_lock_present); +ACPI_GLOBAL(u8, acpi_gbl_global_lock_pending); /* * Spinlocks are used for interfaces that can be possibly called at * interrupt level */ -ACPI_EXTERN acpi_spinlock acpi_gbl_gpe_lock; /* For GPE data structs and registers */ -ACPI_EXTERN acpi_spinlock acpi_gbl_hardware_lock; /* For ACPI H/W except GPE registers */ -ACPI_EXTERN acpi_spinlock acpi_gbl_reference_count_lock; +ACPI_GLOBAL(acpi_spinlock, acpi_gbl_gpe_lock); /* For GPE data structs and registers */ +ACPI_GLOBAL(acpi_spinlock, acpi_gbl_hardware_lock); /* For ACPI H/W except GPE registers */ +ACPI_GLOBAL(acpi_spinlock, acpi_gbl_reference_count_lock); /* Mutex for _OSI support */ -ACPI_EXTERN acpi_mutex acpi_gbl_osi_mutex; +ACPI_GLOBAL(acpi_mutex, acpi_gbl_osi_mutex); /* Reader/Writer lock is used for namespace walk and dynamic table unload */ -ACPI_EXTERN struct acpi_rw_lock acpi_gbl_namespace_rw_lock; +ACPI_GLOBAL(struct acpi_rw_lock, acpi_gbl_namespace_rw_lock); /***************************************************************************** * @@ -272,70 +261,69 @@ ACPI_EXTERN struct acpi_rw_lock acpi_gbl_namespace_rw_lock; /* Object caches */ -ACPI_EXTERN acpi_cache_t *acpi_gbl_namespace_cache; -ACPI_EXTERN acpi_cache_t *acpi_gbl_state_cache; -ACPI_EXTERN acpi_cache_t *acpi_gbl_ps_node_cache; -ACPI_EXTERN acpi_cache_t *acpi_gbl_ps_node_ext_cache; -ACPI_EXTERN acpi_cache_t *acpi_gbl_operand_cache; +ACPI_GLOBAL(acpi_cache_t *, acpi_gbl_namespace_cache); +ACPI_GLOBAL(acpi_cache_t *, acpi_gbl_state_cache); +ACPI_GLOBAL(acpi_cache_t *, acpi_gbl_ps_node_cache); +ACPI_GLOBAL(acpi_cache_t *, acpi_gbl_ps_node_ext_cache); +ACPI_GLOBAL(acpi_cache_t *, acpi_gbl_operand_cache); + +/* System */ + +ACPI_INIT_GLOBAL(u32, acpi_gbl_startup_flags, 0); +ACPI_INIT_GLOBAL(u8, acpi_gbl_shutdown, TRUE); /* Global handlers */ -ACPI_EXTERN struct acpi_global_notify_handler acpi_gbl_global_notify[2]; -ACPI_EXTERN acpi_exception_handler acpi_gbl_exception_handler; -ACPI_EXTERN acpi_init_handler acpi_gbl_init_handler; -ACPI_EXTERN acpi_table_handler acpi_gbl_table_handler; -ACPI_EXTERN void *acpi_gbl_table_handler_context; -ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk; -ACPI_EXTERN acpi_interface_handler acpi_gbl_interface_handler; -ACPI_EXTERN struct acpi_sci_handler_info *acpi_gbl_sci_handler_list; +ACPI_GLOBAL(struct acpi_global_notify_handler, acpi_gbl_global_notify[2]); +ACPI_GLOBAL(acpi_exception_handler, acpi_gbl_exception_handler); +ACPI_GLOBAL(acpi_init_handler, acpi_gbl_init_handler); +ACPI_GLOBAL(acpi_table_handler, acpi_gbl_table_handler); +ACPI_GLOBAL(void *, acpi_gbl_table_handler_context); +ACPI_GLOBAL(struct acpi_walk_state *, acpi_gbl_breakpoint_walk); +ACPI_GLOBAL(acpi_interface_handler, acpi_gbl_interface_handler); +ACPI_GLOBAL(struct acpi_sci_handler_info *, acpi_gbl_sci_handler_list); /* Owner ID support */ -ACPI_EXTERN u32 acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS]; -ACPI_EXTERN u8 acpi_gbl_last_owner_id_index; -ACPI_EXTERN u8 acpi_gbl_next_owner_id_offset; +ACPI_GLOBAL(u32, acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS]); +ACPI_GLOBAL(u8, acpi_gbl_last_owner_id_index); +ACPI_GLOBAL(u8, acpi_gbl_next_owner_id_offset); /* Initialization sequencing */ -ACPI_EXTERN u8 acpi_gbl_reg_methods_executed; +ACPI_GLOBAL(u8, acpi_gbl_reg_methods_executed); /* Misc */ -ACPI_EXTERN u32 acpi_gbl_original_mode; -ACPI_EXTERN u32 acpi_gbl_rsdp_original_location; -ACPI_EXTERN u32 acpi_gbl_ns_lookup_count; -ACPI_EXTERN u32 acpi_gbl_ps_find_count; -ACPI_EXTERN u16 acpi_gbl_pm1_enable_register_save; -ACPI_EXTERN u8 acpi_gbl_debugger_configuration; -ACPI_EXTERN u8 acpi_gbl_step_to_next_call; -ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present; -ACPI_EXTERN u8 acpi_gbl_events_initialized; -ACPI_EXTERN struct acpi_interface_info *acpi_gbl_supported_interfaces; -ACPI_EXTERN struct acpi_address_range - *acpi_gbl_address_range_list[ACPI_ADDRESS_RANGE_MAX]; - -#ifndef DEFINE_ACPI_GLOBALS - -/* Other miscellaneous */ - -extern u8 acpi_gbl_shutdown; -extern u32 acpi_gbl_startup_flags; +ACPI_GLOBAL(u32, acpi_gbl_original_mode); +ACPI_GLOBAL(u32, acpi_gbl_rsdp_original_location); +ACPI_GLOBAL(u32, acpi_gbl_ns_lookup_count); +ACPI_GLOBAL(u32, acpi_gbl_ps_find_count); +ACPI_GLOBAL(u16, acpi_gbl_pm1_enable_register_save); +ACPI_GLOBAL(u8, acpi_gbl_debugger_configuration); +ACPI_GLOBAL(u8, acpi_gbl_step_to_next_call); +ACPI_GLOBAL(u8, acpi_gbl_acpi_hardware_present); +ACPI_GLOBAL(u8, acpi_gbl_events_initialized); +ACPI_GLOBAL(struct acpi_interface_info *, acpi_gbl_supported_interfaces); +ACPI_GLOBAL(struct acpi_address_range *, + acpi_gbl_address_range_list[ACPI_ADDRESS_RANGE_MAX]); + +/* Other miscellaneous, declared and initialized in utglobal */ + extern const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT]; extern const char *acpi_gbl_lowest_dstate_names[ACPI_NUM_sx_w_METHODS]; extern const char *acpi_gbl_highest_dstate_names[ACPI_NUM_sx_d_METHODS]; -extern const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES]; extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS]; - -#endif +extern const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES]; #ifdef ACPI_DBG_TRACK_ALLOCATIONS -/* Lists for tracking memory allocations */ +/* Lists for tracking memory allocations (debug only) */ -ACPI_EXTERN struct acpi_memory_list *acpi_gbl_global_list; -ACPI_EXTERN struct acpi_memory_list *acpi_gbl_ns_node_list; -ACPI_EXTERN u8 acpi_gbl_display_final_mem_stats; -ACPI_EXTERN u8 acpi_gbl_disable_mem_tracking; +ACPI_GLOBAL(struct acpi_memory_list *, acpi_gbl_global_list); +ACPI_GLOBAL(struct acpi_memory_list *, acpi_gbl_ns_node_list); +ACPI_GLOBAL(u8, acpi_gbl_display_final_mem_stats); +ACPI_GLOBAL(u8, acpi_gbl_disable_mem_tracking); #endif /***************************************************************************** @@ -350,22 +338,23 @@ ACPI_EXTERN u8 acpi_gbl_disable_mem_tracking; #define NUM_PREDEFINED_NAMES 9 #endif -ACPI_EXTERN struct acpi_namespace_node acpi_gbl_root_node_struct; -ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_root_node; -ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_fadt_gpe_device; -ACPI_EXTERN union acpi_operand_object *acpi_gbl_module_code_list; +ACPI_GLOBAL(struct acpi_namespace_node, acpi_gbl_root_node_struct); +ACPI_GLOBAL(struct acpi_namespace_node *, acpi_gbl_root_node); +ACPI_GLOBAL(struct acpi_namespace_node *, acpi_gbl_fadt_gpe_device); +ACPI_GLOBAL(union acpi_operand_object *, acpi_gbl_module_code_list); extern const u8 acpi_gbl_ns_properties[ACPI_NUM_NS_TYPES]; extern const struct acpi_predefined_names acpi_gbl_pre_defined_names[NUM_PREDEFINED_NAMES]; #ifdef ACPI_DEBUG_OUTPUT -ACPI_EXTERN u32 acpi_gbl_current_node_count; -ACPI_EXTERN u32 acpi_gbl_current_node_size; -ACPI_EXTERN u32 acpi_gbl_max_concurrent_node_count; -ACPI_EXTERN acpi_size *acpi_gbl_entry_stack_pointer; -ACPI_EXTERN acpi_size *acpi_gbl_lowest_stack_pointer; -ACPI_EXTERN u32 acpi_gbl_deepest_nesting; +ACPI_GLOBAL(u32, acpi_gbl_current_node_count); +ACPI_GLOBAL(u32, acpi_gbl_current_node_size); +ACPI_GLOBAL(u32, acpi_gbl_max_concurrent_node_count); +ACPI_GLOBAL(acpi_size *, acpi_gbl_entry_stack_pointer); +ACPI_GLOBAL(acpi_size *, acpi_gbl_lowest_stack_pointer); +ACPI_GLOBAL(u32, acpi_gbl_deepest_nesting); +ACPI_INIT_GLOBAL(u32, acpi_gbl_nesting_level, 0); #endif /***************************************************************************** @@ -374,11 +363,11 @@ ACPI_EXTERN u32 acpi_gbl_deepest_nesting; * ****************************************************************************/ -ACPI_EXTERN struct acpi_thread_state *acpi_gbl_current_walk_list; +ACPI_GLOBAL(struct acpi_thread_state *, acpi_gbl_current_walk_list); /* Control method single step flag */ -ACPI_EXTERN u8 acpi_gbl_cm_single_step; +ACPI_GLOBAL(u8, acpi_gbl_cm_single_step); /***************************************************************************** * @@ -388,8 +377,9 @@ ACPI_EXTERN u8 acpi_gbl_cm_single_step; extern struct acpi_bit_register_info acpi_gbl_bit_register_info[ACPI_NUM_BITREG]; -ACPI_EXTERN u8 acpi_gbl_sleep_type_a; -ACPI_EXTERN u8 acpi_gbl_sleep_type_b; + +ACPI_GLOBAL(u8, acpi_gbl_sleep_type_a); +ACPI_GLOBAL(u8, acpi_gbl_sleep_type_b); /***************************************************************************** * @@ -399,14 +389,15 @@ ACPI_EXTERN u8 acpi_gbl_sleep_type_b; #if (!ACPI_REDUCED_HARDWARE) -ACPI_EXTERN u8 acpi_gbl_all_gpes_initialized; -ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head; -ACPI_EXTERN struct acpi_gpe_block_info - *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS]; -ACPI_EXTERN acpi_gbl_event_handler acpi_gbl_global_event_handler; -ACPI_EXTERN void *acpi_gbl_global_event_handler_context; -ACPI_EXTERN struct acpi_fixed_event_handler - acpi_gbl_fixed_event_handlers[ACPI_NUM_FIXED_EVENTS]; +ACPI_GLOBAL(u8, acpi_gbl_all_gpes_initialized); +ACPI_GLOBAL(struct acpi_gpe_xrupt_info *, acpi_gbl_gpe_xrupt_list_head); +ACPI_GLOBAL(struct acpi_gpe_block_info *, + acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS]); +ACPI_GLOBAL(acpi_gbl_event_handler, acpi_gbl_global_event_handler); +ACPI_GLOBAL(void *, acpi_gbl_global_event_handler_context); +ACPI_GLOBAL(struct acpi_fixed_event_handler, + acpi_gbl_fixed_event_handlers[ACPI_NUM_FIXED_EVENTS]); + extern struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS]; @@ -418,23 +409,19 @@ extern struct acpi_fixed_event_info * ****************************************************************************/ -/* Procedure nesting level for debug output */ - -extern u32 acpi_gbl_nesting_level; - /* Event counters */ -ACPI_EXTERN u32 acpi_method_count; -ACPI_EXTERN u32 acpi_gpe_count; -ACPI_EXTERN u32 acpi_sci_count; -ACPI_EXTERN u32 acpi_fixed_event_count[ACPI_NUM_FIXED_EVENTS]; +ACPI_GLOBAL(u32, acpi_method_count); +ACPI_GLOBAL(u32, acpi_gpe_count); +ACPI_GLOBAL(u32, acpi_sci_count); +ACPI_GLOBAL(u32, acpi_fixed_event_count[ACPI_NUM_FIXED_EVENTS]); /* Support for dynamic control method tracing mechanism */ -ACPI_EXTERN u32 acpi_gbl_original_dbg_level; -ACPI_EXTERN u32 acpi_gbl_original_dbg_layer; -ACPI_EXTERN u32 acpi_gbl_trace_dbg_level; -ACPI_EXTERN u32 acpi_gbl_trace_dbg_layer; +ACPI_GLOBAL(u32, acpi_gbl_original_dbg_level); +ACPI_GLOBAL(u32, acpi_gbl_original_dbg_layer); +ACPI_GLOBAL(u32, acpi_gbl_trace_dbg_level); +ACPI_GLOBAL(u32, acpi_gbl_trace_dbg_layer); /***************************************************************************** * @@ -442,61 +429,64 @@ ACPI_EXTERN u32 acpi_gbl_trace_dbg_layer; * ****************************************************************************/ -ACPI_EXTERN u8 acpi_gbl_db_output_flags; +ACPI_GLOBAL(u8, acpi_gbl_db_output_flags); #ifdef ACPI_DISASSEMBLER -ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_ignore_noop_operator, FALSE); +/* Do not disassemble buffers to resource descriptors */ + +ACPI_INIT_GLOBAL(u8, acpi_gbl_no_resource_disassembly, FALSE); +ACPI_INIT_GLOBAL(u8, acpi_gbl_ignore_noop_operator, FALSE); -ACPI_EXTERN u8 acpi_gbl_db_opt_disasm; -ACPI_EXTERN u8 acpi_gbl_db_opt_verbose; -ACPI_EXTERN u8 acpi_gbl_num_external_methods; -ACPI_EXTERN u32 acpi_gbl_resolved_external_methods; -ACPI_EXTERN struct acpi_external_list *acpi_gbl_external_list; -ACPI_EXTERN struct acpi_external_file *acpi_gbl_external_file_list; +ACPI_GLOBAL(u8, acpi_gbl_db_opt_disasm); +ACPI_GLOBAL(u8, acpi_gbl_db_opt_verbose); +ACPI_GLOBAL(u8, acpi_gbl_num_external_methods); +ACPI_GLOBAL(u32, acpi_gbl_resolved_external_methods); +ACPI_GLOBAL(struct acpi_external_list *, acpi_gbl_external_list); +ACPI_GLOBAL(struct acpi_external_file *, acpi_gbl_external_file_list); #endif #ifdef ACPI_DEBUGGER -extern u8 acpi_gbl_method_executing; -extern u8 acpi_gbl_abort_method; -extern u8 acpi_gbl_db_terminate_threads; +ACPI_INIT_GLOBAL(u8, acpi_gbl_db_terminate_threads, FALSE); +ACPI_INIT_GLOBAL(u8, acpi_gbl_abort_method, FALSE); +ACPI_INIT_GLOBAL(u8, acpi_gbl_method_executing, FALSE); -ACPI_EXTERN u8 acpi_gbl_db_opt_tables; -ACPI_EXTERN u8 acpi_gbl_db_opt_stats; -ACPI_EXTERN u8 acpi_gbl_db_opt_ini_methods; -ACPI_EXTERN u8 acpi_gbl_db_opt_no_region_support; -ACPI_EXTERN u8 acpi_gbl_db_output_to_file; -ACPI_EXTERN char *acpi_gbl_db_buffer; -ACPI_EXTERN char *acpi_gbl_db_filename; -ACPI_EXTERN u32 acpi_gbl_db_debug_level; -ACPI_EXTERN u32 acpi_gbl_db_console_debug_level; -ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_db_scope_node; +ACPI_GLOBAL(u8, acpi_gbl_db_opt_tables); +ACPI_GLOBAL(u8, acpi_gbl_db_opt_stats); +ACPI_GLOBAL(u8, acpi_gbl_db_opt_ini_methods); +ACPI_GLOBAL(u8, acpi_gbl_db_opt_no_region_support); +ACPI_GLOBAL(u8, acpi_gbl_db_output_to_file); +ACPI_GLOBAL(char *, acpi_gbl_db_buffer); +ACPI_GLOBAL(char *, acpi_gbl_db_filename); +ACPI_GLOBAL(u32, acpi_gbl_db_debug_level); +ACPI_GLOBAL(u32, acpi_gbl_db_console_debug_level); +ACPI_GLOBAL(struct acpi_namespace_node *, acpi_gbl_db_scope_node); -ACPI_EXTERN char *acpi_gbl_db_args[ACPI_DEBUGGER_MAX_ARGS]; -ACPI_EXTERN acpi_object_type acpi_gbl_db_arg_types[ACPI_DEBUGGER_MAX_ARGS]; +ACPI_GLOBAL(char *, acpi_gbl_db_args[ACPI_DEBUGGER_MAX_ARGS]); +ACPI_GLOBAL(acpi_object_type, acpi_gbl_db_arg_types[ACPI_DEBUGGER_MAX_ARGS]); /* These buffers should all be the same size */ -ACPI_EXTERN char acpi_gbl_db_line_buf[ACPI_DB_LINE_BUFFER_SIZE]; -ACPI_EXTERN char acpi_gbl_db_parsed_buf[ACPI_DB_LINE_BUFFER_SIZE]; -ACPI_EXTERN char acpi_gbl_db_scope_buf[ACPI_DB_LINE_BUFFER_SIZE]; -ACPI_EXTERN char acpi_gbl_db_debug_filename[ACPI_DB_LINE_BUFFER_SIZE]; +ACPI_GLOBAL(char, acpi_gbl_db_line_buf[ACPI_DB_LINE_BUFFER_SIZE]); +ACPI_GLOBAL(char, acpi_gbl_db_parsed_buf[ACPI_DB_LINE_BUFFER_SIZE]); +ACPI_GLOBAL(char, acpi_gbl_db_scope_buf[ACPI_DB_LINE_BUFFER_SIZE]); +ACPI_GLOBAL(char, acpi_gbl_db_debug_filename[ACPI_DB_LINE_BUFFER_SIZE]); /* * Statistic globals */ -ACPI_EXTERN u16 acpi_gbl_obj_type_count[ACPI_TYPE_NS_NODE_MAX + 1]; -ACPI_EXTERN u16 acpi_gbl_node_type_count[ACPI_TYPE_NS_NODE_MAX + 1]; -ACPI_EXTERN u16 acpi_gbl_obj_type_count_misc; -ACPI_EXTERN u16 acpi_gbl_node_type_count_misc; -ACPI_EXTERN u32 acpi_gbl_num_nodes; -ACPI_EXTERN u32 acpi_gbl_num_objects; - -ACPI_EXTERN u32 acpi_gbl_size_of_parse_tree; -ACPI_EXTERN u32 acpi_gbl_size_of_method_trees; -ACPI_EXTERN u32 acpi_gbl_size_of_node_entries; -ACPI_EXTERN u32 acpi_gbl_size_of_acpi_objects; +ACPI_GLOBAL(u16, acpi_gbl_obj_type_count[ACPI_TYPE_NS_NODE_MAX + 1]); +ACPI_GLOBAL(u16, acpi_gbl_node_type_count[ACPI_TYPE_NS_NODE_MAX + 1]); +ACPI_GLOBAL(u16, acpi_gbl_obj_type_count_misc); +ACPI_GLOBAL(u16, acpi_gbl_node_type_count_misc); +ACPI_GLOBAL(u32, acpi_gbl_num_nodes); +ACPI_GLOBAL(u32, acpi_gbl_num_objects); + +ACPI_GLOBAL(u32, acpi_gbl_size_of_parse_tree); +ACPI_GLOBAL(u32, acpi_gbl_size_of_method_trees); +ACPI_GLOBAL(u32, acpi_gbl_size_of_node_entries); +ACPI_GLOBAL(u32, acpi_gbl_size_of_acpi_objects); #endif /* ACPI_DEBUGGER */ @@ -508,7 +498,7 @@ ACPI_EXTERN u32 acpi_gbl_size_of_acpi_objects; #ifdef ACPI_APPLICATION -ACPI_FILE ACPI_INIT_GLOBAL(acpi_gbl_debug_file, NULL); +ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_debug_file, NULL); #endif /* ACPI_APPLICATION */ diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index 6357e932bfd9..2ad2351a9833 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acinterp.h b/drivers/acpi/acpica/acinterp.h index 8af8c9bdeb35..b01f71ce0523 100644 --- a/drivers/acpi/acpica/acinterp.h +++ b/drivers/acpi/acpica/acinterp.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -87,6 +87,10 @@ typedef const struct acpi_exdump_info { #define ACPI_EXD_PACKAGE 11 #define ACPI_EXD_FIELD 12 #define ACPI_EXD_REFERENCE 13 +#define ACPI_EXD_LIST 14 /* Operand object list */ +#define ACPI_EXD_HDLR_LIST 15 /* Address Handler list */ +#define ACPI_EXD_RGN_LIST 16 /* Region list */ +#define ACPI_EXD_NODE 17 /* Namespace Node */ /* restore default alignment */ @@ -454,10 +458,6 @@ void acpi_ex_enter_interpreter(void); void acpi_ex_exit_interpreter(void); -void acpi_ex_reacquire_interpreter(void); - -void acpi_ex_relinquish_interpreter(void); - u8 acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc); void acpi_ex_acquire_global_lock(u32 rule); diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index d95ca5449ace..52a21dafb540 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index 2a86c65d873b..4bceb11c7380 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -63,17 +63,21 @@ #define ACPI_SET64(ptr, val) (*ACPI_CAST64 (ptr) = (u64) (val)) /* - * printf() format helpers + * printf() format helpers. These macros are workarounds for the difficulties + * with emitting 64-bit integers and 64-bit pointers with the same code + * for both 32-bit and 64-bit hosts. */ - -/* Split 64-bit integer into two 32-bit values. Use with %8.8X%8.8X */ - #define ACPI_FORMAT_UINT64(i) ACPI_HIDWORD(i), ACPI_LODWORD(i) #if ACPI_MACHINE_WIDTH == 64 #define ACPI_FORMAT_NATIVE_UINT(i) ACPI_FORMAT_UINT64(i) +#define ACPI_FORMAT_TO_UINT(i) ACPI_FORMAT_UINT64(i) +#define ACPI_PRINTF_UINT "0x%8.8X%8.8X" + #else -#define ACPI_FORMAT_NATIVE_UINT(i) 0, (i) +#define ACPI_FORMAT_NATIVE_UINT(i) 0, (u32) (i) +#define ACPI_FORMAT_TO_UINT(i) (u32) (i) +#define ACPI_PRINTF_UINT "0x%8.8X" #endif /* diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index e6138ac4a160..ee1c040f321c 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index cc7ab6dd724e..22fb6449d3d6 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -193,7 +193,8 @@ struct acpi_object_method { #define ACPI_METHOD_INTERNAL_ONLY 0x02 /* Method is implemented internally (_OSI) */ #define ACPI_METHOD_SERIALIZED 0x04 /* Method is serialized */ #define ACPI_METHOD_SERIALIZED_PENDING 0x08 /* Method is to be marked serialized */ -#define ACPI_METHOD_MODIFIED_NAMESPACE 0x10 /* Method modified the namespace */ +#define ACPI_METHOD_IGNORE_SYNC_LEVEL 0x10 /* Method was auto-serialized at table load time */ +#define ACPI_METHOD_MODIFIED_NAMESPACE 0x20 /* Method modified the namespace */ /****************************************************************************** * diff --git a/drivers/acpi/acpica/acopcode.h b/drivers/acpi/acpica/acopcode.h index 3fc9ca7e8aa3..dda0e6affcf1 100644 --- a/drivers/acpi/acpica/acopcode.h +++ b/drivers/acpi/acpica/acopcode.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acparser.h b/drivers/acpi/acpica/acparser.h index aed319318835..6168b85463ed 100644 --- a/drivers/acpi/acpica/acparser.h +++ b/drivers/acpi/acpica/acparser.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h index f600aded7261..a48d713e9599 100644 --- a/drivers/acpi/acpica/acpredef.h +++ b/drivers/acpi/acpica/acpredef.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -48,7 +48,7 @@ * * Return Package types * - * 1) PTYPE1 packages do not contain sub-packages. + * 1) PTYPE1 packages do not contain subpackages. * * ACPI_PTYPE1_FIXED: Fixed-length length, 1 or 2 object types: * object type @@ -63,8 +63,8 @@ * (Used for _PRW) * * - * 2) PTYPE2 packages contain a Variable-length number of sub-packages. Each - * of the different types describe the contents of each of the sub-packages. + * 2) PTYPE2 packages contain a Variable-length number of subpackages. Each + * of the different types describe the contents of each of the subpackages. * * ACPI_PTYPE2: Each subpackage contains 1 or 2 object types. Zero-length * parent package is allowed: @@ -560,7 +560,7 @@ const union acpi_predefined_info acpi_gbl_predefined_methods[] = { /* * For _HPX, a single package is returned, containing a variable-length number - * of sub-packages. Each sub-package contains a PCI record setting. + * of subpackages. Each subpackage contains a PCI record setting. * There are several different type of record settings, of different * lengths, but all elements of all settings are Integers. */ @@ -698,6 +698,12 @@ const union acpi_predefined_info acpi_gbl_predefined_methods[] = { METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Refs) */ PACKAGE_INFO(ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0), + {{"_PRP", METHOD_0ARGS, + METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Pkgs) each: 1 Str, 1 Int/Str/Pkg */ + PACKAGE_INFO(ACPI_PTYPE2, ACPI_RTYPE_STRING, 1, + ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | + ACPI_RTYPE_PACKAGE | ACPI_RTYPE_REFERENCE, 1, 0), + {{"_PRS", METHOD_0ARGS, METHOD_RETURNS(ACPI_RTYPE_BUFFER)}}, diff --git a/drivers/acpi/acpica/acresrc.h b/drivers/acpi/acpica/acresrc.h index ff97430455cb..4b008e8884a1 100644 --- a/drivers/acpi/acpica/acresrc.h +++ b/drivers/acpi/acpica/acresrc.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acstruct.h b/drivers/acpi/acpica/acstruct.h index fc83c0a5ca70..cf7346110bd8 100644 --- a/drivers/acpi/acpica/acstruct.h +++ b/drivers/acpi/acpica/acstruct.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -133,6 +133,9 @@ struct acpi_init_walk_info { u32 table_index; u32 object_count; u32 method_count; + u32 serial_method_count; + u32 non_serial_method_count; + u32 serialized_method_count; u32 device_count; u32 op_region_count; u32 field_count; diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h index c54f42c64fe2..5fa4b2027697 100644 --- a/drivers/acpi/acpica/actables.h +++ b/drivers/acpi/acpica/actables.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index be8180c17d7e..ceeec0b7ccb1 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -49,7 +49,7 @@ extern const u8 acpi_gbl_resource_aml_serial_bus_sizes[]; /* Strings used by the disassembler and debugger resource dump routines */ -#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER) +#if defined(ACPI_DEBUG_OUTPUT) || defined (ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER) extern const char *acpi_gbl_bm_decode[]; extern const char *acpi_gbl_config_decode[]; diff --git a/drivers/acpi/acpica/amlcode.h b/drivers/acpi/acpica/amlcode.h index 48a3e331b72d..5908ccec6aea 100644 --- a/drivers/acpi/acpica/amlcode.h +++ b/drivers/acpi/acpica/amlcode.h @@ -7,7 +7,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/amlresrc.h b/drivers/acpi/acpica/amlresrc.h index 87c26366d1df..f3f834408441 100644 --- a/drivers/acpi/acpica/amlresrc.h +++ b/drivers/acpi/acpica/amlresrc.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsargs.c b/drivers/acpi/acpica/dsargs.c index afdc6df17abf..720b1cdda711 100644 --- a/drivers/acpi/acpica/dsargs.c +++ b/drivers/acpi/acpica/dsargs.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dscontrol.c b/drivers/acpi/acpica/dscontrol.c index eb56b66444b5..8daf9de82b73 100644 --- a/drivers/acpi/acpica/dscontrol.c +++ b/drivers/acpi/acpica/dscontrol.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c index e7a57c554e84..3661c8e90540 100644 --- a/drivers/acpi/acpica/dsfield.c +++ b/drivers/acpi/acpica/dsfield.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsinit.c b/drivers/acpi/acpica/dsinit.c index 14424200d246..aee5e45f6d35 100644 --- a/drivers/acpi/acpica/dsinit.c +++ b/drivers/acpi/acpica/dsinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -83,8 +83,8 @@ acpi_ds_init_one_object(acpi_handle obj_handle, (struct acpi_init_walk_info *)context; struct acpi_namespace_node *node = (struct acpi_namespace_node *)obj_handle; - acpi_object_type type; acpi_status status; + union acpi_operand_object *obj_desc; ACPI_FUNCTION_ENTRY(); @@ -100,9 +100,7 @@ acpi_ds_init_one_object(acpi_handle obj_handle, /* And even then, we are only interested in a few object types */ - type = acpi_ns_get_type(obj_handle); - - switch (type) { + switch (acpi_ns_get_type(obj_handle)) { case ACPI_TYPE_REGION: status = acpi_ds_initialize_region(obj_handle); @@ -117,8 +115,44 @@ acpi_ds_init_one_object(acpi_handle obj_handle, break; case ACPI_TYPE_METHOD: - + /* + * Auto-serialization support. We will examine each method that is + * not_serialized to determine if it creates any Named objects. If + * it does, it will be marked serialized to prevent problems if + * the method is entered by two or more threads and an attempt is + * made to create the same named object twice -- which results in + * an AE_ALREADY_EXISTS exception and method abort. + */ info->method_count++; + obj_desc = acpi_ns_get_attached_object(node); + if (!obj_desc) { + break; + } + + /* Ignore if already serialized */ + + if (obj_desc->method.info_flags & ACPI_METHOD_SERIALIZED) { + info->serial_method_count++; + break; + } + + if (acpi_gbl_auto_serialize_methods) { + + /* Parse/scan method and serialize it if necessary */ + + acpi_ds_auto_serialize_method(node, obj_desc); + if (obj_desc->method. + info_flags & ACPI_METHOD_SERIALIZED) { + + /* Method was just converted to Serialized */ + + info->serial_method_count++; + info->serialized_method_count++; + break; + } + } + + info->non_serial_method_count++; break; case ACPI_TYPE_DEVICE: @@ -170,7 +204,6 @@ acpi_ds_initialize_objects(u32 table_index, ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "**** Starting initialization of namespace objects ****\n")); - ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "Parsing all Control Methods:")); /* Set all init info to zero */ @@ -205,14 +238,16 @@ acpi_ds_initialize_objects(u32 table_index, } ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, - "\nTable [%4.4s](id %4.4X) - %u Objects with %u Devices %u Methods %u Regions\n", + "Table [%4.4s] (id %4.4X) - %4u Objects with %3u Devices, " + "%3u Regions, %3u Methods (%u/%u/%u Serial/Non/Cvt)\n", table->signature, owner_id, info.object_count, - info.device_count, info.method_count, - info.op_region_count)); + info.device_count, info.op_region_count, + info.method_count, info.serial_method_count, + info.non_serial_method_count, + info.serialized_method_count)); - ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "%u Methods, %u Regions\n", info.method_count, - info.op_region_count)); + ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "%u Methods, %u Regions\n", + info.method_count, info.op_region_count)); return_ACPI_STATUS(AE_OK); } diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index 81a78ba84311..3c7f7378b94d 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -49,16 +49,155 @@ #ifdef ACPI_DISASSEMBLER #include "acdisasm.h" #endif +#include "acparser.h" +#include "amlcode.h" #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME("dsmethod") /* Local prototypes */ static acpi_status +acpi_ds_detect_named_opcodes(struct acpi_walk_state *walk_state, + union acpi_parse_object **out_op); + +static acpi_status acpi_ds_create_method_mutex(union acpi_operand_object *method_desc); /******************************************************************************* * + * FUNCTION: acpi_ds_auto_serialize_method + * + * PARAMETERS: node - Namespace Node of the method + * obj_desc - Method object attached to node + * + * RETURN: Status + * + * DESCRIPTION: Parse a control method AML to scan for control methods that + * need serialization due to the creation of named objects. + * + * NOTE: It is a bit of overkill to mark all such methods serialized, since + * there is only a problem if the method actually blocks during execution. + * A blocking operation is, for example, a Sleep() operation, or any access + * to an operation region. However, it is probably not possible to easily + * detect whether a method will block or not, so we simply mark all suspicious + * methods as serialized. + * + * NOTE2: This code is essentially a generic routine for parsing a single + * control method. + * + ******************************************************************************/ + +acpi_status +acpi_ds_auto_serialize_method(struct acpi_namespace_node *node, + union acpi_operand_object *obj_desc) +{ + acpi_status status; + union acpi_parse_object *op = NULL; + struct acpi_walk_state *walk_state; + + ACPI_FUNCTION_TRACE_PTR(ds_auto_serialize_method, node); + + ACPI_DEBUG_PRINT((ACPI_DB_PARSE, + "Method auto-serialization parse [%4.4s] %p\n", + acpi_ut_get_node_name(node), node)); + + /* Create/Init a root op for the method parse tree */ + + op = acpi_ps_alloc_op(AML_METHOD_OP); + if (!op) { + return_ACPI_STATUS(AE_NO_MEMORY); + } + + acpi_ps_set_name(op, node->name.integer); + op->common.node = node; + + /* Create and initialize a new walk state */ + + walk_state = + acpi_ds_create_walk_state(node->owner_id, NULL, NULL, NULL); + if (!walk_state) { + return_ACPI_STATUS(AE_NO_MEMORY); + } + + status = + acpi_ds_init_aml_walk(walk_state, op, node, + obj_desc->method.aml_start, + obj_desc->method.aml_length, NULL, 0); + if (ACPI_FAILURE(status)) { + acpi_ds_delete_walk_state(walk_state); + return_ACPI_STATUS(status); + } + + walk_state->descending_callback = acpi_ds_detect_named_opcodes; + + /* Parse the method, scan for creation of named objects */ + + status = acpi_ps_parse_aml(walk_state); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + acpi_ps_delete_parse_tree(op); + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ds_detect_named_opcodes + * + * PARAMETERS: walk_state - Current state of the parse tree walk + * out_op - Unused, required for parser interface + * + * RETURN: Status + * + * DESCRIPTION: Descending callback used during the loading of ACPI tables. + * Currently used to detect methods that must be marked serialized + * in order to avoid problems with the creation of named objects. + * + ******************************************************************************/ + +static acpi_status +acpi_ds_detect_named_opcodes(struct acpi_walk_state *walk_state, + union acpi_parse_object **out_op) +{ + + ACPI_FUNCTION_NAME(acpi_ds_detect_named_opcodes); + + /* We are only interested in opcodes that create a new name */ + + if (! + (walk_state->op_info-> + flags & (AML_NAMED | AML_CREATE | AML_FIELD))) { + return (AE_OK); + } + + /* + * At this point, we know we have a Named object opcode. + * Mark the method as serialized. Later code will create a mutex for + * this method to enforce serialization. + * + * Note, ACPI_METHOD_IGNORE_SYNC_LEVEL flag means that we will ignore the + * Sync Level mechanism for this method, even though it is now serialized. + * Otherwise, there can be conflicts with existing ASL code that actually + * uses sync levels. + */ + walk_state->method_desc->method.sync_level = 0; + walk_state->method_desc->method.info_flags |= + (ACPI_METHOD_SERIALIZED | ACPI_METHOD_IGNORE_SYNC_LEVEL); + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Method serialized [%4.4s] %p - [%s] (%4.4X)\n", + walk_state->method_node->name.ascii, + walk_state->method_node, walk_state->op_info->name, + walk_state->opcode)); + + /* Abort the parse, no need to examine this method any further */ + + return (AE_CTRL_TERMINATE); +} + +/******************************************************************************* + * * FUNCTION: acpi_ds_method_error * * PARAMETERS: status - Execution status @@ -74,7 +213,7 @@ acpi_ds_create_method_mutex(union acpi_operand_object *method_desc); ******************************************************************************/ acpi_status -acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state) +acpi_ds_method_error(acpi_status status, struct acpi_walk_state * walk_state) { ACPI_FUNCTION_ENTRY(); @@ -217,13 +356,19 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, /* * The current_sync_level (per-thread) must be less than or equal to * the sync level of the method. This mechanism provides some - * deadlock prevention + * deadlock prevention. + * + * If the method was auto-serialized, we just ignore the sync level + * mechanism, because auto-serialization of methods can interfere + * with ASL code that actually uses sync levels. * * Top-level method invocation has no walk state at this point */ if (walk_state && - (walk_state->thread->current_sync_level > - obj_desc->method.mutex->mutex.sync_level)) { + (!(obj_desc->method. + info_flags & ACPI_METHOD_IGNORE_SYNC_LEVEL)) + && (walk_state->thread->current_sync_level > + obj_desc->method.mutex->mutex.sync_level)) { ACPI_ERROR((AE_INFO, "Cannot acquire Mutex for method [%4.4s], current SyncLevel is too large (%u)", acpi_ut_get_node_name(method_node), @@ -668,7 +813,8 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, method_desc->method.info_flags &= ~ACPI_METHOD_SERIALIZED_PENDING; method_desc->method.info_flags |= - ACPI_METHOD_SERIALIZED; + (ACPI_METHOD_SERIALIZED | + ACPI_METHOD_IGNORE_SYNC_LEVEL); method_desc->method.sync_level = 0; } diff --git a/drivers/acpi/acpica/dsmthdat.c b/drivers/acpi/acpica/dsmthdat.c index c4b0b3657237..b67522df01ac 100644 --- a/drivers/acpi/acpica/dsmthdat.c +++ b/drivers/acpi/acpica/dsmthdat.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c index b1746a68dad1..a1e7e6b6fcf7 100644 --- a/drivers/acpi/acpica/dsobject.c +++ b/drivers/acpi/acpica/dsobject.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c index 5205edcf2c01..6c0759c0db47 100644 --- a/drivers/acpi/acpica/dsopcode.c +++ b/drivers/acpi/acpica/dsopcode.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c index d7f53fb2979a..9f74795e2268 100644 --- a/drivers/acpi/acpica/dsutils.c +++ b/drivers/acpi/acpica/dsutils.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dswexec.c b/drivers/acpi/acpica/dswexec.c index 1bbb22fd6fa0..f7f5107e754d 100644 --- a/drivers/acpi/acpica/dswexec.c +++ b/drivers/acpi/acpica/dswexec.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dswload.c b/drivers/acpi/acpica/dswload.c index 2dbe109727c8..15623da26200 100644 --- a/drivers/acpi/acpica/dswload.c +++ b/drivers/acpi/acpica/dswload.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -73,8 +73,20 @@ acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number) { switch (pass_number) { + case 0: + + /* Parse only - caller will setup callbacks */ + + walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 | + ACPI_PARSE_DELETE_TREE | ACPI_PARSE_DISASSEMBLE; + walk_state->descending_callback = NULL; + walk_state->ascending_callback = NULL; + break; + case 1: + /* Load pass 1 */ + walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE; walk_state->descending_callback = acpi_ds_load1_begin_op; @@ -83,6 +95,8 @@ acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number) case 2: + /* Load pass 2 */ + walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE; walk_state->descending_callback = acpi_ds_load2_begin_op; @@ -91,6 +105,8 @@ acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number) case 3: + /* Execution pass */ + #ifndef ACPI_NO_METHOD_EXECUTION walk_state->parse_flags |= ACPI_PARSE_EXECUTE | ACPI_PARSE_DELETE_TREE; diff --git a/drivers/acpi/acpica/dswload2.c b/drivers/acpi/acpica/dswload2.c index 7f569d573027..2ac28d297305 100644 --- a/drivers/acpi/acpica/dswload2.c +++ b/drivers/acpi/acpica/dswload2.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dswscope.c b/drivers/acpi/acpica/dswscope.c index d67891de1b54..9d6e2c1de1f8 100644 --- a/drivers/acpi/acpica/dswscope.c +++ b/drivers/acpi/acpica/dswscope.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dswstate.c b/drivers/acpi/acpica/dswstate.c index ecb12e2137ff..24f7d5ea678a 100644 --- a/drivers/acpi/acpica/dswstate.c +++ b/drivers/acpi/acpica/dswstate.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c index 83cd45f4a870..c7bffff9ed32 100644 --- a/drivers/acpi/acpica/evevent.c +++ b/drivers/acpi/acpica/evevent.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evglock.c b/drivers/acpi/acpica/evglock.c index 4c67193a9fa7..3393a73ca0d6 100644 --- a/drivers/acpi/acpica/evglock.c +++ b/drivers/acpi/acpica/evglock.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index a9cb4a1a4bb8..955f83da68a5 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index a31e549e64cc..caaed3c673fd 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evgpeinit.c b/drivers/acpi/acpica/evgpeinit.c index a3e2f38aadf6..ae779c1e871d 100644 --- a/drivers/acpi/acpica/evgpeinit.c +++ b/drivers/acpi/acpica/evgpeinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evgpeutil.c b/drivers/acpi/acpica/evgpeutil.c index 4d764e847a08..17e4bbfdb096 100644 --- a/drivers/acpi/acpica/evgpeutil.c +++ b/drivers/acpi/acpica/evgpeutil.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evhandler.c b/drivers/acpi/acpica/evhandler.c index e3157313eb27..78ac29351c9e 100644 --- a/drivers/acpi/acpica/evhandler.c +++ b/drivers/acpi/acpica/evhandler.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c index a5687540e9a6..5d594eb2e5ec 100644 --- a/drivers/acpi/acpica/evmisc.c +++ b/drivers/acpi/acpica/evmisc.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index 144cbb9b73bc..9957297d1580 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -314,6 +314,7 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj, { union acpi_operand_object *handler_obj; union acpi_operand_object *obj_desc; + union acpi_operand_object *start_desc; union acpi_operand_object **last_obj_ptr; acpi_adr_space_setup region_setup; void **region_context; @@ -341,6 +342,7 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj, /* Find this region in the handler's list */ obj_desc = handler_obj->address_space.region_list; + start_desc = obj_desc; last_obj_ptr = &handler_obj->address_space.region_list; while (obj_desc) { @@ -438,6 +440,15 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj, last_obj_ptr = &obj_desc->region.next; obj_desc = obj_desc->region.next; + + /* Prevent infinite loop if list is corrupted */ + + if (obj_desc == start_desc) { + ACPI_ERROR((AE_INFO, + "Circular handler list in region object %p", + region_obj)); + return_VOID; + } } /* If we get here, the region was not in the handler's region list */ diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index 8354c4f7f10c..1b148a440d67 100644 --- a/drivers/acpi/acpica/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evsci.c b/drivers/acpi/acpica/evsci.c index 9e9e3454d893..4d8a709c1fc4 100644 --- a/drivers/acpi/acpica/evsci.c +++ b/drivers/acpi/acpica/evsci.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index 23a7fadca412..a734b27da061 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index 39d06af5e347..e286640ad4ff 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c index 5713da77c665..20a1392ffe06 100644 --- a/drivers/acpi/acpica/evxfgpe.c +++ b/drivers/acpi/acpica/evxfgpe.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -583,6 +583,18 @@ acpi_install_gpe_block(acpi_handle gpe_device, goto unlock_and_exit; } + /* Validate the parent device */ + + if (node->type != ACPI_TYPE_DEVICE) { + status = AE_TYPE; + goto unlock_and_exit; + } + + if (node->object) { + status = AE_ALREADY_EXISTS; + goto unlock_and_exit; + } + /* * For user-installed GPE Block Devices, the gpe_block_base_number * is always zero @@ -666,6 +678,13 @@ acpi_status acpi_remove_gpe_block(acpi_handle gpe_device) goto unlock_and_exit; } + /* Validate the parent device */ + + if (node->type != ACPI_TYPE_DEVICE) { + status = AE_TYPE; + goto unlock_and_exit; + } + /* Get the device_object attached to the node */ obj_desc = acpi_ns_get_attached_object(node); diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c index 02ed75ac56cd..2d6f187939c7 100644 --- a/drivers/acpi/acpica/evxfregn.c +++ b/drivers/acpi/acpica/evxfregn.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 06d216c8d43a..8ba1464efd11 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exconvrt.c b/drivers/acpi/acpica/exconvrt.c index 69e4a8cc9b71..c545386fee96 100644 --- a/drivers/acpi/acpica/exconvrt.c +++ b/drivers/acpi/acpica/exconvrt.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/excreate.c b/drivers/acpi/acpica/excreate.c index 3c2e6dcdad3e..95d23dabcfbb 100644 --- a/drivers/acpi/acpica/excreate.c +++ b/drivers/acpi/acpica/excreate.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exdebug.c b/drivers/acpi/acpica/exdebug.c index 81c72a4ecd82..4cfc3d3b5c97 100644 --- a/drivers/acpi/acpica/exdebug.c +++ b/drivers/acpi/acpica/exdebug.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index 4d046faac48c..973fdae00f94 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -94,12 +94,13 @@ static struct acpi_exdump_info acpi_ex_dump_buffer[5] = { {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_buffer), NULL}, {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(buffer.length), "Length"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(buffer.pointer), "Pointer"}, - {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(buffer.node), "Parent Node"}, + {ACPI_EXD_NODE, ACPI_EXD_OFFSET(buffer.node), "Parent Node"}, {ACPI_EXD_BUFFER, 0, NULL} }; -static struct acpi_exdump_info acpi_ex_dump_package[5] = { +static struct acpi_exdump_info acpi_ex_dump_package[6] = { {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_package), NULL}, + {ACPI_EXD_NODE, ACPI_EXD_OFFSET(package.node), "Parent Node"}, {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(package.flags), "Flags"}, {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(package.count), "Elements"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(package.elements), "Element List"}, @@ -108,11 +109,11 @@ static struct acpi_exdump_info acpi_ex_dump_package[5] = { static struct acpi_exdump_info acpi_ex_dump_device[4] = { {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_device), NULL}, - {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(device.handler), "Handler"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(device.notify_list[0]), "System Notify"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(device.notify_list[1]), - "Device Notify"} + "Device Notify"}, + {ACPI_EXD_HDLR_LIST, ACPI_EXD_OFFSET(device.handler), "Handler"} }; static struct acpi_exdump_info acpi_ex_dump_event[2] = { @@ -142,17 +143,18 @@ static struct acpi_exdump_info acpi_ex_dump_mutex[5] = { {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.os_mutex), "OsMutex"} }; -static struct acpi_exdump_info acpi_ex_dump_region[7] = { +static struct acpi_exdump_info acpi_ex_dump_region[8] = { {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_region), NULL}, {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(region.space_id), "Space Id"}, {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(region.flags), "Flags"}, + {ACPI_EXD_NODE, ACPI_EXD_OFFSET(region.node), "Parent Node"}, {ACPI_EXD_ADDRESS, ACPI_EXD_OFFSET(region.address), "Address"}, {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(region.length), "Length"}, - {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(region.handler), "Handler"}, + {ACPI_EXD_HDLR_LIST, ACPI_EXD_OFFSET(region.handler), "Handler"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(region.next), "Next"} }; -static struct acpi_exdump_info acpi_ex_dump_power[5] = { +static struct acpi_exdump_info acpi_ex_dump_power[6] = { {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_power), NULL}, {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(power_resource.system_level), "System Level"}, @@ -161,7 +163,8 @@ static struct acpi_exdump_info acpi_ex_dump_power[5] = { {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(power_resource.notify_list[0]), "System Notify"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(power_resource.notify_list[1]), - "Device Notify"} + "Device Notify"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(power_resource.handler), "Handler"} }; static struct acpi_exdump_info acpi_ex_dump_processor[7] = { @@ -225,7 +228,7 @@ static struct acpi_exdump_info acpi_ex_dump_reference[8] = { {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(reference.target_type), "Target Type"}, {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(reference.value), "Value"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.object), "Object Desc"}, - {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.node), "Node"}, + {ACPI_EXD_NODE, ACPI_EXD_OFFSET(reference.node), "Node"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.where), "Where"}, {ACPI_EXD_REFERENCE, 0, NULL} }; @@ -234,16 +237,16 @@ static struct acpi_exdump_info acpi_ex_dump_address_handler[6] = { {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_address_handler), NULL}, {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(address_space.space_id), "Space Id"}, - {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(address_space.next), "Next"}, - {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(address_space.region_list), + {ACPI_EXD_HDLR_LIST, ACPI_EXD_OFFSET(address_space.next), "Next"}, + {ACPI_EXD_RGN_LIST, ACPI_EXD_OFFSET(address_space.region_list), "Region List"}, - {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(address_space.node), "Node"}, + {ACPI_EXD_NODE, ACPI_EXD_OFFSET(address_space.node), "Node"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(address_space.context), "Context"} }; static struct acpi_exdump_info acpi_ex_dump_notify[7] = { {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_notify), NULL}, - {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(notify.node), "Node"}, + {ACPI_EXD_NODE, ACPI_EXD_OFFSET(notify.node), "Node"}, {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(notify.handler_type), "Handler Type"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(notify.handler), "Handler"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(notify.context), "Context"}, @@ -252,14 +255,31 @@ static struct acpi_exdump_info acpi_ex_dump_notify[7] = { {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(notify.next[1]), "Next Device Notify"} }; +static struct acpi_exdump_info acpi_ex_dump_extra[6] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_extra), NULL}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(extra.method_REG), "_REG Method"}, + {ACPI_EXD_NODE, ACPI_EXD_OFFSET(extra.scope_node), "Scope Node"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(extra.region_context), + "Region Context"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(extra.aml_start), "Aml Start"}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(extra.aml_length), "Aml Length"} +}; + +static struct acpi_exdump_info acpi_ex_dump_data[3] = { + {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_data), NULL}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(data.handler), "Handler"}, + {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(data.pointer), "Raw Data"} +}; + /* Miscellaneous tables */ -static struct acpi_exdump_info acpi_ex_dump_common[4] = { +static struct acpi_exdump_info acpi_ex_dump_common[5] = { {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_common), NULL}, {ACPI_EXD_TYPE, 0, NULL}, {ACPI_EXD_UINT16, ACPI_EXD_OFFSET(common.reference_count), "Reference Count"}, - {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(common.flags), "Flags"} + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(common.flags), "Flags"}, + {ACPI_EXD_LIST, ACPI_EXD_OFFSET(common.next_object), "Object List"} }; static struct acpi_exdump_info acpi_ex_dump_field_common[7] = { @@ -274,15 +294,17 @@ static struct acpi_exdump_info acpi_ex_dump_field_common[7] = { "Field Bit Offset"}, {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(common_field.base_byte_offset), "Base Byte Offset"}, - {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(common_field.node), "Parent Node"} + {ACPI_EXD_NODE, ACPI_EXD_OFFSET(common_field.node), "Parent Node"} }; -static struct acpi_exdump_info acpi_ex_dump_node[5] = { +static struct acpi_exdump_info acpi_ex_dump_node[7] = { {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_node), NULL}, {ACPI_EXD_UINT8, ACPI_EXD_NSOFFSET(flags), "Flags"}, {ACPI_EXD_UINT8, ACPI_EXD_NSOFFSET(owner_id), "Owner Id"}, - {ACPI_EXD_POINTER, ACPI_EXD_NSOFFSET(child), "Child List"}, - {ACPI_EXD_POINTER, ACPI_EXD_NSOFFSET(peer), "Next Peer"} + {ACPI_EXD_LIST, ACPI_EXD_NSOFFSET(object), "Object List"}, + {ACPI_EXD_NODE, ACPI_EXD_NSOFFSET(parent), "Parent"}, + {ACPI_EXD_NODE, ACPI_EXD_NSOFFSET(child), "Child"}, + {ACPI_EXD_NODE, ACPI_EXD_NSOFFSET(peer), "Peer"} }; /* Dispatch table, indexed by object type */ @@ -315,7 +337,9 @@ static struct acpi_exdump_info *acpi_ex_dump_info[] = { acpi_ex_dump_address_handler, NULL, NULL, - NULL + NULL, + acpi_ex_dump_extra, + acpi_ex_dump_data }; /******************************************************************************* @@ -340,6 +364,10 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, char *name; const char *reference_name; u8 count; + union acpi_operand_object *start; + union acpi_operand_object *data = NULL; + union acpi_operand_object *next; + struct acpi_namespace_node *node; if (!info) { acpi_os_printf @@ -363,9 +391,9 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, case ACPI_EXD_TYPE: - acpi_ex_out_string("Type", - acpi_ut_get_object_type_name - (obj_desc)); + acpi_os_printf("%20s : %2.2X [%s]\n", "Type", + obj_desc->common.type, + acpi_ut_get_object_type_name(obj_desc)); break; case ACPI_EXD_UINT8: @@ -433,6 +461,121 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, acpi_ex_dump_reference_obj(obj_desc); break; + case ACPI_EXD_LIST: + + start = *ACPI_CAST_PTR(void *, target); + next = start; + + acpi_os_printf("%20s : %p", name, next); + if (next) { + acpi_os_printf("(%s %2.2X)", + acpi_ut_get_object_type_name + (next), next->common.type); + + while (next->common.next_object) { + if ((next->common.type == + ACPI_TYPE_LOCAL_DATA) && !data) { + data = next; + } + + next = next->common.next_object; + acpi_os_printf("->%p(%s %2.2X)", next, + acpi_ut_get_object_type_name + (next), + next->common.type); + + if ((next == start) || (next == data)) { + acpi_os_printf + ("\n**** Error: Object list appears to be circular linked"); + break; + } + } + } + + acpi_os_printf("\n", next); + break; + + case ACPI_EXD_HDLR_LIST: + + start = *ACPI_CAST_PTR(void *, target); + next = start; + + acpi_os_printf("%20s : %p", name, next); + if (next) { + acpi_os_printf("(%s %2.2X)", + acpi_ut_get_object_type_name + (next), next->common.type); + + while (next->address_space.next) { + if ((next->common.type == + ACPI_TYPE_LOCAL_DATA) && !data) { + data = next; + } + + next = next->address_space.next; + acpi_os_printf("->%p(%s %2.2X)", next, + acpi_ut_get_object_type_name + (next), + next->common.type); + + if ((next == start) || (next == data)) { + acpi_os_printf + ("\n**** Error: Handler list appears to be circular linked"); + break; + } + } + } + + acpi_os_printf("\n", next); + break; + + case ACPI_EXD_RGN_LIST: + + start = *ACPI_CAST_PTR(void *, target); + next = start; + + acpi_os_printf("%20s : %p", name, next); + if (next) { + acpi_os_printf("(%s %2.2X)", + acpi_ut_get_object_type_name + (next), next->common.type); + + while (next->region.next) { + if ((next->common.type == + ACPI_TYPE_LOCAL_DATA) && !data) { + data = next; + } + + next = next->region.next; + acpi_os_printf("->%p(%s %2.2X)", next, + acpi_ut_get_object_type_name + (next), + next->common.type); + + if ((next == start) || (next == data)) { + acpi_os_printf + ("\n**** Error: Region list appears to be circular linked"); + break; + } + } + } + + acpi_os_printf("\n", next); + break; + + case ACPI_EXD_NODE: + + node = + *ACPI_CAST_PTR(struct acpi_namespace_node *, + target); + + acpi_os_printf("%20s : %p", name, node); + if (node) { + acpi_os_printf(" [%4.4s]", node->name.ascii); + } + acpi_os_printf("\n"); + break; + default: acpi_os_printf("**** Invalid table opcode [%X] ****\n", @@ -821,10 +964,8 @@ void acpi_ex_dump_namespace_node(struct acpi_namespace_node *node, u32 flags) } acpi_os_printf("%20s : %4.4s\n", "Name", acpi_ut_get_node_name(node)); - acpi_ex_out_string("Type", acpi_ut_get_type_name(node->type)); - acpi_ex_out_pointer("Attached Object", - acpi_ns_get_attached_object(node)); - acpi_ex_out_pointer("Parent", node->parent); + acpi_os_printf("%20s : %2.2X [%s]\n", "Type", + node->type, acpi_ut_get_type_name(node->type)); acpi_ex_dump_object(ACPI_CAST_PTR(union acpi_operand_object, node), acpi_ex_dump_node); @@ -1017,22 +1158,26 @@ acpi_ex_dump_object_descriptor(union acpi_operand_object *obj_desc, u32 flags) ((struct acpi_namespace_node *)obj_desc)-> object); - acpi_ex_dump_object_descriptor(((struct acpi_namespace_node *) - obj_desc)->object, flags); - return_VOID; + obj_desc = ((struct acpi_namespace_node *)obj_desc)->object; + goto dump_object; } if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) { - acpi_os_printf - ("ExDumpObjectDescriptor: %p is not an ACPI operand object: [%s]\n", - obj_desc, acpi_ut_get_descriptor_name(obj_desc)); + acpi_os_printf("%p is not an ACPI operand object: [%s]\n", + obj_desc, acpi_ut_get_descriptor_name(obj_desc)); return_VOID; } - if (obj_desc->common.type > ACPI_TYPE_NS_NODE_MAX) { + /* Validate the object type */ + + if (obj_desc->common.type > ACPI_TYPE_LOCAL_MAX) { + acpi_os_printf("Not a known object type: %2.2X\n", + obj_desc->common.type); return_VOID; } +dump_object: + /* Common Fields */ acpi_ex_dump_object(obj_desc, acpi_ex_dump_common); @@ -1040,6 +1185,22 @@ acpi_ex_dump_object_descriptor(union acpi_operand_object *obj_desc, u32 flags) /* Object-specific fields */ acpi_ex_dump_object(obj_desc, acpi_ex_dump_info[obj_desc->common.type]); + + if (obj_desc->common.type == ACPI_TYPE_REGION) { + obj_desc = obj_desc->common.next_object; + if (obj_desc->common.type > ACPI_TYPE_LOCAL_MAX) { + acpi_os_printf + ("Secondary object is not a known object type: %2.2X\n", + obj_desc->common.type); + + return_VOID; + } + + acpi_os_printf("\nExtra attached Object (%p):\n", obj_desc); + acpi_ex_dump_object(obj_desc, + acpi_ex_dump_info[obj_desc->common.type]); + } + return_VOID; } diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c index cfd875243421..68d97441432c 100644 --- a/drivers/acpi/acpica/exfield.c +++ b/drivers/acpi/acpica/exfield.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c index 49fb742d61b9..1d1b27a96c5b 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exmisc.c b/drivers/acpi/acpica/exmisc.c index 65d93607f368..2207e624f538 100644 --- a/drivers/acpi/acpica/exmisc.c +++ b/drivers/acpi/acpica/exmisc.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c index 7be0205ad067..b49ea2a95f4f 100644 --- a/drivers/acpi/acpica/exmutex.c +++ b/drivers/acpi/acpica/exmutex.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exnames.c b/drivers/acpi/acpica/exnames.c index 14689dec4960..dbb03b544e8c 100644 --- a/drivers/acpi/acpica/exnames.c +++ b/drivers/acpi/acpica/exnames.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c index d74cea416ca0..1b8e94104407 100644 --- a/drivers/acpi/acpica/exoparg1.c +++ b/drivers/acpi/acpica/exoparg1.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exoparg2.c b/drivers/acpi/acpica/exoparg2.c index d6fa0fce1fc9..2ede656ee26a 100644 --- a/drivers/acpi/acpica/exoparg2.c +++ b/drivers/acpi/acpica/exoparg2.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exoparg3.c b/drivers/acpi/acpica/exoparg3.c index bc042adf8804..363767cf01e5 100644 --- a/drivers/acpi/acpica/exoparg3.c +++ b/drivers/acpi/acpica/exoparg3.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exoparg6.c b/drivers/acpi/acpica/exoparg6.c index 4459e32c683d..29e9e99f7fe3 100644 --- a/drivers/acpi/acpica/exoparg6.c +++ b/drivers/acpi/acpica/exoparg6.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c index 5a588611ab48..ee3f872870bc 100644 --- a/drivers/acpi/acpica/exprep.c +++ b/drivers/acpi/acpica/exprep.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c index 9d28867e60dc..cd5288a257a9 100644 --- a/drivers/acpi/acpica/exregion.c +++ b/drivers/acpi/acpica/exregion.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exresnte.c b/drivers/acpi/acpica/exresnte.c index 7ca6925a87ca..ab060261b43e 100644 --- a/drivers/acpi/acpica/exresnte.c +++ b/drivers/acpi/acpica/exresnte.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exresolv.c b/drivers/acpi/acpica/exresolv.c index 1606524312e3..3cde553bcbe1 100644 --- a/drivers/acpi/acpica/exresolv.c +++ b/drivers/acpi/acpica/exresolv.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exresop.c b/drivers/acpi/acpica/exresop.c index be3f66973ee8..3af8de3fcea4 100644 --- a/drivers/acpi/acpica/exresop.c +++ b/drivers/acpi/acpica/exresop.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c index f0b09bf9887d..daf49f7ea311 100644 --- a/drivers/acpi/acpica/exstore.c +++ b/drivers/acpi/acpica/exstore.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exstoren.c b/drivers/acpi/acpica/exstoren.c index 20d809d90c5b..04bd16c08f9e 100644 --- a/drivers/acpi/acpica/exstoren.c +++ b/drivers/acpi/acpica/exstoren.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exstorob.c b/drivers/acpi/acpica/exstorob.c index 26e371073b1a..fd11018b0168 100644 --- a/drivers/acpi/acpica/exstorob.c +++ b/drivers/acpi/acpica/exstorob.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exsystem.c b/drivers/acpi/acpica/exsystem.c index 6578dee2e51b..f7da64123ed5 100644 --- a/drivers/acpi/acpica/exsystem.c +++ b/drivers/acpi/acpica/exsystem.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -77,7 +77,7 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) /* We must wait, so unlock the interpreter */ - acpi_ex_relinquish_interpreter(); + acpi_ex_exit_interpreter(); status = acpi_os_wait_semaphore(semaphore, 1, timeout); @@ -87,7 +87,7 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) /* Reacquire the interpreter */ - acpi_ex_reacquire_interpreter(); + acpi_ex_enter_interpreter(); } return_ACPI_STATUS(status); @@ -123,7 +123,7 @@ acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout) /* We must wait, so unlock the interpreter */ - acpi_ex_relinquish_interpreter(); + acpi_ex_exit_interpreter(); status = acpi_os_acquire_mutex(mutex, timeout); @@ -133,7 +133,7 @@ acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout) /* Reacquire the interpreter */ - acpi_ex_reacquire_interpreter(); + acpi_ex_enter_interpreter(); } return_ACPI_STATUS(status); @@ -198,7 +198,7 @@ acpi_status acpi_ex_system_do_sleep(u64 how_long) /* Since this thread will sleep, we must release the interpreter */ - acpi_ex_relinquish_interpreter(); + acpi_ex_exit_interpreter(); /* * For compatibility with other ACPI implementations and to prevent @@ -212,7 +212,7 @@ acpi_status acpi_ex_system_do_sleep(u64 how_long) /* And now we must get the interpreter again */ - acpi_ex_reacquire_interpreter(); + acpi_ex_enter_interpreter(); return (AE_OK); } diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c index 99dc7b287d55..d9d72dff2a76 100644 --- a/drivers/acpi/acpica/exutils.c +++ b/drivers/acpi/acpica/exutils.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -100,37 +100,6 @@ void acpi_ex_enter_interpreter(void) /******************************************************************************* * - * FUNCTION: acpi_ex_reacquire_interpreter - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Reacquire the interpreter execution region from within the - * interpreter code. Failure to enter the interpreter region is a - * fatal system error. Used in conjunction with - * relinquish_interpreter - * - ******************************************************************************/ - -void acpi_ex_reacquire_interpreter(void) -{ - ACPI_FUNCTION_TRACE(ex_reacquire_interpreter); - - /* - * If the global serialized flag is set, do not release the interpreter, - * since it was not actually released by acpi_ex_relinquish_interpreter. - * This forces the interpreter to be single threaded. - */ - if (!acpi_gbl_all_methods_serialized) { - acpi_ex_enter_interpreter(); - } - - return_VOID; -} - -/******************************************************************************* - * * FUNCTION: acpi_ex_exit_interpreter * * PARAMETERS: None @@ -139,7 +108,16 @@ void acpi_ex_reacquire_interpreter(void) * * DESCRIPTION: Exit the interpreter execution region. This is the top level * routine used to exit the interpreter when all processing has - * been completed. + * been completed, or when the method blocks. + * + * Cases where the interpreter is unlocked internally: + * 1) Method will be blocked on a Sleep() AML opcode + * 2) Method will be blocked on an Acquire() AML opcode + * 3) Method will be blocked on a Wait() AML opcode + * 4) Method will be blocked to acquire the global lock + * 5) Method will be blocked waiting to execute a serialized control + * method that is currently executing + * 6) About to invoke a user-installed opregion handler * ******************************************************************************/ @@ -160,44 +138,6 @@ void acpi_ex_exit_interpreter(void) /******************************************************************************* * - * FUNCTION: acpi_ex_relinquish_interpreter - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Exit the interpreter execution region, from within the - * interpreter - before attempting an operation that will possibly - * block the running thread. - * - * Cases where the interpreter is unlocked internally - * 1) Method to be blocked on a Sleep() AML opcode - * 2) Method to be blocked on an Acquire() AML opcode - * 3) Method to be blocked on a Wait() AML opcode - * 4) Method to be blocked to acquire the global lock - * 5) Method to be blocked waiting to execute a serialized control method - * that is currently executing - * 6) About to invoke a user-installed opregion handler - * - ******************************************************************************/ - -void acpi_ex_relinquish_interpreter(void) -{ - ACPI_FUNCTION_TRACE(ex_relinquish_interpreter); - - /* - * If the global serialized flag is set, do not release the interpreter. - * This forces the interpreter to be single threaded. - */ - if (!acpi_gbl_all_methods_serialized) { - acpi_ex_exit_interpreter(); - } - - return_VOID; -} - -/******************************************************************************* - * * FUNCTION: acpi_ex_truncate_for32bit_table * * PARAMETERS: obj_desc - Object to be truncated diff --git a/drivers/acpi/acpica/hwacpi.c b/drivers/acpi/acpica/hwacpi.c index 3d36df828f52..1e66d960fc11 100644 --- a/drivers/acpi/acpica/hwacpi.c +++ b/drivers/acpi/acpica/hwacpi.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwesleep.c b/drivers/acpi/acpica/hwesleep.c index 414076818d40..858fdd6be598 100644 --- a/drivers/acpi/acpica/hwesleep.c +++ b/drivers/acpi/acpica/hwesleep.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index 96540506058f..2e6caabba07a 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwpci.c b/drivers/acpi/acpica/hwpci.c index 0889a629505f..e701d8c33dbf 100644 --- a/drivers/acpi/acpica/hwpci.c +++ b/drivers/acpi/acpica/hwpci.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index 12e6cff54f78..e0fd9b4978cd 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c index e3828cc4361b..d590693eb54e 100644 --- a/drivers/acpi/acpica/hwsleep.c +++ b/drivers/acpi/acpica/hwsleep.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwtimer.c b/drivers/acpi/acpica/hwtimer.c index 3c498dc1636e..76ab5c1a814e 100644 --- a/drivers/acpi/acpica/hwtimer.c +++ b/drivers/acpi/acpica/hwtimer.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c index eab70d58852a..6b919127cd9d 100644 --- a/drivers/acpi/acpica/hwvalid.c +++ b/drivers/acpi/acpica/hwvalid.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c index b4b47db2dee2..96d007df65ec 100644 --- a/drivers/acpi/acpica/hwxface.c +++ b/drivers/acpi/acpica/hwxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwxfsleep.c b/drivers/acpi/acpica/hwxfsleep.c index 15dddc10fc9b..6921c7f3d208 100644 --- a/drivers/acpi/acpica/hwxfsleep.c +++ b/drivers/acpi/acpica/hwxfsleep.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c index 14f65f6345b9..f1249e3463be 100644 --- a/drivers/acpi/acpica/nsaccess.c +++ b/drivers/acpi/acpica/nsaccess.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c index fd1ff54cda19..607eb9e5150d 100644 --- a/drivers/acpi/acpica/nsalloc.c +++ b/drivers/acpi/acpica/nsalloc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsarguments.c b/drivers/acpi/acpica/nsarguments.c index 74b24c82707e..80fcfc8c9c1b 100644 --- a/drivers/acpi/acpica/nsarguments.c +++ b/drivers/acpi/acpica/nsarguments.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsconvert.c b/drivers/acpi/acpica/nsconvert.c index acd2964c2690..b55642c4ee58 100644 --- a/drivers/acpi/acpica/nsconvert.c +++ b/drivers/acpi/acpica/nsconvert.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c index 48b9c6f12643..3d88ef4a3e0d 100644 --- a/drivers/acpi/acpica/nsdump.c +++ b/drivers/acpi/acpica/nsdump.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsdumpdv.c b/drivers/acpi/acpica/nsdumpdv.c index 283762511b73..42d37109aa5d 100644 --- a/drivers/acpi/acpica/nsdumpdv.c +++ b/drivers/acpi/acpica/nsdumpdv.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c index 963ceef063f8..e634a05974db 100644 --- a/drivers/acpi/acpica/nseval.c +++ b/drivers/acpi/acpica/nseval.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c index 3a0423af968c..a3fb7e4c0809 100644 --- a/drivers/acpi/acpica/nsinit.c +++ b/drivers/acpi/acpica/nsinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -111,9 +111,8 @@ acpi_status acpi_ns_initialize_objects(void) info.object_count)); ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "%u Control Methods found\n", info.method_count)); - ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "%u Op Regions found\n", info.op_region_count)); + "%u Control Methods found\n%u Op Regions found\n", + info.method_count, info.op_region_count)); return_ACPI_STATUS(AE_OK); } diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c index 89ec645e7730..7c9d0181f341 100644 --- a/drivers/acpi/acpica/nsload.c +++ b/drivers/acpi/acpica/nsload.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -128,12 +128,12 @@ unlock: * parse trees. */ ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "**** Begin Table Method Parsing and Object Initialization\n")); + "**** Begin Table Object Initialization\n")); status = acpi_ds_initialize_objects(table_index, node); ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "**** Completed Table Method Parsing and Object Initialization\n")); + "**** Completed Table Object Initialization\n")); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/acpica/nsnames.c b/drivers/acpi/acpica/nsnames.c index 90a0380fb8a0..7eee0a6f02f6 100644 --- a/drivers/acpi/acpica/nsnames.c +++ b/drivers/acpi/acpica/nsnames.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c index 7a736f4d1fd8..fe54a8c73b8c 100644 --- a/drivers/acpi/acpica/nsobject.c +++ b/drivers/acpi/acpica/nsobject.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -222,13 +222,19 @@ void acpi_ns_detach_object(struct acpi_namespace_node *node) } } - /* Clear the entry in all cases */ + /* Clear the Node entry in all cases */ node->object = NULL; if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_OPERAND) { + + /* Unlink object from front of possible object list */ + node->object = obj_desc->common.next_object; + + /* Handle possible 2-descriptor object */ + if (node->object && - ((node->object)->common.type != ACPI_TYPE_LOCAL_DATA)) { + (node->object->common.type != ACPI_TYPE_LOCAL_DATA)) { node->object = node->object->common.next_object; } } diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c index 177857340271..e83cff31754b 100644 --- a/drivers/acpi/acpica/nsparse.c +++ b/drivers/acpi/acpica/nsparse.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index d2855d9857c4..392910ffbed9 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsprepkg.c b/drivers/acpi/acpica/nsprepkg.c index 3d5391f9bcb5..68f725839eb6 100644 --- a/drivers/acpi/acpica/nsprepkg.c +++ b/drivers/acpi/acpica/nsprepkg.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -132,12 +132,12 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, * Decode the type of the expected package contents * * PTYPE1 packages contain no subpackages - * PTYPE2 packages contain sub-packages + * PTYPE2 packages contain subpackages */ switch (package->ret_info.type) { case ACPI_PTYPE1_FIXED: /* - * The package count is fixed and there are no sub-packages + * The package count is fixed and there are no subpackages * * If package is too small, exit. * If package is larger than expected, issue warning but continue @@ -169,7 +169,7 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, case ACPI_PTYPE1_VAR: /* - * The package count is variable, there are no sub-packages, and all + * The package count is variable, there are no subpackages, and all * elements must be of the same type */ for (i = 0; i < count; i++) { @@ -185,7 +185,7 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, case ACPI_PTYPE1_OPTION: /* - * The package count is variable, there are no sub-packages. There are + * The package count is variable, there are no subpackages. There are * a fixed number of required elements, and a variable number of * optional elements. * @@ -242,7 +242,7 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, elements++; count--; - /* Examine the sub-packages */ + /* Examine the subpackages */ status = acpi_ns_check_package_list(info, package, elements, count); @@ -250,7 +250,7 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, case ACPI_PTYPE2_PKG_COUNT: - /* First element is the (Integer) count of sub-packages to follow */ + /* First element is the (Integer) count of subpackages to follow */ status = acpi_ns_check_object_type(info, elements, ACPI_RTYPE_INTEGER, 0); @@ -270,7 +270,7 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, count = expected_count; elements++; - /* Examine the sub-packages */ + /* Examine the subpackages */ status = acpi_ns_check_package_list(info, package, elements, count); @@ -283,9 +283,9 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, case ACPI_PTYPE2_FIX_VAR: /* * These types all return a single Package that consists of a - * variable number of sub-Packages. + * variable number of subpackages. * - * First, ensure that the first element is a sub-Package. If not, + * First, ensure that the first element is a subpackage. If not, * the BIOS may have incorrectly returned the object as a single * package instead of a Package of Packages (a common error if * there is only one entry). We may be able to repair this by @@ -310,7 +310,7 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, count = 1; } - /* Examine the sub-packages */ + /* Examine the subpackages */ status = acpi_ns_check_package_list(info, package, elements, count); @@ -370,9 +370,9 @@ acpi_ns_check_package_list(struct acpi_evaluate_info *info, u32 j; /* - * Validate each sub-Package in the parent Package + * Validate each subpackage in the parent Package * - * NOTE: assumes list of sub-packages contains no NULL elements. + * NOTE: assumes list of subpackages contains no NULL elements. * Any NULL elements should have been removed by earlier call * to acpi_ns_remove_null_elements. */ @@ -389,7 +389,7 @@ acpi_ns_check_package_list(struct acpi_evaluate_info *info, return (status); } - /* Examine the different types of expected sub-packages */ + /* Examine the different types of expected subpackages */ info->parent_package = sub_package; switch (package->ret_info.type) { @@ -450,14 +450,14 @@ acpi_ns_check_package_list(struct acpi_evaluate_info *info, case ACPI_PTYPE2_FIXED: - /* Each sub-package has a fixed length */ + /* Each subpackage has a fixed length */ expected_count = package->ret_info2.count; if (sub_package->package.count < expected_count) { goto package_too_small; } - /* Check the type of each sub-package element */ + /* Check the type of each subpackage element */ for (j = 0; j < expected_count; j++) { status = @@ -475,14 +475,14 @@ acpi_ns_check_package_list(struct acpi_evaluate_info *info, case ACPI_PTYPE2_MIN: - /* Each sub-package has a variable but minimum length */ + /* Each subpackage has a variable but minimum length */ expected_count = package->ret_info.count1; if (sub_package->package.count < expected_count) { goto package_too_small; } - /* Check the type of each sub-package element */ + /* Check the type of each subpackage element */ status = acpi_ns_check_package_elements(info, sub_elements, @@ -531,7 +531,7 @@ acpi_ns_check_package_list(struct acpi_evaluate_info *info, (*sub_elements)->integer.value = expected_count; } - /* Check the type of each sub-package element */ + /* Check the type of each subpackage element */ status = acpi_ns_check_package_elements(info, @@ -557,10 +557,10 @@ acpi_ns_check_package_list(struct acpi_evaluate_info *info, package_too_small: - /* The sub-package count was smaller than required */ + /* The subpackage count was smaller than required */ ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, info->node_flags, - "Return Sub-Package[%u] is too small - found %u elements, expected %u", + "Return SubPackage[%u] is too small - found %u elements, expected %u", i, sub_package->package.count, expected_count)); return (AE_AML_OPERAND_VALUE); diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c index a05afff50eb9..7e417aa5c91e 100644 --- a/drivers/acpi/acpica/nsrepair.c +++ b/drivers/acpi/acpica/nsrepair.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -207,13 +207,30 @@ acpi_ns_simple_repair(struct acpi_evaluate_info *info, * this predefined name. Either one return value is expected, or none, * for both methods and other objects. * - * Exit now if there is no return object. Warning if one was expected. + * Try to fix if there was no return object. Warning if failed to fix. */ if (!return_object) { if (expected_btypes && (!(expected_btypes & ACPI_RTYPE_NONE))) { - ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, - ACPI_WARN_ALWAYS, - "Missing expected return value")); + if (package_index != ACPI_NOT_PACKAGE_ELEMENT) { + ACPI_WARN_PREDEFINED((AE_INFO, + info->full_pathname, + ACPI_WARN_ALWAYS, + "Found unexpected NULL package element")); + + status = + acpi_ns_repair_null_element(info, + expected_btypes, + package_index, + return_object_ptr); + if (ACPI_SUCCESS(status)) { + return (AE_OK); /* Repair was successful */ + } + } else { + ACPI_WARN_PREDEFINED((AE_INFO, + info->full_pathname, + ACPI_WARN_ALWAYS, + "Missing expected return value")); + } return (AE_AML_NO_RETURN_VALUE); } @@ -448,7 +465,7 @@ acpi_ns_repair_null_element(struct acpi_evaluate_info * info, * RETURN: None. * * DESCRIPTION: Remove all NULL package elements from packages that contain - * a variable number of sub-packages. For these types of + * a variable number of subpackages. For these types of * packages, NULL elements can be safely removed. * *****************************************************************************/ @@ -469,7 +486,7 @@ acpi_ns_remove_null_elements(struct acpi_evaluate_info *info, /* * We can safely remove all NULL elements from these package types: * PTYPE1_VAR packages contain a variable number of simple data types. - * PTYPE2 packages contain a variable number of sub-packages. + * PTYPE2 packages contain a variable number of subpackages. */ switch (package_type) { case ACPI_PTYPE1_VAR: diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c index 6a25d320b169..b09e6bef72b8 100644 --- a/drivers/acpi/acpica/nsrepair2.c +++ b/drivers/acpi/acpica/nsrepair2.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -432,8 +432,8 @@ acpi_ns_repair_CID(struct acpi_evaluate_info *info, * DESCRIPTION: Repair for the _CST object: * 1. Sort the list ascending by C state type * 2. Ensure type cannot be zero - * 3. A sub-package count of zero means _CST is meaningless - * 4. Count must match the number of C state sub-packages + * 3. A subpackage count of zero means _CST is meaningless + * 4. Count must match the number of C state subpackages * *****************************************************************************/ @@ -611,6 +611,7 @@ acpi_ns_repair_PRT(struct acpi_evaluate_info *info, union acpi_operand_object **top_object_list; union acpi_operand_object **sub_object_list; union acpi_operand_object *obj_desc; + union acpi_operand_object *sub_package; u32 element_count; u32 index; @@ -619,8 +620,17 @@ acpi_ns_repair_PRT(struct acpi_evaluate_info *info, top_object_list = package_object->package.elements; element_count = package_object->package.count; - for (index = 0; index < element_count; index++) { - sub_object_list = (*top_object_list)->package.elements; + /* Examine each subpackage */ + + for (index = 0; index < element_count; index++, top_object_list++) { + sub_package = *top_object_list; + sub_object_list = sub_package->package.elements; + + /* Check for minimum required element count */ + + if (sub_package->package.count < 4) { + continue; + } /* * If the BIOS has erroneously reversed the _PRT source_name (index 2) @@ -634,15 +644,12 @@ acpi_ns_repair_PRT(struct acpi_evaluate_info *info, sub_object_list[2] = obj_desc; info->return_flags |= ACPI_OBJECT_REPAIRED; - ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, + ACPI_WARN_PREDEFINED((AE_INFO, + info->full_pathname, info->node_flags, "PRT[%X]: Fixed reversed SourceName and SourceIndex", index)); } - - /* Point to the next union acpi_operand_object in the top level package */ - - top_object_list++; } return (AE_OK); @@ -679,7 +686,7 @@ acpi_ns_repair_PSS(struct acpi_evaluate_info *info, u32 i; /* - * Entries (sub-packages) in the _PSS Package must be sorted by power + * Entries (subpackages) in the _PSS Package must be sorted by power * dissipation, in descending order. If it appears that the list is * incorrectly sorted, sort it. We sort by cpu_frequency, since this * should be proportional to the power. @@ -767,9 +774,9 @@ acpi_ns_repair_TSS(struct acpi_evaluate_info *info, * * PARAMETERS: info - Method execution information block * return_object - Pointer to the top-level returned object - * start_index - Index of the first sub-package - * expected_count - Minimum length of each sub-package - * sort_index - Sub-package entry to sort on + * start_index - Index of the first subpackage + * expected_count - Minimum length of each subpackage + * sort_index - Subpackage entry to sort on * sort_direction - Ascending or descending * sort_key_name - Name of the sort_index field * @@ -805,7 +812,7 @@ acpi_ns_check_sorted_list(struct acpi_evaluate_info *info, } /* - * NOTE: assumes list of sub-packages contains no NULL elements. + * NOTE: assumes list of subpackages contains no NULL elements. * Any NULL elements should have been removed by earlier call * to acpi_ns_remove_null_elements. */ @@ -832,7 +839,7 @@ acpi_ns_check_sorted_list(struct acpi_evaluate_info *info, return (AE_AML_OPERAND_TYPE); } - /* Each sub-package must have the minimum length */ + /* Each subpackage must have the minimum length */ if ((*outer_elements)->package.count < expected_count) { return (AE_AML_PACKAGE_LIMIT); diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c index 47420faef073..af1cc42a8aa1 100644 --- a/drivers/acpi/acpica/nssearch.c +++ b/drivers/acpi/acpica/nssearch.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index 4a0665b6bcc1..4a5e3f5c0ff7 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c index e81f15ef659a..4758a1f2ce22 100644 --- a/drivers/acpi/acpica/nswalk.c +++ b/drivers/acpi/acpica/nswalk.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c index 1f0c28ba50df..4bd558bf10d2 100644 --- a/drivers/acpi/acpica/nsxfeval.c +++ b/drivers/acpi/acpica/nsxfeval.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -923,19 +923,22 @@ ACPI_EXPORT_SYMBOL(acpi_detach_data) /******************************************************************************* * - * FUNCTION: acpi_get_data + * FUNCTION: acpi_get_data_full * * PARAMETERS: obj_handle - Namespace node * handler - Handler used in call to attach_data * data - Where the data is returned + * callback - function to execute before returning * * RETURN: Status * - * DESCRIPTION: Retrieve data that was previously attached to a namespace node. + * DESCRIPTION: Retrieve data that was previously attached to a namespace node + * and execute a callback before returning. * ******************************************************************************/ acpi_status -acpi_get_data(acpi_handle obj_handle, acpi_object_handler handler, void **data) +acpi_get_data_full(acpi_handle obj_handle, acpi_object_handler handler, + void **data, void (*callback)(void *)) { struct acpi_namespace_node *node; acpi_status status; @@ -960,10 +963,34 @@ acpi_get_data(acpi_handle obj_handle, acpi_object_handler handler, void **data) } status = acpi_ns_get_attached_data(node, handler, data); + if (ACPI_SUCCESS(status) && callback) { + callback(*data); + } unlock_and_exit: (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); return (status); } +ACPI_EXPORT_SYMBOL(acpi_get_data_full) + +/******************************************************************************* + * + * FUNCTION: acpi_get_data + * + * PARAMETERS: obj_handle - Namespace node + * handler - Handler used in call to attach_data + * data - Where the data is returned + * + * RETURN: Status + * + * DESCRIPTION: Retrieve data that was previously attached to a namespace node. + * + ******************************************************************************/ +acpi_status +acpi_get_data(acpi_handle obj_handle, acpi_object_handler handler, void **data) +{ + return acpi_get_data_full(obj_handle, handler, data, NULL); +} + ACPI_EXPORT_SYMBOL(acpi_get_data) diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c index 3a4bd3ff49a3..8c6c11ce9760 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsxfobj.c b/drivers/acpi/acpica/nsxfobj.c index 0e6d79e462d4..dae9401be7a2 100644 --- a/drivers/acpi/acpica/nsxfobj.c +++ b/drivers/acpi/acpica/nsxfobj.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psargs.c b/drivers/acpi/acpica/psargs.c index 91a5a69db80c..314d314340ae 100644 --- a/drivers/acpi/acpica/psargs.c +++ b/drivers/acpi/acpica/psargs.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c index 065b44ae538f..b058e2390fdd 100644 --- a/drivers/acpi/acpica/psloop.c +++ b/drivers/acpi/acpica/psloop.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -480,6 +480,10 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) status = AE_OK; } + if (status == AE_CTRL_TERMINATE) { + return_ACPI_STATUS(status); + } + status = acpi_ps_complete_op(walk_state, &op, status); diff --git a/drivers/acpi/acpica/psobject.c b/drivers/acpi/acpica/psobject.c index 95dc608a66a8..a6885077d59e 100644 --- a/drivers/acpi/acpica/psobject.c +++ b/drivers/acpi/acpica/psobject.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -219,7 +219,10 @@ acpi_ps_build_named_op(struct acpi_walk_state *walk_state, status = walk_state->descending_callback(walk_state, op); if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "During name lookup/catalog")); + if (status != AE_CTRL_TERMINATE) { + ACPI_EXCEPTION((AE_INFO, status, + "During name lookup/catalog")); + } return_ACPI_STATUS(status); } @@ -230,7 +233,7 @@ acpi_ps_build_named_op(struct acpi_walk_state *walk_state, status = acpi_ps_next_parse_state(walk_state, *op, status); if (ACPI_FAILURE(status)) { if (status == AE_CTRL_PENDING) { - return_ACPI_STATUS(AE_CTRL_PARSE_PENDING); + status = AE_CTRL_PARSE_PENDING; } return_ACPI_STATUS(status); } diff --git a/drivers/acpi/acpica/psopcode.c b/drivers/acpi/acpica/psopcode.c index 1b659e59710a..1755d2ac5656 100644 --- a/drivers/acpi/acpica/psopcode.c +++ b/drivers/acpi/acpica/psopcode.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psopinfo.c b/drivers/acpi/acpica/psopinfo.c index b0c9787dbe61..0d8d37ffd04d 100644 --- a/drivers/acpi/acpica/psopinfo.c +++ b/drivers/acpi/acpica/psopinfo.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psparse.c b/drivers/acpi/acpica/psparse.c index 79d9a28dedef..6d27b597394e 100644 --- a/drivers/acpi/acpica/psparse.c +++ b/drivers/acpi/acpica/psparse.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psscope.c b/drivers/acpi/acpica/psscope.c index 6a4b6fb39f32..32d250feea21 100644 --- a/drivers/acpi/acpica/psscope.c +++ b/drivers/acpi/acpica/psscope.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/pstree.c b/drivers/acpi/acpica/pstree.c index 877dc0de8df3..0b64181e7720 100644 --- a/drivers/acpi/acpica/pstree.c +++ b/drivers/acpi/acpica/pstree.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psutils.c b/drivers/acpi/acpica/psutils.c index 91fa73a6e55e..3cd48802eede 100644 --- a/drivers/acpi/acpica/psutils.c +++ b/drivers/acpi/acpica/psutils.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/pswalk.c b/drivers/acpi/acpica/pswalk.c index abd65624754f..9cb07e1e76d9 100644 --- a/drivers/acpi/acpica/pswalk.c +++ b/drivers/acpi/acpica/pswalk.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psxface.c b/drivers/acpi/acpica/psxface.c index fcb7a840e996..e135acaa5e1c 100644 --- a/drivers/acpi/acpica/psxface.c +++ b/drivers/acpi/acpica/psxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsaddr.c b/drivers/acpi/acpica/rsaddr.c index f3a9276ac665..916fd095ff34 100644 --- a/drivers/acpi/acpica/rsaddr.c +++ b/drivers/acpi/acpica/rsaddr.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c index b60c9cf82862..689556744b03 100644 --- a/drivers/acpi/acpica/rscalc.c +++ b/drivers/acpi/acpica/rscalc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -636,7 +636,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, for (index = 0; index < number_of_elements; index++) { - /* Dereference the sub-package */ + /* Dereference the subpackage */ package_element = *top_object_list; diff --git a/drivers/acpi/acpica/rscreate.c b/drivers/acpi/acpica/rscreate.c index 3a2ace93e62c..75d369050657 100644 --- a/drivers/acpi/acpica/rscreate.c +++ b/drivers/acpi/acpica/rscreate.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -273,7 +273,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, */ user_prt->length = (sizeof(struct acpi_pci_routing_table) - 4); - /* Each sub-package must be of length 4 */ + /* Each subpackage must be of length 4 */ if ((*top_object_list)->package.count != 4) { ACPI_ERROR((AE_INFO, @@ -283,7 +283,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, } /* - * Dereference the sub-package. + * Dereference the subpackage. * The sub_object_list will now point to an array of the four IRQ * elements: [Address, Pin, Source, source_index] */ @@ -292,7 +292,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 (obj_desc->common.type != ACPI_TYPE_INTEGER) { + if (!obj_desc || obj_desc->common.type != ACPI_TYPE_INTEGER) { ACPI_ERROR((AE_INFO, "(PRT[%u].Address) Need Integer, found %s", index, @@ -305,7 +305,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, /* 2) Second subobject: Dereference the PRT.Pin */ obj_desc = sub_object_list[1]; - if (obj_desc->common.type != ACPI_TYPE_INTEGER) { + if (!obj_desc || obj_desc->common.type != ACPI_TYPE_INTEGER) { ACPI_ERROR((AE_INFO, "(PRT[%u].Pin) Need Integer, found %s", index, @@ -394,7 +394,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[3]; - if (obj_desc->common.type != ACPI_TYPE_INTEGER) { + if (!obj_desc || obj_desc->common.type != ACPI_TYPE_INTEGER) { ACPI_ERROR((AE_INFO, "(PRT[%u].SourceIndex) Need Integer, found %s", index, diff --git a/drivers/acpi/acpica/rsdump.c b/drivers/acpi/acpica/rsdump.c index 8a2d4986b0aa..c3c56b5a9788 100644 --- a/drivers/acpi/acpica/rsdump.c +++ b/drivers/acpi/acpica/rsdump.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -47,7 +47,8 @@ #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rsdump") -#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) + +#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DISASSEMBLER) || defined(ACPI_DEBUGGER) /* Local prototypes */ static void acpi_rs_out_string(char *title, char *value); diff --git a/drivers/acpi/acpica/rsdumpinfo.c b/drivers/acpi/acpica/rsdumpinfo.c index 46192bd53653..2f9332d5c973 100644 --- a/drivers/acpi/acpica/rsdumpinfo.c +++ b/drivers/acpi/acpica/rsdumpinfo.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -48,7 +48,7 @@ #define _COMPONENT ACPI_RESOURCES ACPI_MODULE_NAME("rsdumpinfo") -#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) +#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DISASSEMBLER) || defined(ACPI_DEBUGGER) #define ACPI_RSD_OFFSET(f) (u8) ACPI_OFFSET (union acpi_resource_data,f) #define ACPI_PRT_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_pci_routing_table,f) #define ACPI_RSD_TABLE_SIZE(name) (sizeof(name) / sizeof (struct acpi_rsdump_info)) diff --git a/drivers/acpi/acpica/rsinfo.c b/drivers/acpi/acpica/rsinfo.c index 41fed78e0de6..9d3f8a9a24bd 100644 --- a/drivers/acpi/acpica/rsinfo.c +++ b/drivers/acpi/acpica/rsinfo.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -132,8 +132,7 @@ struct acpi_rsconvert_info *acpi_gbl_convert_resource_serial_bus_dispatch[] = { acpi_rs_convert_uart_serial_bus, }; -#ifdef ACPI_FUTURE_USAGE -#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) +#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DISASSEMBLER) || defined(ACPI_DEBUGGER) /* Dispatch table for resource dump functions */ @@ -168,7 +167,6 @@ struct acpi_rsdump_info *acpi_gbl_dump_serial_bus_dispatch[] = { }; #endif -#endif /* ACPI_FUTURE_USAGE */ /* * Base sizes for external AML resource descriptors, indexed by internal type. * Includes size of the descriptor header (1 byte for small descriptors, diff --git a/drivers/acpi/acpica/rsio.c b/drivers/acpi/acpica/rsio.c index ca183755a6f9..19d64873290a 100644 --- a/drivers/acpi/acpica/rsio.c +++ b/drivers/acpi/acpica/rsio.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsirq.c b/drivers/acpi/acpica/rsirq.c index 364decc1028a..3461f7db26df 100644 --- a/drivers/acpi/acpica/rsirq.c +++ b/drivers/acpi/acpica/rsirq.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rslist.c b/drivers/acpi/acpica/rslist.c index 6053aa182093..77291293af64 100644 --- a/drivers/acpi/acpica/rslist.c +++ b/drivers/acpi/acpica/rslist.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsmemory.c b/drivers/acpi/acpica/rsmemory.c index ebc773a1b350..eab4483ff5f8 100644 --- a/drivers/acpi/acpica/rsmemory.c +++ b/drivers/acpi/acpica/rsmemory.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsmisc.c b/drivers/acpi/acpica/rsmisc.c index c99cec9cefde..41eea4bc089c 100644 --- a/drivers/acpi/acpica/rsmisc.c +++ b/drivers/acpi/acpica/rsmisc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsserial.c b/drivers/acpi/acpica/rsserial.c index fe49fc43e10f..9e8407223d95 100644 --- a/drivers/acpi/acpica/rsserial.c +++ b/drivers/acpi/acpica/rsserial.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsutils.c b/drivers/acpi/acpica/rsutils.c index 14a7982c9961..897a5ceb0420 100644 --- a/drivers/acpi/acpica/rsutils.c +++ b/drivers/acpi/acpica/rsutils.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsxface.c b/drivers/acpi/acpica/rsxface.c index 01e476988aae..877ab9202133 100644 --- a/drivers/acpi/acpica/rsxface.c +++ b/drivers/acpi/acpica/rsxface.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index 8f89263ac47e..ec14588254d4 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbfind.c b/drivers/acpi/acpica/tbfind.c index e4f4f02d49e7..c12003947bd5 100644 --- a/drivers/acpi/acpica/tbfind.c +++ b/drivers/acpi/acpica/tbfind.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c index 634357d51fe9..e3040947e9a0 100644 --- a/drivers/acpi/acpica/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -292,10 +292,11 @@ struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header new_table = acpi_os_map_memory(new_address, new_table_length); if (!new_table) { ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, - "%4.4s %p Attempted physical table override failed", + "%4.4s " ACPI_PRINTF_UINT + " Attempted physical table override failed", table_header->signature, - ACPI_CAST_PTR(void, - table_desc->address))); + ACPI_FORMAT_TO_UINT(table_desc-> + address))); return (NULL); } @@ -308,11 +309,11 @@ struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header finish_override: - ACPI_INFO((AE_INFO, - "%4.4s %p %s table override, new table: %p", + ACPI_INFO((AE_INFO, "%4.4s " ACPI_PRINTF_UINT + " %s table override, new table: " ACPI_PRINTF_UINT, table_header->signature, - ACPI_CAST_PTR(void, table_desc->address), - override_type, new_table)); + ACPI_FORMAT_TO_UINT(table_desc->address), + override_type, ACPI_FORMAT_TO_UINT(new_table))); /* We can now unmap/delete the original table (if fully mapped) */ diff --git a/drivers/acpi/acpica/tbprint.c b/drivers/acpi/acpica/tbprint.c index 6866e767ba90..df3bb20ea325 100644 --- a/drivers/acpi/acpica/tbprint.c +++ b/drivers/acpi/acpica/tbprint.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -128,15 +128,17 @@ acpi_tb_print_table_header(acpi_physical_address address, struct acpi_table_header local_header; /* - * The reason that the Address is cast to a void pointer is so that we - * can use %p which will work properly on both 32-bit and 64-bit hosts. + * The reason that we use ACPI_PRINTF_UINT and ACPI_FORMAT_TO_UINT is to + * support both 32-bit and 64-bit hosts/addresses in a consistent manner. + * The %p specifier does not emit uniform output on all hosts. On some, + * leading zeros are not supported. */ if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) { /* FACS only has signature and length fields */ - ACPI_INFO((AE_INFO, "%4.4s %p %06X", - header->signature, ACPI_CAST_PTR(void, address), + ACPI_INFO((AE_INFO, "%-4.4s " ACPI_PRINTF_UINT " %06X", + header->signature, ACPI_FORMAT_TO_UINT(address), header->length)); } else if (ACPI_VALIDATE_RSDP_SIG(header->signature)) { @@ -147,8 +149,9 @@ acpi_tb_print_table_header(acpi_physical_address address, header)->oem_id, ACPI_OEM_ID_SIZE); acpi_tb_fix_string(local_header.oem_id, ACPI_OEM_ID_SIZE); - ACPI_INFO((AE_INFO, "RSDP %p %06X (v%.2d %6.6s)", - ACPI_CAST_PTR(void, address), + ACPI_INFO((AE_INFO, + "RSDP " ACPI_PRINTF_UINT " %06X (v%.2d %-6.6s)", + ACPI_FORMAT_TO_UINT(address), (ACPI_CAST_PTR(struct acpi_table_rsdp, header)-> revision > 0) ? ACPI_CAST_PTR(struct acpi_table_rsdp, @@ -162,8 +165,9 @@ acpi_tb_print_table_header(acpi_physical_address address, acpi_tb_cleanup_table_header(&local_header, header); ACPI_INFO((AE_INFO, - "%4.4s %p %06X (v%.2d %6.6s %8.8s %08X %4.4s %08X)", - local_header.signature, ACPI_CAST_PTR(void, address), + "%-4.4s " ACPI_PRINTF_UINT + " %06X (v%.2d %-6.6s %-8.8s %08X %-4.4s %08X)", + local_header.signature, ACPI_FORMAT_TO_UINT(address), local_header.length, local_header.revision, local_header.oem_id, local_header.oem_table_id, local_header.oem_revision, diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index 6412d3c301cb..a4702eee91a8 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c index db826eaadd1c..a1593159d9ea 100644 --- a/drivers/acpi/acpica/tbxface.c +++ b/drivers/acpi/acpica/tbxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c index 60b5a871833c..0909420fc776 100644 --- a/drivers/acpi/acpica/tbxfload.c +++ b/drivers/acpi/acpica/tbxfload.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c index e4e1468877c3..65ab8fed3d5e 100644 --- a/drivers/acpi/acpica/tbxfroot.c +++ b/drivers/acpi/acpica/tbxfroot.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utaddress.c b/drivers/acpi/acpica/utaddress.c index 2c2b6ae5dfc4..a1acec9d2ef3 100644 --- a/drivers/acpi/acpica/utaddress.c +++ b/drivers/acpi/acpica/utaddress.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utalloc.c b/drivers/acpi/acpica/utalloc.c index 1851762fc5b5..efac83c606dc 100644 --- a/drivers/acpi/acpica/utalloc.c +++ b/drivers/acpi/acpica/utalloc.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utbuffer.c b/drivers/acpi/acpica/utbuffer.c index 11fde93be120..3c1699740653 100644 --- a/drivers/acpi/acpica/utbuffer.c +++ b/drivers/acpi/acpica/utbuffer.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utcache.c b/drivers/acpi/acpica/utcache.c index cacd2fd9e665..78fde0aac487 100644 --- a/drivers/acpi/acpica/utcache.c +++ b/drivers/acpi/acpica/utcache.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c index edff4e653d9a..270c16464dd9 100644 --- a/drivers/acpi/acpica/utcopy.c +++ b/drivers/acpi/acpica/utcopy.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -535,10 +535,10 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object, case ACPI_TYPE_LOCAL_REFERENCE: - /* TBD: should validate incoming handle */ + /* An incoming reference is defined to be a namespace node */ - internal_object->reference.class = ACPI_REFCLASS_NAME; - internal_object->reference.node = + internal_object->reference.class = ACPI_REFCLASS_REFOF; + internal_object->reference.object = external_object->reference.handle; break; diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c index d971c8631263..21a20ac5b1e1 100644 --- a/drivers/acpi/acpica/utdebug.c +++ b/drivers/acpi/acpica/utdebug.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c index b3f31dd89a45..fbfa9eca011f 100644 --- a/drivers/acpi/acpica/utdecode.c +++ b/drivers/acpi/acpica/utdecode.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c index c07d2227ea42..a3516de213fa 100644 --- a/drivers/acpi/acpica/utdelete.c +++ b/drivers/acpi/acpica/utdelete.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -75,6 +75,7 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) union acpi_operand_object *handler_desc; union acpi_operand_object *second_desc; union acpi_operand_object *next_desc; + union acpi_operand_object *start_desc; union acpi_operand_object **last_obj_ptr; ACPI_FUNCTION_TRACE_PTR(ut_delete_internal_obj, object); @@ -235,10 +236,11 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) if (handler_desc) { next_desc = handler_desc->address_space.region_list; + start_desc = next_desc; last_obj_ptr = &handler_desc->address_space.region_list; - /* Remove the region object from the handler's list */ + /* Remove the region object from the handler list */ while (next_desc) { if (next_desc == object) { @@ -247,10 +249,19 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) break; } - /* Walk the linked list of handler */ + /* Walk the linked list of handlers */ last_obj_ptr = &next_desc->region.next; next_desc = next_desc->region.next; + + /* Prevent infinite loop if list is corrupted */ + + if (next_desc == start_desc) { + ACPI_ERROR((AE_INFO, + "Circular region list in address handler object %p", + handler_desc)); + return_VOID; + } } if (handler_desc->address_space.handler_flags & diff --git a/drivers/acpi/acpica/uterror.c b/drivers/acpi/acpica/uterror.c index 154fdcaa5830..8e544d4688cd 100644 --- a/drivers/acpi/acpica/uterror.c +++ b/drivers/acpi/acpica/uterror.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c index 16fb90506db7..8fed1482d228 100644 --- a/drivers/acpi/acpica/uteval.c +++ b/drivers/acpi/acpica/uteval.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utexcep.c b/drivers/acpi/acpica/utexcep.c index 3cf7b597edb9..0403dcaabaf2 100644 --- a/drivers/acpi/acpica/utexcep.c +++ b/drivers/acpi/acpica/utexcep.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index 030cb0dc673c..f3abeae9d2f8 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -55,31 +55,27 @@ ACPI_MODULE_NAME("utglobal") * Static global variable initialization. * ******************************************************************************/ -/* - * We want the debug switches statically initialized so they - * are already set when the debugger is entered. - */ -/* Debug switch - level and trace mask */ +/* Debug output control masks */ u32 acpi_dbg_level = ACPI_DEBUG_DEFAULT; -/* Debug switch - layer (component) mask */ - u32 acpi_dbg_layer = 0; -u32 acpi_gbl_nesting_level = 0; -/* Debugger globals */ +/* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */ -u8 acpi_gbl_db_terminate_threads = FALSE; -u8 acpi_gbl_abort_method = FALSE; -u8 acpi_gbl_method_executing = FALSE; +struct acpi_table_fadt acpi_gbl_FADT; +u32 acpi_gbl_trace_flags; +acpi_name acpi_gbl_trace_method_name; +u8 acpi_gbl_system_awake_and_running; +u32 acpi_current_gpe_count; -/* System flags */ - -u32 acpi_gbl_startup_flags = 0; - -/* System starts uninitialized */ +/* + * ACPI 5.0 introduces the concept of a "reduced hardware platform", meaning + * that the ACPI hardware is no longer required. A flag in the FADT indicates + * a reduced HW machine, and that flag is duplicated here for convenience. + */ +u8 acpi_gbl_reduced_hardware; -u8 acpi_gbl_shutdown = TRUE; +/* Various state name strings */ const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = { "\\_S0_", @@ -335,7 +331,6 @@ acpi_status acpi_ut_init_globals(void) acpi_gbl_DSDT = NULL; acpi_gbl_cm_single_step = FALSE; - acpi_gbl_db_terminate_threads = FALSE; acpi_gbl_shutdown = FALSE; acpi_gbl_ns_lookup_count = 0; acpi_gbl_ps_find_count = 0; @@ -382,6 +377,10 @@ acpi_status acpi_ut_init_globals(void) acpi_gbl_disable_mem_tracking = FALSE; #endif +#ifdef ACPI_DEBUGGER + acpi_gbl_db_terminate_threads = FALSE; +#endif + return_ACPI_STATUS(AE_OK); } diff --git a/drivers/acpi/acpica/utids.c b/drivers/acpi/acpica/utids.c index bfca7b4b6731..4b12880e5b11 100644 --- a/drivers/acpi/acpica/utids.c +++ b/drivers/acpi/acpica/utids.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c index c5d1ac44c07d..5f56fc49021e 100644 --- a/drivers/acpi/acpica/utinit.c +++ b/drivers/acpi/acpica/utinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utlock.c b/drivers/acpi/acpica/utlock.c index 5c26ad420344..dc6e96547f18 100644 --- a/drivers/acpi/acpica/utlock.c +++ b/drivers/acpi/acpica/utlock.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utmath.c b/drivers/acpi/acpica/utmath.c index 909fe66e1934..d44dee6ee10a 100644 --- a/drivers/acpi/acpica/utmath.c +++ b/drivers/acpi/acpica/utmath.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index 02f9101b65e4..2e2bb14e1099 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index 08c323245584..82717fff9ffc 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utobject.c b/drivers/acpi/acpica/utobject.c index 517af700399d..dfa9009bfc87 100644 --- a/drivers/acpi/acpica/utobject.c +++ b/drivers/acpi/acpica/utobject.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utosi.c b/drivers/acpi/acpica/utosi.c index 8856bd37bc76..685766fc6ca8 100644 --- a/drivers/acpi/acpica/utosi.c +++ b/drivers/acpi/acpica/utosi.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -47,6 +47,31 @@ #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utosi") +/****************************************************************************** + * + * ACPICA policy for new _OSI strings: + * + * It is the stated policy of ACPICA that new _OSI strings will be integrated + * into this module as soon as possible after they are defined. It is strongly + * recommended that all ACPICA hosts mirror this policy and integrate any + * changes to this module as soon as possible. There are several historical + * reasons behind this policy: + * + * 1) New BIOSs tend to test only the case where the host responds TRUE to + * the latest version of Windows, which would respond to the latest/newest + * _OSI string. Not responding TRUE to the latest version of Windows will + * risk executing untested code paths throughout the DSDT and SSDTs. + * + * 2) If a new _OSI string is recognized only after a significant delay, this + * has the potential to cause problems on existing working machines because + * of the possibility that a new and different path through the ASL code + * will be executed. + * + * 3) New _OSI strings are tending to come out about once per year. A delay + * in recognizing a new string for a significant amount of time risks the + * release of another string which only compounds the initial problem. + * + *****************************************************************************/ /* * Strings supported by the _OSI predefined control method (which is * implemented internally within this module.) @@ -74,6 +99,7 @@ static struct acpi_interface_info acpi_default_supported_interfaces[] = { {"Windows 2006 SP2", NULL, 0, ACPI_OSI_WIN_VISTA_SP2}, /* Windows Vista SP2 - Added 09/2010 */ {"Windows 2009", NULL, 0, ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */ {"Windows 2012", NULL, 0, ACPI_OSI_WIN_8}, /* Windows 8 and Server 2012 - Added 08/2012 */ + {"Windows 2013", NULL, 0, ACPI_OSI_WIN_8}, /* Windows 8.1 and Server 2012 R2 - Added 01/2014 */ /* Feature Group Strings */ diff --git a/drivers/acpi/acpica/utownerid.c b/drivers/acpi/acpica/utownerid.c index eb3aca761369..36bec57ebd23 100644 --- a/drivers/acpi/acpica/utownerid.c +++ b/drivers/acpi/acpica/utownerid.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utpredef.c b/drivers/acpi/acpica/utpredef.c index 2b1ce4cd3207..db30caff130a 100644 --- a/drivers/acpi/acpica/utpredef.c +++ b/drivers/acpi/acpica/utpredef.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utresrc.c b/drivers/acpi/acpica/utresrc.c index 2c2accb9e534..14cb6c0c8be2 100644 --- a/drivers/acpi/acpica/utresrc.c +++ b/drivers/acpi/acpica/utresrc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -47,7 +47,8 @@ #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utresrc") -#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER) + +#if defined(ACPI_DEBUG_OUTPUT) || defined (ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER) /* * Strings used to decode resource descriptors. * Used by both the disassembler and the debugger resource dump routines diff --git a/drivers/acpi/acpica/utstate.c b/drivers/acpi/acpica/utstate.c index 03c4c2febd84..1cc97a752c15 100644 --- a/drivers/acpi/acpica/utstate.c +++ b/drivers/acpi/acpica/utstate.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utstring.c b/drivers/acpi/acpica/utstring.c index 45c0eb26b33d..77219336c7e0 100644 --- a/drivers/acpi/acpica/utstring.c +++ b/drivers/acpi/acpica/utstring.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/uttrack.c b/drivers/acpi/acpica/uttrack.c index c0027773cccb..7d0ee969d781 100644 --- a/drivers/acpi/acpica/uttrack.c +++ b/drivers/acpi/acpica/uttrack.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -276,7 +276,8 @@ acpi_ut_free_and_track(void *allocation, } acpi_os_free(debug_block); - ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "%p freed\n", allocation)); + ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "%p freed (block %p)\n", + allocation, debug_block)); return_VOID; } diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index be322c83643a..502a8492dc83 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utxferror.c b/drivers/acpi/acpica/utxferror.c index f7edb88f6054..edd861102f1b 100644 --- a/drivers/acpi/acpica/utxferror.c +++ b/drivers/acpi/acpica/utxferror.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utxfinit.c b/drivers/acpi/acpica/utxfinit.c index 246ef68681f4..13380d818462 100644 --- a/drivers/acpi/acpica/utxfinit.c +++ b/drivers/acpi/acpica/utxfinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utxfmutex.c b/drivers/acpi/acpica/utxfmutex.c index 312299721ba1..2a0f9e04d3a4 100644 --- a/drivers/acpi/acpica/utxfmutex.c +++ b/drivers/acpi/acpica/utxfmutex.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig index 3650b2183227..c4dac7150960 100644 --- a/drivers/acpi/apei/Kconfig +++ b/drivers/acpi/apei/Kconfig @@ -12,7 +12,7 @@ config ACPI_APEI config ACPI_APEI_GHES bool "APEI Generic Hardware Error Source" - depends on ACPI_APEI && X86 + depends on ACPI_APEI select ACPI_HED select IRQ_WORK select GENERIC_ALLOCATOR diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 797a6938d051..9a2c63b20050 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -39,15 +39,13 @@ #include <linux/acpi.h> #include <linux/power_supply.h> +#include "battery.h" + #define PREFIX "ACPI: " #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF -#define ACPI_BATTERY_CLASS "battery" #define ACPI_BATTERY_DEVICE_NAME "Battery" -#define ACPI_BATTERY_NOTIFY_STATUS 0x80 -#define ACPI_BATTERY_NOTIFY_INFO 0x81 -#define ACPI_BATTERY_NOTIFY_THRESHOLD 0x82 /* Battery power unit: 0 means mW, 1 means mA */ #define ACPI_BATTERY_POWER_UNIT_MA 1 @@ -736,6 +734,7 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event) acpi_bus_generate_netlink_event(device->pnp.device_class, dev_name(&device->dev), event, acpi_battery_present(battery)); + acpi_notifier_call_chain(device, event, acpi_battery_present(battery)); /* acpi_battery_update could remove power_supply object */ if (old && battery->bat.dev) power_supply_changed(&battery->bat); diff --git a/drivers/acpi/battery.h b/drivers/acpi/battery.h new file mode 100644 index 000000000000..6c084976987d --- /dev/null +++ b/drivers/acpi/battery.h @@ -0,0 +1,10 @@ +#ifndef __ACPI_BATTERY_H +#define __ACPI_BATTERY_H + +#define ACPI_BATTERY_CLASS "battery" + +#define ACPI_BATTERY_NOTIFY_STATUS 0x80 +#define ACPI_BATTERY_NOTIFY_INFO 0x81 +#define ACPI_BATTERY_NOTIFY_THRESHOLD 0x82 + +#endif diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index fcb59c21c68d..e7e5844c87d0 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -311,9 +311,7 @@ static void acpi_bus_osc_support(void) capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PPC_OST_SUPPORT; #endif -#ifdef ACPI_HOTPLUG_OST capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_HOTPLUG_OST_SUPPORT; -#endif if (!ghes_disable) capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_APEI_SUPPORT; @@ -340,60 +338,77 @@ static void acpi_bus_osc_support(void) */ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) { - struct acpi_device *device = NULL; + struct acpi_device *adev; struct acpi_driver *driver; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Notification %#02x to handle %p\n", - type, handle)); + acpi_status status; + u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; switch (type) { - case ACPI_NOTIFY_BUS_CHECK: - /* TBD */ + acpi_handle_debug(handle, "ACPI_NOTIFY_BUS_CHECK event\n"); break; case ACPI_NOTIFY_DEVICE_CHECK: - /* TBD */ + acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_CHECK event\n"); break; case ACPI_NOTIFY_DEVICE_WAKE: - /* TBD */ + acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_WAKE event\n"); break; case ACPI_NOTIFY_EJECT_REQUEST: - /* TBD */ + acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n"); break; case ACPI_NOTIFY_DEVICE_CHECK_LIGHT: + acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_CHECK_LIGHT event\n"); /* TBD: Exactly what does 'light' mean? */ break; case ACPI_NOTIFY_FREQUENCY_MISMATCH: - /* TBD */ + acpi_handle_err(handle, "Device cannot be configured due " + "to a frequency mismatch\n"); break; case ACPI_NOTIFY_BUS_MODE_MISMATCH: - /* TBD */ + acpi_handle_err(handle, "Device cannot be configured due " + "to a bus mode mismatch\n"); break; case ACPI_NOTIFY_POWER_FAULT: - /* TBD */ + acpi_handle_err(handle, "Device has suffered a power fault\n"); break; default: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Received unknown/unsupported notification [%08x]\n", - type)); - break; + acpi_handle_warn(handle, "Unsupported event type 0x%x\n", type); + ost_code = ACPI_OST_SC_UNRECOGNIZED_NOTIFY; + goto err; } - acpi_bus_get_device(handle, &device); - if (device) { - driver = device->driver; - if (driver && driver->ops.notify && - (driver->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS)) - driver->ops.notify(device, type); + adev = acpi_bus_get_acpi_device(handle); + if (!adev) + goto err; + + driver = adev->driver; + if (driver && driver->ops.notify && + (driver->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS)) + driver->ops.notify(adev, type); + + switch (type) { + case ACPI_NOTIFY_BUS_CHECK: + case ACPI_NOTIFY_DEVICE_CHECK: + case ACPI_NOTIFY_EJECT_REQUEST: + status = acpi_hotplug_schedule(adev, type); + if (ACPI_SUCCESS(status)) + return; + default: + break; } + acpi_bus_put_acpi_device(adev); + return; + + err: + acpi_evaluate_ost(handle, type, ost_code, NULL); } /* -------------------------------------------------------------------------- diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 714e957a871a..db35594d4df7 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -302,6 +302,10 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) input_sync(input); pm_wakeup_event(&device->dev, 0); + acpi_bus_generate_netlink_event( + device->pnp.device_class, + dev_name(&device->dev), + event, ++button->pushed); } break; default: diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index 368f9ddb8480..63119d09b354 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c @@ -31,8 +31,6 @@ #include "internal.h" -#define PREFIX "ACPI: " - #define _COMPONENT ACPI_CONTAINER_COMPONENT ACPI_MODULE_NAME("container"); @@ -68,6 +66,9 @@ static int container_device_attach(struct acpi_device *adev, struct device *dev; int ret; + if (adev->flags.is_dock_station) + return 0; + cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); if (!cdev) return -ENOMEM; diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index c14a00d3dca6..d047739f3380 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -901,15 +901,30 @@ EXPORT_SYMBOL_GPL(acpi_dev_resume_early); int acpi_subsys_prepare(struct device *dev) { /* - * Follow PCI and resume devices suspended at run time before running - * their system suspend callbacks. + * Devices having power.ignore_children set may still be necessary for + * suspending their children in the next phase of device suspend. */ - pm_runtime_resume(dev); + if (dev->power.ignore_children) + pm_runtime_resume(dev); + return pm_generic_prepare(dev); } EXPORT_SYMBOL_GPL(acpi_subsys_prepare); /** + * acpi_subsys_suspend - Run the device driver's suspend callback. + * @dev: Device to handle. + * + * Follow PCI and resume devices suspended at run time before running their + * system suspend callbacks. + */ +int acpi_subsys_suspend(struct device *dev) +{ + pm_runtime_resume(dev); + return pm_generic_suspend(dev); +} + +/** * acpi_subsys_suspend_late - Suspend device using ACPI. * @dev: Device to suspend. * @@ -937,6 +952,23 @@ int acpi_subsys_resume_early(struct device *dev) return ret ? ret : pm_generic_resume_early(dev); } EXPORT_SYMBOL_GPL(acpi_subsys_resume_early); + +/** + * acpi_subsys_freeze - Run the device driver's freeze callback. + * @dev: Device to handle. + */ +int acpi_subsys_freeze(struct device *dev) +{ + /* + * This used to be done in acpi_subsys_prepare() for all devices and + * some drivers may depend on it, so do it here. Ideally, however, + * runtime-suspended devices should not be touched during freeze/thaw + * transitions. + */ + pm_runtime_resume(dev); + return pm_generic_freeze(dev); +} + #endif /* CONFIG_PM_SLEEP */ static struct dev_pm_domain acpi_general_pm_domain = { @@ -947,8 +979,11 @@ static struct dev_pm_domain acpi_general_pm_domain = { #endif #ifdef CONFIG_PM_SLEEP .prepare = acpi_subsys_prepare, + .suspend = acpi_subsys_suspend, .suspend_late = acpi_subsys_suspend_late, .resume_early = acpi_subsys_resume_early, + .freeze = acpi_subsys_freeze, + .poweroff = acpi_subsys_suspend, .poweroff_late = acpi_subsys_suspend_late, .restore_early = acpi_subsys_resume_early, #endif diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 5bfd769fc91f..f0fc6260266b 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -1,7 +1,9 @@ /* * dock.c - ACPI dock station driver * - * Copyright (C) 2006 Kristen Carlson Accardi <kristen.c.accardi@intel.com> + * Copyright (C) 2006, 2014, Intel Corp. + * Author: Kristen Carlson Accardi <kristen.c.accardi@intel.com> + * Rafael J. Wysocki <rafael.j.wysocki@intel.com> * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * @@ -35,8 +37,6 @@ #include "internal.h" -#define PREFIX "ACPI: " - #define ACPI_DOCK_DRIVER_DESCRIPTION "ACPI Dock Station Driver" ACPI_MODULE_NAME("dock"); @@ -68,15 +68,10 @@ struct dock_station { }; static LIST_HEAD(dock_stations); static int dock_station_count; -static DEFINE_MUTEX(hotplug_lock); struct dock_dependent_device { struct list_head list; - acpi_handle handle; - const struct acpi_dock_ops *hp_ops; - void *hp_context; - unsigned int hp_refcount; - void (*hp_release)(void *); + struct acpi_device *adev; }; #define DOCK_DOCKING 0x00000001 @@ -98,13 +93,13 @@ enum dock_callback_type { *****************************************************************************/ /** * add_dock_dependent_device - associate a device with the dock station - * @ds: The dock station - * @handle: handle of the dependent device + * @ds: Dock station. + * @adev: Dependent ACPI device object. * * Add the dependent device to the dock's dependent device list. */ -static int __init -add_dock_dependent_device(struct dock_station *ds, acpi_handle handle) +static int add_dock_dependent_device(struct dock_station *ds, + struct acpi_device *adev) { struct dock_dependent_device *dd; @@ -112,180 +107,120 @@ add_dock_dependent_device(struct dock_station *ds, acpi_handle handle) if (!dd) return -ENOMEM; - dd->handle = handle; + dd->adev = adev; INIT_LIST_HEAD(&dd->list); list_add_tail(&dd->list, &ds->dependent_devices); return 0; } -static void remove_dock_dependent_devices(struct dock_station *ds) +static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event, + enum dock_callback_type cb_type) { - struct dock_dependent_device *dd, *aux; + struct acpi_device *adev = dd->adev; - list_for_each_entry_safe(dd, aux, &ds->dependent_devices, list) { - list_del(&dd->list); - kfree(dd); - } -} + acpi_lock_hp_context(); -/** - * dock_init_hotplug - Initialize a hotplug device on a docking station. - * @dd: Dock-dependent device. - * @ops: Dock operations to attach to the dependent device. - * @context: Data to pass to the @ops callbacks and @release. - * @init: Optional initialization routine to run after setting up context. - * @release: Optional release routine to run on removal. - */ -static int dock_init_hotplug(struct dock_dependent_device *dd, - const struct acpi_dock_ops *ops, void *context, - void (*init)(void *), void (*release)(void *)) -{ - int ret = 0; + if (!adev->hp) + goto out; - mutex_lock(&hotplug_lock); - if (WARN_ON(dd->hp_context)) { - ret = -EEXIST; - } else { - dd->hp_refcount = 1; - dd->hp_ops = ops; - dd->hp_context = context; - dd->hp_release = release; - if (init) - init(context); - } - mutex_unlock(&hotplug_lock); - return ret; -} + if (cb_type == DOCK_CALL_FIXUP) { + void (*fixup)(struct acpi_device *); -/** - * dock_release_hotplug - Decrement hotplug reference counter of dock device. - * @dd: Dock-dependent device. - * - * Decrement the reference counter of @dd and if 0, detach its hotplug - * operations from it, reset its context pointer and run the optional release - * routine if present. - */ -static void dock_release_hotplug(struct dock_dependent_device *dd) -{ - mutex_lock(&hotplug_lock); - if (dd->hp_context && !--dd->hp_refcount) { - void (*release)(void *) = dd->hp_release; - void *context = dd->hp_context; - - dd->hp_ops = NULL; - dd->hp_context = NULL; - dd->hp_release = NULL; - if (release) - release(context); - } - mutex_unlock(&hotplug_lock); -} + fixup = adev->hp->fixup; + if (fixup) { + acpi_unlock_hp_context(); + fixup(adev); + return; + } + } else if (cb_type == DOCK_CALL_UEVENT) { + void (*uevent)(struct acpi_device *, u32); + + uevent = adev->hp->uevent; + if (uevent) { + acpi_unlock_hp_context(); + uevent(adev, event); + return; + } + } else { + int (*notify)(struct acpi_device *, u32); -static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event, - enum dock_callback_type cb_type) -{ - acpi_notify_handler cb = NULL; - bool run = false; - - mutex_lock(&hotplug_lock); - - if (dd->hp_context) { - run = true; - dd->hp_refcount++; - if (dd->hp_ops) { - switch (cb_type) { - case DOCK_CALL_FIXUP: - cb = dd->hp_ops->fixup; - break; - case DOCK_CALL_UEVENT: - cb = dd->hp_ops->uevent; - break; - default: - cb = dd->hp_ops->handler; - } + notify = adev->hp->notify; + if (notify) { + acpi_unlock_hp_context(); + notify(adev, event); + return; } } - mutex_unlock(&hotplug_lock); + out: + acpi_unlock_hp_context(); +} - if (!run) - return; +static struct dock_station *find_dock_station(acpi_handle handle) +{ + struct dock_station *ds; - if (cb) - cb(dd->handle, event, dd->hp_context); + list_for_each_entry(ds, &dock_stations, sibling) + if (ds->handle == handle) + return ds; - dock_release_hotplug(dd); + return NULL; } /** * find_dock_dependent_device - get a device dependent on this dock * @ds: the dock station - * @handle: the acpi_handle of the device we want + * @adev: ACPI device object to find. * * iterate over the dependent device list for this dock. If the * dependent device matches the handle, return. */ static struct dock_dependent_device * -find_dock_dependent_device(struct dock_station *ds, acpi_handle handle) +find_dock_dependent_device(struct dock_station *ds, struct acpi_device *adev) { struct dock_dependent_device *dd; list_for_each_entry(dd, &ds->dependent_devices, list) - if (handle == dd->handle) + if (adev == dd->adev) return dd; return NULL; } -/***************************************************************************** - * Dock functions * - *****************************************************************************/ -static int __init is_battery(acpi_handle handle) +void register_dock_dependent_device(struct acpi_device *adev, + acpi_handle dshandle) { - struct acpi_device_info *info; - int ret = 1; + struct dock_station *ds = find_dock_station(dshandle); - if (!ACPI_SUCCESS(acpi_get_object_info(handle, &info))) - return 0; - if (!(info->valid & ACPI_VALID_HID)) - ret = 0; - else - ret = !strcmp("PNP0C0A", info->hardware_id.string); - - kfree(info); - return ret; + if (ds && !find_dock_dependent_device(ds, adev)) + add_dock_dependent_device(ds, adev); } -/* Check whether ACPI object is an ejectable battery or disk bay */ -static bool __init is_ejectable_bay(acpi_handle handle) -{ - if (acpi_has_method(handle, "_EJ0") && is_battery(handle)) - return true; - - return acpi_bay_match(handle); -} +/***************************************************************************** + * Dock functions * + *****************************************************************************/ /** * is_dock_device - see if a device is on a dock station - * @handle: acpi handle of the device + * @adev: ACPI device object to check. * * If this device is either the dock station itself, * or is a device dependent on the dock station, then it * is a dock device */ -int is_dock_device(acpi_handle handle) +int is_dock_device(struct acpi_device *adev) { struct dock_station *dock_station; if (!dock_station_count) return 0; - if (acpi_dock_match(handle)) + if (acpi_dock_match(adev->handle)) return 1; list_for_each_entry(dock_station, &dock_stations, sibling) - if (find_dock_dependent_device(dock_station, handle)) + if (find_dock_dependent_device(dock_station, adev)) return 1; return 0; @@ -313,43 +248,6 @@ static int dock_present(struct dock_station *ds) } /** - * dock_create_acpi_device - add new devices to acpi - * @handle - handle of the device to add - * - * This function will create a new acpi_device for the given - * handle if one does not exist already. This should cause - * acpi to scan for drivers for the given devices, and call - * matching driver's add routine. - */ -static void dock_create_acpi_device(acpi_handle handle) -{ - struct acpi_device *device = NULL; - int ret; - - acpi_bus_get_device(handle, &device); - if (!acpi_device_enumerated(device)) { - ret = acpi_bus_scan(handle); - if (ret) - pr_debug("error adding bus, %x\n", -ret); - } -} - -/** - * dock_remove_acpi_device - remove the acpi_device struct from acpi - * @handle - the handle of the device to remove - * - * Tell acpi to remove the acpi_device. This should cause any loaded - * driver to have it's remove routine called. - */ -static void dock_remove_acpi_device(acpi_handle handle) -{ - struct acpi_device *device; - - if (!acpi_bus_get_device(handle, &device)) - acpi_bus_trim(device); -} - -/** * hot_remove_dock_devices - Remove dock station devices. * @ds: Dock station. */ @@ -366,7 +264,7 @@ static void hot_remove_dock_devices(struct dock_station *ds) dock_hotplug_event(dd, ACPI_NOTIFY_EJECT_REQUEST, false); list_for_each_entry_reverse(dd, &ds->dependent_devices, list) - dock_remove_acpi_device(dd->handle); + acpi_bus_trim(dd->adev); } /** @@ -392,12 +290,20 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event) dock_hotplug_event(dd, event, DOCK_CALL_HANDLER); /* - * Now make sure that an acpi_device is created for each dependent - * device. That will cause scan handlers to be attached to device - * objects or acpi_drivers to be stopped/started if they are present. + * Check if all devices have been enumerated already. If not, run + * acpi_bus_scan() for them and that will cause scan handlers to be + * attached to device objects or acpi_drivers to be stopped/started if + * they are present. */ - list_for_each_entry(dd, &ds->dependent_devices, list) - dock_create_acpi_device(dd->handle); + list_for_each_entry(dd, &ds->dependent_devices, list) { + struct acpi_device *adev = dd->adev; + + if (!acpi_device_enumerated(adev)) { + int ret = acpi_bus_scan(adev->handle); + if (ret) + dev_dbg(&adev->dev, "scan error %d\n", -ret); + } + } } static void dock_event(struct dock_station *ds, u32 event, int num) @@ -501,71 +407,6 @@ static int dock_in_progress(struct dock_station *ds) } /** - * register_hotplug_dock_device - register a hotplug function - * @handle: the handle of the device - * @ops: handlers to call after docking - * @context: device specific data - * @init: Optional initialization routine to run after registration - * @release: Optional release routine to run on unregistration - * - * If a driver would like to perform a hotplug operation after a dock - * event, they can register an acpi_notifiy_handler to be called by - * the dock driver after _DCK is executed. - */ -int register_hotplug_dock_device(acpi_handle handle, - const struct acpi_dock_ops *ops, void *context, - void (*init)(void *), void (*release)(void *)) -{ - struct dock_dependent_device *dd; - struct dock_station *dock_station; - int ret = -EINVAL; - - if (WARN_ON(!context)) - return -EINVAL; - - if (!dock_station_count) - return -ENODEV; - - /* - * make sure this handle is for a device dependent on the dock, - * this would include the dock station itself - */ - list_for_each_entry(dock_station, &dock_stations, sibling) { - /* - * An ATA bay can be in a dock and itself can be ejected - * separately, so there are two 'dock stations' which need the - * ops - */ - dd = find_dock_dependent_device(dock_station, handle); - if (dd && !dock_init_hotplug(dd, ops, context, init, release)) - ret = 0; - } - - return ret; -} -EXPORT_SYMBOL_GPL(register_hotplug_dock_device); - -/** - * unregister_hotplug_dock_device - remove yourself from the hotplug list - * @handle: the acpi handle of the device - */ -void unregister_hotplug_dock_device(acpi_handle handle) -{ - struct dock_dependent_device *dd; - struct dock_station *dock_station; - - if (!dock_station_count) - return; - - list_for_each_entry(dock_station, &dock_stations, sibling) { - dd = find_dock_dependent_device(dock_station, handle); - if (dd) - dock_release_hotplug(dd); - } -} -EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device); - -/** * handle_eject_request - handle an undock request checking for error conditions * * Check to make sure the dock device is still present, then undock and @@ -598,20 +439,23 @@ static int handle_eject_request(struct dock_station *ds, u32 event) } /** - * dock_notify - act upon an acpi dock notification - * @ds: dock station - * @event: the acpi event + * dock_notify - Handle ACPI dock notification. + * @adev: Dock station's ACPI device object. + * @event: Event code. * * If we are notified to dock, then check to see if the dock is * present and then dock. Notify all drivers of the dock event, * and then hotplug and devices that may need hotplugging. */ -static void dock_notify(struct dock_station *ds, u32 event) +int dock_notify(struct acpi_device *adev, u32 event) { - acpi_handle handle = ds->handle; - struct acpi_device *adev = NULL; + acpi_handle handle = adev->handle; + struct dock_station *ds = find_dock_station(handle); int surprise_removal = 0; + if (!ds) + return -ENODEV; + /* * According to acpi spec 3.0a, if a DEVICE_CHECK notification * is sent and _DCK is present, it is assumed to mean an undock @@ -632,7 +476,6 @@ static void dock_notify(struct dock_station *ds, u32 event) switch (event) { case ACPI_NOTIFY_BUS_CHECK: case ACPI_NOTIFY_DEVICE_CHECK: - acpi_bus_get_device(handle, &adev); if (!dock_in_progress(ds) && !acpi_device_enumerated(adev)) { begin_dock(ds); dock(ds); @@ -662,49 +505,8 @@ static void dock_notify(struct dock_station *ds, u32 event) else dock_event(ds, event, UNDOCK_EVENT); break; - default: - acpi_handle_err(handle, "Unknown dock event %d\n", event); } -} - -static void acpi_dock_deferred_cb(void *data, u32 event) -{ - acpi_scan_lock_acquire(); - dock_notify(data, event); - acpi_scan_lock_release(); -} - -static void dock_notify_handler(acpi_handle handle, u32 event, void *data) -{ - if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK - && event != ACPI_NOTIFY_EJECT_REQUEST) - return; - - acpi_hotplug_execute(acpi_dock_deferred_cb, data, event); -} - -/** - * find_dock_devices - find devices on the dock station - * @handle: the handle of the device we are examining - * @lvl: unused - * @context: the dock station private data - * @rv: unused - * - * This function is called by acpi_walk_namespace. It will - * check to see if an object has an _EJD method. If it does, then it - * will see if it is dependent on the dock station. - */ -static acpi_status __init find_dock_devices(acpi_handle handle, u32 lvl, - void *context, void **rv) -{ - struct dock_station *ds = context; - acpi_handle ejd = NULL; - - acpi_bus_get_ejd(handle, &ejd); - if (ejd == ds->handle) - add_dock_dependent_device(ds, handle); - - return AE_OK; + return 0; } /* @@ -803,23 +605,28 @@ static struct attribute_group dock_attribute_group = { }; /** - * dock_add - add a new dock station - * @handle: the dock station handle + * acpi_dock_add - Add a new dock station + * @adev: Dock station ACPI device object. * - * allocated and initialize a new dock station device. Find all devices - * that are on the dock station, and register for dock event notifications. + * allocated and initialize a new dock station device. */ -static int __init dock_add(acpi_handle handle) +void acpi_dock_add(struct acpi_device *adev) { struct dock_station *dock_station, ds = { NULL, }; + struct platform_device_info pdevinfo; + acpi_handle handle = adev->handle; struct platform_device *dd; - acpi_status status; int ret; - dd = platform_device_register_data(NULL, "dock", dock_station_count, - &ds, sizeof(ds)); + memset(&pdevinfo, 0, sizeof(pdevinfo)); + pdevinfo.name = "dock"; + pdevinfo.id = dock_station_count; + pdevinfo.acpi_node.companion = adev; + pdevinfo.data = &ds; + pdevinfo.size_data = sizeof(ds); + dd = platform_device_register_full(&pdevinfo); if (IS_ERR(dd)) - return PTR_ERR(dd); + return; dock_station = dd->dev.platform_data; @@ -837,72 +644,29 @@ static int __init dock_add(acpi_handle handle) dock_station->flags |= DOCK_IS_DOCK; if (acpi_ata_match(handle)) dock_station->flags |= DOCK_IS_ATA; - if (is_battery(handle)) + if (acpi_device_is_battery(adev)) dock_station->flags |= DOCK_IS_BAT; ret = sysfs_create_group(&dd->dev.kobj, &dock_attribute_group); if (ret) goto err_unregister; - /* Find dependent devices */ - acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, find_dock_devices, NULL, - dock_station, NULL); - /* add the dock station as a device dependent on itself */ - ret = add_dock_dependent_device(dock_station, handle); + ret = add_dock_dependent_device(dock_station, adev); if (ret) goto err_rmgroup; - status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, - dock_notify_handler, dock_station); - if (ACPI_FAILURE(status)) { - ret = -ENODEV; - goto err_rmgroup; - } - dock_station_count++; list_add(&dock_station->sibling, &dock_stations); - return 0; + adev->flags.is_dock_station = true; + dev_info(&adev->dev, "ACPI dock station (docks/bays count: %d)\n", + dock_station_count); + return; err_rmgroup: - remove_dock_dependent_devices(dock_station); sysfs_remove_group(&dd->dev.kobj, &dock_attribute_group); + err_unregister: platform_device_unregister(dd); acpi_handle_err(handle, "%s encountered error %d\n", __func__, ret); - return ret; -} - -/** - * find_dock_and_bay - look for dock stations and bays - * @handle: acpi handle of a device - * @lvl: unused - * @context: unused - * @rv: unused - * - * This is called by acpi_walk_namespace to look for dock stations and bays. - */ -static acpi_status __init -find_dock_and_bay(acpi_handle handle, u32 lvl, void *context, void **rv) -{ - if (acpi_dock_match(handle) || is_ejectable_bay(handle)) - dock_add(handle); - - return AE_OK; -} - -void __init acpi_dock_init(void) -{ - /* look for dock stations and bays */ - acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, find_dock_and_bay, NULL, NULL, NULL); - - if (!dock_station_count) { - pr_info(PREFIX "No dock devices found.\n"); - return; - } - - pr_info(PREFIX "%s: %d docks/bays found\n", - ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count); } diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 09e423f3d8ad..8acf53e62966 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -55,11 +55,16 @@ MODULE_DEVICE_TABLE(acpi, fan_device_ids); #ifdef CONFIG_PM_SLEEP static int acpi_fan_suspend(struct device *dev); static int acpi_fan_resume(struct device *dev); +static struct dev_pm_ops acpi_fan_pm = { + .resume = acpi_fan_resume, + .freeze = acpi_fan_suspend, + .thaw = acpi_fan_resume, + .restore = acpi_fan_resume, +}; +#define FAN_PM_OPS_PTR (&acpi_fan_pm) #else -#define acpi_fan_suspend NULL -#define acpi_fan_resume NULL +#define FAN_PM_OPS_PTR NULL #endif -static SIMPLE_DEV_PM_OPS(acpi_fan_pm, acpi_fan_suspend, acpi_fan_resume); static struct acpi_driver acpi_fan_driver = { .name = "fan", @@ -69,7 +74,7 @@ static struct acpi_driver acpi_fan_driver = { .add = acpi_fan_add, .remove = acpi_fan_remove, }, - .drv.pm = &acpi_fan_pm, + .drv.pm = FAN_PM_OPS_PTR, }; /* thermal cooling device callbacks */ diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 0c789224d40d..f774c65ecb8b 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -287,6 +287,7 @@ EXPORT_SYMBOL_GPL(acpi_unbind_one); static int acpi_platform_notify(struct device *dev) { struct acpi_bus_type *type = acpi_get_bus_type(dev); + struct acpi_device *adev; int ret; ret = acpi_bind_one(dev, NULL); @@ -303,9 +304,14 @@ static int acpi_platform_notify(struct device *dev) if (ret) goto out; } + adev = ACPI_COMPANION(dev); + if (!adev) + goto out; if (type && type->setup) type->setup(dev); + else if (adev->handler && adev->handler->bind) + adev->handler->bind(dev); out: #if ACPI_GLUE_DEBUG @@ -324,11 +330,17 @@ static int acpi_platform_notify(struct device *dev) static int acpi_platform_notify_remove(struct device *dev) { + struct acpi_device *adev = ACPI_COMPANION(dev); struct acpi_bus_type *type; + if (!adev) + return 0; + type = acpi_get_bus_type(dev); if (type && type->cleanup) type->cleanup(dev); + else if (adev->handler && adev->handler->unbind) + adev->handler->unbind(dev); acpi_unbind_one(dev); return 0; diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index dedbb2d802f1..957391306cbf 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -37,9 +37,15 @@ void acpi_container_init(void); static inline void acpi_container_init(void) {} #endif #ifdef CONFIG_ACPI_DOCK -void acpi_dock_init(void); +void register_dock_dependent_device(struct acpi_device *adev, + acpi_handle dshandle); +int dock_notify(struct acpi_device *adev, u32 event); +void acpi_dock_add(struct acpi_device *adev); #else -static inline void acpi_dock_init(void) {} +static inline void register_dock_dependent_device(struct acpi_device *adev, + acpi_handle dshandle) {} +static inline int dock_notify(struct acpi_device *adev, u32 event) { return -ENODEV; } +static inline void acpi_dock_add(struct acpi_device *adev) {} #endif #ifdef CONFIG_ACPI_HOTPLUG_MEMORY void acpi_memory_hotplug_init(void); @@ -72,7 +78,9 @@ void acpi_lpss_init(void); static inline void acpi_lpss_init(void) {} #endif +acpi_status acpi_hotplug_schedule(struct acpi_device *adev, u32 src); bool acpi_queue_hotplug_work(struct work_struct *work); +void acpi_device_hotplug(struct acpi_device *adev, u32 src); bool acpi_scan_is_offline(struct acpi_device *adev, bool uevent); /* -------------------------------------------------------------------------- @@ -90,6 +98,7 @@ void acpi_free_pnp_ids(struct acpi_device_pnp *pnp); int acpi_bind_one(struct device *dev, struct acpi_device *adev); int acpi_unbind_one(struct device *dev); bool acpi_device_is_present(struct acpi_device *adev); +bool acpi_device_is_battery(struct acpi_device *adev); /* -------------------------------------------------------------------------- Power Resource diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index fc1aa7909690..f7fd72ac69cf 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -52,7 +52,7 @@ #define _COMPONENT ACPI_OS_SERVICES ACPI_MODULE_NAME("osl"); -#define PREFIX "ACPI: " + struct acpi_os_dpc { acpi_osd_exec_callback function; void *context; @@ -1168,8 +1168,7 @@ void acpi_os_wait_events_complete(void) struct acpi_hp_work { struct work_struct work; - acpi_hp_callback func; - void *data; + struct acpi_device *adev; u32 src; }; @@ -1178,25 +1177,24 @@ static void acpi_hotplug_work_fn(struct work_struct *work) struct acpi_hp_work *hpw = container_of(work, struct acpi_hp_work, work); acpi_os_wait_events_complete(); - hpw->func(hpw->data, hpw->src); + acpi_device_hotplug(hpw->adev, hpw->src); kfree(hpw); } -acpi_status acpi_hotplug_execute(acpi_hp_callback func, void *data, u32 src) +acpi_status acpi_hotplug_schedule(struct acpi_device *adev, u32 src) { struct acpi_hp_work *hpw; ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Scheduling function [%p(%p, %u)] for deferred execution.\n", - func, data, src)); + "Scheduling hotplug event (%p, %u) for deferred execution.\n", + adev, src)); hpw = kmalloc(sizeof(*hpw), GFP_KERNEL); if (!hpw) return AE_NO_MEMORY; INIT_WORK(&hpw->work, acpi_hotplug_work_fn); - hpw->func = func; - hpw->data = data; + hpw->adev = adev; hpw->src = src; /* * We can't run hotplug code in kacpid_wq/kacpid_notify_wq etc., because @@ -1539,17 +1537,21 @@ static int __init osi_setup(char *str) __setup("acpi_osi=", osi_setup); -/* enable serialization to combat AE_ALREADY_EXISTS errors */ -static int __init acpi_serialize_setup(char *str) +/* + * Disable the auto-serialization of named objects creation methods. + * + * This feature is enabled by default. It marks the AML control methods + * that contain the opcodes to create named objects as "Serialized". + */ +static int __init acpi_no_auto_serialize_setup(char *str) { - printk(KERN_INFO PREFIX "serialize enabled\n"); - - acpi_gbl_all_methods_serialized = TRUE; + acpi_gbl_auto_serialize_methods = FALSE; + pr_info("ACPI: auto-serialization disabled\n"); return 1; } -__setup("acpi_serialize", acpi_serialize_setup); +__setup("acpi_no_auto_serialize", acpi_no_auto_serialize_setup); /* Check of resource interference between native drivers and ACPI * OperationRegions (SystemIO and System Memory only). @@ -1780,6 +1782,17 @@ static int __init acpi_no_auto_ssdt_setup(char *s) __setup("acpi_no_auto_ssdt", acpi_no_auto_ssdt_setup); +static int __init acpi_disable_return_repair(char *s) +{ + printk(KERN_NOTICE PREFIX + "ACPI: Predefined validation mechanism disabled\n"); + acpi_gbl_disable_auto_repair = TRUE; + + return 1; +} + +__setup("acpica_no_return_repair", acpi_disable_return_repair); + acpi_status __init acpi_os_initialize(void) { acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1a_event_block); diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 361b40c10c3f..9c62340c2360 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -370,6 +370,30 @@ static struct acpi_prt_entry *acpi_pci_irq_lookup(struct pci_dev *dev, int pin) return NULL; } +#if IS_ENABLED(CONFIG_ISA) || IS_ENABLED(CONFIG_EISA) +static int acpi_isa_register_gsi(struct pci_dev *dev) +{ + u32 dev_gsi; + + /* Interrupt Line values above 0xF are forbidden */ + if (dev->irq > 0 && (dev->irq <= 0xF) && + (acpi_isa_irq_to_gsi(dev->irq, &dev_gsi) == 0)) { + dev_warn(&dev->dev, "PCI INT %c: no GSI - using ISA IRQ %d\n", + pin_name(dev->pin), dev->irq); + acpi_register_gsi(&dev->dev, dev_gsi, + ACPI_LEVEL_SENSITIVE, + ACPI_ACTIVE_LOW); + return 0; + } + return -EINVAL; +} +#else +static inline int acpi_isa_register_gsi(struct pci_dev *dev) +{ + return -ENODEV; +} +#endif + int acpi_pci_irq_enable(struct pci_dev *dev) { struct acpi_prt_entry *entry; @@ -416,19 +440,9 @@ int acpi_pci_irq_enable(struct pci_dev *dev) * driver reported one, then use it. Exit in any case. */ if (gsi < 0) { - u32 dev_gsi; - /* Interrupt Line values above 0xF are forbidden */ - if (dev->irq > 0 && (dev->irq <= 0xF) && - (acpi_isa_irq_to_gsi(dev->irq, &dev_gsi) == 0)) { - dev_warn(&dev->dev, "PCI INT %c: no GSI - using ISA IRQ %d\n", - pin_name(pin), dev->irq); - acpi_register_gsi(&dev->dev, dev_gsi, - ACPI_LEVEL_SENSITIVE, - ACPI_ACTIVE_LOW); - } else { + if (acpi_isa_register_gsi(dev)) dev_warn(&dev->dev, "PCI INT %c: no GSI\n", pin_name(pin)); - } kfree(entry); return 0; diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index 9418c7a1f786..cfd7581cc19f 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -43,8 +43,6 @@ #include "internal.h" -#define PREFIX "ACPI: " - #define _COMPONENT ACPI_PCI_COMPONENT ACPI_MODULE_NAME("pci_link"); #define ACPI_PCI_LINK_CLASS "pci_irq_routing" diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index c1c4102e6478..d388f13d48b4 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -39,8 +39,6 @@ #include "internal.h" -#define PREFIX "ACPI: " - #define _COMPONENT ACPI_PCI_COMPONENT ACPI_MODULE_NAME("pci_root"); #define ACPI_PCI_ROOT_CLASS "pci_bridge" @@ -51,7 +49,7 @@ static void acpi_pci_root_remove(struct acpi_device *device); static int acpi_pci_root_scan_dependent(struct acpi_device *adev) { - acpiphp_check_host_bridge(adev->handle); + acpiphp_check_host_bridge(adev); return 0; } diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index ad7da686e6e6..e0bcfb642b52 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -46,8 +46,6 @@ #include "sleep.h" #include "internal.h" -#define PREFIX "ACPI: " - #define _COMPONENT ACPI_POWER_COMPONENT ACPI_MODULE_NAME("power"); #define ACPI_POWER_CLASS "power_resource" diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index a4eea9a508d3..71e2065639a6 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -15,28 +15,9 @@ #include "internal.h" -#define PREFIX "ACPI: " #define _COMPONENT ACPI_PROCESSOR_COMPONENT ACPI_MODULE_NAME("processor_core"); -static int __init set_no_mwait(const struct dmi_system_id *id) -{ - printk(KERN_NOTICE PREFIX "%s detected - " - "disabling mwait for CPU C-states\n", id->ident); - boot_option_idle_override = IDLE_NOMWAIT; - return 0; -} - -static struct dmi_system_id processor_idle_dmi_table[] __initdata = { - { - 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}, - {}, -}; - static int map_lapic_id(struct acpi_subtable_header *entry, u32 acpi_id, int *apic_id) { @@ -323,7 +304,7 @@ static struct acpi_object_list *acpi_processor_alloc_pdc(void) * _PDC is required for a BIOS-OS handshake for most of the newer * ACPI processor features. */ -static int +static acpi_status acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in) { acpi_status status = AE_OK; @@ -379,16 +360,43 @@ early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv) return AE_OK; } -void __init acpi_early_processor_set_pdc(void) +#if defined(CONFIG_X86) || defined(CONFIG_IA64) +static int __init set_no_mwait(const struct dmi_system_id *id) +{ + pr_notice(PREFIX "%s detected - disabling mwait for CPU C-states\n", + id->ident); + boot_option_idle_override = IDLE_NOMWAIT; + return 0; +} + +static struct dmi_system_id processor_idle_dmi_table[] __initdata = { + { + 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}, + {}, +}; + +static void __init processor_dmi_check(void) { /* * Check whether the system is DMI table. If yes, OSPM * should not use mwait for CPU-states. */ dmi_check_system(processor_idle_dmi_table); +} +#else +static inline void processor_dmi_check(void) {} +#endif + +void __init acpi_early_processor_set_pdc(void) +{ + processor_dmi_check(); acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, early_init_pdc, NULL, NULL, NULL); - acpi_get_devices("ACPI0007", early_init_pdc, NULL, NULL); + acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID, early_init_pdc, NULL, NULL); } diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index c1c35623550f..7f70f3182d50 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -41,8 +41,6 @@ #include "internal.h" -#define PREFIX "ACPI: " - #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80 #define ACPI_PROCESSOR_NOTIFY_POWER 0x81 #define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82 diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index ff90054f04fd..cfc8aba72f86 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -156,17 +156,9 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr) */ static void acpi_processor_ppc_ost(acpi_handle handle, int status) { - union acpi_object params[2] = { - {.type = ACPI_TYPE_INTEGER,}, - {.type = ACPI_TYPE_INTEGER,}, - }; - struct acpi_object_list arg_list = {2, params}; - - if (acpi_has_method(handle, "_OST")) { - params[0].integer.value = ACPI_PROCESSOR_NOTIFY_PERFORMANCE; - params[1].integer.value = status; - acpi_evaluate_object(handle, "_OST", &arg_list, NULL); - } + if (acpi_has_method(handle, "_OST")) + acpi_evaluate_ost(handle, ACPI_PROCESSOR_NOTIFY_PERFORMANCE, + status, NULL); } int acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag) diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index dbd48498b938..366ca40a6f70 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -37,12 +37,12 @@ #include <linux/power_supply.h> #include "sbshc.h" +#include "battery.h" #define PREFIX "ACPI: " #define ACPI_SBS_CLASS "sbs" #define ACPI_AC_CLASS "ac_adapter" -#define ACPI_BATTERY_CLASS "battery" #define ACPI_SBS_DEVICE_NAME "Smart Battery System" #define ACPI_SBS_FILE_INFO "info" #define ACPI_SBS_FILE_STATE "state" diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 57b053f424d1..7efe546a8c42 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -41,6 +41,7 @@ static DEFINE_MUTEX(acpi_scan_lock); static LIST_HEAD(acpi_scan_handlers_list); DEFINE_MUTEX(acpi_device_lock); LIST_HEAD(acpi_wakeup_device_list); +static DEFINE_MUTEX(acpi_hp_context_lock); struct acpi_device_bus_id{ char bus_id[15]; @@ -60,6 +61,27 @@ void acpi_scan_lock_release(void) } EXPORT_SYMBOL_GPL(acpi_scan_lock_release); +void acpi_lock_hp_context(void) +{ + mutex_lock(&acpi_hp_context_lock); +} + +void acpi_unlock_hp_context(void) +{ + mutex_unlock(&acpi_hp_context_lock); +} + +void acpi_initialize_hp_context(struct acpi_device *adev, + struct acpi_hotplug_context *hp, + int (*notify)(struct acpi_device *, u32), + void (*uevent)(struct acpi_device *, u32)) +{ + acpi_lock_hp_context(); + acpi_set_hp_context(adev, hp, notify, uevent, NULL); + acpi_unlock_hp_context(); +} +EXPORT_SYMBOL_GPL(acpi_initialize_hp_context); + int acpi_scan_add_handler(struct acpi_scan_handler *handler) { if (!handler || !handler->attach) @@ -439,90 +461,75 @@ static int acpi_scan_bus_check(struct acpi_device *adev) return 0; } -static void acpi_device_hotplug(void *data, u32 src) +static int acpi_generic_hotplug_event(struct acpi_device *adev, u32 type) { - u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; - struct acpi_device *adev = data; - int error; - - lock_device_hotplug(); - mutex_lock(&acpi_scan_lock); - - /* - * The device object's ACPI handle cannot become invalid as long as we - * are holding acpi_scan_lock, but it may have become invalid before - * that lock was acquired. - */ - if (adev->handle == INVALID_ACPI_HANDLE) - goto out; - - switch (src) { + switch (type) { case ACPI_NOTIFY_BUS_CHECK: - error = acpi_scan_bus_check(adev); - break; + return acpi_scan_bus_check(adev); case ACPI_NOTIFY_DEVICE_CHECK: - error = acpi_scan_device_check(adev); - break; + return acpi_scan_device_check(adev); case ACPI_NOTIFY_EJECT_REQUEST: case ACPI_OST_EC_OSPM_EJECT: - error = acpi_scan_hot_remove(adev); - break; - default: - error = -EINVAL; - break; + if (adev->handler && !adev->handler->hotplug.enabled) { + dev_info(&adev->dev, "Eject disabled\n"); + return -EPERM; + } + acpi_evaluate_ost(adev->handle, ACPI_NOTIFY_EJECT_REQUEST, + ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); + return acpi_scan_hot_remove(adev); } - if (!error) - ost_code = ACPI_OST_SC_SUCCESS; - - out: - acpi_evaluate_hotplug_ost(adev->handle, src, ost_code, NULL); - put_device(&adev->dev); - mutex_unlock(&acpi_scan_lock); - unlock_device_hotplug(); + return -EINVAL; } -static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) +void acpi_device_hotplug(struct acpi_device *adev, u32 src) { u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; - struct acpi_device *adev; - acpi_status status; + int error = -ENODEV; - if (acpi_bus_get_device(handle, &adev)) - goto err_out; + lock_device_hotplug(); + mutex_lock(&acpi_scan_lock); - switch (type) { - case ACPI_NOTIFY_BUS_CHECK: - acpi_handle_debug(handle, "ACPI_NOTIFY_BUS_CHECK event\n"); - break; - case ACPI_NOTIFY_DEVICE_CHECK: - acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_CHECK event\n"); - break; - case ACPI_NOTIFY_EJECT_REQUEST: - acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n"); - if (!adev->handler) - goto err_out; + /* + * The device object's ACPI handle cannot become invalid as long as we + * are holding acpi_scan_lock, but it might have become invalid before + * that lock was acquired. + */ + if (adev->handle == INVALID_ACPI_HANDLE) + goto err_out; - if (!adev->handler->hotplug.enabled) { - acpi_handle_err(handle, "Eject disabled\n"); + if (adev->flags.is_dock_station) { + error = dock_notify(adev, src); + } else if (adev->flags.hotplug_notify) { + error = acpi_generic_hotplug_event(adev, src); + if (error == -EPERM) { ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED; goto err_out; } - acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST, - ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); - break; - default: - /* non-hotplug event; possibly handled by other handler */ - return; - } - get_device(&adev->dev); - status = acpi_hotplug_execute(acpi_device_hotplug, adev, type); - if (ACPI_SUCCESS(status)) - return; + } else { + int (*notify)(struct acpi_device *, u32); - put_device(&adev->dev); + acpi_lock_hp_context(); + notify = adev->hp ? adev->hp->notify : NULL; + acpi_unlock_hp_context(); + /* + * There may be additional notify handlers for device objects + * without the .event() callback, so ignore them here. + */ + if (notify) + error = notify(adev, src); + else + goto out; + } + if (!error) + ost_code = ACPI_OST_SC_SUCCESS; err_out: - acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL); + acpi_evaluate_ost(adev->handle, src, ost_code, NULL); + + out: + acpi_bus_put_acpi_device(adev); + mutex_unlock(&acpi_scan_lock); + unlock_device_hotplug(); } static ssize_t real_power_state_show(struct device *dev, @@ -570,17 +577,14 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, if (ACPI_FAILURE(status) || !acpi_device->flags.ejectable) return -ENODEV; - acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT, - ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); get_device(&acpi_device->dev); - status = acpi_hotplug_execute(acpi_device_hotplug, acpi_device, - ACPI_OST_EC_OSPM_EJECT); + status = acpi_hotplug_schedule(acpi_device, ACPI_OST_EC_OSPM_EJECT); if (ACPI_SUCCESS(status)) return count; put_device(&acpi_device->dev); - acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT, - ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL); + acpi_evaluate_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT, + ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL); return status == AE_NO_MEMORY ? -ENOMEM : -EAGAIN; } @@ -1114,14 +1118,16 @@ static void acpi_scan_drop_device(acpi_handle handle, void *context) mutex_unlock(&acpi_device_del_lock); } -int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device) +static int acpi_get_device_data(acpi_handle handle, struct acpi_device **device, + void (*callback)(void *)) { acpi_status status; if (!device) return -EINVAL; - status = acpi_get_data(handle, acpi_scan_drop_device, (void **)device); + status = acpi_get_data_full(handle, acpi_scan_drop_device, + (void **)device, callback); if (ACPI_FAILURE(status) || !*device) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No context for object [%p]\n", handle)); @@ -1129,8 +1135,32 @@ int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device) } return 0; } + +int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device) +{ + return acpi_get_device_data(handle, device, NULL); +} EXPORT_SYMBOL(acpi_bus_get_device); +static void get_acpi_device(void *dev) +{ + if (dev) + get_device(&((struct acpi_device *)dev)->dev); +} + +struct acpi_device *acpi_bus_get_acpi_device(acpi_handle handle) +{ + struct acpi_device *adev = NULL; + + acpi_get_device_data(handle, &adev, get_acpi_device); + return adev; +} + +void acpi_bus_put_acpi_device(struct acpi_device *adev) +{ + put_device(&adev->dev); +} + int acpi_device_add(struct acpi_device *device, void (*release)(struct device *)) { @@ -1641,6 +1671,27 @@ bool acpi_bay_match(acpi_handle handle) return acpi_ata_match(phandle); } +bool acpi_device_is_battery(struct acpi_device *adev) +{ + struct acpi_hardware_id *hwid; + + list_for_each_entry(hwid, &adev->pnp.ids, list) + if (!strcmp("PNP0C0A", hwid->id)) + return true; + + return false; +} + +static bool is_ejectable_bay(struct acpi_device *adev) +{ + acpi_handle handle = adev->handle; + + if (acpi_has_method(handle, "_EJ0") && acpi_device_is_battery(adev)) + return true; + + return acpi_bay_match(handle); +} + /* * acpi_dock_match - see if an acpi object has a _DCK method */ @@ -1706,6 +1757,20 @@ static bool acpi_ibm_smbus_match(acpi_handle handle) return false; } +static bool acpi_object_is_system_bus(acpi_handle handle) +{ + acpi_handle tmp; + + if (ACPI_SUCCESS(acpi_get_handle(NULL, "\\_SB", &tmp)) && + tmp == handle) + return true; + if (ACPI_SUCCESS(acpi_get_handle(NULL, "\\_TZ", &tmp)) && + tmp == handle) + return true; + + return false; +} + static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp, int device_type) { @@ -1757,8 +1822,10 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp, acpi_add_id(pnp, ACPI_DOCK_HID); else if (acpi_ibm_smbus_match(handle)) acpi_add_id(pnp, ACPI_SMBUS_IBM_HID); - else if (list_empty(&pnp->ids) && handle == ACPI_ROOT_OBJECT) { - acpi_add_id(pnp, ACPI_BUS_HID); /* \_SB, LNXSYBUS */ + else if (list_empty(&pnp->ids) && + acpi_object_is_system_bus(handle)) { + /* \_SB, \_TZ, LNXSYBUS */ + acpi_add_id(pnp, ACPI_BUS_HID); strcpy(pnp->device_name, ACPI_BUS_DEVICE_NAME); strcpy(pnp->device_class, ACPI_BUS_CLASS); } @@ -1941,33 +2008,23 @@ void acpi_scan_hotplug_enabled(struct acpi_hotplug_profile *hotplug, bool val) mutex_unlock(&acpi_scan_lock); } -static void acpi_scan_init_hotplug(acpi_handle handle, int type) +static void acpi_scan_init_hotplug(struct acpi_device *adev) { - struct acpi_device_pnp pnp = {}; struct acpi_hardware_id *hwid; - struct acpi_scan_handler *handler; - INIT_LIST_HEAD(&pnp.ids); - acpi_set_pnp_ids(handle, &pnp, type); - - if (!pnp.type.hardware_id) - goto out; + if (acpi_dock_match(adev->handle) || is_ejectable_bay(adev)) { + acpi_dock_add(adev); + return; + } + list_for_each_entry(hwid, &adev->pnp.ids, list) { + struct acpi_scan_handler *handler; - /* - * This relies on the fact that acpi_install_notify_handler() will not - * install the same notify handler routine twice for the same handle. - */ - list_for_each_entry(hwid, &pnp.ids, list) { handler = acpi_scan_match_handler(hwid->id, NULL); if (handler) { - acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, - acpi_hotplug_notify_cb, handler); + adev->flags.hotplug_notify = true; break; } } - -out: - acpi_free_pnp_ids(&pnp); } static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, @@ -1991,12 +2048,12 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, return AE_OK; } - acpi_scan_init_hotplug(handle, type); - acpi_add_single_object(&device, handle, type, sta); if (!device) return AE_CTRL_DEPTH; + acpi_scan_init_hotplug(device); + out: if (!*return_value) *return_value = device; @@ -2015,13 +2072,14 @@ static int acpi_scan_attach_handler(struct acpi_device *device) handler = acpi_scan_match_handler(hwid->id, &devid); if (handler) { + device->handler = handler; ret = handler->attach(device, devid); - if (ret > 0) { - device->handler = handler; + if (ret > 0) break; - } else if (ret < 0) { + + device->handler = NULL; + if (ret < 0) break; - } } } return ret; @@ -2030,8 +2088,12 @@ static int acpi_scan_attach_handler(struct acpi_device *device) static void acpi_bus_attach(struct acpi_device *device) { struct acpi_device *child; + acpi_handle ejd; int ret; + if (ACPI_SUCCESS(acpi_bus_get_ejd(device->handle, &ejd))) + register_dock_dependent_device(device, ejd); + acpi_bus_get_status(device); /* Skip devices that are not present. */ if (!acpi_device_is_present(device)) { @@ -2184,7 +2246,6 @@ int __init acpi_scan_init(void) acpi_cmos_rtc_init(); acpi_container_init(); acpi_memory_hotplug_init(); - acpi_dock_init(); mutex_lock(&acpi_scan_lock); /* diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index b718806657cd..c40fb2e81bbc 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -71,6 +71,17 @@ static int acpi_sleep_prepare(u32 acpi_state) return 0; } +static bool acpi_sleep_state_supported(u8 sleep_state) +{ + acpi_status status; + u8 type_a, type_b; + + status = acpi_get_sleep_type_data(sleep_state, &type_a, &type_b); + return ACPI_SUCCESS(status) && (!acpi_gbl_reduced_hardware + || (acpi_gbl_FADT.sleep_control.address + && acpi_gbl_FADT.sleep_status.address)); +} + #ifdef CONFIG_ACPI_SLEEP static u32 acpi_target_sleep_state = ACPI_STATE_S0; @@ -604,15 +615,9 @@ static void acpi_sleep_suspend_setup(void) { int i; - for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++) { - acpi_status status; - u8 type_a, type_b; - - status = acpi_get_sleep_type_data(i, &type_a, &type_b); - if (ACPI_SUCCESS(status)) { + for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++) + if (acpi_sleep_state_supported(i)) sleep_states[i] = 1; - } - } suspend_set_ops(old_suspend_ordering ? &acpi_suspend_ops_old : &acpi_suspend_ops); @@ -740,11 +745,7 @@ static const struct platform_hibernation_ops acpi_hibernation_ops_old = { static void acpi_sleep_hibernate_setup(void) { - acpi_status status; - u8 type_a, type_b; - - status = acpi_get_sleep_type_data(ACPI_STATE_S4, &type_a, &type_b); - if (ACPI_FAILURE(status)) + if (!acpi_sleep_state_supported(ACPI_STATE_S4)) return; hibernation_set_ops(old_suspend_ordering ? @@ -793,8 +794,6 @@ static void acpi_power_off(void) int __init acpi_sleep_init(void) { - acpi_status status; - u8 type_a, type_b; char supported[ACPI_S_STATE_COUNT * 3 + 1]; char *pos = supported; int i; @@ -806,8 +805,7 @@ int __init acpi_sleep_init(void) acpi_sleep_suspend_setup(); acpi_sleep_hibernate_setup(); - status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b); - if (ACPI_SUCCESS(status)) { + if (acpi_sleep_state_supported(ACPI_STATE_S5)) { sleep_states[ACPI_STATE_S5] = 1; pm_power_off_prepare = acpi_power_off_prepare; pm_power_off = acpi_power_off; diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 91a32cefb11f..38cb9782d4b8 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -12,8 +12,6 @@ #define _COMPONENT ACPI_SYSTEM_COMPONENT ACPI_MODULE_NAME("sysfs"); -#define PREFIX "ACPI: " - #ifdef CONFIG_ACPI_DEBUG /* * ACPI debug sysfs I/F, including: diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 5837f857ac2e..21782290df41 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c @@ -23,6 +23,8 @@ * */ +#define pr_fmt(fmt) "ACPI: " fmt + #include <linux/init.h> #include <linux/kernel.h> #include <linux/smp.h> @@ -33,8 +35,6 @@ #include <linux/acpi.h> #include <linux/bootmem.h> -#define PREFIX "ACPI: " - #define ACPI_MAX_TABLES 128 static char *mps_inti_flags_polarity[] = { "dfl", "high", "res", "low" }; @@ -55,10 +55,9 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) { struct acpi_madt_local_apic *p = (struct acpi_madt_local_apic *)header; - printk(KERN_INFO PREFIX - "LAPIC (acpi_id[0x%02x] lapic_id[0x%02x] %s)\n", - p->processor_id, p->id, - (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); + pr_info("LAPIC (acpi_id[0x%02x] lapic_id[0x%02x] %s)\n", + p->processor_id, p->id, + (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); } break; @@ -66,11 +65,9 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) { struct acpi_madt_local_x2apic *p = (struct acpi_madt_local_x2apic *)header; - printk(KERN_INFO PREFIX - "X2APIC (apic_id[0x%02x] uid[0x%02x] %s)\n", - p->local_apic_id, p->uid, - (p->lapic_flags & ACPI_MADT_ENABLED) ? - "enabled" : "disabled"); + pr_info("X2APIC (apic_id[0x%02x] uid[0x%02x] %s)\n", + p->local_apic_id, p->uid, + (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); } break; @@ -78,9 +75,8 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) { struct acpi_madt_io_apic *p = (struct acpi_madt_io_apic *)header; - printk(KERN_INFO PREFIX - "IOAPIC (id[0x%02x] address[0x%08x] gsi_base[%d])\n", - p->id, p->address, p->global_irq_base); + pr_info("IOAPIC (id[0x%02x] address[0x%08x] gsi_base[%d])\n", + p->id, p->address, p->global_irq_base); } break; @@ -88,18 +84,15 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) { struct acpi_madt_interrupt_override *p = (struct acpi_madt_interrupt_override *)header; - printk(KERN_INFO PREFIX - "INT_SRC_OVR (bus %d bus_irq %d global_irq %d %s %s)\n", - p->bus, p->source_irq, p->global_irq, - mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK], - mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2]); + pr_info("INT_SRC_OVR (bus %d bus_irq %d global_irq %d %s %s)\n", + p->bus, p->source_irq, p->global_irq, + mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK], + mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2]); if (p->inti_flags & ~(ACPI_MADT_POLARITY_MASK | ACPI_MADT_TRIGGER_MASK)) - printk(KERN_INFO PREFIX - "INT_SRC_OVR unexpected reserved flags: 0x%x\n", - p->inti_flags & + pr_info("INT_SRC_OVR unexpected reserved flags: 0x%x\n", + p->inti_flags & ~(ACPI_MADT_POLARITY_MASK | ACPI_MADT_TRIGGER_MASK)); - } break; @@ -107,11 +100,10 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) { struct acpi_madt_nmi_source *p = (struct acpi_madt_nmi_source *)header; - printk(KERN_INFO PREFIX - "NMI_SRC (%s %s global_irq %d)\n", - mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK], - mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2], - p->global_irq); + pr_info("NMI_SRC (%s %s global_irq %d)\n", + mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK], + mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2], + p->global_irq); } break; @@ -119,12 +111,11 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) { struct acpi_madt_local_apic_nmi *p = (struct acpi_madt_local_apic_nmi *)header; - printk(KERN_INFO PREFIX - "LAPIC_NMI (acpi_id[0x%02x] %s %s lint[0x%x])\n", - p->processor_id, - mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK ], - mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2], - p->lint); + pr_info("LAPIC_NMI (acpi_id[0x%02x] %s %s lint[0x%x])\n", + p->processor_id, + mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK ], + mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2], + p->lint); } break; @@ -137,12 +128,11 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) polarity = p->inti_flags & ACPI_MADT_POLARITY_MASK; trigger = (p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2; - printk(KERN_INFO PREFIX - "X2APIC_NMI (uid[0x%02x] %s %s lint[0x%x])\n", - p->uid, - mps_inti_flags_polarity[polarity], - mps_inti_flags_trigger[trigger], - p->lint); + pr_info("X2APIC_NMI (uid[0x%02x] %s %s lint[0x%x])\n", + p->uid, + mps_inti_flags_polarity[polarity], + mps_inti_flags_trigger[trigger], + p->lint); } break; @@ -150,9 +140,8 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) { struct acpi_madt_local_apic_override *p = (struct acpi_madt_local_apic_override *)header; - printk(KERN_INFO PREFIX - "LAPIC_ADDR_OVR (address[%p])\n", - (void *)(unsigned long)p->address); + pr_info("LAPIC_ADDR_OVR (address[%p])\n", + (void *)(unsigned long)p->address); } break; @@ -160,10 +149,9 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) { struct acpi_madt_io_sapic *p = (struct acpi_madt_io_sapic *)header; - printk(KERN_INFO PREFIX - "IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n", - p->id, (void *)(unsigned long)p->address, - p->global_irq_base); + pr_info("IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n", + p->id, (void *)(unsigned long)p->address, + p->global_irq_base); } break; @@ -171,10 +159,9 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) { struct acpi_madt_local_sapic *p = (struct acpi_madt_local_sapic *)header; - printk(KERN_INFO PREFIX - "LSAPIC (acpi_id[0x%02x] lsapic_id[0x%02x] lsapic_eid[0x%02x] %s)\n", - p->processor_id, p->id, p->eid, - (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); + pr_info("LSAPIC (acpi_id[0x%02x] lsapic_id[0x%02x] lsapic_eid[0x%02x] %s)\n", + p->processor_id, p->id, p->eid, + (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); } break; @@ -182,19 +169,17 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) { struct acpi_madt_interrupt_source *p = (struct acpi_madt_interrupt_source *)header; - printk(KERN_INFO PREFIX - "PLAT_INT_SRC (%s %s type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n", - mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK], - mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2], - p->type, p->id, p->eid, p->io_sapic_vector, - p->global_irq); + pr_info("PLAT_INT_SRC (%s %s type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n", + mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK], + mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2], + p->type, p->id, p->eid, p->io_sapic_vector, + p->global_irq); } break; default: - printk(KERN_WARNING PREFIX - "Found unsupported MADT entry (type = 0x%x)\n", - header->type); + pr_warn("Found unsupported MADT entry (type = 0x%x)\n", + header->type); break; } } @@ -225,7 +210,7 @@ acpi_table_parse_entries(char *id, acpi_get_table_with_size(id, 0, &table_header, &tbl_size); if (!table_header) { - printk(KERN_WARNING PREFIX "%4.4s not present\n", id); + pr_warn("%4.4s not present\n", id); return -ENODEV; } @@ -248,7 +233,7 @@ acpi_table_parse_entries(char *id, * infinite loop. */ if (entry->length == 0) { - pr_err(PREFIX "[%4.4s:0x%02x] Invalid zero length\n", id, entry_id); + pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, entry_id); goto err; } @@ -256,8 +241,8 @@ acpi_table_parse_entries(char *id, ((unsigned long)entry + entry->length); } if (max_entries && count > max_entries) { - printk(KERN_WARNING PREFIX "[%4.4s:0x%02x] ignored %i entries of " - "%i found\n", id, entry_id, count - max_entries, count); + pr_warn("[%4.4s:0x%02x] ignored %i entries of %i found\n", + id, entry_id, count - max_entries, count); } early_acpi_os_unmap_memory((char *)table_header, tbl_size); @@ -322,13 +307,11 @@ static void __init check_multiple_madt(void) acpi_get_table_with_size(ACPI_SIG_MADT, 2, &table, &tbl_size); if (table) { - printk(KERN_WARNING PREFIX - "BIOS bug: multiple APIC/MADT found," - " using %d\n", acpi_apic_instance); - printk(KERN_WARNING PREFIX - "If \"acpi_apic_instance=%d\" works better, " - "notify linux-acpi@vger.kernel.org\n", - acpi_apic_instance ? 0 : 2); + pr_warn("BIOS bug: multiple APIC/MADT found, using %d\n", + acpi_apic_instance); + pr_warn("If \"acpi_apic_instance=%d\" works better, " + "notify linux-acpi@vger.kernel.org\n", + acpi_apic_instance ? 0 : 2); early_acpi_os_unmap_memory(table, tbl_size); } else @@ -365,8 +348,7 @@ static int __init acpi_parse_apic_instance(char *str) acpi_apic_instance = simple_strtoul(str, NULL, 0); - printk(KERN_NOTICE PREFIX "Shall use APIC/MADT table %d\n", - acpi_apic_instance); + pr_notice("Shall use APIC/MADT table %d\n", acpi_apic_instance); return 0; } diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 08626c851be7..964068553334 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -43,6 +43,7 @@ #include <linux/device.h> #include <linux/thermal.h> #include <linux/acpi.h> +#include <linux/workqueue.h> #include <asm/uaccess.h> #define PREFIX "ACPI: " @@ -90,6 +91,8 @@ static int psv; module_param(psv, int, 0644); MODULE_PARM_DESC(psv, "Disable or override all passive trip points."); +static struct workqueue_struct *acpi_thermal_pm_queue; + static int acpi_thermal_add(struct acpi_device *device); static int acpi_thermal_remove(struct acpi_device *device); static void acpi_thermal_notify(struct acpi_device *device, u32 event); @@ -101,11 +104,13 @@ static const struct acpi_device_id thermal_device_ids[] = { MODULE_DEVICE_TABLE(acpi, thermal_device_ids); #ifdef CONFIG_PM_SLEEP +static int acpi_thermal_suspend(struct device *dev); static int acpi_thermal_resume(struct device *dev); #else +#define acpi_thermal_suspend NULL #define acpi_thermal_resume NULL #endif -static SIMPLE_DEV_PM_OPS(acpi_thermal_pm, NULL, acpi_thermal_resume); +static SIMPLE_DEV_PM_OPS(acpi_thermal_pm, acpi_thermal_suspend, acpi_thermal_resume); static struct acpi_driver acpi_thermal_driver = { .name = "thermal", @@ -186,6 +191,7 @@ struct acpi_thermal { struct thermal_zone_device *thermal_zone; int tz_enabled; int kelvin_offset; + struct work_struct thermal_check_work; }; /* -------------------------------------------------------------------------- @@ -1064,6 +1070,13 @@ static void acpi_thermal_guess_offset(struct acpi_thermal *tz) tz->kelvin_offset = 2732; } +static void acpi_thermal_check_fn(struct work_struct *work) +{ + struct acpi_thermal *tz = container_of(work, struct acpi_thermal, + thermal_check_work); + acpi_thermal_check(tz); +} + static int acpi_thermal_add(struct acpi_device *device) { int result = 0; @@ -1093,6 +1106,8 @@ static int acpi_thermal_add(struct acpi_device *device) if (result) goto free_memory; + INIT_WORK(&tz->thermal_check_work, acpi_thermal_check_fn); + pr_info(PREFIX "%s [%s] (%ld C)\n", acpi_device_name(device), acpi_device_bid(device), KELVIN_TO_CELSIUS(tz->temperature)); goto end; @@ -1110,6 +1125,7 @@ static int acpi_thermal_remove(struct acpi_device *device) if (!device || !acpi_driver_data(device)) return -EINVAL; + flush_workqueue(acpi_thermal_pm_queue); tz = acpi_driver_data(device); acpi_thermal_unregister_thermal_zone(tz); @@ -1118,6 +1134,13 @@ static int acpi_thermal_remove(struct acpi_device *device) } #ifdef CONFIG_PM_SLEEP +static int acpi_thermal_suspend(struct device *dev) +{ + /* Make sure the previously queued thermal check work has been done */ + flush_workqueue(acpi_thermal_pm_queue); + return 0; +} + static int acpi_thermal_resume(struct device *dev) { struct acpi_thermal *tz; @@ -1148,7 +1171,7 @@ static int acpi_thermal_resume(struct device *dev) tz->state.active |= tz->trips.active[i].flags.enabled; } - acpi_thermal_check(tz); + queue_work(acpi_thermal_pm_queue, &tz->thermal_check_work); return AE_OK; } @@ -1240,16 +1263,22 @@ static int __init acpi_thermal_init(void) return -ENODEV; } + acpi_thermal_pm_queue = create_workqueue("acpi_thermal_pm"); + if (!acpi_thermal_pm_queue) + return -ENODEV; + result = acpi_bus_register_driver(&acpi_thermal_driver); - if (result < 0) + if (result < 0) { + destroy_workqueue(acpi_thermal_pm_queue); return -ENODEV; + } return 0; } static void __exit acpi_thermal_exit(void) { - + destroy_workqueue(acpi_thermal_pm_queue); acpi_bus_unregister_driver(&acpi_thermal_driver); return; diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 85e3b612bdc0..0f5f78fa6545 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -422,7 +422,7 @@ out: EXPORT_SYMBOL(acpi_get_physical_device_location); /** - * acpi_evaluate_hotplug_ost: Evaluate _OST for hotplug operations + * acpi_evaluate_ost: Evaluate _OST for hotplug operations * @handle: ACPI device handle * @source_event: source event code * @status_code: status code @@ -433,17 +433,15 @@ EXPORT_SYMBOL(acpi_get_physical_device_location); * When the platform does not support _OST, this function has no effect. */ acpi_status -acpi_evaluate_hotplug_ost(acpi_handle handle, u32 source_event, - u32 status_code, struct acpi_buffer *status_buf) +acpi_evaluate_ost(acpi_handle handle, u32 source_event, u32 status_code, + struct acpi_buffer *status_buf) { -#ifdef ACPI_HOTPLUG_OST union acpi_object params[3] = { {.type = ACPI_TYPE_INTEGER,}, {.type = ACPI_TYPE_INTEGER,}, {.type = ACPI_TYPE_BUFFER,} }; struct acpi_object_list arg_list = {3, params}; - acpi_status status; params[0].integer.value = source_event; params[1].integer.value = status_code; @@ -455,13 +453,9 @@ acpi_evaluate_hotplug_ost(acpi_handle handle, u32 source_event, params[2].buffer.length = 0; } - status = acpi_evaluate_object(handle, "_OST", &arg_list, NULL); - return status; -#else - return AE_OK; -#endif + return acpi_evaluate_object(handle, "_OST", &arg_list, NULL); } -EXPORT_SYMBOL(acpi_evaluate_hotplug_ost); +EXPORT_SYMBOL(acpi_evaluate_ost); /** * acpi_handle_printk: Print message with ACPI prefix and object path diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index b6ba88ed31ae..48c7e8af9c96 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -45,8 +45,6 @@ #include "internal.h" -#define PREFIX "ACPI: " - #define ACPI_VIDEO_BUS_NAME "Video Bus" #define ACPI_VIDEO_DEVICE_NAME "Video Device" #define ACPI_VIDEO_NOTIFY_SWITCH 0x80 diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 19080c8e2f2a..33e3db548a29 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -40,8 +40,6 @@ #include "internal.h" -#define PREFIX "ACPI: " - ACPI_MODULE_NAME("video"); #define _COMPONENT ACPI_VIDEO_COMPONENT diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 9e69a5308693..acb95dffdb6a 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -38,6 +38,16 @@ static void ata_acpi_clear_gtf(struct ata_device *dev) dev->gtf_cache = NULL; } +struct ata_acpi_hotplug_context { + struct acpi_hotplug_context hp; + union { + struct ata_port *ap; + struct ata_device *dev; + } data; +}; + +#define ata_hotplug_data(context) (container_of((context), struct ata_acpi_hotplug_context, hp)->data) + /** * ata_dev_acpi_handle - provide the acpi_handle for an ata_device * @dev: the acpi_handle returned will correspond to this device @@ -121,18 +131,17 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev, ata_port_wait_eh(ap); } -static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data) +static int ata_acpi_dev_notify_dock(struct acpi_device *adev, u32 event) { - struct ata_device *dev = data; - + struct ata_device *dev = ata_hotplug_data(adev->hp).dev; ata_acpi_handle_hotplug(dev->link->ap, dev, event); + return 0; } -static void ata_acpi_ap_notify_dock(acpi_handle handle, u32 event, void *data) +static int ata_acpi_ap_notify_dock(struct acpi_device *adev, u32 event) { - struct ata_port *ap = data; - - ata_acpi_handle_hotplug(ap, NULL, event); + ata_acpi_handle_hotplug(ata_hotplug_data(adev->hp).ap, NULL, event); + return 0; } static void ata_acpi_uevent(struct ata_port *ap, struct ata_device *dev, @@ -154,31 +163,23 @@ static void ata_acpi_uevent(struct ata_port *ap, struct ata_device *dev, } } -static void ata_acpi_ap_uevent(acpi_handle handle, u32 event, void *data) +static void ata_acpi_ap_uevent(struct acpi_device *adev, u32 event) { - ata_acpi_uevent(data, NULL, event); + ata_acpi_uevent(ata_hotplug_data(adev->hp).ap, NULL, event); } -static void ata_acpi_dev_uevent(acpi_handle handle, u32 event, void *data) +static void ata_acpi_dev_uevent(struct acpi_device *adev, u32 event) { - struct ata_device *dev = data; + struct ata_device *dev = ata_hotplug_data(adev->hp).dev; ata_acpi_uevent(dev->link->ap, dev, event); } -static const struct acpi_dock_ops ata_acpi_dev_dock_ops = { - .handler = ata_acpi_dev_notify_dock, - .uevent = ata_acpi_dev_uevent, -}; - -static const struct acpi_dock_ops ata_acpi_ap_dock_ops = { - .handler = ata_acpi_ap_notify_dock, - .uevent = ata_acpi_ap_uevent, -}; - /* bind acpi handle to pata port */ void ata_acpi_bind_port(struct ata_port *ap) { struct acpi_device *host_companion = ACPI_COMPANION(ap->host->dev); + struct acpi_device *adev; + struct ata_acpi_hotplug_context *context; if (libata_noacpi || ap->flags & ATA_FLAG_ACPI_SATA || !host_companion) return; @@ -188,9 +189,17 @@ void ata_acpi_bind_port(struct ata_port *ap) if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0) ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; - /* we might be on a docking station */ - register_hotplug_dock_device(ACPI_HANDLE(&ap->tdev), - &ata_acpi_ap_dock_ops, ap, NULL, NULL); + adev = ACPI_COMPANION(&ap->tdev); + if (!adev || adev->hp) + return; + + context = kzalloc(sizeof(*context), GFP_KERNEL); + if (!context) + return; + + context->data.ap = ap; + acpi_initialize_hp_context(adev, &context->hp, ata_acpi_ap_notify_dock, + ata_acpi_ap_uevent); } void ata_acpi_bind_dev(struct ata_device *dev) @@ -198,7 +207,8 @@ void ata_acpi_bind_dev(struct ata_device *dev) struct ata_port *ap = dev->link->ap; struct acpi_device *port_companion = ACPI_COMPANION(&ap->tdev); struct acpi_device *host_companion = ACPI_COMPANION(ap->host->dev); - struct acpi_device *parent; + struct acpi_device *parent, *adev; + struct ata_acpi_hotplug_context *context; u64 adr; /* @@ -221,9 +231,17 @@ void ata_acpi_bind_dev(struct ata_device *dev) } acpi_preset_companion(&dev->tdev, parent, adr); + adev = ACPI_COMPANION(&dev->tdev); + if (!adev || adev->hp) + return; + + context = kzalloc(sizeof(*context), GFP_KERNEL); + if (!context) + return; - register_hotplug_dock_device(ata_dev_acpi_handle(dev), - &ata_acpi_dev_dock_ops, dev, NULL, NULL); + context->data.dev = dev; + acpi_initialize_hp_context(adev, &context->hp, ata_acpi_dev_notify_dock, + ata_acpi_dev_uevent); } /** diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 65d3f1b5966c..8cb2522d592a 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4225,8 +4225,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { /* devices that don't properly handle queued TRIM commands */ { "Micron_M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, - { "Crucial_CT???M500SSD1", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, - { "Crucial_CT???M500SSD3", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, + { "Crucial_CT???M500SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, /* * Some WD SATA-I drives spin up and down erratically when the link diff --git a/drivers/base/power/Makefile b/drivers/base/power/Makefile index 2e58ebb1f6c0..1cb8544598d5 100644 --- a/drivers/base/power/Makefile +++ b/drivers/base/power/Makefile @@ -1,6 +1,5 @@ -obj-$(CONFIG_PM) += sysfs.o generic_ops.o common.o qos.o +obj-$(CONFIG_PM) += sysfs.o generic_ops.o common.o qos.o runtime.o obj-$(CONFIG_PM_SLEEP) += main.o wakeup.o -obj-$(CONFIG_PM_RUNTIME) += runtime.o obj-$(CONFIG_PM_TRACE_RTC) += trace.o obj-$(CONFIG_PM_OPP) += opp.o obj-$(CONFIG_PM_GENERIC_DOMAINS) += domain.o domain_governor.o diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index bfb8955c406c..dc127e5dec4b 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -42,7 +42,7 @@ struct gpd_timing_data *__td = &dev_gpd_data(dev)->td; \ if (!__retval && __elapsed > __td->field) { \ __td->field = __elapsed; \ - dev_warn(dev, name " latency exceeded, new value %lld ns\n", \ + dev_dbg(dev, name " latency exceeded, new value %lld ns\n", \ __elapsed); \ genpd->max_off_time_changed = true; \ __td->constraint_changed = true; \ diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index c9fbb9d5484d..86d5e4fb5b98 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -92,6 +92,8 @@ void device_pm_sleep_init(struct device *dev) { dev->power.is_prepared = false; dev->power.is_suspended = false; + dev->power.is_noirq_suspended = false; + dev->power.is_late_suspended = false; init_completion(&dev->power.completion); complete_all(&dev->power.completion); dev->power.wakeup = NULL; @@ -468,7 +470,7 @@ static void dpm_watchdog_clear(struct dpm_watchdog *wd) * The driver of @dev will not receive interrupts while this function is being * executed. */ -static int device_resume_noirq(struct device *dev, pm_message_t state) +static int device_resume_noirq(struct device *dev, pm_message_t state, bool async) { pm_callback_t callback = NULL; char *info = NULL; @@ -480,6 +482,11 @@ static int device_resume_noirq(struct device *dev, pm_message_t state) if (dev->power.syscore) goto Out; + if (!dev->power.is_noirq_suspended) + goto Out; + + dpm_wait(dev->parent, async); + if (dev->pm_domain) { info = "noirq power domain "; callback = pm_noirq_op(&dev->pm_domain->ops, state); @@ -500,12 +507,32 @@ static int device_resume_noirq(struct device *dev, pm_message_t state) } error = dpm_run_callback(callback, dev, state, info); + dev->power.is_noirq_suspended = false; Out: + complete_all(&dev->power.completion); TRACE_RESUME(error); return error; } +static bool is_async(struct device *dev) +{ + return dev->power.async_suspend && pm_async_enabled + && !pm_trace_is_enabled(); +} + +static void async_resume_noirq(void *data, async_cookie_t cookie) +{ + struct device *dev = (struct device *)data; + int error; + + error = device_resume_noirq(dev, pm_transition, true); + if (error) + pm_dev_err(dev, pm_transition, " async", error); + + put_device(dev); +} + /** * dpm_resume_noirq - Execute "noirq resume" callbacks for all devices. * @state: PM transition of the system being carried out. @@ -515,29 +542,48 @@ static int device_resume_noirq(struct device *dev, pm_message_t state) */ static void dpm_resume_noirq(pm_message_t state) { + struct device *dev; ktime_t starttime = ktime_get(); mutex_lock(&dpm_list_mtx); - while (!list_empty(&dpm_noirq_list)) { - struct device *dev = to_device(dpm_noirq_list.next); - int error; + pm_transition = state; + /* + * Advanced the async threads upfront, + * in case the starting of async threads is + * delayed by non-async resuming devices. + */ + list_for_each_entry(dev, &dpm_noirq_list, power.entry) { + reinit_completion(&dev->power.completion); + if (is_async(dev)) { + get_device(dev); + async_schedule(async_resume_noirq, dev); + } + } + + while (!list_empty(&dpm_noirq_list)) { + dev = to_device(dpm_noirq_list.next); get_device(dev); list_move_tail(&dev->power.entry, &dpm_late_early_list); mutex_unlock(&dpm_list_mtx); - error = device_resume_noirq(dev, state); - if (error) { - suspend_stats.failed_resume_noirq++; - dpm_save_failed_step(SUSPEND_RESUME_NOIRQ); - dpm_save_failed_dev(dev_name(dev)); - pm_dev_err(dev, state, " noirq", error); + if (!is_async(dev)) { + int error; + + error = device_resume_noirq(dev, state, false); + if (error) { + suspend_stats.failed_resume_noirq++; + dpm_save_failed_step(SUSPEND_RESUME_NOIRQ); + dpm_save_failed_dev(dev_name(dev)); + pm_dev_err(dev, state, " noirq", error); + } } mutex_lock(&dpm_list_mtx); put_device(dev); } mutex_unlock(&dpm_list_mtx); + async_synchronize_full(); dpm_show_time(starttime, state, "noirq"); resume_device_irqs(); cpuidle_resume(); @@ -550,7 +596,7 @@ static void dpm_resume_noirq(pm_message_t state) * * Runtime PM is disabled for @dev while this function is being executed. */ -static int device_resume_early(struct device *dev, pm_message_t state) +static int device_resume_early(struct device *dev, pm_message_t state, bool async) { pm_callback_t callback = NULL; char *info = NULL; @@ -562,6 +608,11 @@ static int device_resume_early(struct device *dev, pm_message_t state) if (dev->power.syscore) goto Out; + if (!dev->power.is_late_suspended) + goto Out; + + dpm_wait(dev->parent, async); + if (dev->pm_domain) { info = "early power domain "; callback = pm_late_early_op(&dev->pm_domain->ops, state); @@ -582,43 +633,75 @@ static int device_resume_early(struct device *dev, pm_message_t state) } error = dpm_run_callback(callback, dev, state, info); + dev->power.is_late_suspended = false; Out: TRACE_RESUME(error); pm_runtime_enable(dev); + complete_all(&dev->power.completion); return error; } +static void async_resume_early(void *data, async_cookie_t cookie) +{ + struct device *dev = (struct device *)data; + int error; + + error = device_resume_early(dev, pm_transition, true); + if (error) + pm_dev_err(dev, pm_transition, " async", error); + + put_device(dev); +} + /** * dpm_resume_early - Execute "early resume" callbacks for all devices. * @state: PM transition of the system being carried out. */ static void dpm_resume_early(pm_message_t state) { + struct device *dev; ktime_t starttime = ktime_get(); mutex_lock(&dpm_list_mtx); - while (!list_empty(&dpm_late_early_list)) { - struct device *dev = to_device(dpm_late_early_list.next); - int error; + pm_transition = state; + + /* + * Advanced the async threads upfront, + * in case the starting of async threads is + * delayed by non-async resuming devices. + */ + list_for_each_entry(dev, &dpm_late_early_list, power.entry) { + reinit_completion(&dev->power.completion); + if (is_async(dev)) { + get_device(dev); + async_schedule(async_resume_early, dev); + } + } + while (!list_empty(&dpm_late_early_list)) { + dev = to_device(dpm_late_early_list.next); get_device(dev); list_move_tail(&dev->power.entry, &dpm_suspended_list); mutex_unlock(&dpm_list_mtx); - error = device_resume_early(dev, state); - if (error) { - suspend_stats.failed_resume_early++; - dpm_save_failed_step(SUSPEND_RESUME_EARLY); - dpm_save_failed_dev(dev_name(dev)); - pm_dev_err(dev, state, " early", error); - } + if (!is_async(dev)) { + int error; + error = device_resume_early(dev, state, false); + if (error) { + suspend_stats.failed_resume_early++; + dpm_save_failed_step(SUSPEND_RESUME_EARLY); + dpm_save_failed_dev(dev_name(dev)); + pm_dev_err(dev, state, " early", error); + } + } mutex_lock(&dpm_list_mtx); put_device(dev); } mutex_unlock(&dpm_list_mtx); + async_synchronize_full(); dpm_show_time(starttime, state, "early"); } @@ -733,12 +816,6 @@ static void async_resume(void *data, async_cookie_t cookie) put_device(dev); } -static bool is_async(struct device *dev) -{ - return dev->power.async_suspend && pm_async_enabled - && !pm_trace_is_enabled(); -} - /** * dpm_resume - Execute "resume" callbacks for non-sysdev devices. * @state: PM transition of the system being carried out. @@ -916,13 +993,24 @@ static pm_message_t resume_event(pm_message_t sleep_state) * The driver of @dev will not receive interrupts while this function is being * executed. */ -static int device_suspend_noirq(struct device *dev, pm_message_t state) +static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool async) { pm_callback_t callback = NULL; char *info = NULL; + int error = 0; + + if (async_error) + goto Complete; + + if (pm_wakeup_pending()) { + async_error = -EBUSY; + goto Complete; + } if (dev->power.syscore) - return 0; + goto Complete; + + dpm_wait_for_children(dev, async); if (dev->pm_domain) { info = "noirq power domain "; @@ -943,7 +1031,41 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state) callback = pm_noirq_op(dev->driver->pm, state); } - return dpm_run_callback(callback, dev, state, info); + error = dpm_run_callback(callback, dev, state, info); + if (!error) + dev->power.is_noirq_suspended = true; + else + async_error = error; + +Complete: + complete_all(&dev->power.completion); + return error; +} + +static void async_suspend_noirq(void *data, async_cookie_t cookie) +{ + struct device *dev = (struct device *)data; + int error; + + error = __device_suspend_noirq(dev, pm_transition, true); + if (error) { + dpm_save_failed_dev(dev_name(dev)); + pm_dev_err(dev, pm_transition, " async", error); + } + + put_device(dev); +} + +static int device_suspend_noirq(struct device *dev) +{ + reinit_completion(&dev->power.completion); + + if (pm_async_enabled && dev->power.async_suspend) { + get_device(dev); + async_schedule(async_suspend_noirq, dev); + return 0; + } + return __device_suspend_noirq(dev, pm_transition, false); } /** @@ -961,19 +1083,20 @@ static int dpm_suspend_noirq(pm_message_t state) cpuidle_pause(); suspend_device_irqs(); mutex_lock(&dpm_list_mtx); + pm_transition = state; + async_error = 0; + while (!list_empty(&dpm_late_early_list)) { struct device *dev = to_device(dpm_late_early_list.prev); get_device(dev); mutex_unlock(&dpm_list_mtx); - error = device_suspend_noirq(dev, state); + error = device_suspend_noirq(dev); mutex_lock(&dpm_list_mtx); if (error) { pm_dev_err(dev, state, " noirq", error); - suspend_stats.failed_suspend_noirq++; - dpm_save_failed_step(SUSPEND_SUSPEND_NOIRQ); dpm_save_failed_dev(dev_name(dev)); put_device(dev); break; @@ -982,16 +1105,21 @@ static int dpm_suspend_noirq(pm_message_t state) list_move(&dev->power.entry, &dpm_noirq_list); put_device(dev); - if (pm_wakeup_pending()) { - error = -EBUSY; + if (async_error) break; - } } mutex_unlock(&dpm_list_mtx); - if (error) + async_synchronize_full(); + if (!error) + error = async_error; + + if (error) { + suspend_stats.failed_suspend_noirq++; + dpm_save_failed_step(SUSPEND_SUSPEND_NOIRQ); dpm_resume_noirq(resume_event(state)); - else + } else { dpm_show_time(starttime, state, "noirq"); + } return error; } @@ -1002,15 +1130,26 @@ static int dpm_suspend_noirq(pm_message_t state) * * Runtime PM is disabled for @dev while this function is being executed. */ -static int device_suspend_late(struct device *dev, pm_message_t state) +static int __device_suspend_late(struct device *dev, pm_message_t state, bool async) { pm_callback_t callback = NULL; char *info = NULL; + int error = 0; __pm_runtime_disable(dev, false); + if (async_error) + goto Complete; + + if (pm_wakeup_pending()) { + async_error = -EBUSY; + goto Complete; + } + if (dev->power.syscore) - return 0; + goto Complete; + + dpm_wait_for_children(dev, async); if (dev->pm_domain) { info = "late power domain "; @@ -1031,7 +1170,41 @@ static int device_suspend_late(struct device *dev, pm_message_t state) callback = pm_late_early_op(dev->driver->pm, state); } - return dpm_run_callback(callback, dev, state, info); + error = dpm_run_callback(callback, dev, state, info); + if (!error) + dev->power.is_late_suspended = true; + else + async_error = error; + +Complete: + complete_all(&dev->power.completion); + return error; +} + +static void async_suspend_late(void *data, async_cookie_t cookie) +{ + struct device *dev = (struct device *)data; + int error; + + error = __device_suspend_late(dev, pm_transition, true); + if (error) { + dpm_save_failed_dev(dev_name(dev)); + pm_dev_err(dev, pm_transition, " async", error); + } + put_device(dev); +} + +static int device_suspend_late(struct device *dev) +{ + reinit_completion(&dev->power.completion); + + if (pm_async_enabled && dev->power.async_suspend) { + get_device(dev); + async_schedule(async_suspend_late, dev); + return 0; + } + + return __device_suspend_late(dev, pm_transition, false); } /** @@ -1044,19 +1217,20 @@ static int dpm_suspend_late(pm_message_t state) int error = 0; mutex_lock(&dpm_list_mtx); + pm_transition = state; + async_error = 0; + while (!list_empty(&dpm_suspended_list)) { struct device *dev = to_device(dpm_suspended_list.prev); get_device(dev); mutex_unlock(&dpm_list_mtx); - error = device_suspend_late(dev, state); + error = device_suspend_late(dev); mutex_lock(&dpm_list_mtx); if (error) { pm_dev_err(dev, state, " late", error); - suspend_stats.failed_suspend_late++; - dpm_save_failed_step(SUSPEND_SUSPEND_LATE); dpm_save_failed_dev(dev_name(dev)); put_device(dev); break; @@ -1065,17 +1239,18 @@ static int dpm_suspend_late(pm_message_t state) list_move(&dev->power.entry, &dpm_late_early_list); put_device(dev); - if (pm_wakeup_pending()) { - error = -EBUSY; + if (async_error) break; - } } mutex_unlock(&dpm_list_mtx); - if (error) + async_synchronize_full(); + if (error) { + suspend_stats.failed_suspend_late++; + dpm_save_failed_step(SUSPEND_SUSPEND_LATE); dpm_resume_early(resume_event(state)); - else + } else { dpm_show_time(starttime, state, "late"); - + } return error; } diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h index cfc3226ec492..a21223d95926 100644 --- a/drivers/base/power/power.h +++ b/drivers/base/power/power.h @@ -89,8 +89,8 @@ extern void dpm_sysfs_remove(struct device *dev); extern void rpm_sysfs_remove(struct device *dev); extern int wakeup_sysfs_add(struct device *dev); extern void wakeup_sysfs_remove(struct device *dev); -extern int pm_qos_sysfs_add_latency(struct device *dev); -extern void pm_qos_sysfs_remove_latency(struct device *dev); +extern int pm_qos_sysfs_add_resume_latency(struct device *dev); +extern void pm_qos_sysfs_remove_resume_latency(struct device *dev); extern int pm_qos_sysfs_add_flags(struct device *dev); extern void pm_qos_sysfs_remove_flags(struct device *dev); diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index 5c1361a9e5dd..36b9eb4862cb 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c @@ -105,7 +105,7 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_flags); s32 __dev_pm_qos_read_value(struct device *dev) { return IS_ERR_OR_NULL(dev->power.qos) ? - 0 : pm_qos_read_value(&dev->power.qos->latency); + 0 : pm_qos_read_value(&dev->power.qos->resume_latency); } /** @@ -141,16 +141,24 @@ static int apply_constraint(struct dev_pm_qos_request *req, int ret; switch(req->type) { - case DEV_PM_QOS_LATENCY: - ret = pm_qos_update_target(&qos->latency, &req->data.pnode, - action, value); + case DEV_PM_QOS_RESUME_LATENCY: + ret = pm_qos_update_target(&qos->resume_latency, + &req->data.pnode, action, value); if (ret) { - value = pm_qos_read_value(&qos->latency); + value = pm_qos_read_value(&qos->resume_latency); blocking_notifier_call_chain(&dev_pm_notifiers, (unsigned long)value, req); } break; + case DEV_PM_QOS_LATENCY_TOLERANCE: + ret = pm_qos_update_target(&qos->latency_tolerance, + &req->data.pnode, action, value); + if (ret) { + value = pm_qos_read_value(&qos->latency_tolerance); + req->dev->power.set_latency_tolerance(req->dev, value); + } + break; case DEV_PM_QOS_FLAGS: ret = pm_qos_update_flags(&qos->flags, &req->data.flr, action, value); @@ -186,13 +194,21 @@ static int dev_pm_qos_constraints_allocate(struct device *dev) } BLOCKING_INIT_NOTIFIER_HEAD(n); - c = &qos->latency; + c = &qos->resume_latency; plist_head_init(&c->list); - c->target_value = PM_QOS_DEV_LAT_DEFAULT_VALUE; - c->default_value = PM_QOS_DEV_LAT_DEFAULT_VALUE; + c->target_value = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE; + c->default_value = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE; + c->no_constraint_value = PM_QOS_RESUME_LATENCY_DEFAULT_VALUE; c->type = PM_QOS_MIN; c->notifiers = n; + c = &qos->latency_tolerance; + plist_head_init(&c->list); + c->target_value = PM_QOS_LATENCY_TOLERANCE_DEFAULT_VALUE; + c->default_value = PM_QOS_LATENCY_TOLERANCE_DEFAULT_VALUE; + c->no_constraint_value = PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT; + c->type = PM_QOS_MIN; + INIT_LIST_HEAD(&qos->flags.list); spin_lock_irq(&dev->power.lock); @@ -224,7 +240,7 @@ void dev_pm_qos_constraints_destroy(struct device *dev) * If the device's PM QoS resume latency limit or PM QoS flags have been * exposed to user space, they have to be hidden at this point. */ - pm_qos_sysfs_remove_latency(dev); + pm_qos_sysfs_remove_resume_latency(dev); pm_qos_sysfs_remove_flags(dev); mutex_lock(&dev_pm_qos_mtx); @@ -237,7 +253,7 @@ void dev_pm_qos_constraints_destroy(struct device *dev) goto out; /* Flush the constraints lists for the device. */ - c = &qos->latency; + c = &qos->resume_latency; plist_for_each_entry_safe(req, tmp, &c->list, data.pnode) { /* * Update constraints list and call the notification @@ -246,6 +262,11 @@ void dev_pm_qos_constraints_destroy(struct device *dev) apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); memset(req, 0, sizeof(*req)); } + c = &qos->latency_tolerance; + plist_for_each_entry_safe(req, tmp, &c->list, data.pnode) { + apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); + memset(req, 0, sizeof(*req)); + } f = &qos->flags; list_for_each_entry_safe(req, tmp, &f->list, data.flr.node) { apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); @@ -265,6 +286,40 @@ void dev_pm_qos_constraints_destroy(struct device *dev) mutex_unlock(&dev_pm_qos_sysfs_mtx); } +static bool dev_pm_qos_invalid_request(struct device *dev, + struct dev_pm_qos_request *req) +{ + return !req || (req->type == DEV_PM_QOS_LATENCY_TOLERANCE + && !dev->power.set_latency_tolerance); +} + +static int __dev_pm_qos_add_request(struct device *dev, + struct dev_pm_qos_request *req, + enum dev_pm_qos_req_type type, s32 value) +{ + int ret = 0; + + if (!dev || dev_pm_qos_invalid_request(dev, req)) + return -EINVAL; + + if (WARN(dev_pm_qos_request_active(req), + "%s() called for already added request\n", __func__)) + return -EINVAL; + + if (IS_ERR(dev->power.qos)) + ret = -ENODEV; + else if (!dev->power.qos) + ret = dev_pm_qos_constraints_allocate(dev); + + trace_dev_pm_qos_add_request(dev_name(dev), type, value); + if (!ret) { + req->dev = dev; + req->type = type; + ret = apply_constraint(req, PM_QOS_ADD_REQ, value); + } + return ret; +} + /** * dev_pm_qos_add_request - inserts new qos request into the list * @dev: target device for the constraint @@ -290,31 +345,11 @@ void dev_pm_qos_constraints_destroy(struct device *dev) int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req, enum dev_pm_qos_req_type type, s32 value) { - int ret = 0; - - if (!dev || !req) /*guard against callers passing in null */ - return -EINVAL; - - if (WARN(dev_pm_qos_request_active(req), - "%s() called for already added request\n", __func__)) - return -EINVAL; + int ret; mutex_lock(&dev_pm_qos_mtx); - - if (IS_ERR(dev->power.qos)) - ret = -ENODEV; - else if (!dev->power.qos) - ret = dev_pm_qos_constraints_allocate(dev); - - trace_dev_pm_qos_add_request(dev_name(dev), type, value); - if (!ret) { - req->dev = dev; - req->type = type; - ret = apply_constraint(req, PM_QOS_ADD_REQ, value); - } - + ret = __dev_pm_qos_add_request(dev, req, type, value); mutex_unlock(&dev_pm_qos_mtx); - return ret; } EXPORT_SYMBOL_GPL(dev_pm_qos_add_request); @@ -341,7 +376,8 @@ static int __dev_pm_qos_update_request(struct dev_pm_qos_request *req, return -ENODEV; switch(req->type) { - case DEV_PM_QOS_LATENCY: + case DEV_PM_QOS_RESUME_LATENCY: + case DEV_PM_QOS_LATENCY_TOLERANCE: curr_value = req->data.pnode.prio; break; case DEV_PM_QOS_FLAGS: @@ -460,8 +496,8 @@ int dev_pm_qos_add_notifier(struct device *dev, struct notifier_block *notifier) ret = dev_pm_qos_constraints_allocate(dev); if (!ret) - ret = blocking_notifier_chain_register( - dev->power.qos->latency.notifiers, notifier); + ret = blocking_notifier_chain_register(dev->power.qos->resume_latency.notifiers, + notifier); mutex_unlock(&dev_pm_qos_mtx); return ret; @@ -487,9 +523,8 @@ int dev_pm_qos_remove_notifier(struct device *dev, /* Silently return if the constraints object is not present. */ if (!IS_ERR_OR_NULL(dev->power.qos)) - retval = blocking_notifier_chain_unregister( - dev->power.qos->latency.notifiers, - notifier); + retval = blocking_notifier_chain_unregister(dev->power.qos->resume_latency.notifiers, + notifier); mutex_unlock(&dev_pm_qos_mtx); return retval; @@ -530,20 +565,32 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_remove_global_notifier); * dev_pm_qos_add_ancestor_request - Add PM QoS request for device's ancestor. * @dev: Device whose ancestor to add the request for. * @req: Pointer to the preallocated handle. + * @type: Type of the request. * @value: Constraint latency value. */ int dev_pm_qos_add_ancestor_request(struct device *dev, - struct dev_pm_qos_request *req, s32 value) + struct dev_pm_qos_request *req, + enum dev_pm_qos_req_type type, s32 value) { struct device *ancestor = dev->parent; int ret = -ENODEV; - while (ancestor && !ancestor->power.ignore_children) - ancestor = ancestor->parent; + switch (type) { + case DEV_PM_QOS_RESUME_LATENCY: + while (ancestor && !ancestor->power.ignore_children) + ancestor = ancestor->parent; + break; + case DEV_PM_QOS_LATENCY_TOLERANCE: + while (ancestor && !ancestor->power.set_latency_tolerance) + ancestor = ancestor->parent; + + break; + default: + ancestor = NULL; + } if (ancestor) - ret = dev_pm_qos_add_request(ancestor, req, - DEV_PM_QOS_LATENCY, value); + ret = dev_pm_qos_add_request(ancestor, req, type, value); if (ret < 0) req->dev = NULL; @@ -559,9 +606,13 @@ static void __dev_pm_qos_drop_user_request(struct device *dev, struct dev_pm_qos_request *req = NULL; switch(type) { - case DEV_PM_QOS_LATENCY: - req = dev->power.qos->latency_req; - dev->power.qos->latency_req = NULL; + case DEV_PM_QOS_RESUME_LATENCY: + req = dev->power.qos->resume_latency_req; + dev->power.qos->resume_latency_req = NULL; + break; + case DEV_PM_QOS_LATENCY_TOLERANCE: + req = dev->power.qos->latency_tolerance_req; + dev->power.qos->latency_tolerance_req = NULL; break; case DEV_PM_QOS_FLAGS: req = dev->power.qos->flags_req; @@ -597,7 +648,7 @@ int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value) if (!req) return -ENOMEM; - ret = dev_pm_qos_add_request(dev, req, DEV_PM_QOS_LATENCY, value); + ret = dev_pm_qos_add_request(dev, req, DEV_PM_QOS_RESUME_LATENCY, value); if (ret < 0) { kfree(req); return ret; @@ -609,7 +660,7 @@ int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value) if (IS_ERR_OR_NULL(dev->power.qos)) ret = -ENODEV; - else if (dev->power.qos->latency_req) + else if (dev->power.qos->resume_latency_req) ret = -EEXIST; if (ret < 0) { @@ -618,13 +669,13 @@ int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value) mutex_unlock(&dev_pm_qos_mtx); goto out; } - dev->power.qos->latency_req = req; + dev->power.qos->resume_latency_req = req; mutex_unlock(&dev_pm_qos_mtx); - ret = pm_qos_sysfs_add_latency(dev); + ret = pm_qos_sysfs_add_resume_latency(dev); if (ret) - dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY); + dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_RESUME_LATENCY); out: mutex_unlock(&dev_pm_qos_sysfs_mtx); @@ -634,8 +685,8 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_expose_latency_limit); static void __dev_pm_qos_hide_latency_limit(struct device *dev) { - if (!IS_ERR_OR_NULL(dev->power.qos) && dev->power.qos->latency_req) - __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY); + if (!IS_ERR_OR_NULL(dev->power.qos) && dev->power.qos->resume_latency_req) + __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_RESUME_LATENCY); } /** @@ -646,7 +697,7 @@ void dev_pm_qos_hide_latency_limit(struct device *dev) { mutex_lock(&dev_pm_qos_sysfs_mtx); - pm_qos_sysfs_remove_latency(dev); + pm_qos_sysfs_remove_resume_latency(dev); mutex_lock(&dev_pm_qos_mtx); __dev_pm_qos_hide_latency_limit(dev); @@ -768,6 +819,67 @@ int dev_pm_qos_update_flags(struct device *dev, s32 mask, bool set) pm_runtime_put(dev); return ret; } + +/** + * dev_pm_qos_get_user_latency_tolerance - Get user space latency tolerance. + * @dev: Device to obtain the user space latency tolerance for. + */ +s32 dev_pm_qos_get_user_latency_tolerance(struct device *dev) +{ + s32 ret; + + mutex_lock(&dev_pm_qos_mtx); + ret = IS_ERR_OR_NULL(dev->power.qos) + || !dev->power.qos->latency_tolerance_req ? + PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT : + dev->power.qos->latency_tolerance_req->data.pnode.prio; + mutex_unlock(&dev_pm_qos_mtx); + return ret; +} + +/** + * dev_pm_qos_update_user_latency_tolerance - Update user space latency tolerance. + * @dev: Device to update the user space latency tolerance for. + * @val: New user space latency tolerance for @dev (negative values disable). + */ +int dev_pm_qos_update_user_latency_tolerance(struct device *dev, s32 val) +{ + int ret; + + mutex_lock(&dev_pm_qos_mtx); + + if (IS_ERR_OR_NULL(dev->power.qos) + || !dev->power.qos->latency_tolerance_req) { + struct dev_pm_qos_request *req; + + if (val < 0) { + ret = -EINVAL; + goto out; + } + req = kzalloc(sizeof(*req), GFP_KERNEL); + if (!req) { + ret = -ENOMEM; + goto out; + } + ret = __dev_pm_qos_add_request(dev, req, DEV_PM_QOS_LATENCY_TOLERANCE, val); + if (ret < 0) { + kfree(req); + goto out; + } + dev->power.qos->latency_tolerance_req = req; + } else { + if (val < 0) { + __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY_TOLERANCE); + ret = 0; + } else { + ret = __dev_pm_qos_update_request(dev->power.qos->latency_tolerance_req, val); + } + } + + out: + mutex_unlock(&dev_pm_qos_mtx); + return ret; +} #else /* !CONFIG_PM_RUNTIME */ static void __dev_pm_qos_hide_latency_limit(struct device *dev) {} static void __dev_pm_qos_hide_flags(struct device *dev) {} diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 72e00e66ecc5..67c7938e430b 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -13,6 +13,43 @@ #include <trace/events/rpm.h> #include "power.h" +#define RPM_GET_CALLBACK(dev, cb) \ +({ \ + int (*__rpm_cb)(struct device *__d); \ + \ + if (dev->pm_domain) \ + __rpm_cb = dev->pm_domain->ops.cb; \ + else if (dev->type && dev->type->pm) \ + __rpm_cb = dev->type->pm->cb; \ + else if (dev->class && dev->class->pm) \ + __rpm_cb = dev->class->pm->cb; \ + else if (dev->bus && dev->bus->pm) \ + __rpm_cb = dev->bus->pm->cb; \ + else \ + __rpm_cb = NULL; \ + \ + if (!__rpm_cb && dev->driver && dev->driver->pm) \ + __rpm_cb = dev->driver->pm->cb; \ + \ + __rpm_cb; \ +}) + +static int (*rpm_get_suspend_cb(struct device *dev))(struct device *) +{ + return RPM_GET_CALLBACK(dev, runtime_suspend); +} + +static int (*rpm_get_resume_cb(struct device *dev))(struct device *) +{ + return RPM_GET_CALLBACK(dev, runtime_resume); +} + +#ifdef CONFIG_PM_RUNTIME +static int (*rpm_get_idle_cb(struct device *dev))(struct device *) +{ + return RPM_GET_CALLBACK(dev, runtime_idle); +} + static int rpm_resume(struct device *dev, int rpmflags); static int rpm_suspend(struct device *dev, int rpmflags); @@ -310,19 +347,7 @@ static int rpm_idle(struct device *dev, int rpmflags) dev->power.idle_notification = true; - if (dev->pm_domain) - callback = dev->pm_domain->ops.runtime_idle; - else if (dev->type && dev->type->pm) - callback = dev->type->pm->runtime_idle; - else if (dev->class && dev->class->pm) - callback = dev->class->pm->runtime_idle; - else if (dev->bus && dev->bus->pm) - callback = dev->bus->pm->runtime_idle; - else - callback = NULL; - - if (!callback && dev->driver && dev->driver->pm) - callback = dev->driver->pm->runtime_idle; + callback = rpm_get_idle_cb(dev); if (callback) retval = __rpm_callback(callback, dev); @@ -492,19 +517,7 @@ static int rpm_suspend(struct device *dev, int rpmflags) __update_runtime_status(dev, RPM_SUSPENDING); - if (dev->pm_domain) - callback = dev->pm_domain->ops.runtime_suspend; - else if (dev->type && dev->type->pm) - callback = dev->type->pm->runtime_suspend; - else if (dev->class && dev->class->pm) - callback = dev->class->pm->runtime_suspend; - else if (dev->bus && dev->bus->pm) - callback = dev->bus->pm->runtime_suspend; - else - callback = NULL; - - if (!callback && dev->driver && dev->driver->pm) - callback = dev->driver->pm->runtime_suspend; + callback = rpm_get_suspend_cb(dev); retval = rpm_callback(callback, dev); if (retval) @@ -724,19 +737,7 @@ static int rpm_resume(struct device *dev, int rpmflags) __update_runtime_status(dev, RPM_RESUMING); - if (dev->pm_domain) - callback = dev->pm_domain->ops.runtime_resume; - else if (dev->type && dev->type->pm) - callback = dev->type->pm->runtime_resume; - else if (dev->class && dev->class->pm) - callback = dev->class->pm->runtime_resume; - else if (dev->bus && dev->bus->pm) - callback = dev->bus->pm->runtime_resume; - else - callback = NULL; - - if (!callback && dev->driver && dev->driver->pm) - callback = dev->driver->pm->runtime_resume; + callback = rpm_get_resume_cb(dev); retval = rpm_callback(callback, dev); if (retval) { @@ -1130,7 +1131,7 @@ EXPORT_SYMBOL_GPL(pm_runtime_barrier); * @dev: Device to handle. * @check_resume: If set, check if there's a resume request for the device. * - * Increment power.disable_depth for the device and if was zero previously, + * Increment power.disable_depth for the device and if it was zero previously, * cancel all pending runtime PM requests for the device and wait for all * operations in progress to complete. The device can be either active or * suspended after its runtime PM has been disabled. @@ -1401,3 +1402,86 @@ void pm_runtime_remove(struct device *dev) if (dev->power.irq_safe && dev->parent) pm_runtime_put(dev->parent); } +#endif + +/** + * pm_runtime_force_suspend - Force a device into suspend state if needed. + * @dev: Device to suspend. + * + * Disable runtime PM so we safely can check the device's runtime PM status and + * if it is active, invoke it's .runtime_suspend callback to bring it into + * suspend state. Keep runtime PM disabled to preserve the state unless we + * encounter errors. + * + * Typically this function may be invoked from a system suspend callback to make + * sure the device is put into low power state. + */ +int pm_runtime_force_suspend(struct device *dev) +{ + int (*callback)(struct device *); + int ret = 0; + + pm_runtime_disable(dev); + + /* + * Note that pm_runtime_status_suspended() returns false while + * !CONFIG_PM_RUNTIME, which means the device will be put into low + * power state. + */ + if (pm_runtime_status_suspended(dev)) + return 0; + + callback = rpm_get_suspend_cb(dev); + + if (!callback) { + ret = -ENOSYS; + goto err; + } + + ret = callback(dev); + if (ret) + goto err; + + pm_runtime_set_suspended(dev); + return 0; +err: + pm_runtime_enable(dev); + return ret; +} +EXPORT_SYMBOL_GPL(pm_runtime_force_suspend); + +/** + * pm_runtime_force_resume - Force a device into resume state. + * @dev: Device to resume. + * + * Prior invoking this function we expect the user to have brought the device + * into low power state by a call to pm_runtime_force_suspend(). Here we reverse + * those actions and brings the device into full power. We update the runtime PM + * status and re-enables runtime PM. + * + * Typically this function may be invoked from a system resume callback to make + * sure the device is put into full power state. + */ +int pm_runtime_force_resume(struct device *dev) +{ + int (*callback)(struct device *); + int ret = 0; + + callback = rpm_get_resume_cb(dev); + + if (!callback) { + ret = -ENOSYS; + goto out; + } + + ret = callback(dev); + if (ret) + goto out; + + pm_runtime_set_active(dev); + pm_runtime_mark_last_busy(dev); +out: + pm_runtime_enable(dev); + return ret; +} +EXPORT_SYMBOL_GPL(pm_runtime_force_resume); diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c index 03e089ade5ce..95b181d1ca6d 100644 --- a/drivers/base/power/sysfs.c +++ b/drivers/base/power/sysfs.c @@ -218,15 +218,16 @@ static ssize_t autosuspend_delay_ms_store(struct device *dev, static DEVICE_ATTR(autosuspend_delay_ms, 0644, autosuspend_delay_ms_show, autosuspend_delay_ms_store); -static ssize_t pm_qos_latency_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t pm_qos_resume_latency_show(struct device *dev, + struct device_attribute *attr, + char *buf) { - return sprintf(buf, "%d\n", dev_pm_qos_requested_latency(dev)); + return sprintf(buf, "%d\n", dev_pm_qos_requested_resume_latency(dev)); } -static ssize_t pm_qos_latency_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t n) +static ssize_t pm_qos_resume_latency_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t n) { s32 value; int ret; @@ -237,12 +238,47 @@ static ssize_t pm_qos_latency_store(struct device *dev, if (value < 0) return -EINVAL; - ret = dev_pm_qos_update_request(dev->power.qos->latency_req, value); + ret = dev_pm_qos_update_request(dev->power.qos->resume_latency_req, + value); return ret < 0 ? ret : n; } static DEVICE_ATTR(pm_qos_resume_latency_us, 0644, - pm_qos_latency_show, pm_qos_latency_store); + pm_qos_resume_latency_show, pm_qos_resume_latency_store); + +static ssize_t pm_qos_latency_tolerance_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + s32 value = dev_pm_qos_get_user_latency_tolerance(dev); + + if (value < 0) + return sprintf(buf, "auto\n"); + else if (value == PM_QOS_LATENCY_ANY) + return sprintf(buf, "any\n"); + + return sprintf(buf, "%d\n", value); +} + +static ssize_t pm_qos_latency_tolerance_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t n) +{ + s32 value; + int ret; + + if (kstrtos32(buf, 0, &value)) { + if (!strcmp(buf, "auto") || !strcmp(buf, "auto\n")) + value = PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT; + else if (!strcmp(buf, "any") || !strcmp(buf, "any\n")) + value = PM_QOS_LATENCY_ANY; + } + ret = dev_pm_qos_update_user_latency_tolerance(dev, value); + return ret < 0 ? ret : n; +} + +static DEVICE_ATTR(pm_qos_latency_tolerance_us, 0644, + pm_qos_latency_tolerance_show, pm_qos_latency_tolerance_store); static ssize_t pm_qos_no_power_off_show(struct device *dev, struct device_attribute *attr, @@ -618,15 +654,26 @@ static struct attribute_group pm_runtime_attr_group = { .attrs = runtime_attrs, }; -static struct attribute *pm_qos_latency_attrs[] = { +static struct attribute *pm_qos_resume_latency_attrs[] = { #ifdef CONFIG_PM_RUNTIME &dev_attr_pm_qos_resume_latency_us.attr, #endif /* CONFIG_PM_RUNTIME */ NULL, }; -static struct attribute_group pm_qos_latency_attr_group = { +static struct attribute_group pm_qos_resume_latency_attr_group = { + .name = power_group_name, + .attrs = pm_qos_resume_latency_attrs, +}; + +static struct attribute *pm_qos_latency_tolerance_attrs[] = { +#ifdef CONFIG_PM_RUNTIME + &dev_attr_pm_qos_latency_tolerance_us.attr, +#endif /* CONFIG_PM_RUNTIME */ + NULL, +}; +static struct attribute_group pm_qos_latency_tolerance_attr_group = { .name = power_group_name, - .attrs = pm_qos_latency_attrs, + .attrs = pm_qos_latency_tolerance_attrs, }; static struct attribute *pm_qos_flags_attrs[] = { @@ -654,18 +701,23 @@ int dpm_sysfs_add(struct device *dev) if (rc) goto err_out; } - if (device_can_wakeup(dev)) { rc = sysfs_merge_group(&dev->kobj, &pm_wakeup_attr_group); - if (rc) { - if (pm_runtime_callbacks_present(dev)) - sysfs_unmerge_group(&dev->kobj, - &pm_runtime_attr_group); - goto err_out; - } + if (rc) + goto err_runtime; + } + if (dev->power.set_latency_tolerance) { + rc = sysfs_merge_group(&dev->kobj, + &pm_qos_latency_tolerance_attr_group); + if (rc) + goto err_wakeup; } return 0; + err_wakeup: + sysfs_unmerge_group(&dev->kobj, &pm_wakeup_attr_group); + err_runtime: + sysfs_unmerge_group(&dev->kobj, &pm_runtime_attr_group); err_out: sysfs_remove_group(&dev->kobj, &pm_attr_group); return rc; @@ -681,14 +733,14 @@ void wakeup_sysfs_remove(struct device *dev) sysfs_unmerge_group(&dev->kobj, &pm_wakeup_attr_group); } -int pm_qos_sysfs_add_latency(struct device *dev) +int pm_qos_sysfs_add_resume_latency(struct device *dev) { - return sysfs_merge_group(&dev->kobj, &pm_qos_latency_attr_group); + return sysfs_merge_group(&dev->kobj, &pm_qos_resume_latency_attr_group); } -void pm_qos_sysfs_remove_latency(struct device *dev) +void pm_qos_sysfs_remove_resume_latency(struct device *dev) { - sysfs_unmerge_group(&dev->kobj, &pm_qos_latency_attr_group); + sysfs_unmerge_group(&dev->kobj, &pm_qos_resume_latency_attr_group); } int pm_qos_sysfs_add_flags(struct device *dev) @@ -708,6 +760,7 @@ void rpm_sysfs_remove(struct device *dev) void dpm_sysfs_remove(struct device *dev) { + sysfs_unmerge_group(&dev->kobj, &pm_qos_latency_tolerance_attr_group); dev_pm_qos_constraints_destroy(dev); rpm_sysfs_remove(dev); sysfs_unmerge_group(&dev->kobj, &pm_wakeup_attr_group); diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index a55e68f2cfc8..366e6840ec46 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -85,7 +85,8 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, time_end = ktime_get(); - local_irq_enable(); + if (!cpuidle_state_is_coupled(dev, drv, entered_state)) + local_irq_enable(); diff = ktime_to_us(ktime_sub(time_end, time_start)); if (diff > INT_MAX) diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c index 06dbe7c86199..136d6a283e0a 100644 --- a/drivers/cpuidle/driver.c +++ b/drivers/cpuidle/driver.c @@ -209,7 +209,7 @@ static void poll_idle_init(struct cpuidle_driver *drv) state->exit_latency = 0; state->target_residency = 0; state->power_usage = -1; - state->flags = 0; + state->flags = CPUIDLE_FLAG_TIME_VALID; state->enter = poll_idle; state->disabled = false; } diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index cf7f2f0e4ef5..71b523293354 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -122,9 +122,8 @@ struct menu_device { int last_state_idx; int needs_update; - unsigned int expected_us; + unsigned int next_timer_us; unsigned int predicted_us; - unsigned int exit_us; unsigned int bucket; unsigned int correction_factor[BUCKETS]; unsigned int intervals[INTERVALS]; @@ -257,7 +256,7 @@ again: stddev = int_sqrt(stddev); if (((avg > stddev * 6) && (divisor * 4 >= INTERVALS * 3)) || stddev <= 20) { - if (data->expected_us > avg) + if (data->next_timer_us > avg) data->predicted_us = avg; return; } @@ -289,7 +288,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) struct menu_device *data = &__get_cpu_var(menu_devices); int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); int i; - int multiplier; + unsigned int interactivity_req; struct timespec t; if (data->needs_update) { @@ -298,7 +297,6 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) } data->last_state_idx = 0; - data->exit_us = 0; /* Special case when user has set very strict latency requirement */ if (unlikely(latency_req == 0)) @@ -306,13 +304,11 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) /* determine the expected residency time, round up */ t = ktime_to_timespec(tick_nohz_get_sleep_length()); - data->expected_us = + data->next_timer_us = t.tv_sec * USEC_PER_SEC + t.tv_nsec / NSEC_PER_USEC; - data->bucket = which_bucket(data->expected_us); - - multiplier = performance_multiplier(); + data->bucket = which_bucket(data->next_timer_us); /* * if the correction factor is 0 (eg first time init or cpu hotplug @@ -326,17 +322,26 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) * operands are 32 bits. * Make sure to round up for half microseconds. */ - data->predicted_us = div_round64((uint64_t)data->expected_us * + data->predicted_us = div_round64((uint64_t)data->next_timer_us * data->correction_factor[data->bucket], RESOLUTION * DECAY); get_typical_interval(data); /* + * Performance multiplier defines a minimum predicted idle + * duration / latency ratio. Adjust the latency limit if + * necessary. + */ + interactivity_req = data->predicted_us / performance_multiplier(); + if (latency_req > interactivity_req) + latency_req = interactivity_req; + + /* * We want to default to C1 (hlt), not to busy polling * unless the timer is happening really really soon. */ - if (data->expected_us > 5 && + if (data->next_timer_us > 5 && !drv->states[CPUIDLE_DRIVER_STATE_START].disabled && dev->states_usage[CPUIDLE_DRIVER_STATE_START].disable == 0) data->last_state_idx = CPUIDLE_DRIVER_STATE_START; @@ -355,11 +360,8 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) continue; if (s->exit_latency > latency_req) continue; - if (s->exit_latency * multiplier > data->predicted_us) - continue; data->last_state_idx = i; - data->exit_us = s->exit_latency; } return data->last_state_idx; @@ -390,36 +392,47 @@ static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev) { struct menu_device *data = &__get_cpu_var(menu_devices); int last_idx = data->last_state_idx; - unsigned int last_idle_us = cpuidle_get_last_residency(dev); struct cpuidle_state *target = &drv->states[last_idx]; unsigned int measured_us; unsigned int new_factor; /* - * Ugh, this idle state doesn't support residency measurements, so we - * are basically lost in the dark. As a compromise, assume we slept - * for the whole expected time. + * Try to figure out how much time passed between entry to low + * power state and occurrence of the wakeup event. + * + * If the entered idle state didn't support residency measurements, + * we are basically lost in the dark how much time passed. + * As a compromise, assume we slept for the whole expected time. + * + * Any measured amount of time will include the exit latency. + * Since we are interested in when the wakeup begun, not when it + * was completed, we must substract the exit latency. However, if + * the measured amount of time is less than the exit latency, + * assume the state was never reached and the exit latency is 0. */ - if (unlikely(!(target->flags & CPUIDLE_FLAG_TIME_VALID))) - last_idle_us = data->expected_us; + if (unlikely(!(target->flags & CPUIDLE_FLAG_TIME_VALID))) { + /* Use timer value as is */ + measured_us = data->next_timer_us; + } else { + /* Use measured value */ + measured_us = cpuidle_get_last_residency(dev); - measured_us = last_idle_us; - - /* - * We correct for the exit latency; we are assuming here that the - * exit latency happens after the event that we're interested in. - */ - if (measured_us > data->exit_us) - measured_us -= data->exit_us; + /* Deduct exit latency */ + if (measured_us > target->exit_latency) + measured_us -= target->exit_latency; + /* Make sure our coefficients do not exceed unity */ + if (measured_us > data->next_timer_us) + measured_us = data->next_timer_us; + } /* Update our correction ratio */ new_factor = data->correction_factor[data->bucket]; new_factor -= new_factor / DECAY; - if (data->expected_us > 0 && measured_us < MAX_INTERESTING) - new_factor += RESOLUTION * measured_us / data->expected_us; + if (data->next_timer_us > 0 && measured_us < MAX_INTERESTING) + new_factor += RESOLUTION * measured_us / data->next_timer_us; else /* * we were idle so long that we count it as a perfect @@ -439,7 +452,7 @@ static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev) data->correction_factor[data->bucket] = new_factor; /* update the repeating-pattern data */ - data->intervals[data->interval_ptr++] = last_idle_us; + data->intervals[data->interval_ptr++] = measured_us; if (data->interval_ptr >= INTERVALS) data->interval_ptr = 0; } diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index a0b2f7e0eedb..2042ec3656ba 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -91,26 +91,35 @@ static int devfreq_get_freq_level(struct devfreq *devfreq, unsigned long freq) */ static int devfreq_update_status(struct devfreq *devfreq, unsigned long freq) { - int lev, prev_lev; + int lev, prev_lev, ret = 0; unsigned long cur_time; - lev = devfreq_get_freq_level(devfreq, freq); - if (lev < 0) - return lev; - cur_time = jiffies; - devfreq->time_in_state[lev] += + + prev_lev = devfreq_get_freq_level(devfreq, devfreq->previous_freq); + if (prev_lev < 0) { + ret = prev_lev; + goto out; + } + + devfreq->time_in_state[prev_lev] += cur_time - devfreq->last_stat_updated; - if (freq != devfreq->previous_freq) { - prev_lev = devfreq_get_freq_level(devfreq, - devfreq->previous_freq); + + lev = devfreq_get_freq_level(devfreq, freq); + if (lev < 0) { + ret = lev; + goto out; + } + + if (lev != prev_lev) { devfreq->trans_table[(prev_lev * devfreq->profile->max_state) + lev]++; devfreq->total_trans++; } - devfreq->last_stat_updated = cur_time; - return 0; +out: + devfreq->last_stat_updated = cur_time; + return ret; } /** diff --git a/drivers/gpu/drm/gma500/Kconfig b/drivers/gpu/drm/gma500/Kconfig index 508cf99a292d..17f928ec84ea 100644 --- a/drivers/gpu/drm/gma500/Kconfig +++ b/drivers/gpu/drm/gma500/Kconfig @@ -10,7 +10,6 @@ config DRM_GMA500 # GMA500 depends on ACPI_VIDEO when ACPI is enabled, just like i915 select ACPI_VIDEO if ACPI select BACKLIGHT_CLASS_DEVICE if ACPI - select VIDEO_OUTPUT_CONTROL if ACPI select INPUT if ACPI help Say yes for an experimental 2D KMS framebuffer driver for the diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index 73ed59eff139..bea2d67196fb 100644 --- a/drivers/gpu/drm/i915/Kconfig +++ b/drivers/gpu/drm/i915/Kconfig @@ -14,7 +14,6 @@ config DRM_I915 # but for select to work, need to select ACPI_VIDEO's dependencies, ick select BACKLIGHT_LCD_SUPPORT if ACPI select BACKLIGHT_CLASS_DEVICE if ACPI - select VIDEO_OUTPUT_CONTROL if ACPI select INPUT if ACPI select ACPI_VIDEO if ACPI select ACPI_BUTTON if ACPI diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig index 7cf787d697b1..637c29a33127 100644 --- a/drivers/gpu/drm/nouveau/Kconfig +++ b/drivers/gpu/drm/nouveau/Kconfig @@ -11,7 +11,7 @@ config DRM_NOUVEAU select FB select FRAMEBUFFER_CONSOLE if !EXPERT select FB_BACKLIGHT if DRM_NOUVEAU_BACKLIGHT - select ACPI_VIDEO if ACPI && X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL && INPUT + select ACPI_VIDEO if ACPI && X86 && BACKLIGHT_CLASS_DEVICE && INPUT select X86_PLATFORM_DEVICES if ACPI && X86 select ACPI_WMI if ACPI && X86 select MXM_WMI if ACPI && X86 @@ -19,7 +19,6 @@ config DRM_NOUVEAU # Similar to i915, we need to select ACPI_VIDEO and it's dependencies select BACKLIGHT_LCD_SUPPORT if ACPI && X86 select BACKLIGHT_CLASS_DEVICE if ACPI && X86 - select VIDEO_OUTPUT_CONTROL if ACPI && X86 select INPUT if ACPI && X86 select THERMAL if ACPI && X86 select ACPI_VIDEO if ACPI && X86 diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index e22be8458d92..bbb17841a9e5 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -4134,8 +4134,11 @@ static void cik_cp_compute_enable(struct radeon_device *rdev, bool enable) { if (enable) WREG32(CP_MEC_CNTL, 0); - else + else { WREG32(CP_MEC_CNTL, (MEC_ME1_HALT | MEC_ME2_HALT)); + rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; + rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false; + } udelay(50); } diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c index 1ecb3f1070e3..94626ea90fa5 100644 --- a/drivers/gpu/drm/radeon/cik_sdma.c +++ b/drivers/gpu/drm/radeon/cik_sdma.c @@ -264,6 +264,8 @@ static void cik_sdma_gfx_stop(struct radeon_device *rdev) WREG32(SDMA0_GFX_RB_CNTL + reg_offset, rb_cntl); WREG32(SDMA0_GFX_IB_CNTL + reg_offset, 0); } + rdev->ring[R600_RING_TYPE_DMA_INDEX].ready = false; + rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX].ready = false; } /** @@ -291,6 +293,11 @@ void cik_sdma_enable(struct radeon_device *rdev, bool enable) u32 me_cntl, reg_offset; int i; + if (enable == false) { + cik_sdma_gfx_stop(rdev); + cik_sdma_rlc_stop(rdev); + } + for (i = 0; i < 2; i++) { if (i == 0) reg_offset = SDMA0_REGISTER_OFFSET; @@ -420,10 +427,6 @@ static int cik_sdma_load_microcode(struct radeon_device *rdev) if (!rdev->sdma_fw) return -EINVAL; - /* stop the gfx rings and rlc compute queues */ - cik_sdma_gfx_stop(rdev); - cik_sdma_rlc_stop(rdev); - /* halt the MEs */ cik_sdma_enable(rdev, false); @@ -492,9 +495,6 @@ int cik_sdma_resume(struct radeon_device *rdev) */ void cik_sdma_fini(struct radeon_device *rdev) { - /* stop the gfx rings and rlc compute queues */ - cik_sdma_gfx_stop(rdev); - cik_sdma_rlc_stop(rdev); /* halt the MEs */ cik_sdma_enable(rdev, false); radeon_ring_fini(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX]); diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 2aecd6dc2610..66ed3ea71440 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -33,6 +33,13 @@ #include <linux/vga_switcheroo.h> #include <linux/slab.h> #include <linux/pm_runtime.h> + +#if defined(CONFIG_VGA_SWITCHEROO) +bool radeon_is_px(void); +#else +static inline bool radeon_is_px(void) { return false; } +#endif + /** * radeon_driver_unload_kms - Main unload function for KMS. * @@ -130,7 +137,8 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) "Error during ACPI methods call\n"); } - if (radeon_runtime_pm != 0) { + if ((radeon_runtime_pm == 1) || + ((radeon_runtime_pm == -1) && radeon_is_px())) { pm_runtime_use_autosuspend(dev->dev); pm_runtime_set_autosuspend_delay(dev->dev, 5000); pm_runtime_set_active(dev->dev); diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index a06651309388..214b7992a3aa 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -351,9 +351,11 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, moved: if (bo->evicted) { - ret = bdev->driver->invalidate_caches(bdev, bo->mem.placement); - if (ret) - pr_err("Can not flush read caches\n"); + if (bdev->driver->invalidate_caches) { + ret = bdev->driver->invalidate_caches(bdev, bo->mem.placement); + if (ret) + pr_err("Can not flush read caches\n"); + } bo->evicted = false; } diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index 801231c9ae48..0ce48e5a9cb4 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -339,11 +339,13 @@ int ttm_bo_mmap(struct file *filp, struct vm_area_struct *vma, vma->vm_private_data = bo; /* - * PFNMAP is faster than MIXEDMAP due to reduced page - * administration. So use MIXEDMAP only if private VMA, where - * we need to support COW. + * We'd like to use VM_PFNMAP on shared mappings, where + * (vma->vm_flags & VM_SHARED) != 0, for performance reasons, + * but for some reason VM_PFNMAP + x86 PAT + write-combine is very + * bad for performance. Until that has been sorted out, use + * VM_MIXEDMAP on all mappings. See freedesktop.org bug #75719 */ - vma->vm_flags |= (vma->vm_flags & VM_SHARED) ? VM_PFNMAP : VM_MIXEDMAP; + vma->vm_flags |= VM_MIXEDMAP; vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP; return 0; out_unref: @@ -359,7 +361,7 @@ int ttm_fbdev_mmap(struct vm_area_struct *vma, struct ttm_buffer_object *bo) vma->vm_ops = &ttm_bo_vm_ops; vma->vm_private_data = ttm_bo_reference(bo); - vma->vm_flags |= (vma->vm_flags & VM_SHARED) ? VM_PFNMAP : VM_MIXEDMAP; + vma->vm_flags |= VM_MIXEDMAP; vma->vm_flags |= VM_IO | VM_DONTEXPAND; return 0; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c index 82468d902915..e7af580ab977 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c @@ -830,6 +830,24 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, if (unlikely(ret != 0)) goto out_unlock; + /* + * A gb-aware client referencing a shared surface will + * expect a backup buffer to be present. + */ + if (dev_priv->has_mob && req->shareable) { + uint32_t backup_handle; + + ret = vmw_user_dmabuf_alloc(dev_priv, tfile, + res->backup_size, + true, + &backup_handle, + &res->backup); + if (unlikely(ret != 0)) { + vmw_resource_unreference(&res); + goto out_unlock; + } + } + tmp = vmw_resource_reference(&srf->res); ret = ttm_prime_object_init(tfile, res->backup_size, &user_srf->prime, req->shareable, VMW_RES_SURFACE, diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index f5ed03164d86..de17c5593d97 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -387,7 +387,7 @@ config I2C_CBUS_GPIO config I2C_CPM tristate "Freescale CPM1 or CPM2 (MPC8xx/826x)" - depends on (CPM1 || CPM2) && OF_I2C + depends on CPM1 || CPM2 help This supports the use of the I2C interface on Freescale processors with CPM1 or CPM2. diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c index 5c342b3139e8..3c0f57efe7b1 100644 --- a/drivers/input/touchscreen/st1232.c +++ b/drivers/input/touchscreen/st1232.c @@ -134,7 +134,8 @@ static irqreturn_t st1232_ts_irq_handler(int irq, void *dev_id) } else if (!ts->low_latency_req.dev) { /* First contact, request 100 us latency. */ dev_pm_qos_add_ancestor_request(&ts->client->dev, - &ts->low_latency_req, 100); + &ts->low_latency_req, + DEV_PM_QOS_RESUME_LATENCY, 100); } /* SYN_REPORT */ diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index 1af70145fab9..074b9c8e4cf0 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c @@ -979,12 +979,13 @@ static void issue_copy_real(struct dm_cache_migration *mg) int r; struct dm_io_region o_region, c_region; struct cache *cache = mg->cache; + sector_t cblock = from_cblock(mg->cblock); o_region.bdev = cache->origin_dev->bdev; o_region.count = cache->sectors_per_block; c_region.bdev = cache->cache_dev->bdev; - c_region.sector = from_cblock(mg->cblock) * cache->sectors_per_block; + c_region.sector = cblock * cache->sectors_per_block; c_region.count = cache->sectors_per_block; if (mg->writeback || mg->demote) { @@ -2464,20 +2465,18 @@ static int cache_map(struct dm_target *ti, struct bio *bio) bool discarded_block; struct dm_bio_prison_cell *cell; struct policy_result lookup_result; - struct per_bio_data *pb; + struct per_bio_data *pb = init_per_bio_data(bio, pb_data_size); - if (from_oblock(block) > from_oblock(cache->origin_blocks)) { + if (unlikely(from_oblock(block) >= from_oblock(cache->origin_blocks))) { /* * This can only occur if the io goes to a partial block at * the end of the origin device. We don't cache these. * Just remap to the origin and carry on. */ - remap_to_origin_clear_discard(cache, bio, block); + remap_to_origin(cache, bio); return DM_MAPIO_REMAPPED; } - pb = init_per_bio_data(bio, pb_data_size); - if (bio->bi_rw & (REQ_FLUSH | REQ_FUA | REQ_DISCARD)) { defer_bio(cache, bio); return DM_MAPIO_SUBMITTED; diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c index b9e2000969f0..95c894482fdd 100644 --- a/drivers/misc/sgi-xp/xpc_uv.c +++ b/drivers/misc/sgi-xp/xpc_uv.c @@ -240,7 +240,7 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name, nid = cpu_to_node(cpu); page = alloc_pages_exact_node(nid, - GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, + GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE, pg_order); if (page == NULL) { dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d " diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c index d72783dd7b96..c0670237e7a2 100644 --- a/drivers/mtd/nand/sh_flctl.c +++ b/drivers/mtd/nand/sh_flctl.c @@ -897,7 +897,7 @@ static void flctl_select_chip(struct mtd_info *mtd, int chipnr) if (!flctl->qos_request) { ret = dev_pm_qos_add_request(&flctl->pdev->dev, &flctl->pm_qos, - DEV_PM_QOS_LATENCY, + DEV_PM_QOS_RESUME_LATENCY, 100); if (ret < 0) dev_err(&flctl->pdev->dev, diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index a2c47476804d..e8f133e926aa 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -730,7 +730,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon client_info->ntt = 0; } - if (!vlan_get_tag(skb, &client_info->vlan_id)) + if (vlan_get_tag(skb, &client_info->vlan_id)) client_info->vlan_id = 0; if (!client_info->assigned) { diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index c37878432717..298c26509095 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c @@ -121,6 +121,7 @@ static struct bond_opt_value bond_resend_igmp_tbl[] = { static struct bond_opt_value bond_lp_interval_tbl[] = { { "minval", 1, BOND_VALFLAG_MIN | BOND_VALFLAG_DEFAULT}, { "maxval", INT_MAX, BOND_VALFLAG_MAX}, + { NULL, -1, 0}, }; static struct bond_option bond_opts[] = { diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index cda25ac45b47..6c9e1c9bdeb8 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -2507,6 +2507,7 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int ack, int silent) bp->fw_wr_seq++; msg_data |= bp->fw_wr_seq; + bp->fw_last_msg = msg_data; bnx2_shmem_wr(bp, BNX2_DRV_MB, msg_data); @@ -4000,8 +4001,23 @@ bnx2_setup_wol(struct bnx2 *bp) wol_msg = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL; } - if (!(bp->flags & BNX2_FLAG_NO_WOL)) - bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT3 | wol_msg, 1, 0); + if (!(bp->flags & BNX2_FLAG_NO_WOL)) { + u32 val; + + wol_msg |= BNX2_DRV_MSG_DATA_WAIT3; + if (bp->fw_last_msg || BNX2_CHIP(bp) != BNX2_CHIP_5709) { + bnx2_fw_sync(bp, wol_msg, 1, 0); + return; + } + /* Tell firmware not to power down the PHY yet, otherwise + * the chip will take a long time to respond to MMIO reads. + */ + val = bnx2_shmem_rd(bp, BNX2_PORT_FEATURE); + bnx2_shmem_wr(bp, BNX2_PORT_FEATURE, + val | BNX2_PORT_FEATURE_ASF_ENABLED); + bnx2_fw_sync(bp, wol_msg, 1, 0); + bnx2_shmem_wr(bp, BNX2_PORT_FEATURE, val); + } } @@ -4033,9 +4049,22 @@ bnx2_set_power_state(struct bnx2 *bp, pci_power_t state) if (bp->wol) pci_set_power_state(bp->pdev, PCI_D3hot); - } else { - pci_set_power_state(bp->pdev, PCI_D3hot); + break; + + } + if (!bp->fw_last_msg && BNX2_CHIP(bp) == BNX2_CHIP_5709) { + u32 val; + + /* Tell firmware not to power down the PHY yet, + * otherwise the other port may not respond to + * MMIO reads. + */ + val = bnx2_shmem_rd(bp, BNX2_BC_STATE_CONDITION); + val &= ~BNX2_CONDITION_PM_STATE_MASK; + val |= BNX2_CONDITION_PM_STATE_UNPREP; + bnx2_shmem_wr(bp, BNX2_BC_STATE_CONDITION, val); } + pci_set_power_state(bp->pdev, PCI_D3hot); /* No more memory access after this point until * device is brought back to D0. diff --git a/drivers/net/ethernet/broadcom/bnx2.h b/drivers/net/ethernet/broadcom/bnx2.h index f1cf2c44e7ed..e341bc366fa5 100644 --- a/drivers/net/ethernet/broadcom/bnx2.h +++ b/drivers/net/ethernet/broadcom/bnx2.h @@ -6900,6 +6900,7 @@ struct bnx2 { u16 fw_wr_seq; u16 fw_drv_pulse_wr_seq; + u32 fw_last_msg; int rx_max_ring; int rx_ring_size; @@ -7406,6 +7407,10 @@ struct bnx2_rv2p_fw_file { #define BNX2_CONDITION_MFW_RUN_NCSI 0x00006000 #define BNX2_CONDITION_MFW_RUN_NONE 0x0000e000 #define BNX2_CONDITION_MFW_RUN_MASK 0x0000e000 +#define BNX2_CONDITION_PM_STATE_MASK 0x00030000 +#define BNX2_CONDITION_PM_STATE_FULL 0x00030000 +#define BNX2_CONDITION_PM_STATE_PREP 0x00020000 +#define BNX2_CONDITION_PM_STATE_UNPREP 0x00010000 #define BNX2_BC_STATE_DEBUG_CMD 0x1dc #define BNX2_BC_STATE_BC_DBG_CMD_SIGNATURE 0x42440000 diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc.c b/drivers/net/ethernet/brocade/bna/bfa_ioc.c index 1803c3959044..354ae9792bad 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_ioc.c +++ b/drivers/net/ethernet/brocade/bna/bfa_ioc.c @@ -1704,7 +1704,7 @@ bfa_flash_sem_get(void __iomem *bar) while (!bfa_raw_sem_get(bar)) { if (--n <= 0) return BFA_STATUS_BADFLASH; - udelay(10000); + mdelay(10); } return BFA_STATUS_OK; } diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index 3190d38e16fb..d0c38e01e99f 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -632,11 +632,16 @@ static void gem_rx_refill(struct macb *bp) "Unable to allocate sk_buff\n"); break; } - bp->rx_skbuff[entry] = skb; /* now fill corresponding descriptor entry */ paddr = dma_map_single(&bp->pdev->dev, skb->data, bp->rx_buffer_size, DMA_FROM_DEVICE); + if (dma_mapping_error(&bp->pdev->dev, paddr)) { + dev_kfree_skb(skb); + break; + } + + bp->rx_skbuff[entry] = skb; if (entry == RX_RING_SIZE - 1) paddr |= MACB_BIT(RX_WRAP); @@ -725,7 +730,7 @@ static int gem_rx(struct macb *bp, int budget) skb_put(skb, len); addr = MACB_BF(RX_WADDR, MACB_BFEXT(RX_WADDR, addr)); dma_unmap_single(&bp->pdev->dev, addr, - len, DMA_FROM_DEVICE); + bp->rx_buffer_size, DMA_FROM_DEVICE); skb->protocol = eth_type_trans(skb, bp->dev); skb_checksum_none_assert(skb); @@ -1036,11 +1041,15 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev) } entry = macb_tx_ring_wrap(bp->tx_head); - bp->tx_head++; netdev_vdbg(bp->dev, "Allocated ring entry %u\n", entry); mapping = dma_map_single(&bp->pdev->dev, skb->data, len, DMA_TO_DEVICE); + if (dma_mapping_error(&bp->pdev->dev, mapping)) { + kfree_skb(skb); + goto unlock; + } + bp->tx_head++; tx_skb = &bp->tx_skb[entry]; tx_skb->skb = skb; tx_skb->mapping = mapping; @@ -1066,6 +1075,7 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev) if (CIRC_SPACE(bp->tx_head, bp->tx_tail, TX_RING_SIZE) < 1) netif_stop_queue(dev); +unlock: spin_unlock_irqrestore(&bp->lock, flags); return NETDEV_TX_OK; diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 479a7cba45c0..03a351300013 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -528,13 +528,6 @@ fec_restart(struct net_device *ndev, int duplex) /* Clear any outstanding interrupt. */ writel(0xffc00000, fep->hwp + FEC_IEVENT); - /* Setup multicast filter. */ - set_multicast_list(ndev); -#ifndef CONFIG_M5272 - writel(0, fep->hwp + FEC_HASH_TABLE_HIGH); - writel(0, fep->hwp + FEC_HASH_TABLE_LOW); -#endif - /* Set maximum receive buffer size. */ writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE); @@ -655,6 +648,13 @@ fec_restart(struct net_device *ndev, int duplex) writel(rcntl, fep->hwp + FEC_R_CNTRL); + /* Setup multicast filter. */ + set_multicast_list(ndev); +#ifndef CONFIG_M5272 + writel(0, fep->hwp + FEC_HASH_TABLE_HIGH); + writel(0, fep->hwp + FEC_HASH_TABLE_LOW); +#endif + if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) { /* enable ENET endian swap */ ecntl |= (1 << 8); diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c index 4be971590461..1fc8334fc181 100644 --- a/drivers/net/ethernet/ibm/ibmveth.c +++ b/drivers/net/ethernet/ibm/ibmveth.c @@ -522,10 +522,21 @@ retry: return rc; } +static u64 ibmveth_encode_mac_addr(u8 *mac) +{ + int i; + u64 encoded = 0; + + for (i = 0; i < ETH_ALEN; i++) + encoded = (encoded << 8) | mac[i]; + + return encoded; +} + static int ibmveth_open(struct net_device *netdev) { struct ibmveth_adapter *adapter = netdev_priv(netdev); - u64 mac_address = 0; + u64 mac_address; int rxq_entries = 1; unsigned long lpar_rc; int rc; @@ -579,8 +590,7 @@ static int ibmveth_open(struct net_device *netdev) adapter->rx_queue.num_slots = rxq_entries; adapter->rx_queue.toggle = 1; - memcpy(&mac_address, netdev->dev_addr, netdev->addr_len); - mac_address = mac_address >> 16; + mac_address = ibmveth_encode_mac_addr(netdev->dev_addr); rxq_desc.fields.flags_len = IBMVETH_BUF_VALID | adapter->rx_queue.queue_len; @@ -1183,8 +1193,8 @@ static void ibmveth_set_multicast_list(struct net_device *netdev) /* add the addresses to the filter table */ netdev_for_each_mc_addr(ha, netdev) { /* add the multicast address to the filter table */ - unsigned long mcast_addr = 0; - memcpy(((char *)&mcast_addr)+2, ha->addr, ETH_ALEN); + u64 mcast_addr; + mcast_addr = ibmveth_encode_mac_addr(ha->addr); lpar_rc = h_multicast_ctrl(adapter->vdev->unit_address, IbmVethMcastAddFilter, mcast_addr); @@ -1372,9 +1382,6 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id) netif_napi_add(netdev, &adapter->napi, ibmveth_poll, 16); - adapter->mac_addr = 0; - memcpy(&adapter->mac_addr, mac_addr_p, ETH_ALEN); - netdev->irq = dev->irq; netdev->netdev_ops = &ibmveth_netdev_ops; netdev->ethtool_ops = &netdev_ethtool_ops; @@ -1383,7 +1390,7 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id) NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; netdev->features |= netdev->hw_features; - memcpy(netdev->dev_addr, &adapter->mac_addr, netdev->addr_len); + memcpy(netdev->dev_addr, mac_addr_p, ETH_ALEN); for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) { struct kobject *kobj = &adapter->rx_buff_pool[i].kobj; diff --git a/drivers/net/ethernet/ibm/ibmveth.h b/drivers/net/ethernet/ibm/ibmveth.h index 451ba7949e15..1f37499d4398 100644 --- a/drivers/net/ethernet/ibm/ibmveth.h +++ b/drivers/net/ethernet/ibm/ibmveth.h @@ -138,7 +138,6 @@ struct ibmveth_adapter { struct napi_struct napi; struct net_device_stats stats; unsigned int mcastFilterSize; - unsigned long mac_addr; void * buffer_list_addr; void * filter_list_addr; dma_addr_t buffer_list_dma; diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index fad45316200a..84a96f70dfb5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -742,6 +742,14 @@ static int mlx4_en_replace_mac(struct mlx4_en_priv *priv, int qpn, err = mlx4_en_uc_steer_add(priv, new_mac, &qpn, &entry->reg_id); + if (err) + return err; + if (priv->tunnel_reg_id) { + mlx4_flow_detach(priv->mdev->dev, priv->tunnel_reg_id); + priv->tunnel_reg_id = 0; + } + err = mlx4_en_tunnel_steer_add(priv, new_mac, qpn, + &priv->tunnel_reg_id); return err; } } @@ -1792,6 +1800,8 @@ void mlx4_en_stop_port(struct net_device *dev, int detach) mc_list[5] = priv->port; mlx4_multicast_detach(mdev->dev, &priv->rss_map.indir_qp, mc_list, MLX4_PROT_ETH, mclist->reg_id); + if (mclist->tunnel_reg_id) + mlx4_flow_detach(mdev->dev, mclist->tunnel_reg_id); } mlx4_en_clear_list(dev); list_for_each_entry_safe(mclist, tmp, &priv->curr_list, list) { diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 91b69ff4b4a2..7e2995ecea6f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c @@ -129,13 +129,14 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags) [0] = "RSS support", [1] = "RSS Toeplitz Hash Function support", [2] = "RSS XOR Hash Function support", - [3] = "Device manage flow steering support", + [3] = "Device managed flow steering support", [4] = "Automatic MAC reassignment support", [5] = "Time stamping support", [6] = "VST (control vlan insertion/stripping) support", [7] = "FSM (MAC anti-spoofing) support", [8] = "Dynamic QP updates support", - [9] = "TCP/IP offloads/flow-steering for VXLAN support" + [9] = "Device managed flow steering IPoIB support", + [10] = "TCP/IP offloads/flow-steering for VXLAN support" }; int i; @@ -859,7 +860,7 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave, MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_CQ_TS_SUPPORT_OFFSET); /* For guests, disable vxlan tunneling */ - MLX4_GET(field, outbox, QUERY_DEV_CAP_VXLAN); + MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_VXLAN); field &= 0xf7; MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_VXLAN); @@ -869,7 +870,7 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave, MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_BF_OFFSET); /* For guests, disable mw type 2 */ - MLX4_GET(bmme_flags, outbox, QUERY_DEV_CAP_BMME_FLAGS_OFFSET); + MLX4_GET(bmme_flags, outbox->buf, QUERY_DEV_CAP_BMME_FLAGS_OFFSET); bmme_flags &= ~MLX4_BMME_FLAG_TYPE_2_WIN; MLX4_PUT(outbox->buf, bmme_flags, QUERY_DEV_CAP_BMME_FLAGS_OFFSET); @@ -883,7 +884,7 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave, } /* turn off ipoib managed steering for guests */ - MLX4_GET(field, outbox, QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET); + MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET); field &= ~0x80; MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET); diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index d711158b0d4b..936c15364739 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -150,6 +150,8 @@ struct mlx4_port_config { struct pci_dev *pdev; }; +static atomic_t pf_loading = ATOMIC_INIT(0); + int mlx4_check_port_params(struct mlx4_dev *dev, enum mlx4_port_type *port_type) { @@ -749,7 +751,7 @@ static void mlx4_request_modules(struct mlx4_dev *dev) has_eth_port = true; } - if (has_ib_port) + if (has_ib_port || (dev->caps.flags & MLX4_DEV_CAP_FLAG_IBOE)) request_module_nowait(IB_DRV_NAME); if (has_eth_port) request_module_nowait(EN_DRV_NAME); @@ -1407,6 +1409,11 @@ static int mlx4_init_slave(struct mlx4_dev *dev) u32 slave_read; u32 cmd_channel_ver; + if (atomic_read(&pf_loading)) { + mlx4_warn(dev, "PF is not ready. Deferring probe\n"); + return -EPROBE_DEFER; + } + mutex_lock(&priv->cmd.slave_cmd_mutex); priv->cmd.max_cmds = 1; mlx4_warn(dev, "Sending reset\n"); @@ -2319,7 +2326,11 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data) if (num_vfs) { mlx4_warn(dev, "Enabling SR-IOV with %d VFs\n", num_vfs); + + atomic_inc(&pf_loading); err = pci_enable_sriov(pdev, num_vfs); + atomic_dec(&pf_loading); + if (err) { mlx4_err(dev, "Failed to enable SR-IOV, continuing without SR-IOV (err = %d).\n", err); @@ -2684,6 +2695,7 @@ static struct pci_driver mlx4_driver = { .name = DRV_NAME, .id_table = mlx4_pci_table, .probe = mlx4_init_one, + .shutdown = mlx4_remove_one, .remove = mlx4_remove_one, .err_handler = &mlx4_err_handler, }; diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index e9779653cd4c..3ff7bc3e7a23 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -209,7 +209,7 @@ static const struct { [RTL_GIGA_MAC_VER_16] = _R("RTL8101e", RTL_TD_0, NULL, JUMBO_1K, true), [RTL_GIGA_MAC_VER_17] = - _R("RTL8168b/8111b", RTL_TD_1, NULL, JUMBO_4K, false), + _R("RTL8168b/8111b", RTL_TD_0, NULL, JUMBO_4K, false), [RTL_GIGA_MAC_VER_18] = _R("RTL8168cp/8111cp", RTL_TD_1, NULL, JUMBO_6K, false), [RTL_GIGA_MAC_VER_19] = diff --git a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c index 72d282bf33a5..c553f6b5a913 100644 --- a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c +++ b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c @@ -151,7 +151,7 @@ static void stmmac_clean_desc3(void *priv_ptr, struct dma_desc *p) sizeof(struct dma_desc))); } -const struct stmmac_chain_mode_ops chain_mode_ops = { +const struct stmmac_mode_ops chain_mode_ops = { .init = stmmac_init_dma_chain, .is_jumbo_frm = stmmac_is_jumbo_frm, .jumbo_frm = stmmac_jumbo_frm, diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 7834a3993946..74610f3aca9e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -419,20 +419,13 @@ struct mii_regs { unsigned int data; /* MII Data */ }; -struct stmmac_ring_mode_ops { - unsigned int (*is_jumbo_frm) (int len, int ehn_desc); - unsigned int (*jumbo_frm) (void *priv, struct sk_buff *skb, int csum); - void (*refill_desc3) (void *priv, struct dma_desc *p); - void (*init_desc3) (struct dma_desc *p); - void (*clean_desc3) (void *priv, struct dma_desc *p); - int (*set_16kib_bfsize) (int mtu); -}; - -struct stmmac_chain_mode_ops { +struct stmmac_mode_ops { void (*init) (void *des, dma_addr_t phy_addr, unsigned int size, unsigned int extend_desc); unsigned int (*is_jumbo_frm) (int len, int ehn_desc); unsigned int (*jumbo_frm) (void *priv, struct sk_buff *skb, int csum); + int (*set_16kib_bfsize)(int mtu); + void (*init_desc3)(struct dma_desc *p); void (*refill_desc3) (void *priv, struct dma_desc *p); void (*clean_desc3) (void *priv, struct dma_desc *p); }; @@ -441,8 +434,7 @@ struct mac_device_info { const struct stmmac_ops *mac; const struct stmmac_desc_ops *desc; const struct stmmac_dma_ops *dma; - const struct stmmac_ring_mode_ops *ring; - const struct stmmac_chain_mode_ops *chain; + const struct stmmac_mode_ops *mode; const struct stmmac_hwtimestamp *ptp; struct mii_regs mii; /* MII register Addresses */ struct mac_link link; @@ -460,7 +452,7 @@ void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr, void stmmac_set_mac(void __iomem *ioaddr, bool enable); void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr); -extern const struct stmmac_ring_mode_ops ring_mode_ops; -extern const struct stmmac_chain_mode_ops chain_mode_ops; +extern const struct stmmac_mode_ops ring_mode_ops; +extern const struct stmmac_mode_ops chain_mode_ops; #endif /* __COMMON_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c index a96c7c2f5f3f..650a4be6bce5 100644 --- a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c +++ b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c @@ -100,10 +100,9 @@ static void stmmac_refill_desc3(void *priv_ptr, struct dma_desc *p) { struct stmmac_priv *priv = (struct stmmac_priv *)priv_ptr; - if (unlikely(priv->plat->has_gmac)) - /* Fill DES3 in case of RING mode */ - if (priv->dma_buf_sz >= BUF_SIZE_8KiB) - p->des3 = p->des2 + BUF_SIZE_8KiB; + /* Fill DES3 in case of RING mode */ + if (priv->dma_buf_sz >= BUF_SIZE_8KiB) + p->des3 = p->des2 + BUF_SIZE_8KiB; } /* In ring mode we need to fill the desc3 because it is used as buffer */ @@ -126,7 +125,7 @@ static int stmmac_set_16kib_bfsize(int mtu) return ret; } -const struct stmmac_ring_mode_ops ring_mode_ops = { +const struct stmmac_mode_ops ring_mode_ops = { .is_jumbo_frm = stmmac_is_jumbo_frm, .jumbo_frm = stmmac_jumbo_frm, .refill_desc3 = stmmac_refill_desc3, diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 078ad0ec8593..8543e1cfd55e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -92,8 +92,8 @@ static int tc = TC_DEFAULT; module_param(tc, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(tc, "DMA threshold control value"); -#define DMA_BUFFER_SIZE BUF_SIZE_4KiB -static int buf_sz = DMA_BUFFER_SIZE; +#define DEFAULT_BUFSIZE 1536 +static int buf_sz = DEFAULT_BUFSIZE; module_param(buf_sz, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(buf_sz, "DMA buffer size"); @@ -136,8 +136,8 @@ static void stmmac_verify_args(void) dma_rxsize = DMA_RX_SIZE; if (unlikely(dma_txsize < 0)) dma_txsize = DMA_TX_SIZE; - if (unlikely((buf_sz < DMA_BUFFER_SIZE) || (buf_sz > BUF_SIZE_16KiB))) - buf_sz = DMA_BUFFER_SIZE; + if (unlikely((buf_sz < DEFAULT_BUFSIZE) || (buf_sz > BUF_SIZE_16KiB))) + buf_sz = DEFAULT_BUFSIZE; if (unlikely(flow_ctrl > 1)) flow_ctrl = FLOW_AUTO; else if (likely(flow_ctrl < 0)) @@ -286,10 +286,25 @@ bool stmmac_eee_init(struct stmmac_priv *priv) /* MAC core supports the EEE feature. */ if (priv->dma_cap.eee) { + int tx_lpi_timer = priv->tx_lpi_timer; + /* Check if the PHY supports EEE */ - if (phy_init_eee(priv->phydev, 1)) + if (phy_init_eee(priv->phydev, 1)) { + /* To manage at run-time if the EEE cannot be supported + * anymore (for example because the lp caps have been + * changed). + * In that case the driver disable own timers. + */ + if (priv->eee_active) { + pr_debug("stmmac: disable EEE\n"); + del_timer_sync(&priv->eee_ctrl_timer); + priv->hw->mac->set_eee_timer(priv->ioaddr, 0, + tx_lpi_timer); + } + priv->eee_active = 0; goto out; - + } + /* Activate the EEE and start timers */ if (!priv->eee_active) { priv->eee_active = 1; init_timer(&priv->eee_ctrl_timer); @@ -300,13 +315,13 @@ bool stmmac_eee_init(struct stmmac_priv *priv) priv->hw->mac->set_eee_timer(priv->ioaddr, STMMAC_DEFAULT_LIT_LS, - priv->tx_lpi_timer); + tx_lpi_timer); } else /* Set HW EEE according to the speed */ priv->hw->mac->set_eee_pls(priv->ioaddr, priv->phydev->link); - pr_info("stmmac: Energy-Efficient Ethernet initialized\n"); + pr_debug("stmmac: Energy-Efficient Ethernet initialized\n"); ret = true; } @@ -886,10 +901,10 @@ static int stmmac_set_bfsize(int mtu, int bufsize) ret = BUF_SIZE_8KiB; else if (mtu >= BUF_SIZE_2KiB) ret = BUF_SIZE_4KiB; - else if (mtu >= DMA_BUFFER_SIZE) + else if (mtu > DEFAULT_BUFSIZE) ret = BUF_SIZE_2KiB; else - ret = DMA_BUFFER_SIZE; + ret = DEFAULT_BUFSIZE; return ret; } @@ -951,9 +966,9 @@ static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p, p->des2 = priv->rx_skbuff_dma[i]; - if ((priv->mode == STMMAC_RING_MODE) && + if ((priv->hw->mode->init_desc3) && (priv->dma_buf_sz == BUF_SIZE_16KiB)) - priv->hw->ring->init_desc3(p); + priv->hw->mode->init_desc3(p); return 0; } @@ -984,11 +999,8 @@ static int init_dma_desc_rings(struct net_device *dev) unsigned int bfsize = 0; int ret = -ENOMEM; - /* Set the max buffer size according to the DESC mode - * and the MTU. Note that RING mode allows 16KiB bsize. - */ - if (priv->mode == STMMAC_RING_MODE) - bfsize = priv->hw->ring->set_16kib_bfsize(dev->mtu); + if (priv->hw->mode->set_16kib_bfsize) + bfsize = priv->hw->mode->set_16kib_bfsize(dev->mtu); if (bfsize < BUF_SIZE_16KiB) bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_buf_sz); @@ -1029,15 +1041,15 @@ static int init_dma_desc_rings(struct net_device *dev) /* Setup the chained descriptor addresses */ if (priv->mode == STMMAC_CHAIN_MODE) { if (priv->extend_desc) { - priv->hw->chain->init(priv->dma_erx, priv->dma_rx_phy, - rxsize, 1); - priv->hw->chain->init(priv->dma_etx, priv->dma_tx_phy, - txsize, 1); + priv->hw->mode->init(priv->dma_erx, priv->dma_rx_phy, + rxsize, 1); + priv->hw->mode->init(priv->dma_etx, priv->dma_tx_phy, + txsize, 1); } else { - priv->hw->chain->init(priv->dma_rx, priv->dma_rx_phy, - rxsize, 0); - priv->hw->chain->init(priv->dma_tx, priv->dma_tx_phy, - txsize, 0); + priv->hw->mode->init(priv->dma_rx, priv->dma_rx_phy, + rxsize, 0); + priv->hw->mode->init(priv->dma_tx, priv->dma_tx_phy, + txsize, 0); } } @@ -1288,7 +1300,7 @@ static void stmmac_tx_clean(struct stmmac_priv *priv) DMA_TO_DEVICE); priv->tx_skbuff_dma[entry] = 0; } - priv->hw->ring->clean_desc3(priv, p); + priv->hw->mode->clean_desc3(priv, p); if (likely(skb != NULL)) { dev_kfree_skb(skb); @@ -1844,6 +1856,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) int nfrags = skb_shinfo(skb)->nr_frags; struct dma_desc *desc, *first; unsigned int nopaged_len = skb_headlen(skb); + unsigned int enh_desc = priv->plat->enh_desc; if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) { if (!netif_queue_stopped(dev)) { @@ -1871,27 +1884,19 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) first = desc; /* To program the descriptors according to the size of the frame */ - if (priv->mode == STMMAC_RING_MODE) { - is_jumbo = priv->hw->ring->is_jumbo_frm(skb->len, - priv->plat->enh_desc); - if (unlikely(is_jumbo)) - entry = priv->hw->ring->jumbo_frm(priv, skb, - csum_insertion); - } else { - is_jumbo = priv->hw->chain->is_jumbo_frm(skb->len, - priv->plat->enh_desc); - if (unlikely(is_jumbo)) - entry = priv->hw->chain->jumbo_frm(priv, skb, - csum_insertion); - } + if (enh_desc) + is_jumbo = priv->hw->mode->is_jumbo_frm(skb->len, enh_desc); + if (likely(!is_jumbo)) { desc->des2 = dma_map_single(priv->device, skb->data, nopaged_len, DMA_TO_DEVICE); priv->tx_skbuff_dma[entry] = desc->des2; priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, csum_insertion, priv->mode); - } else + } else { desc = first; + entry = priv->hw->mode->jumbo_frm(priv, skb, csum_insertion); + } for (i = 0; i < nfrags; i++) { const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; @@ -2029,7 +2034,7 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv) p->des2 = priv->rx_skbuff_dma[entry]; - priv->hw->ring->refill_desc3(priv, p); + priv->hw->mode->refill_desc3(priv, p); if (netif_msg_rx_status(priv)) pr_debug("\trefill entry #%d\n", entry); @@ -2633,11 +2638,11 @@ static int stmmac_hw_init(struct stmmac_priv *priv) /* To use the chained or ring mode */ if (chain_mode) { - priv->hw->chain = &chain_mode_ops; + priv->hw->mode = &chain_mode_ops; pr_info(" Chain mode enabled\n"); priv->mode = STMMAC_CHAIN_MODE; } else { - priv->hw->ring = &ring_mode_ops; + priv->hw->mode = &ring_mode_ops; pr_info(" Ring mode enabled\n"); priv->mode = STMMAC_RING_MODE; } diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index c61bc72b8e90..8fb32a80f1c1 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -36,7 +36,7 @@ static const struct of_device_id stmmac_dt_ids[] = { #ifdef CONFIG_DWMAC_STI { .compatible = "st,stih415-dwmac", .data = &sti_gmac_data}, { .compatible = "st,stih416-dwmac", .data = &sti_gmac_data}, - { .compatible = "st,stih127-dwmac", .data = &sti_gmac_data}, + { .compatible = "st,stid127-dwmac", .data = &sti_gmac_data}, #endif /* SoC specific glue layers should come before generic bindings */ { .compatible = "st,spear600-gmac"}, diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 7141a1937360..d6fce9750b95 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -442,6 +442,8 @@ static int netvsc_probe(struct hv_device *dev, if (!net) return -ENOMEM; + netif_carrier_off(net); + net_device_ctx = netdev_priv(net); net_device_ctx->device_ctx = dev; hv_set_drvdata(dev, net); @@ -473,6 +475,8 @@ static int netvsc_probe(struct hv_device *dev, pr_err("Unable to register netdev.\n"); rndis_filter_device_remove(dev); free_netdev(net); + } else { + schedule_delayed_work(&net_device_ctx->dwork, 0); } return ret; diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index 1084e5de3ceb..b54fd257652b 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c @@ -243,6 +243,22 @@ static int rndis_filter_send_request(struct rndis_device *dev, return ret; } +static void rndis_set_link_state(struct rndis_device *rdev, + struct rndis_request *request) +{ + u32 link_status; + struct rndis_query_complete *query_complete; + + query_complete = &request->response_msg.msg.query_complete; + + if (query_complete->status == RNDIS_STATUS_SUCCESS && + query_complete->info_buflen == sizeof(u32)) { + memcpy(&link_status, (void *)((unsigned long)query_complete + + query_complete->info_buf_offset), sizeof(u32)); + rdev->link_state = link_status != 0; + } +} + static void rndis_filter_receive_response(struct rndis_device *dev, struct rndis_message *resp) { @@ -272,6 +288,10 @@ static void rndis_filter_receive_response(struct rndis_device *dev, sizeof(struct rndis_message) + RNDIS_EXT_LEN) { memcpy(&request->response_msg, resp, resp->msg_len); + if (request->request_msg.ndis_msg_type == + RNDIS_MSG_QUERY && request->request_msg.msg. + query_req.oid == RNDIS_OID_GEN_MEDIA_CONNECT_STATUS) + rndis_set_link_state(dev, request); } else { netdev_err(ndev, "rndis response buffer overflow " @@ -620,7 +640,6 @@ static int rndis_filter_query_device_link_status(struct rndis_device *dev) ret = rndis_filter_query_device(dev, RNDIS_OID_GEN_MEDIA_CONNECT_STATUS, &link_status, &size); - dev->link_state = (link_status != 0) ? true : false; return ret; } diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index ab31544bc254..a30258aad139 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -546,12 +546,12 @@ at86rf230_xmit(struct ieee802154_dev *dev, struct sk_buff *skb) int rc; unsigned long flags; - spin_lock(&lp->lock); + spin_lock_irqsave(&lp->lock, flags); if (lp->irq_busy) { - spin_unlock(&lp->lock); + spin_unlock_irqrestore(&lp->lock, flags); return -EBUSY; } - spin_unlock(&lp->lock); + spin_unlock_irqrestore(&lp->lock, flags); might_sleep(); @@ -725,10 +725,11 @@ static void at86rf230_irqwork_level(struct work_struct *work) static irqreturn_t at86rf230_isr(int irq, void *data) { struct at86rf230_local *lp = data; + unsigned long flags; - spin_lock(&lp->lock); + spin_lock_irqsave(&lp->lock, flags); lp->irq_busy = 1; - spin_unlock(&lp->lock); + spin_unlock_irqrestore(&lp->lock, flags); schedule_work(&lp->irqwork); diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 19c9eca0ef26..76d96b9ebcdb 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -164,9 +164,9 @@ static const struct phy_setting settings[] = { * of that setting. Returns the index of the last setting if * none of the others match. */ -static inline int phy_find_setting(int speed, int duplex) +static inline unsigned int phy_find_setting(int speed, int duplex) { - int idx = 0; + unsigned int idx = 0; while (idx < ARRAY_SIZE(settings) && (settings[idx].speed != speed || settings[idx].duplex != duplex)) @@ -185,7 +185,7 @@ static inline int phy_find_setting(int speed, int duplex) * the mask in features. Returns the index of the last setting * if nothing else matches. */ -static inline int phy_find_valid(int idx, u32 features) +static inline unsigned int phy_find_valid(unsigned int idx, u32 features) { while (idx < MAX_NUM_SETTINGS && !(settings[idx].setting & features)) idx++; @@ -204,7 +204,7 @@ static inline int phy_find_valid(int idx, u32 features) static void phy_sanitize_settings(struct phy_device *phydev) { u32 features = phydev->supported; - int idx; + unsigned int idx; /* Sanitize settings based on PHY capabilities */ if ((features & SUPPORTED_Autoneg) == 0) @@ -954,7 +954,8 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable) (phydev->interface == PHY_INTERFACE_MODE_RGMII))) { int eee_lp, eee_cap, eee_adv; u32 lp, cap, adv; - int idx, status; + int status; + unsigned int idx; /* Read phy status to properly get the right settings */ status = phy_read_status(phydev); diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index 433f0a00c683..e2797f1e1b31 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile @@ -11,7 +11,7 @@ obj-$(CONFIG_USB_HSO) += hso.o obj-$(CONFIG_USB_NET_AX8817X) += asix.o asix-y := asix_devices.o asix_common.o ax88172a.o obj-$(CONFIG_USB_NET_AX88179_178A) += ax88179_178a.o -obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o r815x.o +obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o obj-$(CONFIG_USB_NET_DM9601) += dm9601.o obj-$(CONFIG_USB_NET_SR9700) += sr9700.o diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 42e176912c8e..bd363b27e854 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -652,6 +652,13 @@ static const struct usb_device_id products[] = { .driver_info = 0, }, +/* Samsung USB Ethernet Adapters */ +{ + USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, 0xa101, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), + .driver_info = 0, +}, + /* WHITELIST!!! * * CDC Ether uses two interfaces, not necessarily consecutive. diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index d89dbe395ad2..adb12f349a61 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -449,9 +449,6 @@ enum rtl8152_flags { #define MCU_TYPE_PLA 0x0100 #define MCU_TYPE_USB 0x0000 -#define REALTEK_USB_DEVICE(vend, prod) \ - USB_DEVICE_INTERFACE_CLASS(vend, prod, USB_CLASS_VENDOR_SPEC) - struct rx_desc { __le32 opts1; #define RX_LEN_MASK 0x7fff @@ -2739,6 +2736,12 @@ static int rtl8152_probe(struct usb_interface *intf, struct net_device *netdev; int ret; + if (udev->actconfig->desc.bConfigurationValue != 1) { + usb_driver_set_configuration(udev, 1); + return -ENODEV; + } + + usb_reset_device(udev); netdev = alloc_etherdev(sizeof(struct r8152)); if (!netdev) { dev_err(&intf->dev, "Out of memory\n"); @@ -2819,9 +2822,9 @@ static void rtl8152_disconnect(struct usb_interface *intf) /* table of devices that work with this driver */ static struct usb_device_id rtl8152_table[] = { - {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8152)}, - {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8153)}, - {REALTEK_USB_DEVICE(VENDOR_ID_SAMSUNG, PRODUCT_ID_SAMSUNG)}, + {USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8152)}, + {USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8153)}, + {USB_DEVICE(VENDOR_ID_SAMSUNG, PRODUCT_ID_SAMSUNG)}, {} }; diff --git a/drivers/net/usb/r815x.c b/drivers/net/usb/r815x.c deleted file mode 100644 index f0a8791b7636..000000000000 --- a/drivers/net/usb/r815x.c +++ /dev/null @@ -1,248 +0,0 @@ -#include <linux/module.h> -#include <linux/netdevice.h> -#include <linux/mii.h> -#include <linux/usb.h> -#include <linux/usb/cdc.h> -#include <linux/usb/usbnet.h> - -#define RTL815x_REQT_READ 0xc0 -#define RTL815x_REQT_WRITE 0x40 -#define RTL815x_REQ_GET_REGS 0x05 -#define RTL815x_REQ_SET_REGS 0x05 - -#define MCU_TYPE_PLA 0x0100 -#define OCP_BASE 0xe86c -#define BASE_MII 0xa400 - -#define BYTE_EN_DWORD 0xff -#define BYTE_EN_WORD 0x33 -#define BYTE_EN_BYTE 0x11 - -#define R815x_PHY_ID 32 -#define REALTEK_VENDOR_ID 0x0bda - - -static int pla_read_word(struct usb_device *udev, u16 index) -{ - int ret; - u8 shift = index & 2; - __le32 *tmp; - - tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); - if (!tmp) - return -ENOMEM; - - index &= ~3; - - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - RTL815x_REQ_GET_REGS, RTL815x_REQT_READ, - index, MCU_TYPE_PLA, tmp, sizeof(*tmp), 500); - if (ret < 0) - goto out2; - - ret = __le32_to_cpu(*tmp); - ret >>= (shift * 8); - ret &= 0xffff; - -out2: - kfree(tmp); - return ret; -} - -static int pla_write_word(struct usb_device *udev, u16 index, u32 data) -{ - __le32 *tmp; - u32 mask = 0xffff; - u16 byen = BYTE_EN_WORD; - u8 shift = index & 2; - int ret; - - tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); - if (!tmp) - return -ENOMEM; - - data &= mask; - - if (shift) { - byen <<= shift; - mask <<= (shift * 8); - data <<= (shift * 8); - index &= ~3; - } - - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - RTL815x_REQ_GET_REGS, RTL815x_REQT_READ, - index, MCU_TYPE_PLA, tmp, sizeof(*tmp), 500); - if (ret < 0) - goto out3; - - data |= __le32_to_cpu(*tmp) & ~mask; - *tmp = __cpu_to_le32(data); - - ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - RTL815x_REQ_SET_REGS, RTL815x_REQT_WRITE, - index, MCU_TYPE_PLA | byen, tmp, sizeof(*tmp), - 500); - -out3: - kfree(tmp); - return ret; -} - -static int ocp_reg_read(struct usbnet *dev, u16 addr) -{ - u16 ocp_base, ocp_index; - int ret; - - ocp_base = addr & 0xf000; - ret = pla_write_word(dev->udev, OCP_BASE, ocp_base); - if (ret < 0) - goto out; - - ocp_index = (addr & 0x0fff) | 0xb000; - ret = pla_read_word(dev->udev, ocp_index); - -out: - return ret; -} - -static int ocp_reg_write(struct usbnet *dev, u16 addr, u16 data) -{ - u16 ocp_base, ocp_index; - int ret; - - ocp_base = addr & 0xf000; - ret = pla_write_word(dev->udev, OCP_BASE, ocp_base); - if (ret < 0) - goto out1; - - ocp_index = (addr & 0x0fff) | 0xb000; - ret = pla_write_word(dev->udev, ocp_index, data); - -out1: - return ret; -} - -static int r815x_mdio_read(struct net_device *netdev, int phy_id, int reg) -{ - struct usbnet *dev = netdev_priv(netdev); - int ret; - - if (phy_id != R815x_PHY_ID) - return -EINVAL; - - if (usb_autopm_get_interface(dev->intf) < 0) - return -ENODEV; - - ret = ocp_reg_read(dev, BASE_MII + reg * 2); - - usb_autopm_put_interface(dev->intf); - return ret; -} - -static -void r815x_mdio_write(struct net_device *netdev, int phy_id, int reg, int val) -{ - struct usbnet *dev = netdev_priv(netdev); - - if (phy_id != R815x_PHY_ID) - return; - - if (usb_autopm_get_interface(dev->intf) < 0) - return; - - ocp_reg_write(dev, BASE_MII + reg * 2, val); - - usb_autopm_put_interface(dev->intf); -} - -static int r8153_bind(struct usbnet *dev, struct usb_interface *intf) -{ - int status; - - status = usbnet_cdc_bind(dev, intf); - if (status < 0) - return status; - - dev->mii.dev = dev->net; - dev->mii.mdio_read = r815x_mdio_read; - dev->mii.mdio_write = r815x_mdio_write; - dev->mii.phy_id_mask = 0x3f; - dev->mii.reg_num_mask = 0x1f; - dev->mii.phy_id = R815x_PHY_ID; - dev->mii.supports_gmii = 1; - - return status; -} - -static int r8152_bind(struct usbnet *dev, struct usb_interface *intf) -{ - int status; - - status = usbnet_cdc_bind(dev, intf); - if (status < 0) - return status; - - dev->mii.dev = dev->net; - dev->mii.mdio_read = r815x_mdio_read; - dev->mii.mdio_write = r815x_mdio_write; - dev->mii.phy_id_mask = 0x3f; - dev->mii.reg_num_mask = 0x1f; - dev->mii.phy_id = R815x_PHY_ID; - dev->mii.supports_gmii = 0; - - return status; -} - -static const struct driver_info r8152_info = { - .description = "RTL8152 ECM Device", - .flags = FLAG_ETHER | FLAG_POINTTOPOINT, - .bind = r8152_bind, - .unbind = usbnet_cdc_unbind, - .status = usbnet_cdc_status, - .manage_power = usbnet_manage_power, -}; - -static const struct driver_info r8153_info = { - .description = "RTL8153 ECM Device", - .flags = FLAG_ETHER | FLAG_POINTTOPOINT, - .bind = r8153_bind, - .unbind = usbnet_cdc_unbind, - .status = usbnet_cdc_status, - .manage_power = usbnet_manage_power, -}; - -static const struct usb_device_id products[] = { -{ - USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8152, USB_CLASS_COMM, - USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), - .driver_info = (unsigned long) &r8152_info, -}, - -{ - USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8153, USB_CLASS_COMM, - USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), - .driver_info = (unsigned long) &r8153_info, -}, - - { }, /* END */ -}; -MODULE_DEVICE_TABLE(usb, products); - -static struct usb_driver r815x_driver = { - .name = "r815x", - .id_table = products, - .probe = usbnet_probe, - .disconnect = usbnet_disconnect, - .suspend = usbnet_suspend, - .resume = usbnet_resume, - .reset_resume = usbnet_resume, - .supports_autosuspend = 1, - .disable_hub_initiated_lpm = 1, -}; - -module_usb_driver(r815x_driver); - -MODULE_AUTHOR("Hayes Wang"); -MODULE_DESCRIPTION("Realtek USB ECM device"); -MODULE_LICENSE("GPL"); diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 3be786faaaec..0fa3b44f7342 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -1762,11 +1762,20 @@ vmxnet3_netpoll(struct net_device *netdev) { struct vmxnet3_adapter *adapter = netdev_priv(netdev); - if (adapter->intr.mask_mode == VMXNET3_IMM_ACTIVE) - vmxnet3_disable_all_intrs(adapter); - - vmxnet3_do_poll(adapter, adapter->rx_queue[0].rx_ring[0].size); - vmxnet3_enable_all_intrs(adapter); + switch (adapter->intr.type) { +#ifdef CONFIG_PCI_MSI + case VMXNET3_IT_MSIX: { + int i; + for (i = 0; i < adapter->num_rx_queues; i++) + vmxnet3_msix_rx(0, &adapter->rx_queue[i]); + break; + } +#endif + case VMXNET3_IT_MSI: + default: + vmxnet3_intr(0, adapter->netdev); + break; + } } #endif /* CONFIG_NET_POLL_CONTROLLER */ diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c index 76cde6ce6551..18a895a949d4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c @@ -872,8 +872,11 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif, lockdep_assert_held(&mvm->mutex); - /* Rssi update while not associated ?! */ - if (WARN_ON_ONCE(mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT)) + /* + * Rssi update while not associated - can happen since the statistics + * are handled asynchronously + */ + if (mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT) return; /* No BT - reports should be disabled */ diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index f47bcbe2945a..3872ead75488 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c @@ -359,13 +359,12 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { /* 7265 Series */ {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x5110, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x5112, iwl7265_2ac_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x5100, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095A, 0x510A, iwl7265_2ac_cfg)}, {IWL_PCI_DEVICE(0x095B, 0x5310, iwl7265_2ac_cfg)}, - {IWL_PCI_DEVICE(0x095B, 0x5302, iwl7265_2ac_cfg)}, + {IWL_PCI_DEVICE(0x095B, 0x5302, iwl7265_n_cfg)}, {IWL_PCI_DEVICE(0x095B, 0x5210, iwl7265_2ac_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x5012, iwl7265_2ac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x5412, iwl7265_2ac_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x5410, iwl7265_2ac_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x5400, iwl7265_2ac_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x1010, iwl7265_2ac_cfg)}, diff --git a/drivers/net/wireless/mwifiex/11ac.c b/drivers/net/wireless/mwifiex/11ac.c index 5e0eec4d71c7..5d9a8084665d 100644 --- a/drivers/net/wireless/mwifiex/11ac.c +++ b/drivers/net/wireless/mwifiex/11ac.c @@ -189,8 +189,7 @@ int mwifiex_cmd_append_11ac_tlv(struct mwifiex_private *priv, vht_cap->header.len = cpu_to_le16(sizeof(struct ieee80211_vht_cap)); memcpy((u8 *)vht_cap + sizeof(struct mwifiex_ie_types_header), - (u8 *)bss_desc->bcn_vht_cap + - sizeof(struct ieee_types_header), + (u8 *)bss_desc->bcn_vht_cap, le16_to_cpu(vht_cap->header.len)); mwifiex_fill_vht_cap_tlv(priv, vht_cap, bss_desc->bss_band); diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index 6261f8c53d44..7db1a89fdd95 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c @@ -308,8 +308,7 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, ht_cap->header.len = cpu_to_le16(sizeof(struct ieee80211_ht_cap)); memcpy((u8 *) ht_cap + sizeof(struct mwifiex_ie_types_header), - (u8 *) bss_desc->bcn_ht_cap + - sizeof(struct ieee_types_header), + (u8 *)bss_desc->bcn_ht_cap, le16_to_cpu(ht_cap->header.len)); mwifiex_fill_cap_info(priv, radio_type, ht_cap); diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 0a8a26e10f01..668547c2de84 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -2101,12 +2101,12 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv) curr_bss->ht_info_offset); if (curr_bss->bcn_vht_cap) - curr_bss->bcn_ht_cap = (void *)(curr_bss->beacon_buf + - curr_bss->vht_cap_offset); + curr_bss->bcn_vht_cap = (void *)(curr_bss->beacon_buf + + curr_bss->vht_cap_offset); if (curr_bss->bcn_vht_oper) - curr_bss->bcn_ht_oper = (void *)(curr_bss->beacon_buf + - curr_bss->vht_info_offset); + curr_bss->bcn_vht_oper = (void *)(curr_bss->beacon_buf + + curr_bss->vht_info_offset); if (curr_bss->bcn_bss_co_2040) curr_bss->bcn_bss_co_2040 = diff --git a/drivers/net/wireless/ti/wl1251/rx.c b/drivers/net/wireless/ti/wl1251/rx.c index 123c4bb50e0a..cde0eaf99714 100644 --- a/drivers/net/wireless/ti/wl1251/rx.c +++ b/drivers/net/wireless/ti/wl1251/rx.c @@ -180,7 +180,7 @@ static void wl1251_rx_body(struct wl1251 *wl, wl1251_mem_read(wl, rx_packet_ring_addr, rx_buffer, length); /* The actual length doesn't include the target's alignment */ - skb->len = desc->length - PLCP_HEADER_LENGTH; + skb_trim(skb, desc->length - PLCP_HEADER_LENGTH); fc = (u16 *)skb->data; diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index 7669d49a67e2..301cc037fda8 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c @@ -132,8 +132,7 @@ static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev) /* If the skb is GSO then we'll also need an extra slot for the * metadata. */ - if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4 || - skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) + if (skb_is_gso(skb)) min_slots_needed++; /* If the skb can't possibly fit in the remaining slots diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index e5284bca2d90..438d0c09b7e6 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -240,7 +240,7 @@ static void xenvif_gop_frag_copy(struct xenvif *vif, struct sk_buff *skb, struct gnttab_copy *copy_gop; struct xenvif_rx_meta *meta; unsigned long bytes; - int gso_type; + int gso_type = XEN_NETIF_GSO_TYPE_NONE; /* Data must not cross a page boundary. */ BUG_ON(size + offset > PAGE_SIZE<<compound_order(page)); @@ -299,12 +299,12 @@ static void xenvif_gop_frag_copy(struct xenvif *vif, struct sk_buff *skb, } /* Leave a gap for the GSO descriptor. */ - if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) - gso_type = XEN_NETIF_GSO_TYPE_TCPV4; - else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) - gso_type = XEN_NETIF_GSO_TYPE_TCPV6; - else - gso_type = XEN_NETIF_GSO_TYPE_NONE; + if (skb_is_gso(skb)) { + if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) + gso_type = XEN_NETIF_GSO_TYPE_TCPV4; + else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) + gso_type = XEN_NETIF_GSO_TYPE_TCPV6; + } if (*head && ((1 << gso_type) & vif->gso_mask)) vif->rx.req_cons++; @@ -338,19 +338,15 @@ static int xenvif_gop_skb(struct sk_buff *skb, int head = 1; int old_meta_prod; int gso_type; - int gso_size; old_meta_prod = npo->meta_prod; - if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) { - gso_type = XEN_NETIF_GSO_TYPE_TCPV4; - gso_size = skb_shinfo(skb)->gso_size; - } else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) { - gso_type = XEN_NETIF_GSO_TYPE_TCPV6; - gso_size = skb_shinfo(skb)->gso_size; - } else { - gso_type = XEN_NETIF_GSO_TYPE_NONE; - gso_size = 0; + gso_type = XEN_NETIF_GSO_TYPE_NONE; + if (skb_is_gso(skb)) { + if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) + gso_type = XEN_NETIF_GSO_TYPE_TCPV4; + else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) + gso_type = XEN_NETIF_GSO_TYPE_TCPV6; } /* Set up a GSO prefix descriptor, if necessary */ @@ -358,7 +354,7 @@ static int xenvif_gop_skb(struct sk_buff *skb, req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++); meta = npo->meta + npo->meta_prod++; meta->gso_type = gso_type; - meta->gso_size = gso_size; + meta->gso_size = skb_shinfo(skb)->gso_size; meta->size = 0; meta->id = req->id; } @@ -368,7 +364,7 @@ static int xenvif_gop_skb(struct sk_buff *skb, if ((1 << gso_type) & vif->gso_mask) { meta->gso_type = gso_type; - meta->gso_size = gso_size; + meta->gso_size = skb_shinfo(skb)->gso_size; } else { meta->gso_type = XEN_NETIF_GSO_TYPE_NONE; meta->gso_size = 0; @@ -500,8 +496,9 @@ static void xenvif_rx_action(struct xenvif *vif) size = skb_frag_size(&skb_shinfo(skb)->frags[i]); max_slots_needed += DIV_ROUND_UP(size, PAGE_SIZE); } - if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4 || - skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) + if (skb_is_gso(skb) && + (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4 || + skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)) max_slots_needed++; /* If the skb may not fit then bail out now */ diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 00660cc502c5..38901665c770 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -162,8 +162,6 @@ static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res, avail = *r; pci_clip_resource_to_region(bus, &avail, region); - if (!resource_size(&avail)) - continue; /* * "min" is typically PCIBIOS_MIN_IO or PCIBIOS_MIN_MEM to diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index b6162be4df40..2b859249303b 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h @@ -93,7 +93,6 @@ struct acpiphp_slot { struct list_head funcs; /* one slot may have different objects (i.e. for each function) */ struct slot *slot; - struct mutex crit_sect; u8 device; /* pci device# */ u32 flags; /* see below */ @@ -117,20 +116,30 @@ struct acpiphp_func { }; struct acpiphp_context { - acpi_handle handle; + struct acpi_hotplug_context hp; struct acpiphp_func func; struct acpiphp_bridge *bridge; unsigned int refcount; }; +static inline struct acpiphp_context *to_acpiphp_context(struct acpi_hotplug_context *hp) +{ + return container_of(hp, struct acpiphp_context, hp); +} + static inline struct acpiphp_context *func_to_context(struct acpiphp_func *func) { return container_of(func, struct acpiphp_context, func); } +static inline struct acpi_device *func_to_acpi_device(struct acpiphp_func *func) +{ + return func_to_context(func)->hp.self; +} + static inline acpi_handle func_to_handle(struct acpiphp_func *func) { - return func_to_context(func)->handle; + return func_to_acpi_device(func)->handle; } /* @@ -158,7 +167,6 @@ struct acpiphp_attention_info #define FUNC_HAS_STA (0x00000001) #define FUNC_HAS_EJ0 (0x00000002) -#define FUNC_HAS_DCK (0x00000004) /* function prototypes */ diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 7c7a388c85ab..828acf422c17 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -58,71 +58,59 @@ static LIST_HEAD(bridge_list); static DEFINE_MUTEX(bridge_mutex); -static DEFINE_MUTEX(acpiphp_context_lock); -static void handle_hotplug_event(acpi_handle handle, u32 type, void *data); +static int acpiphp_hotplug_notify(struct acpi_device *adev, u32 type); +static void acpiphp_post_dock_fixup(struct acpi_device *adev); static void acpiphp_sanitize_bus(struct pci_bus *bus); static void acpiphp_set_hpp_values(struct pci_bus *bus); -static void hotplug_event(acpi_handle handle, u32 type, void *data); +static void hotplug_event(u32 type, struct acpiphp_context *context); static void free_bridge(struct kref *kref); -static void acpiphp_context_handler(acpi_handle handle, void *context) -{ - /* Intentionally empty. */ -} - /** * acpiphp_init_context - Create hotplug context and grab a reference to it. - * @handle: ACPI object handle to create the context for. + * @adev: ACPI device object to create the context for. * - * Call under acpiphp_context_lock. + * Call under acpi_hp_context_lock. */ -static struct acpiphp_context *acpiphp_init_context(acpi_handle handle) +static struct acpiphp_context *acpiphp_init_context(struct acpi_device *adev) { struct acpiphp_context *context; - acpi_status status; context = kzalloc(sizeof(*context), GFP_KERNEL); if (!context) return NULL; - context->handle = handle; context->refcount = 1; - status = acpi_attach_data(handle, acpiphp_context_handler, context); - if (ACPI_FAILURE(status)) { - kfree(context); - return NULL; - } + acpi_set_hp_context(adev, &context->hp, acpiphp_hotplug_notify, NULL, + acpiphp_post_dock_fixup); return context; } /** * acpiphp_get_context - Get hotplug context and grab a reference to it. - * @handle: ACPI object handle to get the context for. + * @adev: ACPI device object to get the context for. * - * Call under acpiphp_context_lock. + * Call under acpi_hp_context_lock. */ -static struct acpiphp_context *acpiphp_get_context(acpi_handle handle) +static struct acpiphp_context *acpiphp_get_context(struct acpi_device *adev) { - struct acpiphp_context *context = NULL; - acpi_status status; - void *data; + struct acpiphp_context *context; - status = acpi_get_data(handle, acpiphp_context_handler, &data); - if (ACPI_SUCCESS(status)) { - context = data; - context->refcount++; - } + if (!adev->hp) + return NULL; + + context = to_acpiphp_context(adev->hp); + context->refcount++; return context; } /** * acpiphp_put_context - Drop a reference to ACPI hotplug context. - * @handle: ACPI object handle to put the context for. + * @context: ACPI hotplug context to drop a reference to. * * The context object is removed if there are no more references to it. * - * Call under acpiphp_context_lock. + * Call under acpi_hp_context_lock. */ static void acpiphp_put_context(struct acpiphp_context *context) { @@ -130,7 +118,7 @@ static void acpiphp_put_context(struct acpiphp_context *context) return; WARN_ON(context->bridge); - acpi_detach_data(context->handle, acpiphp_context_handler); + context->hp.self->hp = NULL; kfree(context); } @@ -144,6 +132,27 @@ static inline void put_bridge(struct acpiphp_bridge *bridge) kref_put(&bridge->ref, free_bridge); } +static struct acpiphp_context *acpiphp_grab_context(struct acpi_device *adev) +{ + struct acpiphp_context *context; + + acpi_lock_hp_context(); + context = acpiphp_get_context(adev); + if (!context || context->func.parent->is_going_away) { + acpi_unlock_hp_context(); + return NULL; + } + get_bridge(context->func.parent); + acpiphp_put_context(context); + acpi_unlock_hp_context(); + return context; +} + +static void acpiphp_let_context_go(struct acpiphp_context *context) +{ + put_bridge(context->func.parent); +} + static void free_bridge(struct kref *kref) { struct acpiphp_context *context; @@ -151,7 +160,7 @@ static void free_bridge(struct kref *kref) struct acpiphp_slot *slot, *next; struct acpiphp_func *func, *tmp; - mutex_lock(&acpiphp_context_lock); + acpi_lock_hp_context(); bridge = container_of(kref, struct acpiphp_bridge, ref); @@ -175,31 +184,32 @@ static void free_bridge(struct kref *kref) pci_dev_put(bridge->pci_dev); kfree(bridge); - mutex_unlock(&acpiphp_context_lock); + acpi_unlock_hp_context(); } -/* - * the _DCK method can do funny things... and sometimes not - * hah-hah funny. +/** + * acpiphp_post_dock_fixup - Post-dock fixups for PCI devices. + * @adev: ACPI device object corresponding to a PCI device. * - * TBD - figure out a way to only call fixups for - * systems that require them. + * TBD - figure out a way to only call fixups for systems that require them. */ -static void post_dock_fixups(acpi_handle not_used, u32 event, void *data) +static void acpiphp_post_dock_fixup(struct acpi_device *adev) { - struct acpiphp_context *context = data; - struct pci_bus *bus = context->func.slot->bus; + struct acpiphp_context *context = acpiphp_grab_context(adev); + struct pci_bus *bus; u32 buses; - if (!bus->self) + if (!context) return; + bus = context->func.slot->bus; + if (!bus->self) + goto out; + /* fixup bad _DCK function that rewrites * secondary bridge on slot */ - pci_read_config_dword(bus->self, - PCI_PRIMARY_BUS, - &buses); + pci_read_config_dword(bus->self, PCI_PRIMARY_BUS, &buses); if (((buses >> 8) & 0xff) != bus->busn_res.start) { buses = (buses & 0xff000000) @@ -208,33 +218,11 @@ static void post_dock_fixups(acpi_handle not_used, u32 event, void *data) | ((unsigned int)(bus->busn_res.end) << 16); pci_write_config_dword(bus->self, PCI_PRIMARY_BUS, buses); } -} - -static void dock_event(acpi_handle handle, u32 type, void *data) -{ - struct acpiphp_context *context; - - mutex_lock(&acpiphp_context_lock); - context = acpiphp_get_context(handle); - if (!context || WARN_ON(context->handle != handle) - || context->func.parent->is_going_away) { - mutex_unlock(&acpiphp_context_lock); - return; - } - get_bridge(context->func.parent); - acpiphp_put_context(context); - mutex_unlock(&acpiphp_context_lock); - - hotplug_event(handle, type, data); - put_bridge(context->func.parent); + out: + acpiphp_let_context_go(context); } -static const struct acpi_dock_ops acpiphp_dock_ops = { - .fixup = post_dock_fixups, - .handler = dock_event, -}; - /* Check whether the PCI device is managed by native PCIe hotplug driver */ static bool device_is_managed_by_native_pciehp(struct pci_dev *pdev) { @@ -264,26 +252,19 @@ static bool device_is_managed_by_native_pciehp(struct pci_dev *pdev) return true; } -static void acpiphp_dock_init(void *data) -{ - struct acpiphp_context *context = data; - - get_bridge(context->func.parent); -} - -static void acpiphp_dock_release(void *data) -{ - struct acpiphp_context *context = data; - - put_bridge(context->func.parent); -} - -/* callback routine to register each ACPI PCI slot object */ -static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data, - void **rv) +/** + * acpiphp_add_context - Add ACPIPHP context to an ACPI device object. + * @handle: ACPI handle of the object to add a context to. + * @lvl: Not used. + * @data: The object's parent ACPIPHP bridge. + * @rv: Not used. + */ +static acpi_status acpiphp_add_context(acpi_handle handle, u32 lvl, void *data, + void **rv) { struct acpiphp_bridge *bridge = data; struct acpiphp_context *context; + struct acpi_device *adev; struct acpiphp_slot *slot; struct acpiphp_func *newfunc; acpi_status status = AE_OK; @@ -293,9 +274,6 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data, struct pci_dev *pdev = bridge->pci_dev; u32 val; - if (pdev && device_is_managed_by_native_pciehp(pdev)) - return AE_OK; - status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr); if (ACPI_FAILURE(status)) { if (status != AE_NOT_FOUND) @@ -303,31 +281,34 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data, "can't evaluate _ADR (%#x)\n", status); return AE_OK; } + if (acpi_bus_get_device(handle, &adev)) + return AE_OK; device = (adr >> 16) & 0xffff; function = adr & 0xffff; - mutex_lock(&acpiphp_context_lock); - context = acpiphp_init_context(handle); + acpi_lock_hp_context(); + context = acpiphp_init_context(adev); if (!context) { - mutex_unlock(&acpiphp_context_lock); + acpi_unlock_hp_context(); acpi_handle_err(handle, "No hotplug context\n"); return AE_NOT_EXIST; } newfunc = &context->func; newfunc->function = function; newfunc->parent = bridge; - mutex_unlock(&acpiphp_context_lock); + acpi_unlock_hp_context(); - if (acpi_has_method(handle, "_EJ0")) + /* + * If this is a dock device, its _EJ0 should be executed by the dock + * notify handler after calling _DCK. + */ + if (!is_dock_device(adev) && acpi_has_method(handle, "_EJ0")) newfunc->flags = FUNC_HAS_EJ0; if (acpi_has_method(handle, "_STA")) newfunc->flags |= FUNC_HAS_STA; - if (acpi_has_method(handle, "_DCK")) - newfunc->flags |= FUNC_HAS_DCK; - /* search for objects that share the same slot */ list_for_each_entry(slot, &bridge->slots, node) if (slot->device == device) @@ -335,19 +316,26 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data, slot = kzalloc(sizeof(struct acpiphp_slot), GFP_KERNEL); if (!slot) { - status = AE_NO_MEMORY; - goto err; + acpi_lock_hp_context(); + acpiphp_put_context(context); + acpi_unlock_hp_context(); + return AE_NO_MEMORY; } slot->bus = bridge->pci_bus; slot->device = device; INIT_LIST_HEAD(&slot->funcs); - mutex_init(&slot->crit_sect); list_add_tail(&slot->node, &bridge->slots); - /* Register slots for ejectable functions only. */ - if (acpi_pci_check_ejectable(pbus, handle) || is_dock_device(handle)) { + /* + * Expose slots to user space for functions that have _EJ0 or _RMV or + * are located in dock stations. Do not expose them for devices handled + * by the native PCIe hotplug (PCIeHP), becuase that code is supposed to + * expose slots to user space in those cases. + */ + if ((acpi_pci_check_ejectable(pbus, handle) || is_dock_device(adev)) + && !(pdev && device_is_managed_by_native_pciehp(pdev))) { unsigned long long sun; int retval; @@ -381,44 +369,16 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data, &val, 60*1000)) slot->flags |= SLOT_ENABLED; - if (is_dock_device(handle)) { - /* we don't want to call this device's _EJ0 - * because we want the dock notify handler - * to call it after it calls _DCK - */ - newfunc->flags &= ~FUNC_HAS_EJ0; - if (register_hotplug_dock_device(handle, - &acpiphp_dock_ops, context, - acpiphp_dock_init, acpiphp_dock_release)) - pr_debug("failed to register dock device\n"); - } - - /* install notify handler */ - if (!(newfunc->flags & FUNC_HAS_DCK)) { - status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, - handle_hotplug_event, - context); - if (ACPI_FAILURE(status)) - acpi_handle_err(handle, - "failed to install notify handler\n"); - } - return AE_OK; - - err: - mutex_lock(&acpiphp_context_lock); - acpiphp_put_context(context); - mutex_unlock(&acpiphp_context_lock); - return status; } -static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) +static struct acpiphp_bridge *acpiphp_dev_to_bridge(struct acpi_device *adev) { struct acpiphp_context *context; struct acpiphp_bridge *bridge = NULL; - mutex_lock(&acpiphp_context_lock); - context = acpiphp_get_context(handle); + acpi_lock_hp_context(); + context = acpiphp_get_context(adev); if (context) { bridge = context->bridge; if (bridge) @@ -426,7 +386,7 @@ static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) acpiphp_put_context(context); } - mutex_unlock(&acpiphp_context_lock); + acpi_unlock_hp_context(); return bridge; } @@ -434,22 +394,15 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) { struct acpiphp_slot *slot; struct acpiphp_func *func; - acpi_status status; list_for_each_entry(slot, &bridge->slots, node) { list_for_each_entry(func, &slot->funcs, sibling) { - acpi_handle handle = func_to_handle(func); - - if (is_dock_device(handle)) - unregister_hotplug_dock_device(handle); + struct acpi_device *adev = func_to_acpi_device(func); - if (!(func->flags & FUNC_HAS_DCK)) { - status = acpi_remove_notify_handler(handle, - ACPI_SYSTEM_NOTIFY, - handle_hotplug_event); - if (ACPI_FAILURE(status)) - pr_err("failed to remove notify handler\n"); - } + acpi_lock_hp_context(); + adev->hp->notify = NULL; + adev->hp->fixup = NULL; + acpi_unlock_hp_context(); } slot->flags |= SLOT_IS_GOING_AWAY; if (slot->slot) @@ -460,9 +413,9 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) list_del(&bridge->list); mutex_unlock(&bridge_mutex); - mutex_lock(&acpiphp_context_lock); + acpi_lock_hp_context(); bridge->is_going_away = true; - mutex_unlock(&acpiphp_context_lock); + acpi_unlock_hp_context(); } /** @@ -492,33 +445,6 @@ static unsigned char acpiphp_max_busnr(struct pci_bus *bus) return max; } -/** - * acpiphp_bus_trim - Trim device objects in an ACPI namespace subtree. - * @handle: ACPI device object handle to start from. - */ -static void acpiphp_bus_trim(acpi_handle handle) -{ - struct acpi_device *adev = NULL; - - acpi_bus_get_device(handle, &adev); - if (adev) - acpi_bus_trim(adev); -} - -/** - * acpiphp_bus_add - Scan ACPI namespace subtree. - * @handle: ACPI object handle to start the scan from. - */ -static void acpiphp_bus_add(acpi_handle handle) -{ - struct acpi_device *adev = NULL; - - acpi_bus_scan(handle); - acpi_bus_get_device(handle, &adev); - if (acpi_device_enumerated(adev)) - acpi_device_set_power(adev, ACPI_STATE_D0); -} - static void acpiphp_set_acpi_region(struct acpiphp_slot *slot) { struct acpiphp_func *func; @@ -558,9 +484,13 @@ static int acpiphp_rescan_slot(struct acpiphp_slot *slot) { struct acpiphp_func *func; - list_for_each_entry(func, &slot->funcs, sibling) - acpiphp_bus_add(func_to_handle(func)); + list_for_each_entry(func, &slot->funcs, sibling) { + struct acpi_device *adev = func_to_acpi_device(func); + acpi_bus_scan(adev->handle); + if (acpi_device_enumerated(adev)) + acpi_device_set_power(adev, ACPI_STATE_D0); + } return pci_scan_slot(slot->bus, PCI_DEVFN(slot->device, 0)); } @@ -625,32 +555,15 @@ static void __ref enable_slot(struct acpiphp_slot *slot) } } -/* return first device in slot, acquiring a reference on it */ -static struct pci_dev *dev_in_slot(struct acpiphp_slot *slot) -{ - struct pci_bus *bus = slot->bus; - struct pci_dev *dev; - struct pci_dev *ret = NULL; - - down_read(&pci_bus_sem); - list_for_each_entry(dev, &bus->devices, bus_list) - if (PCI_SLOT(dev->devfn) == slot->device) { - ret = pci_dev_get(dev); - break; - } - up_read(&pci_bus_sem); - - return ret; -} - /** * disable_slot - disable a slot * @slot: ACPI PHP slot */ static void disable_slot(struct acpiphp_slot *slot) { + struct pci_bus *bus = slot->bus; + struct pci_dev *dev, *prev; struct acpiphp_func *func; - struct pci_dev *pdev; /* * enable_slot() enumerates all functions in this device via @@ -658,22 +571,18 @@ static void disable_slot(struct acpiphp_slot *slot) * methods (_EJ0, etc.) or not. Therefore, we remove all functions * here. */ - while ((pdev = dev_in_slot(slot))) { - pci_stop_and_remove_bus_device(pdev); - pci_dev_put(pdev); - } + list_for_each_entry_safe_reverse(dev, prev, &bus->devices, bus_list) + if (PCI_SLOT(dev->devfn) == slot->device) + pci_stop_and_remove_bus_device(dev); list_for_each_entry(func, &slot->funcs, sibling) - acpiphp_bus_trim(func_to_handle(func)); + acpi_bus_trim(func_to_acpi_device(func)); slot->flags &= (~SLOT_ENABLED); } -static bool acpiphp_no_hotplug(acpi_handle handle) +static bool acpiphp_no_hotplug(struct acpi_device *adev) { - struct acpi_device *adev = NULL; - - acpi_bus_get_device(handle, &adev); return adev && adev->flags.no_hotplug; } @@ -682,7 +591,7 @@ static bool slot_no_hotplug(struct acpiphp_slot *slot) struct acpiphp_func *func; list_for_each_entry(func, &slot->funcs, sibling) - if (acpiphp_no_hotplug(func_to_handle(func))) + if (acpiphp_no_hotplug(func_to_acpi_device(func))) return true; return false; @@ -747,28 +656,25 @@ static inline bool device_status_valid(unsigned int sta) */ static void trim_stale_devices(struct pci_dev *dev) { - acpi_handle handle = ACPI_HANDLE(&dev->dev); + struct acpi_device *adev = ACPI_COMPANION(&dev->dev); struct pci_bus *bus = dev->subordinate; bool alive = false; - if (handle) { + if (adev) { acpi_status status; unsigned long long sta; - status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); + status = acpi_evaluate_integer(adev->handle, "_STA", NULL, &sta); alive = (ACPI_SUCCESS(status) && device_status_valid(sta)) - || acpiphp_no_hotplug(handle); + || acpiphp_no_hotplug(adev); } - if (!alive) { - u32 v; + if (!alive) + alive = pci_device_is_present(dev); - /* Check if the device responds. */ - alive = pci_bus_read_dev_vendor_id(dev->bus, dev->devfn, &v, 0); - } if (!alive) { pci_stop_and_remove_bus_device(dev); - if (handle) - acpiphp_bus_trim(handle); + if (adev) + acpi_bus_trim(adev); } else if (bus) { struct pci_dev *child, *tmp; @@ -800,7 +706,6 @@ static void acpiphp_check_bridge(struct acpiphp_bridge *bridge) struct pci_bus *bus = slot->bus; struct pci_dev *dev, *tmp; - mutex_lock(&slot->crit_sect); if (slot_no_hotplug(slot)) { ; /* do nothing */ } else if (device_status_valid(get_slot_status(slot))) { @@ -815,7 +720,6 @@ static void acpiphp_check_bridge(struct acpiphp_bridge *bridge) } else { disable_slot(slot); } - mutex_unlock(&slot->crit_sect); } } @@ -855,11 +759,11 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus) * ACPI event handlers */ -void acpiphp_check_host_bridge(acpi_handle handle) +void acpiphp_check_host_bridge(struct acpi_device *adev) { struct acpiphp_bridge *bridge; - bridge = acpiphp_handle_to_bridge(handle); + bridge = acpiphp_dev_to_bridge(adev); if (bridge) { pci_lock_rescan_remove(); @@ -872,73 +776,52 @@ void acpiphp_check_host_bridge(acpi_handle handle) static int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot); -static void hotplug_event(acpi_handle handle, u32 type, void *data) +static void hotplug_event(u32 type, struct acpiphp_context *context) { - struct acpiphp_context *context = data; + acpi_handle handle = context->hp.self->handle; struct acpiphp_func *func = &context->func; + struct acpiphp_slot *slot = func->slot; struct acpiphp_bridge *bridge; - char objname[64]; - struct acpi_buffer buffer = { .length = sizeof(objname), - .pointer = objname }; - mutex_lock(&acpiphp_context_lock); + acpi_lock_hp_context(); bridge = context->bridge; if (bridge) get_bridge(bridge); - mutex_unlock(&acpiphp_context_lock); + acpi_unlock_hp_context(); pci_lock_rescan_remove(); - acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); switch (type) { case ACPI_NOTIFY_BUS_CHECK: /* bus re-enumerate */ - pr_debug("%s: Bus check notify on %s\n", __func__, objname); - pr_debug("%s: re-enumerating slots under %s\n", - __func__, objname); - if (bridge) { + acpi_handle_debug(handle, "Bus check in %s()\n", __func__); + if (bridge) acpiphp_check_bridge(bridge); - } else { - struct acpiphp_slot *slot = func->slot; - - if (slot->flags & SLOT_IS_GOING_AWAY) - break; - - mutex_lock(&slot->crit_sect); + else if (!(slot->flags & SLOT_IS_GOING_AWAY)) enable_slot(slot); - mutex_unlock(&slot->crit_sect); - } + break; case ACPI_NOTIFY_DEVICE_CHECK: /* device check */ - pr_debug("%s: Device check notify on %s\n", __func__, objname); + acpi_handle_debug(handle, "Device check in %s()\n", __func__); if (bridge) { acpiphp_check_bridge(bridge); - } else { - struct acpiphp_slot *slot = func->slot; - int ret; - - if (slot->flags & SLOT_IS_GOING_AWAY) - break; - + } else if (!(slot->flags & SLOT_IS_GOING_AWAY)) { /* * Check if anything has changed in the slot and rescan * from the parent if that's the case. */ - mutex_lock(&slot->crit_sect); - ret = acpiphp_rescan_slot(slot); - mutex_unlock(&slot->crit_sect); - if (ret) + if (acpiphp_rescan_slot(slot)) acpiphp_check_bridge(func->parent); } break; case ACPI_NOTIFY_EJECT_REQUEST: /* request device eject */ - pr_debug("%s: Device eject notify on %s\n", __func__, objname); - acpiphp_disable_and_eject_slot(func->slot); + acpi_handle_debug(handle, "Eject request in %s()\n", __func__); + acpiphp_disable_and_eject_slot(slot); break; } @@ -947,106 +830,41 @@ static void hotplug_event(acpi_handle handle, u32 type, void *data) put_bridge(bridge); } -static void hotplug_event_work(void *data, u32 type) +static int acpiphp_hotplug_notify(struct acpi_device *adev, u32 type) { - struct acpiphp_context *context = data; - acpi_handle handle = context->handle; - - acpi_scan_lock_acquire(); + struct acpiphp_context *context; - hotplug_event(handle, type, context); + context = acpiphp_grab_context(adev); + if (!context) + return -ENODATA; - acpi_scan_lock_release(); - acpi_evaluate_hotplug_ost(handle, type, ACPI_OST_SC_SUCCESS, NULL); - put_bridge(context->func.parent); + hotplug_event(type, context); + acpiphp_let_context_go(context); + return 0; } /** - * handle_hotplug_event - handle ACPI hotplug event - * @handle: Notify()'ed acpi_handle - * @type: Notify code - * @data: pointer to acpiphp_context structure + * acpiphp_enumerate_slots - Enumerate PCI slots for a given bus. + * @bus: PCI bus to enumerate the slots for. * - * Handles ACPI event notification on slots. - */ -static void handle_hotplug_event(acpi_handle handle, u32 type, void *data) -{ - struct acpiphp_context *context; - u32 ost_code = ACPI_OST_SC_SUCCESS; - acpi_status status; - - switch (type) { - case ACPI_NOTIFY_BUS_CHECK: - case ACPI_NOTIFY_DEVICE_CHECK: - break; - case ACPI_NOTIFY_EJECT_REQUEST: - ost_code = ACPI_OST_SC_EJECT_IN_PROGRESS; - acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL); - break; - - case ACPI_NOTIFY_DEVICE_WAKE: - return; - - case ACPI_NOTIFY_FREQUENCY_MISMATCH: - acpi_handle_err(handle, "Device cannot be configured due " - "to a frequency mismatch\n"); - goto out; - - case ACPI_NOTIFY_BUS_MODE_MISMATCH: - acpi_handle_err(handle, "Device cannot be configured due " - "to a bus mode mismatch\n"); - goto out; - - case ACPI_NOTIFY_POWER_FAULT: - acpi_handle_err(handle, "Device has suffered a power fault\n"); - goto out; - - default: - acpi_handle_warn(handle, "Unsupported event type 0x%x\n", type); - ost_code = ACPI_OST_SC_UNRECOGNIZED_NOTIFY; - goto out; - } - - mutex_lock(&acpiphp_context_lock); - context = acpiphp_get_context(handle); - if (!context || WARN_ON(context->handle != handle) - || context->func.parent->is_going_away) - goto err_out; - - get_bridge(context->func.parent); - acpiphp_put_context(context); - status = acpi_hotplug_execute(hotplug_event_work, context, type); - if (ACPI_SUCCESS(status)) { - mutex_unlock(&acpiphp_context_lock); - return; - } - put_bridge(context->func.parent); - - err_out: - mutex_unlock(&acpiphp_context_lock); - ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; - - out: - acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL); -} - -/* - * Create hotplug slots for the PCI bus. - * It should always return 0 to avoid skipping following notifiers. + * A "slot" is an object associated with a PCI device number. All functions + * (PCI devices) with the same bus and device number belong to the same slot. */ void acpiphp_enumerate_slots(struct pci_bus *bus) { struct acpiphp_bridge *bridge; + struct acpi_device *adev; acpi_handle handle; acpi_status status; if (acpiphp_disabled) return; - handle = ACPI_HANDLE(bus->bridge); - if (!handle) + adev = ACPI_COMPANION(bus->bridge); + if (!adev) return; + handle = adev->handle; bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); if (!bridge) { acpi_handle_err(handle, "No memory for bridge object\n"); @@ -1074,10 +892,10 @@ void acpiphp_enumerate_slots(struct pci_bus *bus) * parent is going to be handled by pciehp, in which case this * bridge is not interesting to us either. */ - mutex_lock(&acpiphp_context_lock); - context = acpiphp_get_context(handle); + acpi_lock_hp_context(); + context = acpiphp_get_context(adev); if (!context) { - mutex_unlock(&acpiphp_context_lock); + acpi_unlock_hp_context(); put_device(&bus->dev); pci_dev_put(bridge->pci_dev); kfree(bridge); @@ -1087,17 +905,17 @@ void acpiphp_enumerate_slots(struct pci_bus *bus) context->bridge = bridge; /* Get a reference to the parent bridge. */ get_bridge(context->func.parent); - mutex_unlock(&acpiphp_context_lock); + acpi_unlock_hp_context(); } - /* must be added to the list prior to calling register_slot */ + /* Must be added to the list prior to calling acpiphp_add_context(). */ mutex_lock(&bridge_mutex); list_add(&bridge->list, &bridge_list); mutex_unlock(&bridge_mutex); /* register all slot objects under this bridge */ status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, - register_slot, NULL, bridge, NULL); + acpiphp_add_context, NULL, bridge, NULL); if (ACPI_FAILURE(status)) { acpi_handle_err(handle, "failed to register slots\n"); cleanup_bridge(bridge); @@ -1105,7 +923,10 @@ void acpiphp_enumerate_slots(struct pci_bus *bus) } } -/* Destroy hotplug slots associated with the PCI bus */ +/** + * acpiphp_remove_slots - Remove slot objects associated with a given bus. + * @bus: PCI bus to remove the slot objects for. + */ void acpiphp_remove_slots(struct pci_bus *bus) { struct acpiphp_bridge *bridge; @@ -1136,13 +957,10 @@ int acpiphp_enable_slot(struct acpiphp_slot *slot) if (slot->flags & SLOT_IS_GOING_AWAY) return -ENODEV; - mutex_lock(&slot->crit_sect); /* configure all functions */ if (!(slot->flags & SLOT_ENABLED)) enable_slot(slot); - mutex_unlock(&slot->crit_sect); - pci_unlock_rescan_remove(); return 0; } @@ -1158,8 +976,6 @@ static int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot) if (slot->flags & SLOT_IS_GOING_AWAY) return -ENODEV; - mutex_lock(&slot->crit_sect); - /* unconfigure all functions */ disable_slot(slot); @@ -1173,7 +989,6 @@ static int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot) break; } - mutex_unlock(&slot->crit_sect); return 0; } @@ -1181,9 +996,15 @@ int acpiphp_disable_slot(struct acpiphp_slot *slot) { int ret; + /* + * Acquire acpi_scan_lock to ensure that the execution of _EJ0 in + * acpiphp_disable_and_eject_slot() will be synchronized properly. + */ + acpi_scan_lock_acquire(); pci_lock_rescan_remove(); ret = acpiphp_disable_and_eject_slot(slot); pci_unlock_rescan_remove(); + acpi_scan_lock_release(); return ret; } diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 25f0bc659164..d911e0c1f359 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -616,15 +616,11 @@ static int pci_pm_prepare(struct device *dev) int error = 0; /* - * PCI devices suspended at run time need to be resumed at this - * point, because in general it is necessary to reconfigure them for - * system suspend. Namely, if the device is supposed to wake up the - * system from the sleep state, we may need to reconfigure it for this - * purpose. In turn, if the device is not supposed to wake up the - * system from the sleep state, we'll have to prevent it from signaling - * wake-up. + * Devices having power.ignore_children set may still be necessary for + * suspending their children in the next phase of device suspend. */ - pm_runtime_resume(dev); + if (dev->power.ignore_children) + pm_runtime_resume(dev); if (drv && drv->pm && drv->pm->prepare) error = drv->pm->prepare(dev); @@ -654,6 +650,16 @@ static int pci_pm_suspend(struct device *dev) goto Fixup; } + /* + * PCI devices suspended at run time need to be resumed at this point, + * because in general it is necessary to reconfigure them for system + * suspend. Namely, if the device is supposed to wake up the system + * from the sleep state, we may need to reconfigure it for this purpose. + * In turn, if the device is not supposed to wake up the system from the + * sleep state, we'll have to prevent it from signaling wake-up. + */ + pm_runtime_resume(dev); + pci_dev->state_saved = false; if (pm->suspend) { pci_power_t prev = pci_dev->current_state; @@ -808,6 +814,14 @@ static int pci_pm_freeze(struct device *dev) return 0; } + /* + * This used to be done in pci_pm_prepare() for all devices and some + * drivers may depend on it, so do it here. Ideally, runtime-suspended + * devices should not be touched during freeze/thaw transitions, + * however. + */ + pm_runtime_resume(dev); + pci_dev->state_saved = false; if (pm->freeze) { int error; @@ -915,6 +929,9 @@ static int pci_pm_poweroff(struct device *dev) goto Fixup; } + /* The reason to do that is the same as in pci_pm_suspend(). */ + pm_runtime_resume(dev); + pci_dev->state_saved = false; if (pm->poweroff) { int error; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 6b05f6134b68..fdbc294821e6 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1192,6 +1192,9 @@ static int do_pci_enable_device(struct pci_dev *dev, int bars) return err; pci_fixup_device(pci_fixup_enable, dev); + if (dev->msi_enabled || dev->msix_enabled) + return 0; + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); if (pin) { pci_read_config_word(dev, PCI_COMMAND, &cmd); diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 5ae65c11d544..5f67843c7fb7 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -27,8 +27,6 @@ config ACER_WMI depends on ACPI_WMI select INPUT_SPARSEKMAP # Acer WMI depends on ACPI_VIDEO when ACPI is enabled - # but for select to work, need to select ACPI_VIDEO's dependencies, ick - select VIDEO_OUTPUT_CONTROL if ACPI select ACPI_VIDEO if ACPI ---help--- This is a driver for newer Acer (and Wistron) laptops. It adds diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index be02bcc346d3..e6f336270c21 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c @@ -66,7 +66,6 @@ #include <linux/backlight.h> #include <linux/input.h> #include <linux/kfifo.h> -#include <linux/video_output.h> #include <linux/platform_device.h> #include <linux/slab.h> #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 167f3d00c916..66977ebf13b3 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -183,9 +183,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, struct resource r = {0}; int i, flags; - if (acpi_dev_resource_memory(res, &r) - || acpi_dev_resource_io(res, &r) - || acpi_dev_resource_address_space(res, &r) + if (acpi_dev_resource_address_space(res, &r) || acpi_dev_resource_ext_address_space(res, &r)) { pnp_add_resource(dev, &r); return AE_OK; @@ -217,6 +215,17 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, } switch (res->type) { + case ACPI_RESOURCE_TYPE_MEMORY24: + case ACPI_RESOURCE_TYPE_MEMORY32: + case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: + if (acpi_dev_resource_memory(res, &r)) + pnp_add_resource(dev, &r); + break; + case ACPI_RESOURCE_TYPE_IO: + case ACPI_RESOURCE_TYPE_FIXED_IO: + if (acpi_dev_resource_io(res, &r)) + pnp_add_resource(dev, &r); + break; case ACPI_RESOURCE_TYPE_DMA: dma = &res->data.dma; if (dma->channel_count > 0 && dma->channels[0] != (u8) -1) diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index bacddd102ae9..01712cbfd92e 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c @@ -385,7 +385,7 @@ int pnp_check_irq(struct pnp_dev *dev, struct resource *res) * device is active because it itself may be in use */ if (!dev->active) { if (request_irq(*irq, pnp_test_handler, - IRQF_DISABLED | IRQF_PROBE_SHARED, "pnp", NULL)) + IRQF_PROBE_SHARED, "pnp", NULL)) return 0; free_irq(*irq, NULL); } diff --git a/drivers/powercap/intel_rapl.c b/drivers/powercap/intel_rapl.c index 3c6768378a94..61b51e17d932 100644 --- a/drivers/powercap/intel_rapl.c +++ b/drivers/powercap/intel_rapl.c @@ -834,7 +834,7 @@ static int rapl_write_data_raw(struct rapl_domain *rd, } static const struct x86_cpu_id energy_unit_quirk_ids[] = { - { X86_VENDOR_INTEL, 6, 0x37},/* VLV */ + { X86_VENDOR_INTEL, 6, 0x37},/* Valleyview */ {} }; @@ -947,11 +947,11 @@ static void package_power_limit_irq_restore(int package_id) } static const struct x86_cpu_id rapl_ids[] = { - { X86_VENDOR_INTEL, 6, 0x2a},/* SNB */ - { X86_VENDOR_INTEL, 6, 0x2d},/* SNB EP */ - { X86_VENDOR_INTEL, 6, 0x37},/* VLV */ - { X86_VENDOR_INTEL, 6, 0x3a},/* IVB */ - { X86_VENDOR_INTEL, 6, 0x45},/* HSW */ + { X86_VENDOR_INTEL, 6, 0x2a},/* Sandy Bridge */ + { X86_VENDOR_INTEL, 6, 0x2d},/* Sandy Bridge EP */ + { X86_VENDOR_INTEL, 6, 0x37},/* Valleyview */ + { X86_VENDOR_INTEL, 6, 0x3a},/* Ivy Bridge */ + { X86_VENDOR_INTEL, 6, 0x45},/* Haswell */ /* TODO: Add more CPU IDs after testing */ {} }; @@ -1147,6 +1147,11 @@ static int rapl_check_domain(int cpu, int domain) if (rdmsrl_safe_on_cpu(cpu, msr, &val1)) return -ENODEV; + /* PP1/uncore/graphics domain may not be active at the time of + * driver loading. So skip further checks. + */ + if (domain == RAPL_DOMAIN_PP1) + return 0; /* energy counters roll slowly on some domains */ while (++retry < 10) { usleep_range(10000, 15000); diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 1f375051483a..5642a9b250c2 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -325,7 +325,7 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc) if (!abrt_task->sc || abrt_task->state == ISCSI_TASK_FREE) continue; - if (abrt_task->sc->device->lun != abrt_task->sc->device->lun) + if (sc->device->lun != abrt_task->sc->device->lun) continue; /* Invalidate WRB Posted for this Task */ diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h index 4911310a38f5..22a9bb1abae1 100644 --- a/drivers/scsi/isci/host.h +++ b/drivers/scsi/isci/host.h @@ -311,9 +311,8 @@ static inline struct Scsi_Host *to_shost(struct isci_host *ihost) } #define for_each_isci_host(id, ihost, pdev) \ - for (id = 0, ihost = to_pci_info(pdev)->hosts[id]; \ - id < ARRAY_SIZE(to_pci_info(pdev)->hosts) && ihost; \ - ihost = to_pci_info(pdev)->hosts[++id]) + for (id = 0; id < SCI_MAX_CONTROLLERS && \ + (ihost = to_pci_info(pdev)->hosts[id]); id++) static inline void wait_for_start(struct isci_host *ihost) { diff --git a/drivers/scsi/isci/port_config.c b/drivers/scsi/isci/port_config.c index 85c77f6b802b..ac879745ef80 100644 --- a/drivers/scsi/isci/port_config.c +++ b/drivers/scsi/isci/port_config.c @@ -615,13 +615,6 @@ static void sci_apc_agent_link_up(struct isci_host *ihost, SCIC_SDS_APC_WAIT_LINK_UP_NOTIFICATION); } else { /* the phy is already the part of the port */ - u32 port_state = iport->sm.current_state_id; - - /* if the PORT'S state is resetting then the link up is from - * port hard reset in this case, we need to tell the port - * that link up is recieved - */ - BUG_ON(port_state != SCI_PORT_RESETTING); port_agent->phy_ready_mask |= 1 << phy_index; sci_port_link_up(iport, iphy); } diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c index 0d30ca849e8f..5d6fda72d659 100644 --- a/drivers/scsi/isci/task.c +++ b/drivers/scsi/isci/task.c @@ -801,7 +801,7 @@ int isci_task_I_T_nexus_reset(struct domain_device *dev) /* XXX: need to cleanup any ireqs targeting this * domain_device */ - ret = TMF_RESP_FUNC_COMPLETE; + ret = -ENODEV; goto out; } diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index e1fe95ef23e1..266724b6b899 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2996,8 +2996,7 @@ struct qla_hw_data { IS_QLA82XX(ha) || IS_QLA83XX(ha) || \ IS_QLA8044(ha)) #define IS_MSIX_NACK_CAPABLE(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha)) -#define IS_NOPOLLING_TYPE(ha) ((IS_QLA25XX(ha) || IS_QLA81XX(ha) || \ - IS_QLA83XX(ha)) && (ha)->flags.msix_enabled) +#define IS_NOPOLLING_TYPE(ha) (IS_QLA81XX(ha) && (ha)->flags.msix_enabled) #define IS_FAC_REQUIRED(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha)) #define IS_NOCACHE_VPD_TYPE(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha)) #define IS_ALOGIO_CAPABLE(ha) (IS_QLA23XX(ha) || IS_FWI2_CAPABLE(ha)) diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 9bc86b9e86b1..0a1dcb43d18b 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -2880,6 +2880,7 @@ static int qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) { #define MIN_MSIX_COUNT 2 +#define ATIO_VECTOR 2 int i, ret; struct msix_entry *entries; struct qla_msix_entry *qentry; @@ -2936,34 +2937,47 @@ msix_failed: } /* Enable MSI-X vectors for the base queue */ - for (i = 0; i < ha->msix_count; i++) { + for (i = 0; i < 2; i++) { qentry = &ha->msix_entries[i]; - if (QLA_TGT_MODE_ENABLED() && IS_ATIO_MSIX_CAPABLE(ha)) { - ret = request_irq(qentry->vector, - qla83xx_msix_entries[i].handler, - 0, qla83xx_msix_entries[i].name, rsp); - } else if (IS_P3P_TYPE(ha)) { + if (IS_P3P_TYPE(ha)) ret = request_irq(qentry->vector, qla82xx_msix_entries[i].handler, 0, qla82xx_msix_entries[i].name, rsp); - } else { + else ret = request_irq(qentry->vector, msix_entries[i].handler, 0, msix_entries[i].name, rsp); - } - if (ret) { - ql_log(ql_log_fatal, vha, 0x00cb, - "MSI-X: unable to register handler -- %x/%d.\n", - qentry->vector, ret); - qla24xx_disable_msix(ha); - ha->mqenable = 0; - goto msix_out; - } + if (ret) + goto msix_register_fail; qentry->have_irq = 1; qentry->rsp = rsp; rsp->msix = qentry; } + /* + * If target mode is enable, also request the vector for the ATIO + * queue. + */ + if (QLA_TGT_MODE_ENABLED() && IS_ATIO_MSIX_CAPABLE(ha)) { + qentry = &ha->msix_entries[ATIO_VECTOR]; + ret = request_irq(qentry->vector, + qla83xx_msix_entries[ATIO_VECTOR].handler, + 0, qla83xx_msix_entries[ATIO_VECTOR].name, rsp); + qentry->have_irq = 1; + qentry->rsp = rsp; + rsp->msix = qentry; + } + +msix_register_fail: + if (ret) { + ql_log(ql_log_fatal, vha, 0x00cb, + "MSI-X: unable to register handler -- %x/%d.\n", + qentry->vector, ret); + qla24xx_disable_msix(ha); + ha->mqenable = 0; + goto msix_out; + } + /* Enable MSI-X vector for response queue update for queue 0 */ if (IS_QLA83XX(ha)) { if (ha->msixbase && ha->mqiobase && diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 17d740427240..9969fa1ef7c4 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -1419,6 +1419,9 @@ static void storvsc_device_destroy(struct scsi_device *sdevice) { struct stor_mem_pools *memp = sdevice->hostdata; + if (!memp) + return; + mempool_destroy(memp->request_mempool); kmem_cache_destroy(memp->request_pool); kfree(memp); diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index dade5b7699bc..97a8f3a12a7b 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -27,12 +27,6 @@ config VGASTATE tristate default n -config VIDEO_OUTPUT_CONTROL - tristate "Lowlevel video output switch controls" - help - This framework adds support for low-level control of the video - output switch. - config VIDEOMODE_HELPERS bool diff --git a/drivers/video/Makefile b/drivers/video/Makefile index ae17ddf49a00..08d6a4ab3ace 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -172,8 +172,6 @@ obj-$(CONFIG_FB_SIMPLE) += simplefb.o # the test framebuffer is last obj-$(CONFIG_FB_VIRTUAL) += vfb.o -#video output switch sysfs driver -obj-$(CONFIG_VIDEO_OUTPUT_CONTROL) += output.o obj-$(CONFIG_VIDEOMODE_HELPERS) += display_timing.o videomode.o ifeq ($(CONFIG_OF),y) obj-$(CONFIG_VIDEOMODE_HELPERS) += of_display_timing.o of_videomode.o diff --git a/drivers/video/output.c b/drivers/video/output.c deleted file mode 100644 index 1446c49fe6af..000000000000 --- a/drivers/video/output.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * output.c - Display Output Switch driver - * - * Copyright (C) 2006 Luming Yu <luming.yu@intel.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 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ -#include <linux/module.h> -#include <linux/video_output.h> -#include <linux/slab.h> -#include <linux/err.h> -#include <linux/ctype.h> - - -MODULE_DESCRIPTION("Display Output Switcher Lowlevel Control Abstraction"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Luming Yu <luming.yu@intel.com>"); - -static ssize_t state_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - ssize_t ret_size = 0; - struct output_device *od = to_output_device(dev); - if (od->props) - ret_size = sprintf(buf,"%.8x\n",od->props->get_status(od)); - return ret_size; -} - -static ssize_t state_store(struct device *dev, struct device_attribute *attr, - const char *buf,size_t count) -{ - char *endp; - struct output_device *od = to_output_device(dev); - int request_state = simple_strtoul(buf,&endp,0); - size_t size = endp - buf; - - if (isspace(*endp)) - size++; - if (size != count) - return -EINVAL; - - if (od->props) { - od->request_state = request_state; - od->props->set_state(od); - } - return count; -} -static DEVICE_ATTR_RW(state); - -static void video_output_release(struct device *dev) -{ - struct output_device *od = to_output_device(dev); - kfree(od); -} - -static struct attribute *video_output_attrs[] = { - &dev_attr_state.attr, - NULL, -}; -ATTRIBUTE_GROUPS(video_output); - -static struct class video_output_class = { - .name = "video_output", - .dev_release = video_output_release, - .dev_groups = video_output_groups, -}; - -struct output_device *video_output_register(const char *name, - struct device *dev, - void *devdata, - struct output_properties *op) -{ - struct output_device *new_dev; - int ret_code = 0; - - new_dev = kzalloc(sizeof(struct output_device),GFP_KERNEL); - if (!new_dev) { - ret_code = -ENOMEM; - goto error_return; - } - new_dev->props = op; - new_dev->dev.class = &video_output_class; - new_dev->dev.parent = dev; - dev_set_name(&new_dev->dev, "%s", name); - dev_set_drvdata(&new_dev->dev, devdata); - ret_code = device_register(&new_dev->dev); - if (ret_code) { - kfree(new_dev); - goto error_return; - } - return new_dev; - -error_return: - return ERR_PTR(ret_code); -} -EXPORT_SYMBOL(video_output_register); - -void video_output_unregister(struct output_device *dev) -{ - if (!dev) - return; - device_unregister(&dev->dev); -} -EXPORT_SYMBOL(video_output_unregister); - -static void __exit video_output_class_exit(void) -{ - class_unregister(&video_output_class); -} - -static int __init video_output_class_init(void) -{ - return class_register(&video_output_class); -} - -postcore_initcall(video_output_class_init); -module_exit(video_output_class_exit); diff --git a/drivers/xen/xen-acpi-cpuhotplug.c b/drivers/xen/xen-acpi-cpuhotplug.c index 80875fb770ed..3e62ee4b3b66 100644 --- a/drivers/xen/xen-acpi-cpuhotplug.c +++ b/drivers/xen/xen-acpi-cpuhotplug.c @@ -313,7 +313,7 @@ static void acpi_processor_hotplug_notify(acpi_handle handle, goto out; } - (void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL); + (void) acpi_evaluate_ost(handle, event, ost_code, NULL); out: acpi_scan_lock_release(); diff --git a/drivers/xen/xen-acpi-memhotplug.c b/drivers/xen/xen-acpi-memhotplug.c index f8d18626969a..34e40b733f9a 100644 --- a/drivers/xen/xen-acpi-memhotplug.c +++ b/drivers/xen/xen-acpi-memhotplug.c @@ -285,7 +285,7 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data) return; } - (void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL); + (void) acpi_evaluate_ost(handle, event, ost_code, NULL); return; } diff --git a/drivers/xen/xen-acpi-pad.c b/drivers/xen/xen-acpi-pad.c index 40c4bc06b5fa..f83b754505f8 100644 --- a/drivers/xen/xen-acpi-pad.c +++ b/drivers/xen/xen-acpi-pad.c @@ -77,27 +77,14 @@ static int acpi_pad_pur(acpi_handle handle) return num; } -/* Notify firmware how many CPUs are idle */ -static void acpi_pad_ost(acpi_handle handle, int stat, - uint32_t idle_nums) -{ - union acpi_object params[3] = { - {.type = ACPI_TYPE_INTEGER,}, - {.type = ACPI_TYPE_INTEGER,}, - {.type = ACPI_TYPE_BUFFER,}, - }; - struct acpi_object_list arg_list = {3, params}; - - params[0].integer.value = ACPI_PROCESSOR_AGGREGATOR_NOTIFY; - params[1].integer.value = stat; - params[2].buffer.length = 4; - params[2].buffer.pointer = (void *)&idle_nums; - acpi_evaluate_object(handle, "_OST", &arg_list, NULL); -} - static void acpi_pad_handle_notify(acpi_handle handle) { int idle_nums; + struct acpi_buffer param = { + .length = 4, + .pointer = (void *)&idle_nums, + }; + mutex_lock(&xen_cpu_lock); idle_nums = acpi_pad_pur(handle); @@ -109,7 +96,8 @@ static void acpi_pad_handle_notify(acpi_handle handle) idle_nums = xen_acpi_pad_idle_cpus(idle_nums) ?: xen_acpi_pad_idle_cpus_num(); if (idle_nums >= 0) - acpi_pad_ost(handle, 0, idle_nums); + acpi_evaluate_ost(handle, ACPI_PROCESSOR_AGGREGATOR_NOTIFY, + 0, ¶m); mutex_unlock(&xen_cpu_lock); } |