diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/acpi/acpi_platform.c | 2 | ||||
-rw-r--r-- | drivers/acpi/acpica/achware.h | 2 | ||||
-rw-r--r-- | drivers/acpi/acpica/aclocal.h | 4 | ||||
-rw-r--r-- | drivers/acpi/acpica/actables.h | 2 | ||||
-rw-r--r-- | drivers/acpi/acpica/amlresrc.h | 34 | ||||
-rw-r--r-- | drivers/acpi/acpica/evgpe.c | 23 | ||||
-rw-r--r-- | drivers/acpi/acpica/evgpeinit.c | 1 | ||||
-rw-r--r-- | drivers/acpi/acpica/evxface.c | 27 | ||||
-rw-r--r-- | drivers/acpi/acpica/evxfevnt.c | 40 | ||||
-rw-r--r-- | drivers/acpi/acpica/evxfgpe.c | 12 | ||||
-rw-r--r-- | drivers/acpi/acpica/hwgpe.c | 9 | ||||
-rw-r--r-- | drivers/acpi/acpica/tbxfroot.c | 33 | ||||
-rw-r--r-- | drivers/acpi/device_pm.c | 2 | ||||
-rw-r--r-- | drivers/acpi/ec.c | 107 | ||||
-rw-r--r-- | drivers/acpi/scan.c | 2 | ||||
-rw-r--r-- | drivers/acpi/sysfs.c | 4 | ||||
-rw-r--r-- | drivers/cpuidle/cpuidle-powernv.c | 27 | ||||
-rw-r--r-- | drivers/pci/pcie/pme.c | 6 |
18 files changed, 241 insertions, 96 deletions
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index 2bf9082f7523..8d099e636b15 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -16,6 +16,7 @@ #include <linux/err.h> #include <linux/kernel.h> #include <linux/module.h> +#include <linux/dma-mapping.h> #include <linux/platform_device.h> #include "internal.h" @@ -102,6 +103,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev) pdevinfo.res = resources; pdevinfo.num_res = count; pdevinfo.acpi_node.companion = adev; + pdevinfo.dma_mask = DMA_BIT_MASK(32); pdev = platform_device_register_full(&pdevinfo); if (IS_ERR(pdev)) dev_err(&adev->dev, "platform device creation failed: %ld\n", diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index 2ad2351a9833..c318d3e27893 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h @@ -127,7 +127,7 @@ acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, acpi_status acpi_hw_get_gpe_status(struct acpi_gpe_event_info *gpe_event_info, - acpi_event_status * event_status); + acpi_event_status *event_status); acpi_status acpi_hw_disable_all_gpes(void); diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 2747279fbe3c..c00e7e41ad75 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -413,8 +413,8 @@ struct acpi_gpe_handler_info { acpi_gpe_handler address; /* Address of handler, if any */ void *context; /* Context to be passed to handler */ struct acpi_namespace_node *method_node; /* Method node for this GPE level (saved) */ - u8 original_flags; /* Original (pre-handler) GPE info */ - u8 originally_enabled; /* True if GPE was originally enabled */ + u8 original_flags; /* Original (pre-handler) GPE info */ + u8 originally_enabled; /* True if GPE was originally enabled */ }; /* Notify info for implicit notify, multiple device objects */ diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h index f14882788eee..1afe46e44dac 100644 --- a/drivers/acpi/acpica/actables.h +++ b/drivers/acpi/acpica/actables.h @@ -49,6 +49,8 @@ acpi_status acpi_allocate_root_table(u32 initial_table_count); /* * tbxfroot - Root pointer utilities */ +u32 acpi_tb_get_rsdp_length(struct acpi_table_rsdp *rsdp); + acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp); u8 *acpi_tb_scan_memory_for_rsdp(u8 *start_address, u32 length); diff --git a/drivers/acpi/acpica/amlresrc.h b/drivers/acpi/acpica/amlresrc.h index f3f834408441..3a0beeb86ba5 100644 --- a/drivers/acpi/acpica/amlresrc.h +++ b/drivers/acpi/acpica/amlresrc.h @@ -117,6 +117,12 @@ struct asl_resource_node { struct asl_resource_node *next; }; +struct asl_resource_info { + union acpi_parse_object *descriptor_type_op; /* Resource descriptor parse node */ + union acpi_parse_object *mapping_op; /* Used for mapfile support */ + u32 current_byte_offset; /* Offset in resource template */ +}; + /* Macros used to generate AML resource length fields */ #define ACPI_AML_SIZE_LARGE(r) (sizeof (r) - sizeof (struct aml_resource_large_header)) @@ -449,4 +455,32 @@ union aml_resource { u8 byte_item; }; +/* Interfaces used by both the disassembler and compiler */ + +void +mp_save_gpio_info(union acpi_parse_object *op, + union aml_resource *resource, + u32 pin_count, u16 *pin_list, char *device_name); + +void +mp_save_serial_info(union acpi_parse_object *op, + union aml_resource *resource, char *device_name); + +char *mp_get_hid_from_parse_tree(struct acpi_namespace_node *hid_node); + +char *mp_get_hid_via_namestring(char *device_name); + +char *mp_get_connection_info(union acpi_parse_object *op, + u32 pin_index, + struct acpi_namespace_node **target_node, + char **target_name); + +char *mp_get_parent_device_hid(union acpi_parse_object *op, + struct acpi_namespace_node **target_node, + char **parent_device_name); + +char *mp_get_ddn_value(char *device_name); + +char *mp_get_hid_value(struct acpi_namespace_node *device_node); + #endif diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index e4ba4dec86af..2095dfb72bcb 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -100,13 +100,14 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info) * * FUNCTION: acpi_ev_enable_gpe * - * PARAMETERS: gpe_event_info - GPE to enable + * PARAMETERS: gpe_event_info - GPE to enable * * RETURN: Status * * DESCRIPTION: Clear a GPE of stale events and enable it. * ******************************************************************************/ + acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) { acpi_status status; @@ -125,6 +126,7 @@ acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) } /* Clear the GPE (of stale events) */ + status = acpi_hw_clear_gpe(gpe_event_info); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); @@ -136,7 +138,6 @@ acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) return_ACPI_STATUS(status); } - /******************************************************************************* * * FUNCTION: acpi_ev_add_gpe_reference @@ -212,7 +213,7 @@ acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_info) if (ACPI_SUCCESS(status)) { status = acpi_hw_low_set_gpe(gpe_event_info, - ACPI_GPE_DISABLE); + ACPI_GPE_DISABLE); } if (ACPI_FAILURE(status)) { @@ -334,7 +335,7 @@ struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, * ******************************************************************************/ -u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) +u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list) { acpi_status status; struct acpi_gpe_block_info *gpe_block; @@ -427,7 +428,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) /* Check if there is anything active at all in this register */ - enabled_status_byte = (u8) (status_reg & enable_reg); + enabled_status_byte = (u8)(status_reg & enable_reg); if (!enabled_status_byte) { /* No active GPEs in this register, move on */ @@ -450,7 +451,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) acpi_ev_gpe_dispatch(gpe_block-> node, &gpe_block-> - event_info[((acpi_size) i * ACPI_GPE_REGISTER_WIDTH) + j], j + gpe_register_info->base_gpe_number); + event_info[((acpi_size) i * ACPI_GPE_REGISTER_WIDTH) + j], j + gpe_register_info->base_gpe_number); } } } @@ -636,7 +637,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_enable_gpe(void *context) * ******************************************************************************/ -acpi_status acpi_ev_finish_gpe(struct acpi_gpe_event_info *gpe_event_info) +acpi_status acpi_ev_finish_gpe(struct acpi_gpe_event_info * gpe_event_info) { acpi_status status; @@ -666,9 +667,9 @@ acpi_status acpi_ev_finish_gpe(struct acpi_gpe_event_info *gpe_event_info) * * FUNCTION: acpi_ev_gpe_dispatch * - * PARAMETERS: gpe_device - Device node. NULL for GPE0/GPE1 - * gpe_event_info - Info for this GPE - * gpe_number - Number relative to the parent GPE block + * PARAMETERS: gpe_device - Device node. NULL for GPE0/GPE1 + * gpe_event_info - Info for this GPE + * gpe_number - Number relative to the parent GPE block * * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED * @@ -681,7 +682,7 @@ acpi_status acpi_ev_finish_gpe(struct acpi_gpe_event_info *gpe_event_info) u32 acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, - struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) + struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) { acpi_status status; u32 return_value; diff --git a/drivers/acpi/acpica/evgpeinit.c b/drivers/acpi/acpica/evgpeinit.c index 49fc7effd961..7be928379879 100644 --- a/drivers/acpi/acpica/evgpeinit.c +++ b/drivers/acpi/acpica/evgpeinit.c @@ -424,6 +424,7 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, } /* Disable the GPE in case it's been enabled already. */ + (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); /* diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index 11e5803b8b41..55a58f3ec8df 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c @@ -786,18 +786,26 @@ acpi_install_gpe_handler(acpi_handle gpe_device, handler->method_node = gpe_event_info->dispatch.method_node; handler->original_flags = (u8)(gpe_event_info->flags & (ACPI_GPE_XRUPT_TYPE_MASK | - ACPI_GPE_DISPATCH_MASK)); + ACPI_GPE_DISPATCH_MASK)); /* * If the GPE is associated with a method, it may have been enabled * automatically during initialization, in which case it has to be * disabled now to avoid spurious execution of the handler. */ - - if ((handler->original_flags & ACPI_GPE_DISPATCH_METHOD) - && gpe_event_info->runtime_count) { - handler->originally_enabled = 1; + if (((handler->original_flags & ACPI_GPE_DISPATCH_METHOD) || + (handler->original_flags & ACPI_GPE_DISPATCH_NOTIFY)) && + gpe_event_info->runtime_count) { + handler->originally_enabled = TRUE; (void)acpi_ev_remove_gpe_reference(gpe_event_info); + + /* Sanity check of original type against new type */ + + if (type != + (u32)(gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK)) { + ACPI_WARNING((AE_INFO, + "GPE type mismatch (level/edge)")); + } } /* Install the handler */ @@ -808,7 +816,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device, gpe_event_info->flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); - gpe_event_info->flags |= (u8) (type | ACPI_GPE_DISPATCH_HANDLER); + gpe_event_info->flags |= (u8)(type | ACPI_GPE_DISPATCH_HANDLER); acpi_os_release_lock(acpi_gbl_gpe_lock, flags); @@ -893,7 +901,7 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, gpe_event_info->dispatch.method_node = handler->method_node; gpe_event_info->flags &= - ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); + ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); gpe_event_info->flags |= handler->original_flags; /* @@ -901,7 +909,8 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, * enabled, it should be enabled at this point to restore the * post-initialization configuration. */ - if ((handler->original_flags & ACPI_GPE_DISPATCH_METHOD) && + if (((handler->original_flags & ACPI_GPE_DISPATCH_METHOD) || + (handler->original_flags & ACPI_GPE_DISPATCH_NOTIFY)) && handler->originally_enabled) { (void)acpi_ev_add_gpe_reference(gpe_event_info); } @@ -946,7 +955,7 @@ ACPI_EXPORT_SYMBOL(acpi_remove_gpe_handler) * handle is returned. * ******************************************************************************/ -acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle) +acpi_status acpi_acquire_global_lock(u16 timeout, u32 *handle) { acpi_status status; diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index e286640ad4ff..bb8cbf5961bf 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c @@ -324,8 +324,9 @@ ACPI_EXPORT_SYMBOL(acpi_clear_event) ******************************************************************************/ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) { - acpi_status status = AE_OK; - u32 value; + acpi_status status; + acpi_event_status local_event_status = 0; + u32 in_byte; ACPI_FUNCTION_TRACE(acpi_get_event_status); @@ -339,29 +340,40 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) return_ACPI_STATUS(AE_BAD_PARAMETER); } - /* Get the status of the requested fixed event */ + /* Fixed event currently can be dispatched? */ + + if (acpi_gbl_fixed_event_handlers[event].handler) { + local_event_status |= ACPI_EVENT_FLAG_HAS_HANDLER; + } + + /* Fixed event currently enabled? */ status = acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. - enable_register_id, &value); - if (ACPI_FAILURE(status)) + enable_register_id, &in_byte); + if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); + } - *event_status = value; + if (in_byte) { + local_event_status |= ACPI_EVENT_FLAG_ENABLED; + } + + /* Fixed event currently active? */ status = acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. - status_register_id, &value); - if (ACPI_FAILURE(status)) + status_register_id, &in_byte); + if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); + } - if (value) - *event_status |= ACPI_EVENT_FLAG_SET; - - if (acpi_gbl_fixed_event_handlers[event].handler) - *event_status |= ACPI_EVENT_FLAG_HANDLE; + if (in_byte) { + local_event_status |= ACPI_EVENT_FLAG_SET; + } - return_ACPI_STATUS(status); + (*event_status) = local_event_status; + return_ACPI_STATUS(AE_OK); } ACPI_EXPORT_SYMBOL(acpi_get_event_status) diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c index 56710a03c9b0..e889a5304abd 100644 --- a/drivers/acpi/acpica/evxfgpe.c +++ b/drivers/acpi/acpica/evxfgpe.c @@ -106,8 +106,8 @@ ACPI_EXPORT_SYMBOL(acpi_update_all_gpes) * * FUNCTION: acpi_enable_gpe * - * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 - * gpe_number - GPE level within the GPE block + * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 + * gpe_number - GPE level within the GPE block * * RETURN: Status * @@ -115,7 +115,6 @@ ACPI_EXPORT_SYMBOL(acpi_update_all_gpes) * hardware-enabled. * ******************************************************************************/ - acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) { acpi_status status = AE_BAD_PARAMETER; @@ -490,8 +489,8 @@ ACPI_EXPORT_SYMBOL(acpi_clear_gpe) * * FUNCTION: acpi_get_gpe_status * - * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 - * gpe_number - GPE level within the GPE block + * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 + * gpe_number - GPE level within the GPE block * event_status - Where the current status of the event * will be returned * @@ -524,9 +523,6 @@ acpi_get_gpe_status(acpi_handle gpe_device, status = acpi_hw_get_gpe_status(gpe_event_info, event_status); - if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) - *event_status |= ACPI_EVENT_FLAG_HANDLE; - unlock_and_exit: acpi_os_release_lock(acpi_gbl_gpe_lock, flags); return_ACPI_STATUS(status); diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index ea62d40fd161..48ac7b7b59cd 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c @@ -202,7 +202,7 @@ acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) acpi_status acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, - acpi_event_status * event_status) + acpi_event_status *event_status) { u32 in_byte; u32 register_bit; @@ -216,6 +216,13 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, return (AE_BAD_PARAMETER); } + /* GPE currently handled? */ + + if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) != + ACPI_GPE_DISPATCH_NONE) { + local_event_status |= ACPI_EVENT_FLAG_HAS_HANDLER; + } + /* Get the info block for the entire GPE register */ gpe_register_info = gpe_event_info->register_info; diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c index 65ab8fed3d5e..43a54af2b548 100644 --- a/drivers/acpi/acpica/tbxfroot.c +++ b/drivers/acpi/acpica/tbxfroot.c @@ -50,6 +50,36 @@ ACPI_MODULE_NAME("tbxfroot") /******************************************************************************* * + * FUNCTION: acpi_tb_get_rsdp_length + * + * PARAMETERS: rsdp - Pointer to RSDP + * + * RETURN: Table length + * + * DESCRIPTION: Get the length of the RSDP + * + ******************************************************************************/ +u32 acpi_tb_get_rsdp_length(struct acpi_table_rsdp *rsdp) +{ + + if (!ACPI_VALIDATE_RSDP_SIG(rsdp->signature)) { + + /* BAD Signature */ + + return (0); + } + + /* "Length" field is available if table version >= 2 */ + + if (rsdp->revision >= 2) { + return (rsdp->length); + } else { + return (ACPI_RSDP_CHECKSUM_LENGTH); + } +} + +/******************************************************************************* + * * FUNCTION: acpi_tb_validate_rsdp * * PARAMETERS: rsdp - Pointer to unvalidated RSDP @@ -59,7 +89,8 @@ ACPI_MODULE_NAME("tbxfroot") * DESCRIPTION: Validate the RSDP (ptr) * ******************************************************************************/ -acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) + +acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp * rsdp) { /* diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index bea6896be122..85bb3d80a11c 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -710,7 +710,7 @@ int acpi_pm_device_run_wake(struct device *phys_dev, bool enable) return -ENODEV; } - return acpi_device_wakeup(adev, enable, ACPI_STATE_S0); + return acpi_device_wakeup(adev, ACPI_STATE_S0, enable); } EXPORT_SYMBOL(acpi_pm_device_run_wake); #endif /* CONFIG_PM_RUNTIME */ diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index cb6066c809ea..3d304ff7f095 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -128,12 +128,13 @@ static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */ static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */ /* -------------------------------------------------------------------------- - Transaction Management - -------------------------------------------------------------------------- */ + * Transaction Management + * -------------------------------------------------------------------------- */ static inline u8 acpi_ec_read_status(struct acpi_ec *ec) { u8 x = inb(ec->command_addr); + pr_debug("EC_SC(R) = 0x%2.2x " "SCI_EVT=%d BURST=%d CMD=%d IBF=%d OBF=%d\n", x, @@ -148,6 +149,7 @@ static inline u8 acpi_ec_read_status(struct acpi_ec *ec) static inline u8 acpi_ec_read_data(struct acpi_ec *ec) { u8 x = inb(ec->data_addr); + pr_debug("EC_DATA(R) = 0x%2.2x\n", x); return x; } @@ -164,10 +166,32 @@ static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) outb(data, ec->data_addr); } +#ifdef DEBUG +static const char *acpi_ec_cmd_string(u8 cmd) +{ + switch (cmd) { + case 0x80: + return "RD_EC"; + case 0x81: + return "WR_EC"; + case 0x82: + return "BE_EC"; + case 0x83: + return "BD_EC"; + case 0x84: + return "QR_EC"; + } + return "UNKNOWN"; +} +#else +#define acpi_ec_cmd_string(cmd) "UNDEF" +#endif + static int ec_transaction_completed(struct acpi_ec *ec) { unsigned long flags; int ret = 0; + spin_lock_irqsave(&ec->lock, flags); if (ec->curr && (ec->curr->flags & ACPI_EC_COMMAND_COMPLETE)) ret = 1; @@ -181,7 +205,8 @@ static bool advance_transaction(struct acpi_ec *ec) u8 status; bool wakeup = false; - pr_debug("===== %s =====\n", in_interrupt() ? "IRQ" : "TASK"); + pr_debug("===== %s (%d) =====\n", + in_interrupt() ? "IRQ" : "TASK", smp_processor_id()); status = acpi_ec_read_status(ec); t = ec->curr; if (!t) @@ -198,7 +223,8 @@ static bool advance_transaction(struct acpi_ec *ec) if (t->rlen == t->ri) { t->flags |= ACPI_EC_COMMAND_COMPLETE; if (t->command == ACPI_EC_COMMAND_QUERY) - pr_debug("hardware QR_EC completion\n"); + pr_debug("***** Command(%s) hardware completion *****\n", + acpi_ec_cmd_string(t->command)); wakeup = true; } } else @@ -221,7 +247,8 @@ static bool advance_transaction(struct acpi_ec *ec) t->flags |= ACPI_EC_COMMAND_POLL; t->rdata[t->ri++] = 0x00; t->flags |= ACPI_EC_COMMAND_COMPLETE; - pr_debug("software QR_EC completion\n"); + pr_debug("***** Command(%s) software completion *****\n", + acpi_ec_cmd_string(t->command)); wakeup = true; } else if ((status & ACPI_EC_FLAG_IBF) == 0) { acpi_ec_write_cmd(ec, t->command); @@ -264,6 +291,7 @@ static int ec_poll(struct acpi_ec *ec) { unsigned long flags; int repeat = 5; /* number of command restarts */ + while (repeat--) { unsigned long delay = jiffies + msecs_to_jiffies(ec_delay); @@ -296,18 +324,25 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, { unsigned long tmp; int ret = 0; + if (EC_FLAGS_MSI) udelay(ACPI_EC_MSI_UDELAY); /* start transaction */ spin_lock_irqsave(&ec->lock, tmp); /* following two actions should be kept atomic */ ec->curr = t; + pr_debug("***** Command(%s) started *****\n", + acpi_ec_cmd_string(t->command)); start_transaction(ec); spin_unlock_irqrestore(&ec->lock, tmp); ret = ec_poll(ec); spin_lock_irqsave(&ec->lock, tmp); - if (ec->curr->command == ACPI_EC_COMMAND_QUERY) + if (ec->curr->command == ACPI_EC_COMMAND_QUERY) { clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); + pr_debug("***** Event stopped *****\n"); + } + pr_debug("***** Command(%s) stopped *****\n", + acpi_ec_cmd_string(t->command)); ec->curr = NULL; spin_unlock_irqrestore(&ec->lock, tmp); return ret; @@ -317,6 +352,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) { int status; u32 glk; + if (!ec || (!t) || (t->wlen && !t->wdata) || (t->rlen && !t->rdata)) return -EINVAL; if (t->rdata) @@ -333,8 +369,6 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) goto unlock; } } - pr_debug("transaction start (cmd=0x%02x, addr=0x%02x)\n", - t->command, t->wdata ? t->wdata[0] : 0); /* disable GPE during transaction if storm is detected */ if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { /* It has to be disabled, so that it doesn't trigger. */ @@ -355,7 +389,6 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) t->irq_count); set_bit(EC_FLAGS_GPE_STORM, &ec->flags); } - pr_debug("transaction end\n"); if (ec->global_lock) acpi_release_global_lock(glk); unlock: @@ -383,7 +416,7 @@ static int acpi_ec_burst_disable(struct acpi_ec *ec) acpi_ec_transaction(ec, &t) : 0; } -static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) +static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data) { int result; u8 d; @@ -419,10 +452,9 @@ int ec_read(u8 addr, u8 *val) if (!err) { *val = temp_data; return 0; - } else - return err; + } + return err; } - EXPORT_SYMBOL(ec_read); int ec_write(u8 addr, u8 val) @@ -436,22 +468,21 @@ int ec_write(u8 addr, u8 val) return err; } - EXPORT_SYMBOL(ec_write); int ec_transaction(u8 command, - const u8 * wdata, unsigned wdata_len, - u8 * rdata, unsigned rdata_len) + const u8 *wdata, unsigned wdata_len, + u8 *rdata, unsigned rdata_len) { struct transaction t = {.command = command, .wdata = wdata, .rdata = rdata, .wlen = wdata_len, .rlen = rdata_len}; + if (!first_ec) return -ENODEV; return acpi_ec_transaction(first_ec, &t); } - EXPORT_SYMBOL(ec_transaction); /* Get the handle to the EC device */ @@ -461,7 +492,6 @@ acpi_handle ec_get_handle(void) return NULL; return first_ec->handle; } - EXPORT_SYMBOL(ec_get_handle); /* @@ -525,13 +555,14 @@ void acpi_ec_unblock_transactions_early(void) clear_bit(EC_FLAGS_BLOCKED, &first_ec->flags); } -static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data) +static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 *data) { int result; u8 d; struct transaction t = {.command = ACPI_EC_COMMAND_QUERY, .wdata = NULL, .rdata = &d, .wlen = 0, .rlen = 1}; + if (!ec || !data) return -EINVAL; /* @@ -557,6 +588,7 @@ int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, { struct acpi_ec_query_handler *handler = kzalloc(sizeof(struct acpi_ec_query_handler), GFP_KERNEL); + if (!handler) return -ENOMEM; @@ -569,12 +601,12 @@ int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, mutex_unlock(&ec->mutex); return 0; } - EXPORT_SYMBOL_GPL(acpi_ec_add_query_handler); void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) { struct acpi_ec_query_handler *handler, *tmp; + mutex_lock(&ec->mutex); list_for_each_entry_safe(handler, tmp, &ec->list, node) { if (query_bit == handler->query_bit) { @@ -584,20 +616,20 @@ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) } mutex_unlock(&ec->mutex); } - EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler); static void acpi_ec_run(void *cxt) { struct acpi_ec_query_handler *handler = cxt; + if (!handler) return; - pr_debug("start query execution\n"); + pr_debug("##### Query(0x%02x) started #####\n", handler->query_bit); if (handler->func) handler->func(handler->data); else if (handler->handle) acpi_evaluate_object(handler->handle, NULL, NULL, NULL); - pr_debug("stop query execution\n"); + pr_debug("##### Query(0x%02x) stopped #####\n", handler->query_bit); kfree(handler); } @@ -620,8 +652,8 @@ static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data) if (!copy) return -ENOMEM; memcpy(copy, handler, sizeof(*copy)); - pr_debug("push query execution (0x%2x) on queue\n", - value); + pr_debug("##### Query(0x%02x) scheduled #####\n", + handler->query_bit); return acpi_os_execute((copy->func) ? OSL_NOTIFY_HANDLER : OSL_GPE_HANDLER, acpi_ec_run, copy); @@ -633,6 +665,7 @@ static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data) static void acpi_ec_gpe_query(void *ec_cxt) { struct acpi_ec *ec = ec_cxt; + if (!ec) return; mutex_lock(&ec->mutex); @@ -644,7 +677,7 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state) { if (state & ACPI_EC_FLAG_SCI) { if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) { - pr_debug("push gpe query to the queue\n"); + pr_debug("***** Event started *****\n"); return acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ec_gpe_query, ec); } @@ -667,8 +700,8 @@ static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, } /* -------------------------------------------------------------------------- - Address Space Management - -------------------------------------------------------------------------- */ + * Address Space Management + * -------------------------------------------------------------------------- */ static acpi_status acpi_ec_space_handler(u32 function, acpi_physical_address address, @@ -699,27 +732,26 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, switch (result) { case -EINVAL: return AE_BAD_PARAMETER; - break; case -ENODEV: return AE_NOT_FOUND; - break; case -ETIME: return AE_TIME; - break; default: return AE_OK; } } /* -------------------------------------------------------------------------- - Driver Interface - -------------------------------------------------------------------------- */ + * Driver Interface + * -------------------------------------------------------------------------- */ + static acpi_status ec_parse_io_ports(struct acpi_resource *resource, void *context); static struct acpi_ec *make_acpi_ec(void) { struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL); + if (!ec) return NULL; ec->flags = 1 << EC_FLAGS_QUERY_PENDING; @@ -742,9 +774,8 @@ acpi_ec_register_query_methods(acpi_handle handle, u32 level, status = acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer); - if (ACPI_SUCCESS(status) && sscanf(node_name, "_Q%x", &value) == 1) { + if (ACPI_SUCCESS(status) && sscanf(node_name, "_Q%x", &value) == 1) acpi_ec_add_query_handler(ec, value, handle, NULL, NULL); - } return AE_OK; } @@ -753,7 +784,6 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) { acpi_status status; unsigned long long tmp = 0; - struct acpi_ec *ec = context; /* clear addr values, ec_parse_io_ports depend on it */ @@ -781,6 +811,7 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) static int ec_install_handlers(struct acpi_ec *ec) { acpi_status status; + if (test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) return 0; status = acpi_install_gpe_handler(NULL, ec->gpe, @@ -1078,7 +1109,8 @@ int __init acpi_ec_ecdt_probe(void) boot_ec->data_addr = ecdt_ptr->data.address; boot_ec->gpe = ecdt_ptr->gpe; boot_ec->handle = ACPI_ROOT_OBJECT; - acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); + acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, + &boot_ec->handle); /* Don't trust ECDT, which comes from ASUSTek */ if (!EC_FLAGS_VALIDATE_ECDT) goto install; @@ -1162,6 +1194,5 @@ static void __exit acpi_ec_exit(void) { acpi_bus_unregister_driver(&acpi_ec_driver); - return; } #endif /* 0 */ diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index ae44d8654c82..f1d96e7519cb 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1470,7 +1470,7 @@ static void acpi_wakeup_gpe_init(struct acpi_device *device) if (ACPI_FAILURE(status)) return; - wakeup->flags.run_wake = !!(event_status & ACPI_EVENT_FLAG_HANDLE); + wakeup->flags.run_wake = !!(event_status & ACPI_EVENT_FLAG_HAS_HANDLER); } static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device) diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 38cb9782d4b8..13e577c80201 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -537,7 +537,7 @@ static ssize_t counter_show(struct kobject *kobj, if (result) goto end; - if (!(status & ACPI_EVENT_FLAG_HANDLE)) + if (!(status & ACPI_EVENT_FLAG_HAS_HANDLER)) size += sprintf(buf + size, " invalid"); else if (status & ACPI_EVENT_FLAG_ENABLED) size += sprintf(buf + size, " enabled"); @@ -581,7 +581,7 @@ static ssize_t counter_set(struct kobject *kobj, if (result) goto end; - if (!(status & ACPI_EVENT_FLAG_HANDLE)) { + if (!(status & ACPI_EVENT_FLAG_HAS_HANDLER)) { printk(KERN_WARNING PREFIX "Can not change Invalid GPE/Fixed Event status\n"); return -EINVAL; diff --git a/drivers/cpuidle/cpuidle-powernv.c b/drivers/cpuidle/cpuidle-powernv.c index a64be578dab2..7d3a3497dd4c 100644 --- a/drivers/cpuidle/cpuidle-powernv.c +++ b/drivers/cpuidle/cpuidle-powernv.c @@ -163,7 +163,8 @@ static int powernv_add_idle_states(void) int nr_idle_states = 1; /* Snooze */ int dt_idle_states; const __be32 *idle_state_flags; - u32 len_flags, flags; + const __be32 *idle_state_latency; + u32 len_flags, flags, latency_ns; int i; /* Currently we have snooze statically defined */ @@ -180,18 +181,32 @@ static int powernv_add_idle_states(void) return nr_idle_states; } + idle_state_latency = of_get_property(power_mgt, + "ibm,cpu-idle-state-latencies-ns", NULL); + if (!idle_state_latency) { + pr_warn("DT-PowerMgmt: missing ibm,cpu-idle-state-latencies-ns\n"); + return nr_idle_states; + } + dt_idle_states = len_flags / sizeof(u32); for (i = 0; i < dt_idle_states; i++) { flags = be32_to_cpu(idle_state_flags[i]); + + /* Cpuidle accepts exit_latency in us and we estimate + * target residency to be 10x exit_latency + */ + latency_ns = be32_to_cpu(idle_state_latency[i]); if (flags & IDLE_USE_INST_NAP) { /* Add NAP state */ strcpy(powernv_states[nr_idle_states].name, "Nap"); strcpy(powernv_states[nr_idle_states].desc, "Nap"); powernv_states[nr_idle_states].flags = CPUIDLE_FLAG_TIME_VALID; - powernv_states[nr_idle_states].exit_latency = 10; - powernv_states[nr_idle_states].target_residency = 100; + powernv_states[nr_idle_states].exit_latency = + ((unsigned int)latency_ns) / 1000; + powernv_states[nr_idle_states].target_residency = + ((unsigned int)latency_ns / 100); powernv_states[nr_idle_states].enter = &nap_loop; nr_idle_states++; } @@ -202,8 +217,10 @@ static int powernv_add_idle_states(void) strcpy(powernv_states[nr_idle_states].desc, "FastSleep"); powernv_states[nr_idle_states].flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TIMER_STOP; - powernv_states[nr_idle_states].exit_latency = 300; - powernv_states[nr_idle_states].target_residency = 1000000; + powernv_states[nr_idle_states].exit_latency = + ((unsigned int)latency_ns) / 1000; + powernv_states[nr_idle_states].target_residency = + ((unsigned int)latency_ns / 100); powernv_states[nr_idle_states].enter = &fastsleep_loop; nr_idle_states++; } diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c index a9f9c46e5022..63fc63911295 100644 --- a/drivers/pci/pcie/pme.c +++ b/drivers/pci/pcie/pme.c @@ -397,6 +397,7 @@ static int pcie_pme_suspend(struct pcie_device *srv) struct pcie_pme_service_data *data = get_service_data(srv); struct pci_dev *port = srv->port; bool wakeup; + int ret; if (device_may_wakeup(&port->dev)) { wakeup = true; @@ -407,9 +408,10 @@ static int pcie_pme_suspend(struct pcie_device *srv) } spin_lock_irq(&data->lock); if (wakeup) { - enable_irq_wake(srv->irq); + ret = enable_irq_wake(srv->irq); data->suspend_level = PME_SUSPEND_WAKEUP; - } else { + } + if (!wakeup || ret) { struct pci_dev *port = srv->port; pcie_pme_interrupt_enable(port, false); |