From 0a00fd5e20fd5dc89e976e163588d7c54edaf745 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 3 Jun 2014 16:32:53 +0800 Subject: ACPICA: Restore error table definitions to reduce code differences between Linux and ACPICA upstream. The following commit has changed ACPICA table header definitions: Commit: 88f074f4871a8c212b212b725e4dcdcdb09613c1 Subject: ACPI, CPER: Update cper info While such definitions are currently maintained in ACPICA. As the modifications applying to the table definitions affect other OSPMs' drivers, it is very difficult for ACPICA to initiate a process to complete the merge. Thus this commit finally only leaves us divergences. Revert such naming modifications to reduce the source code differecnes between Linux and ACPICA upstream. No functional changes. Signed-off-by: Lv Zheng Cc: Bob Moore Cc: Chen, Gong Cc: Tony Luck Cc: Borislav Petkov Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_extlog.c | 14 +++++++------- drivers/acpi/apei/apei-internal.h | 10 +++++----- drivers/acpi/apei/ghes.c | 32 ++++++++++++++++---------------- 3 files changed, 28 insertions(+), 28 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c index 185334114d71..340d09518f8e 100644 --- a/drivers/acpi/acpi_extlog.c +++ b/drivers/acpi/acpi_extlog.c @@ -69,11 +69,11 @@ static u32 l1_percpu_entry; #define ELOG_ENTRY_ADDR(phyaddr) \ (phyaddr - elog_base + (u8 *)elog_addr) -static struct acpi_generic_status *extlog_elog_entry_check(int cpu, int bank) +static struct acpi_hest_generic_status *extlog_elog_entry_check(int cpu, int bank) { int idx; u64 data; - struct acpi_generic_status *estatus; + struct acpi_hest_generic_status *estatus; WARN_ON(cpu < 0); idx = ELOG_IDX(cpu, bank); @@ -82,7 +82,7 @@ static struct acpi_generic_status *extlog_elog_entry_check(int cpu, int bank) return NULL; data &= EXT_ELOG_ENTRY_MASK; - estatus = (struct acpi_generic_status *)ELOG_ENTRY_ADDR(data); + estatus = (struct acpi_hest_generic_status *)ELOG_ENTRY_ADDR(data); /* if no valid data in elog entry, just return */ if (estatus->block_status == 0) @@ -92,7 +92,7 @@ static struct acpi_generic_status *extlog_elog_entry_check(int cpu, int bank) } static void __print_extlog_rcd(const char *pfx, - struct acpi_generic_status *estatus, int cpu) + struct acpi_hest_generic_status *estatus, int cpu) { static atomic_t seqno; unsigned int curr_seqno; @@ -111,7 +111,7 @@ static void __print_extlog_rcd(const char *pfx, } static int print_extlog_rcd(const char *pfx, - struct acpi_generic_status *estatus, int cpu) + struct acpi_hest_generic_status *estatus, int cpu) { /* Not more than 2 messages every 5 seconds */ static DEFINE_RATELIMIT_STATE(ratelimit_corrected, 5*HZ, 2); @@ -137,7 +137,7 @@ static int extlog_print(struct notifier_block *nb, unsigned long val, struct mce *mce = (struct mce *)data; int bank = mce->bank; int cpu = mce->extcpu; - struct acpi_generic_status *estatus; + struct acpi_hest_generic_status *estatus; int rc; estatus = extlog_elog_entry_check(cpu, bank); @@ -148,7 +148,7 @@ static int extlog_print(struct notifier_block *nb, unsigned long val, /* clear record status to enable BIOS to update it again */ estatus->block_status = 0; - rc = print_extlog_rcd(NULL, (struct acpi_generic_status *)elog_buf, cpu); + rc = print_extlog_rcd(NULL, (struct acpi_hest_generic_status *)elog_buf, cpu); return NOTIFY_STOP; } diff --git a/drivers/acpi/apei/apei-internal.h b/drivers/acpi/apei/apei-internal.h index e5bcd919d4e6..16129c78b489 100644 --- a/drivers/acpi/apei/apei-internal.h +++ b/drivers/acpi/apei/apei-internal.h @@ -121,11 +121,11 @@ struct dentry; struct dentry *apei_get_debugfs_dir(void); #define apei_estatus_for_each_section(estatus, section) \ - for (section = (struct acpi_generic_data *)(estatus + 1); \ + for (section = (struct acpi_hest_generic_data *)(estatus + 1); \ (void *)section - (void *)estatus < estatus->data_length; \ section = (void *)(section+1) + section->error_data_length) -static inline u32 cper_estatus_len(struct acpi_generic_status *estatus) +static inline u32 cper_estatus_len(struct acpi_hest_generic_status *estatus) { if (estatus->raw_data_length) return estatus->raw_data_offset + \ @@ -135,9 +135,9 @@ static inline u32 cper_estatus_len(struct acpi_generic_status *estatus) } void cper_estatus_print(const char *pfx, - const struct acpi_generic_status *estatus); -int cper_estatus_check_header(const struct acpi_generic_status *estatus); -int cper_estatus_check(const struct acpi_generic_status *estatus); + const struct acpi_hest_generic_status *estatus); +int cper_estatus_check_header(const struct acpi_hest_generic_status *estatus); +int cper_estatus_check(const struct acpi_hest_generic_status *estatus); int apei_osc_setup(void); #endif diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index dab7cb7349df..7a38d1465b61 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -74,13 +74,13 @@ #define GHES_ESTATUS_CACHE_LEN(estatus_len) \ (sizeof(struct ghes_estatus_cache) + (estatus_len)) #define GHES_ESTATUS_FROM_CACHE(estatus_cache) \ - ((struct acpi_generic_status *) \ + ((struct acpi_hest_generic_status *) \ ((struct ghes_estatus_cache *)(estatus_cache) + 1)) #define GHES_ESTATUS_NODE_LEN(estatus_len) \ (sizeof(struct ghes_estatus_node) + (estatus_len)) #define GHES_ESTATUS_FROM_NODE(estatus_node) \ - ((struct acpi_generic_status *) \ + ((struct acpi_hest_generic_status *) \ ((struct ghes_estatus_node *)(estatus_node) + 1)) bool ghes_disable; @@ -408,7 +408,7 @@ static void ghes_clear_estatus(struct ghes *ghes) ghes->flags &= ~GHES_TO_CLEAR; } -static void ghes_handle_memory_failure(struct acpi_generic_data *gdata, int sev) +static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int sev) { #ifdef CONFIG_ACPI_APEI_MEMORY_FAILURE unsigned long pfn; @@ -441,10 +441,10 @@ static void ghes_handle_memory_failure(struct acpi_generic_data *gdata, int sev) } static void ghes_do_proc(struct ghes *ghes, - const struct acpi_generic_status *estatus) + const struct acpi_hest_generic_status *estatus) { int sev, sec_sev; - struct acpi_generic_data *gdata; + struct acpi_hest_generic_data *gdata; sev = ghes_severity(estatus->error_severity); apei_estatus_for_each_section(estatus, gdata) { @@ -498,7 +498,7 @@ static void ghes_do_proc(struct ghes *ghes, static void __ghes_print_estatus(const char *pfx, const struct acpi_hest_generic *generic, - const struct acpi_generic_status *estatus) + const struct acpi_hest_generic_status *estatus) { static atomic_t seqno; unsigned int curr_seqno; @@ -520,7 +520,7 @@ static void __ghes_print_estatus(const char *pfx, static int ghes_print_estatus(const char *pfx, const struct acpi_hest_generic *generic, - const struct acpi_generic_status *estatus) + const struct acpi_hest_generic_status *estatus) { /* Not more than 2 messages every 5 seconds */ static DEFINE_RATELIMIT_STATE(ratelimit_corrected, 5*HZ, 2); @@ -542,13 +542,13 @@ static int ghes_print_estatus(const char *pfx, * GHES error status reporting throttle, to report more kinds of * errors, instead of just most frequently occurred errors. */ -static int ghes_estatus_cached(struct acpi_generic_status *estatus) +static int ghes_estatus_cached(struct acpi_hest_generic_status *estatus) { u32 len; int i, cached = 0; unsigned long long now; struct ghes_estatus_cache *cache; - struct acpi_generic_status *cache_estatus; + struct acpi_hest_generic_status *cache_estatus; len = cper_estatus_len(estatus); rcu_read_lock(); @@ -573,12 +573,12 @@ static int ghes_estatus_cached(struct acpi_generic_status *estatus) static struct ghes_estatus_cache *ghes_estatus_cache_alloc( struct acpi_hest_generic *generic, - struct acpi_generic_status *estatus) + struct acpi_hest_generic_status *estatus) { int alloced; u32 len, cache_len; struct ghes_estatus_cache *cache; - struct acpi_generic_status *cache_estatus; + struct acpi_hest_generic_status *cache_estatus; alloced = atomic_add_return(1, &ghes_estatus_cache_alloced); if (alloced > GHES_ESTATUS_CACHE_ALLOCED_MAX) { @@ -621,7 +621,7 @@ static void ghes_estatus_cache_rcu_free(struct rcu_head *head) static void ghes_estatus_cache_add( struct acpi_hest_generic *generic, - struct acpi_generic_status *estatus) + struct acpi_hest_generic_status *estatus) { int i, slot = -1, count; unsigned long long now, duration, period, max_period = 0; @@ -753,7 +753,7 @@ static void ghes_proc_in_irq(struct irq_work *irq_work) struct llist_node *llnode, *next; struct ghes_estatus_node *estatus_node; struct acpi_hest_generic *generic; - struct acpi_generic_status *estatus; + struct acpi_hest_generic_status *estatus; u32 len, node_len; llnode = llist_del_all(&ghes_estatus_llist); @@ -786,7 +786,7 @@ static void ghes_print_queued_estatus(void) struct llist_node *llnode; struct ghes_estatus_node *estatus_node; struct acpi_hest_generic *generic; - struct acpi_generic_status *estatus; + struct acpi_hest_generic_status *estatus; u32 len, node_len; llnode = llist_del_all(&ghes_estatus_llist); @@ -845,7 +845,7 @@ static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs) #ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG u32 len, node_len; struct ghes_estatus_node *estatus_node; - struct acpi_generic_status *estatus; + struct acpi_hest_generic_status *estatus; #endif if (!(ghes->flags & GHES_TO_CLEAR)) continue; @@ -925,7 +925,7 @@ static int ghes_probe(struct platform_device *ghes_dev) rc = -EIO; if (generic->error_block_length < - sizeof(struct acpi_generic_status)) { + sizeof(struct acpi_hest_generic_status)) { pr_warning(FW_BUG GHES_PFX "Invalid error block length: %u for generic hardware error source: %d\n", generic->error_block_length, generic->header.source_id); -- cgit v1.2.3 From 6ec5e12074b42fafec2a340d72e8d8e1fd4c5405 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Sun, 15 Jun 2014 08:42:31 +0800 Subject: ACPICA: Events: Fix edge-triggered GPE by disabling before acknowledging it. Due to ACPI specificiation 5, chapter 5.6.4 General-Purpose Event Handling, OSPMs need to disable GPE before clearing the status bit for edge-triggered GPEs. Signed-off-by: Lv Zheng Tested-by: Gareth Williams Tested-by: Steffen Weber Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/evgpe.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 48f70013b488..e4ba4dec86af 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -697,21 +697,6 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, acpi_gbl_global_event_handler_context); } - /* - * If edge-triggered, clear the GPE status bit now. Note that - * level-triggered events are cleared after the GPE is serviced. - */ - if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == - ACPI_GPE_EDGE_TRIGGERED) { - status = acpi_hw_clear_gpe(gpe_event_info); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, - "Unable to clear GPE %02X", - gpe_number)); - return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); - } - } - /* * Always disable the GPE so that it does not keep firing before * any asynchronous activity completes (either from the execution @@ -728,6 +713,23 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); } + /* + * If edge-triggered, clear the GPE status bit now. Note that + * level-triggered events are cleared after the GPE is serviced. + */ + if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == + ACPI_GPE_EDGE_TRIGGERED) { + status = acpi_hw_clear_gpe(gpe_event_info); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "Unable to clear GPE %02X", + gpe_number)); + (void)acpi_hw_low_set_gpe(gpe_event_info, + ACPI_GPE_CONDITIONAL_ENABLE); + return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); + } + } + /* * Dispatch the GPE to either an installed handler or the control * method associated with this GPE (_Lxx or _Exx). If a handler -- cgit v1.2.3 From f1b1dc845cb1418b2b0de35491b0da87498ea6a8 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 7 Jul 2014 14:07:38 +0200 Subject: ACPI / PNP: do ACPI binding directly PNPACPI uses acpi_bus_type to do ACPI binding for the PNPACPI devices. This is overkill because PNPACPI code already knows which ACPI device object to bind during PNPACPI device enumeration. This patch removes acpi_pnp_bus and does the binding by invoking acpi_bind_one() directly after device enumerated. This also fixes a bug in the previous code that some PNPACPI devices failed to be bound because 1. the ACPI device _HID is not pnpid, e.g. "MSFT0001", but its _CID is, e.g. "PNP0303", thus ACPI _CID is used as the pnp device device id. 2. device is bound only if the pnp device id matches the ACPI device _HID. Tested-by: Prigent Christophe Signed-off-by: Zhang Rui Signed-off-by: Rafael J. Wysocki --- drivers/acpi/internal.h | 2 -- drivers/pnp/pnpacpi/core.c | 41 +++-------------------------------------- include/acpi/acpi_bus.h | 2 ++ 3 files changed, 5 insertions(+), 40 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 7de5b603f272..151f3e76d47a 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -84,8 +84,6 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, int type, unsigned long long sta); void acpi_device_add_finalize(struct acpi_device *device); 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); diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index b81448b2c75d..3bebedaee8e1 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c @@ -295,9 +295,11 @@ static int __init pnpacpi_add_device(struct acpi_device *device) return error; } + error = acpi_bind_one(&dev->dev, device); + num++; - return 0; + return error; } static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle, @@ -313,41 +315,6 @@ static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle, return AE_OK; } -static int __init acpi_pnp_match(struct device *dev, void *_pnp) -{ - struct acpi_device *acpi = to_acpi_device(dev); - struct pnp_dev *pnp = _pnp; - - /* true means it matched */ - return !acpi->physical_node_count - && compare_pnp_id(pnp->id, acpi_device_hid(acpi)); -} - -static struct acpi_device * __init acpi_pnp_find_companion(struct device *dev) -{ - dev = bus_find_device(&acpi_bus_type, NULL, to_pnp_dev(dev), - acpi_pnp_match); - if (!dev) - return NULL; - - put_device(dev); - return to_acpi_device(dev); -} - -/* complete initialization of a PNPACPI device includes having - * pnpdev->dev.archdata.acpi_handle point to its ACPI sibling. - */ -static bool acpi_pnp_bus_match(struct device *dev) -{ - return dev->bus == &pnp_bus_type; -} - -static struct acpi_bus_type __initdata acpi_pnp_bus = { - .name = "PNP", - .match = acpi_pnp_bus_match, - .find_companion = acpi_pnp_find_companion, -}; - int pnpacpi_disabled __initdata; static int __init pnpacpi_init(void) { @@ -357,10 +324,8 @@ static int __init pnpacpi_init(void) } printk(KERN_INFO "pnp: PnP ACPI init\n"); pnp_register_protocol(&pnpacpi_protocol); - register_acpi_bus_type(&acpi_pnp_bus); acpi_get_devices(NULL, pnpacpi_add_device_handler, NULL, NULL); printk(KERN_INFO "pnp: PnP ACPI: found %d devices\n", num); - unregister_acpi_bus_type(&acpi_pnp_bus); pnp_platform_devices = 1; return 0; } diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index b5714580801a..4bcbb941bc09 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -487,6 +487,8 @@ struct acpi_bus_type { }; int register_acpi_bus_type(struct acpi_bus_type *); int unregister_acpi_bus_type(struct acpi_bus_type *); +int acpi_bind_one(struct device *dev, struct acpi_device *adev); +int acpi_unbind_one(struct device *dev); struct acpi_pci_root { struct acpi_device * device; -- cgit v1.2.3 From 8aa5e56eeb61a099ea6519eb30ee399e1bc043ce Mon Sep 17 00:00:00 2001 From: "David E. Box" Date: Tue, 8 Jul 2014 10:05:52 +0800 Subject: ACPICA: Utilities: Fix memory leak in acpi_ut_copy_iobject_to_iobject Adds return status check on copy routines to delete the allocated destination object if either copy fails. Reported by Colin Ian King on bugs.acpica.org, Bug 1087. The last applicable commit: Commit: 3371c19c294a4cb3649aa4e84606be8a1d999e61 Subject: ACPICA: Remove ACPI_GET_OBJECT_TYPE macro Link: https://bugs.acpica.org/show_bug.cgi?id=1087 Reported-by: Colin Ian King Signed-off-by: David E. Box Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Cc: 3.9+ # 3.9+ Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/utcopy.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c index 270c16464dd9..ff601c0f7c7a 100644 --- a/drivers/acpi/acpica/utcopy.c +++ b/drivers/acpi/acpica/utcopy.c @@ -1001,5 +1001,11 @@ acpi_ut_copy_iobject_to_iobject(union acpi_operand_object *source_desc, status = acpi_ut_copy_simple_object(source_desc, *dest_desc); } + /* Delete the allocated object if copy failed */ + + if (ACPI_FAILURE(status)) { + acpi_ut_remove_reference(*dest_desc); + } + return_ACPI_STATUS(status); } -- cgit v1.2.3 From ae8ffc7dbb7e2bb9cbf3d84ef4116c5f7901539a Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 8 Jul 2014 10:06:05 +0800 Subject: ACPICA: Utilities: Fix an issue with non-native ACPI_IS_PRINT() An error was found in the ACPICA provided non-native ACPI_IS_PRINT() causing the following difference with the native isprint() implementation: The GNU libc isprint('\n') test result: isprint(0x20) is FALSE The Linux kernel isprint('\n') test result: ACPI: isprint(0x20) is FALSE The _acpi_ctype isprint('\n') test result: isprint(0x20) is TRUE The ACPI_IS_PRINT() macro generated for _acpi_ctype is wrong. It should use _ACPI_XS instead of _ACPI_SP. _ACPI_XS is white space only. Other space characters should be non printable. This patch fixes this issue. For OSPMs that are using native standard isprint() implementations, this patch is a no-op. Lv Zheng. Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acutils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 1e256c5bda20..caeb81a8752f 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -257,7 +257,7 @@ extern const u8 _acpi_ctype[]; #define ACPI_IS_XDIGIT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_XD)) #define ACPI_IS_UPPER(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_UP)) #define ACPI_IS_LOWER(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO)) -#define ACPI_IS_PRINT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP | _ACPI_DI | _ACPI_SP | _ACPI_PU)) +#define ACPI_IS_PRINT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP | _ACPI_DI | _ACPI_XS | _ACPI_PU)) #define ACPI_IS_ALPHA(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP)) #endif /* !ACPI_USE_SYSTEM_CLIBRARY */ -- cgit v1.2.3 From e740304c7cf389b5d498bd86865fc82518d9ea1a Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 8 Jul 2014 10:06:12 +0800 Subject: ACPICA: Utilities: Add support to read table from files After the new table reading utility functions are well tested, acpidump can also switch to use the generic acpi_ut_read_table_xxx() APIs. Currently this patch is no-op as acpidump does not link to the new APIs. This patch is only useful for ACPICA applications, most of which are not shipped in the Linux kernel. Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/Makefile | 2 +- drivers/acpi/acpica/acdebug.h | 3 - drivers/acpi/acpica/acutils.h | 8 + drivers/acpi/acpica/utfileio.c | 337 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 346 insertions(+), 4 deletions(-) create mode 100644 drivers/acpi/acpica/utfileio.c (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index 8bb43f06e11f..14b851f1a278 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile @@ -175,5 +175,5 @@ acpi-y += \ utxferror.o \ utxfmutex.o -acpi-$(ACPI_FUTURE_USAGE) += uttrack.o utcache.o +acpi-$(ACPI_FUTURE_USAGE) += utfileio.o uttrack.o utcache.o diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index 68a91eb0fa48..1d026ff1683f 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h @@ -233,9 +233,6 @@ acpi_status acpi_db_load_acpi_table(char *filename); acpi_status acpi_db_get_table_from_file(char *filename, struct acpi_table_header **table); -acpi_status -acpi_db_read_table_from_file(char *filename, struct acpi_table_header **table); - /* * dbhistry - debugger HISTORY command */ diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index caeb81a8752f..8a4414869566 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -393,6 +393,14 @@ acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node, const char **method_names, u8 method_count, u8 *out_values); +/* + * utfileio - file operations + */ +#ifdef ACPI_APPLICATION +acpi_status +acpi_ut_read_table_from_file(char *filename, struct acpi_table_header **table); +#endif + /* * utids - device ID support */ diff --git a/drivers/acpi/acpica/utfileio.c b/drivers/acpi/acpica/utfileio.c new file mode 100644 index 000000000000..c8f63594b198 --- /dev/null +++ b/drivers/acpi/acpica/utfileio.c @@ -0,0 +1,337 @@ +/******************************************************************************* + * + * Module Name: utfileio - simple file I/O routines + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2014, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include "accommon.h" +#include "actables.h" +#include "acapps.h" + +#ifdef ACPI_ASL_COMPILER +#include "aslcompiler.h" +#endif + +#define _COMPONENT ACPI_CA_DEBUGGER +ACPI_MODULE_NAME("utfileio") + +#ifdef ACPI_APPLICATION +/* Local prototypes */ +static acpi_status +acpi_ut_check_text_mode_corruption(u8 *table, + u32 table_length, u32 file_length); + +static acpi_status +acpi_ut_read_table(FILE * fp, + struct acpi_table_header **table, u32 *table_length); + +/******************************************************************************* + * + * FUNCTION: acpi_ut_check_text_mode_corruption + * + * PARAMETERS: table - Table buffer + * table_length - Length of table from the table header + * file_length - Length of the file that contains the table + * + * RETURN: Status + * + * DESCRIPTION: Check table for text mode file corruption where all linefeed + * characters (LF) have been replaced by carriage return linefeed + * pairs (CR/LF). + * + ******************************************************************************/ + +static acpi_status +acpi_ut_check_text_mode_corruption(u8 *table, u32 table_length, u32 file_length) +{ + u32 i; + u32 pairs = 0; + + if (table_length != file_length) { + ACPI_WARNING((AE_INFO, + "File length (0x%X) is not the same as the table length (0x%X)", + file_length, table_length)); + } + + /* Scan entire table to determine if each LF has been prefixed with a CR */ + + for (i = 1; i < file_length; i++) { + if (table[i] == 0x0A) { + if (table[i - 1] != 0x0D) { + + /* The LF does not have a preceding CR, table not corrupted */ + + return (AE_OK); + } else { + /* Found a CR/LF pair */ + + pairs++; + } + i++; + } + } + + if (!pairs) { + return (AE_OK); + } + + /* + * Entire table scanned, each CR is part of a CR/LF pair -- + * meaning that the table was treated as a text file somewhere. + * + * NOTE: We can't "fix" the table, because any existing CR/LF pairs in the + * original table are left untouched by the text conversion process -- + * meaning that we cannot simply replace CR/LF pairs with LFs. + */ + acpi_os_printf("Table has been corrupted by text mode conversion\n"); + acpi_os_printf("All LFs (%u) were changed to CR/LF pairs\n", pairs); + acpi_os_printf("Table cannot be repaired!\n"); + return (AE_BAD_VALUE); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_read_table + * + * PARAMETERS: fp - File that contains table + * table - Return value, buffer with table + * table_length - Return value, length of table + * + * RETURN: Status + * + * DESCRIPTION: Load the DSDT from the file pointer + * + ******************************************************************************/ + +static acpi_status +acpi_ut_read_table(FILE * fp, + struct acpi_table_header **table, u32 *table_length) +{ + struct acpi_table_header table_header; + u32 actual; + acpi_status status; + u32 file_size; + u8 standard_header = TRUE; + + /* Get the file size */ + + file_size = cm_get_file_size(fp); + if (file_size == ACPI_UINT32_MAX) { + return (AE_ERROR); + } + + if (file_size < 4) { + return (AE_BAD_HEADER); + } + + /* Read the signature */ + + if (fread(&table_header, 1, 4, fp) != 4) { + acpi_os_printf("Could not read the table signature\n"); + return (AE_BAD_HEADER); + } + + fseek(fp, 0, SEEK_SET); + + /* The RSDP table does not have standard ACPI header */ + + if (ACPI_COMPARE_NAME(table_header.signature, "RSD ")) { + *table_length = file_size; + standard_header = FALSE; + } else { + /* Read the table header */ + + if (fread + (&table_header, 1, sizeof(struct acpi_table_header), + fp) != sizeof(struct acpi_table_header)) { + acpi_os_printf("Could not read the table header\n"); + return (AE_BAD_HEADER); + } +#if 0 + /* Validate the table header/length */ + + status = acpi_tb_validate_table_header(&table_header); + if (ACPI_FAILURE(status)) { + acpi_os_printf("Table header is invalid!\n"); + return (status); + } +#endif + + /* File size must be at least as long as the Header-specified length */ + + if (table_header.length > file_size) { + acpi_os_printf + ("TableHeader length [0x%X] greater than the input file size [0x%X]\n", + table_header.length, file_size); + +#ifdef ACPI_ASL_COMPILER + status = fl_check_for_ascii(fp, NULL, FALSE); + if (ACPI_SUCCESS(status)) { + acpi_os_printf + ("File appears to be ASCII only, must be binary\n", + table_header.length, file_size); + } +#endif + return (AE_BAD_HEADER); + } +#ifdef ACPI_OBSOLETE_CODE + /* We only support a limited number of table types */ + + if (!ACPI_COMPARE_NAME + ((char *)table_header.signature, ACPI_SIG_DSDT) + && !ACPI_COMPARE_NAME((char *)table_header.signature, + ACPI_SIG_PSDT) + && !ACPI_COMPARE_NAME((char *)table_header.signature, + ACPI_SIG_SSDT)) { + acpi_os_printf + ("Table signature [%4.4s] is invalid or not supported\n", + (char *)table_header.signature); + ACPI_DUMP_BUFFER(&table_header, + sizeof(struct acpi_table_header)); + return (AE_ERROR); + } +#endif + + *table_length = table_header.length; + } + + /* Allocate a buffer for the table */ + + *table = acpi_os_allocate((size_t) file_size); + if (!*table) { + acpi_os_printf + ("Could not allocate memory for ACPI table %4.4s (size=0x%X)\n", + table_header.signature, *table_length); + return (AE_NO_MEMORY); + } + + /* Get the rest of the table */ + + fseek(fp, 0, SEEK_SET); + actual = fread(*table, 1, (size_t) file_size, fp); + if (actual == file_size) { + if (standard_header) { + + /* Now validate the checksum */ + + status = acpi_tb_verify_checksum((void *)*table, + ACPI_CAST_PTR(struct + acpi_table_header, + *table)-> + length); + + if (status == AE_BAD_CHECKSUM) { + status = + acpi_ut_check_text_mode_corruption((u8 *) + *table, + file_size, + (*table)-> + length); + return (status); + } + } + return (AE_OK); + } + + if (actual > 0) { + acpi_os_printf("Warning - reading table, asked for %X got %X\n", + file_size, actual); + return (AE_OK); + } + + acpi_os_printf("Error - could not read the table file\n"); + acpi_os_free(*table); + *table = NULL; + *table_length = 0; + return (AE_ERROR); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_read_table_from_file + * + * PARAMETERS: filename - File where table is located + * table - Where a pointer to the table is returned + * + * RETURN: Status + * + * DESCRIPTION: Get an ACPI table from a file + * + ******************************************************************************/ + +acpi_status +acpi_ut_read_table_from_file(char *filename, struct acpi_table_header ** table) +{ + FILE *file; + u32 file_size; + u32 table_length; + acpi_status status = AE_ERROR; + + /* Open the file, get current size */ + + file = fopen(filename, "rb"); + if (!file) { + perror("Could not open input file"); + return (status); + } + + file_size = cm_get_file_size(file); + if (file_size == ACPI_UINT32_MAX) { + goto exit; + } + + /* Get the entire file */ + + fprintf(stderr, + "Loading Acpi table from file %10s - Length %.8u (%06X)\n", + filename, file_size, file_size); + + status = acpi_ut_read_table(file, table, &table_length); + if (ACPI_FAILURE(status)) { + acpi_os_printf("Could not get table from the file\n"); + } + +exit: + fclose(file); + return (status); +} + +#endif -- cgit v1.2.3 From ce5eb07339b9162812458ee611b6e7af7604a3e4 Mon Sep 17 00:00:00 2001 From: "David E. Box" Date: Tue, 8 Jul 2014 10:06:17 +0800 Subject: ACPICA: Utilities: Validate full RSDP header Implement proper RSDP validation in acpi_ut_read_table(). Prevents a segmentation fault that can occur if a user passes the wrong file to iasl. This patch is only useful for iasl, which is not shipped in the Linux kernel. After the new table reading utility functions are well tested, acpidump can also switch to use the generic acpi_ut_read_table_xxx() APIs. Currently this patch is no-op as acpidump does not link to the new APIs. Signed-off-by: David E. Box Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/utfileio.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/utfileio.c b/drivers/acpi/acpica/utfileio.c index c8f63594b198..bdf9914733cb 100644 --- a/drivers/acpi/acpica/utfileio.c +++ b/drivers/acpi/acpica/utfileio.c @@ -150,6 +150,7 @@ acpi_ut_read_table(FILE * fp, acpi_status status; u32 file_size; u8 standard_header = TRUE; + s32 count; /* Get the file size */ @@ -164,27 +165,21 @@ acpi_ut_read_table(FILE * fp, /* Read the signature */ - if (fread(&table_header, 1, 4, fp) != 4) { - acpi_os_printf("Could not read the table signature\n"); + fseek(fp, 0, SEEK_SET); + + count = fread(&table_header, 1, sizeof(struct acpi_table_header), fp); + if (count != sizeof(struct acpi_table_header)) { + acpi_os_printf("Could not read the table header\n"); return (AE_BAD_HEADER); } - fseek(fp, 0, SEEK_SET); - /* The RSDP table does not have standard ACPI header */ - if (ACPI_COMPARE_NAME(table_header.signature, "RSD ")) { + if (ACPI_VALIDATE_RSDP_SIG(table_header.signature)) { *table_length = file_size; standard_header = FALSE; } else { - /* Read the table header */ - if (fread - (&table_header, 1, sizeof(struct acpi_table_header), - fp) != sizeof(struct acpi_table_header)) { - acpi_os_printf("Could not read the table header\n"); - return (AE_BAD_HEADER); - } #if 0 /* Validate the table header/length */ -- cgit v1.2.3 From e23d9b8297546c6ceb7e70771e4915f2a41733cd Mon Sep 17 00:00:00 2001 From: "David E. Box" Date: Tue, 8 Jul 2014 10:06:24 +0800 Subject: ACPICA: Namespace: Properly null terminate objects detached from a namespace node Fixes a bug exposed by an ACPICA unit test around the acpi_attach_data()/acpi_detach_data() APIs where the failure to null terminate a detached object led to the creation of a circular linked list (and infinite looping) when the object is reattached. Reported in acpica bugzilla #1063 Link: https://bugs.acpica.org/show_bug.cgi?id=1063 Signed-off-by: David E. Box Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Cc: 3.15+ # 3.15+ Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/nsobject.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c index fe54a8c73b8c..f1ea8e56cd87 100644 --- a/drivers/acpi/acpica/nsobject.c +++ b/drivers/acpi/acpica/nsobject.c @@ -239,6 +239,17 @@ void acpi_ns_detach_object(struct acpi_namespace_node *node) } } + /* + * Detach the object from any data objects (which are still held by + * the namespace node) + */ + + if (obj_desc->common.next_object && + ((obj_desc->common.next_object)->common.type == + ACPI_TYPE_LOCAL_DATA)) { + obj_desc->common.next_object = NULL; + } + /* Reset the node type to untyped */ node->type = ACPI_TYPE_ANY; -- cgit v1.2.3 From e8c038a3c6227892e6c0982804b6f9d03fa4b3c5 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 8 Jul 2014 10:06:39 +0800 Subject: ACPICA: Utilities: Cleanup DEFINE_ACPI_GLOBALS by moving acpi_ut_init_global() from utglobal.c to utinit.c The utglobal.c is used to define and initialize global variables. It makes sense if just adding utglobal.o to applications that are using such variables. But acpi_ut_init_globals() is preventing us from doing so as this initialization function references other components' initializations code, which leads to the requirement that many files should also get linked if one wants to link utglobal.o. It is possible to just move acpi_ut_init_global() to utinit.c for applications that require this function to link. By linking utglobal.o, we can stop defining DEFINE_ACPI_GLOBALS for applications (currently only acpidump is affected). Lv Zheng. Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/utglobal.c | 146 ----------------------------- drivers/acpi/acpica/utinit.c | 146 +++++++++++++++++++++++++++++ tools/power/acpi/Makefile | 1 + tools/power/acpi/tools/acpidump/acpidump.h | 1 - 4 files changed, 147 insertions(+), 147 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index d69be3cb3fae..77ceac715f28 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c @@ -214,152 +214,6 @@ struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS] = }; #endif /* !ACPI_REDUCED_HARDWARE */ -/******************************************************************************* - * - * FUNCTION: acpi_ut_init_globals - * - * PARAMETERS: None - * - * RETURN: Status - * - * DESCRIPTION: Initialize ACPICA globals. All globals that require specific - * initialization should be initialized here. This allows for - * a warm restart. - * - ******************************************************************************/ - -acpi_status acpi_ut_init_globals(void) -{ - acpi_status status; - u32 i; - - ACPI_FUNCTION_TRACE(ut_init_globals); - - /* Create all memory caches */ - - status = acpi_ut_create_caches(); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* Address Range lists */ - - for (i = 0; i < ACPI_ADDRESS_RANGE_MAX; i++) { - acpi_gbl_address_range_list[i] = NULL; - } - - /* Mutex locked flags */ - - for (i = 0; i < ACPI_NUM_MUTEX; i++) { - acpi_gbl_mutex_info[i].mutex = NULL; - acpi_gbl_mutex_info[i].thread_id = ACPI_MUTEX_NOT_ACQUIRED; - acpi_gbl_mutex_info[i].use_count = 0; - } - - for (i = 0; i < ACPI_NUM_OWNERID_MASKS; i++) { - acpi_gbl_owner_id_mask[i] = 0; - } - - /* Last owner_ID is never valid */ - - acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000; - - /* Event counters */ - - acpi_method_count = 0; - acpi_sci_count = 0; - acpi_gpe_count = 0; - - for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { - acpi_fixed_event_count[i] = 0; - } - -#if (!ACPI_REDUCED_HARDWARE) - - /* GPE/SCI support */ - - acpi_gbl_all_gpes_initialized = FALSE; - acpi_gbl_gpe_xrupt_list_head = NULL; - acpi_gbl_gpe_fadt_blocks[0] = NULL; - acpi_gbl_gpe_fadt_blocks[1] = NULL; - acpi_current_gpe_count = 0; - - acpi_gbl_global_event_handler = NULL; - acpi_gbl_sci_handler_list = NULL; - -#endif /* !ACPI_REDUCED_HARDWARE */ - - /* Global handlers */ - - acpi_gbl_global_notify[0].handler = NULL; - acpi_gbl_global_notify[1].handler = NULL; - acpi_gbl_exception_handler = NULL; - acpi_gbl_init_handler = NULL; - acpi_gbl_table_handler = NULL; - acpi_gbl_interface_handler = NULL; - - /* Global Lock support */ - - acpi_gbl_global_lock_semaphore = NULL; - acpi_gbl_global_lock_mutex = NULL; - acpi_gbl_global_lock_acquired = FALSE; - acpi_gbl_global_lock_handle = 0; - acpi_gbl_global_lock_present = FALSE; - - /* Miscellaneous variables */ - - acpi_gbl_DSDT = NULL; - acpi_gbl_cm_single_step = FALSE; - acpi_gbl_shutdown = FALSE; - acpi_gbl_ns_lookup_count = 0; - acpi_gbl_ps_find_count = 0; - acpi_gbl_acpi_hardware_present = TRUE; - acpi_gbl_last_owner_id_index = 0; - acpi_gbl_next_owner_id_offset = 0; - acpi_gbl_trace_dbg_level = 0; - acpi_gbl_trace_dbg_layer = 0; - acpi_gbl_debugger_configuration = DEBUGGER_THREADING; - acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT; - acpi_gbl_osi_mutex = NULL; - acpi_gbl_reg_methods_executed = FALSE; - - /* Hardware oriented */ - - acpi_gbl_events_initialized = FALSE; - acpi_gbl_system_awake_and_running = TRUE; - - /* Namespace */ - - acpi_gbl_module_code_list = NULL; - acpi_gbl_root_node = NULL; - acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME; - acpi_gbl_root_node_struct.descriptor_type = ACPI_DESC_TYPE_NAMED; - acpi_gbl_root_node_struct.type = ACPI_TYPE_DEVICE; - acpi_gbl_root_node_struct.parent = NULL; - acpi_gbl_root_node_struct.child = NULL; - acpi_gbl_root_node_struct.peer = NULL; - acpi_gbl_root_node_struct.object = NULL; - -#ifdef ACPI_DISASSEMBLER - acpi_gbl_external_list = NULL; - acpi_gbl_num_external_methods = 0; - acpi_gbl_resolved_external_methods = 0; -#endif - -#ifdef ACPI_DEBUG_OUTPUT - acpi_gbl_lowest_stack_pointer = ACPI_CAST_PTR(acpi_size, ACPI_SIZE_MAX); -#endif - -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - acpi_gbl_display_final_mem_stats = FALSE; - acpi_gbl_disable_mem_tracking = FALSE; -#endif - - ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = FALSE); - - return_ACPI_STATUS(AE_OK); -} - /* Public globals */ ACPI_EXPORT_SYMBOL(acpi_gbl_FADT) diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c index 5f56fc49021e..a7936623998f 100644 --- a/drivers/acpi/acpica/utinit.c +++ b/drivers/acpi/acpica/utinit.c @@ -102,6 +102,152 @@ static void acpi_ut_free_gpe_lists(void) } #endif /* !ACPI_REDUCED_HARDWARE */ +/******************************************************************************* + * + * FUNCTION: acpi_ut_init_globals + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Initialize ACPICA globals. All globals that require specific + * initialization should be initialized here. This allows for + * a warm restart. + * + ******************************************************************************/ + +acpi_status acpi_ut_init_globals(void) +{ + acpi_status status; + u32 i; + + ACPI_FUNCTION_TRACE(ut_init_globals); + + /* Create all memory caches */ + + status = acpi_ut_create_caches(); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Address Range lists */ + + for (i = 0; i < ACPI_ADDRESS_RANGE_MAX; i++) { + acpi_gbl_address_range_list[i] = NULL; + } + + /* Mutex locked flags */ + + for (i = 0; i < ACPI_NUM_MUTEX; i++) { + acpi_gbl_mutex_info[i].mutex = NULL; + acpi_gbl_mutex_info[i].thread_id = ACPI_MUTEX_NOT_ACQUIRED; + acpi_gbl_mutex_info[i].use_count = 0; + } + + for (i = 0; i < ACPI_NUM_OWNERID_MASKS; i++) { + acpi_gbl_owner_id_mask[i] = 0; + } + + /* Last owner_ID is never valid */ + + acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000; + + /* Event counters */ + + acpi_method_count = 0; + acpi_sci_count = 0; + acpi_gpe_count = 0; + + for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { + acpi_fixed_event_count[i] = 0; + } + +#if (!ACPI_REDUCED_HARDWARE) + + /* GPE/SCI support */ + + acpi_gbl_all_gpes_initialized = FALSE; + acpi_gbl_gpe_xrupt_list_head = NULL; + acpi_gbl_gpe_fadt_blocks[0] = NULL; + acpi_gbl_gpe_fadt_blocks[1] = NULL; + acpi_current_gpe_count = 0; + + acpi_gbl_global_event_handler = NULL; + acpi_gbl_sci_handler_list = NULL; + +#endif /* !ACPI_REDUCED_HARDWARE */ + + /* Global handlers */ + + acpi_gbl_global_notify[0].handler = NULL; + acpi_gbl_global_notify[1].handler = NULL; + acpi_gbl_exception_handler = NULL; + acpi_gbl_init_handler = NULL; + acpi_gbl_table_handler = NULL; + acpi_gbl_interface_handler = NULL; + + /* Global Lock support */ + + acpi_gbl_global_lock_semaphore = NULL; + acpi_gbl_global_lock_mutex = NULL; + acpi_gbl_global_lock_acquired = FALSE; + acpi_gbl_global_lock_handle = 0; + acpi_gbl_global_lock_present = FALSE; + + /* Miscellaneous variables */ + + acpi_gbl_DSDT = NULL; + acpi_gbl_cm_single_step = FALSE; + acpi_gbl_shutdown = FALSE; + acpi_gbl_ns_lookup_count = 0; + acpi_gbl_ps_find_count = 0; + acpi_gbl_acpi_hardware_present = TRUE; + acpi_gbl_last_owner_id_index = 0; + acpi_gbl_next_owner_id_offset = 0; + acpi_gbl_trace_dbg_level = 0; + acpi_gbl_trace_dbg_layer = 0; + acpi_gbl_debugger_configuration = DEBUGGER_THREADING; + acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT; + acpi_gbl_osi_mutex = NULL; + acpi_gbl_reg_methods_executed = FALSE; + + /* Hardware oriented */ + + acpi_gbl_events_initialized = FALSE; + acpi_gbl_system_awake_and_running = TRUE; + + /* Namespace */ + + acpi_gbl_module_code_list = NULL; + acpi_gbl_root_node = NULL; + acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME; + acpi_gbl_root_node_struct.descriptor_type = ACPI_DESC_TYPE_NAMED; + acpi_gbl_root_node_struct.type = ACPI_TYPE_DEVICE; + acpi_gbl_root_node_struct.parent = NULL; + acpi_gbl_root_node_struct.child = NULL; + acpi_gbl_root_node_struct.peer = NULL; + acpi_gbl_root_node_struct.object = NULL; + +#ifdef ACPI_DISASSEMBLER + acpi_gbl_external_list = NULL; + acpi_gbl_num_external_methods = 0; + acpi_gbl_resolved_external_methods = 0; +#endif + +#ifdef ACPI_DEBUG_OUTPUT + acpi_gbl_lowest_stack_pointer = ACPI_CAST_PTR(acpi_size, ACPI_SIZE_MAX); +#endif + +#ifdef ACPI_DBG_TRACK_ALLOCATIONS + acpi_gbl_display_final_mem_stats = FALSE; + acpi_gbl_disable_mem_tracking = FALSE; +#endif + + ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = FALSE); + + return_ACPI_STATUS(AE_OK); +} + /****************************************************************************** * * FUNCTION: acpi_ut_terminate diff --git a/tools/power/acpi/Makefile b/tools/power/acpi/Makefile index e5a3c4be2a10..61446dbf70a6 100644 --- a/tools/power/acpi/Makefile +++ b/tools/power/acpi/Makefile @@ -112,6 +112,7 @@ DUMP_OBJS = \ tbxfroot.o\ utbuffer.o\ utexcep.o\ + utglobal.o\ utmath.o\ utstring.o\ utxferror.o\ diff --git a/tools/power/acpi/tools/acpidump/acpidump.h b/tools/power/acpi/tools/acpidump/acpidump.h index 46f519597fe5..8efc84824308 100644 --- a/tools/power/acpi/tools/acpidump/acpidump.h +++ b/tools/power/acpi/tools/acpidump/acpidump.h @@ -47,7 +47,6 @@ #ifdef _DECLARE_GLOBALS #define EXTERN #define INIT_GLOBAL(a,b) a=b -#define DEFINE_ACPI_GLOBALS 1 #else #define EXTERN extern #define INIT_GLOBAL(a,b) a -- cgit v1.2.3 From 83b80bace4bdfc61abd16ca6ad0a51734a0f57f0 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 8 Jul 2014 10:06:45 +0800 Subject: ACPICA: OSL: Clean up acpi_os_printf()/acpi_os_vprintf() stubs This patch is mainly for acpidump where there are redundant acpi_os_printf()/acpi_os_vprintf() stubs implemented. This patch cleans up such specific implementation by linking acpidump to osunixxf.c/oswinxf.c. To make acpi_os_printf() exported by osunixxf.c/oswinxf.c to behave as the old acpidump specific ones, applications need to: 1. Initialize acpi_gbl_db_output_flags to ACPI_DB_CONSOLE_OUTPUT. This is automatically done by ACPI_INIT_GLOBAL(), applications need to link utglobal.o to utilize this mechanism. 2. Initialize acpi_gbl_output_file to stdout. For GCC, assigning stdout to acpi_gbl_output_file using ACPI_INIT_GLOBAL() is not possible as stdout is not a constant in GCC environment. As an alternative solution, stdout assignment is put into acpi_os_initialize(). Thus acpi_os_initialize() need to be invoked very early by the applications to initialize the default output of acpi_os_printf(). This patch also releases osunixxf.c to the Linux kernel. Lv Zheng. Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acglobal.h | 3 +- drivers/acpi/acpica/acutils.h | 1 - drivers/acpi/acpica/utinit.c | 1 - tools/power/acpi/Makefile | 1 + .../acpi/os_specific/service_layers/osunixxf.c | 1304 ++++++++++++++++++++ tools/power/acpi/tools/acpidump/apdump.c | 22 - tools/power/acpi/tools/acpidump/apmain.c | 1 + 7 files changed, 1308 insertions(+), 25 deletions(-) create mode 100644 tools/power/acpi/os_specific/service_layers/osunixxf.c (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 115eedcade1e..78cc366ca878 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -297,7 +297,7 @@ ACPI_GLOBAL(u32, acpi_gbl_trace_dbg_layer); * ****************************************************************************/ -ACPI_GLOBAL(u8, acpi_gbl_db_output_flags); +ACPI_INIT_GLOBAL(u8, acpi_gbl_db_output_flags, ACPI_DB_CONSOLE_OUTPUT); #ifdef ACPI_DISASSEMBLER @@ -362,6 +362,7 @@ ACPI_GLOBAL(u32, acpi_gbl_num_objects); #ifdef ACPI_APPLICATION ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_debug_file, NULL); +ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_output_file, NULL); #endif /* ACPI_APPLICATION */ diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 8a4414869566..e0adbc1f52ed 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -95,7 +95,6 @@ extern const char *acpi_gbl_pt_decode[]; #ifdef ACPI_ASL_COMPILER #include -extern FILE *acpi_gbl_output_file; #define ACPI_MSG_REDIRECT_BEGIN \ FILE *output_file = acpi_gbl_output_file; \ diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c index a7936623998f..77120ec9ea86 100644 --- a/drivers/acpi/acpica/utinit.c +++ b/drivers/acpi/acpica/utinit.c @@ -207,7 +207,6 @@ acpi_status acpi_ut_init_globals(void) acpi_gbl_trace_dbg_level = 0; acpi_gbl_trace_dbg_layer = 0; acpi_gbl_debugger_configuration = DEBUGGER_THREADING; - acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT; acpi_gbl_osi_mutex = NULL; acpi_gbl_reg_methods_executed = FALSE; diff --git a/tools/power/acpi/Makefile b/tools/power/acpi/Makefile index 61446dbf70a6..f88a251863c5 100644 --- a/tools/power/acpi/Makefile +++ b/tools/power/acpi/Makefile @@ -108,6 +108,7 @@ DUMP_OBJS = \ apmain.o\ osunixdir.o\ osunixmap.o\ + osunixxf.o\ tbprint.o\ tbxfroot.o\ utbuffer.o\ diff --git a/tools/power/acpi/os_specific/service_layers/osunixxf.c b/tools/power/acpi/os_specific/service_layers/osunixxf.c new file mode 100644 index 000000000000..0e6a8a6be441 --- /dev/null +++ b/tools/power/acpi/os_specific/service_layers/osunixxf.c @@ -0,0 +1,1304 @@ +/****************************************************************************** + * + * Module Name: osunixxf - UNIX OSL interfaces + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2014, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +/* + * These interfaces are required in order to compile the ASL compiler and the + * various ACPICA tools under Linux or other Unix-like system. + */ +#include +#include "accommon.h" +#include "amlcode.h" +#include "acparser.h" +#include "acdebug.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#define _COMPONENT ACPI_OS_SERVICES +ACPI_MODULE_NAME("osunixxf") + +u8 acpi_gbl_debug_timeout = FALSE; + +/* Upcalls to acpi_exec */ + +void +ae_table_override(struct acpi_table_header *existing_table, + struct acpi_table_header **new_table); + +typedef void *(*PTHREAD_CALLBACK) (void *); + +/* Buffer used by acpi_os_vprintf */ + +#define ACPI_VPRINTF_BUFFER_SIZE 512 +#define _ASCII_NEWLINE '\n' + +/* Terminal support for acpi_exec only */ + +#ifdef ACPI_EXEC_APP +#include + +struct termios original_term_attributes; +int term_attributes_were_set = 0; + +acpi_status acpi_ut_read_line(char *buffer, u32 buffer_length, u32 *bytes_read); + +static void os_enter_line_edit_mode(void); + +static void os_exit_line_edit_mode(void); + +/****************************************************************************** + * + * FUNCTION: os_enter_line_edit_mode, os_exit_line_edit_mode + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Enter/Exit the raw character input mode for the terminal. + * + * Interactive line-editing support for the AML debugger. Used with the + * common/acgetline module. + * + * readline() is not used because of non-portability. It is not available + * on all systems, and if it is, often the package must be manually installed. + * + * Therefore, we use the POSIX tcgetattr/tcsetattr and do the minimal line + * editing that we need in acpi_os_get_line. + * + * If the POSIX tcgetattr/tcsetattr interfaces are unavailable, these + * calls will also work: + * For os_enter_line_edit_mode: system ("stty cbreak -echo") + * For os_exit_line_edit_mode: system ("stty cooked echo") + * + *****************************************************************************/ + +static void os_enter_line_edit_mode(void) +{ + struct termios local_term_attributes; + + /* Get and keep the original attributes */ + + if (tcgetattr(STDIN_FILENO, &original_term_attributes)) { + fprintf(stderr, "Could not get terminal attributes!\n"); + return; + } + + /* Set the new attributes to enable raw character input */ + + memcpy(&local_term_attributes, &original_term_attributes, + sizeof(struct termios)); + + local_term_attributes.c_lflag &= ~(ICANON | ECHO); + local_term_attributes.c_cc[VMIN] = 1; + local_term_attributes.c_cc[VTIME] = 0; + + if (tcsetattr(STDIN_FILENO, TCSANOW, &local_term_attributes)) { + fprintf(stderr, "Could not set terminal attributes!\n"); + return; + } + + term_attributes_were_set = 1; +} + +static void os_exit_line_edit_mode(void) +{ + + if (!term_attributes_were_set) { + return; + } + + /* Set terminal attributes back to the original values */ + + if (tcsetattr(STDIN_FILENO, TCSANOW, &original_term_attributes)) { + fprintf(stderr, "Could not restore terminal attributes!\n"); + } +} + +#else + +/* These functions are not needed for other ACPICA utilities */ + +#define os_enter_line_edit_mode() +#define os_exit_line_edit_mode() +#endif + +/****************************************************************************** + * + * FUNCTION: acpi_os_initialize, acpi_os_terminate + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Initialize and terminate this module. + * + *****************************************************************************/ + +acpi_status acpi_os_initialize(void) +{ + + acpi_gbl_output_file = stdout; + + os_enter_line_edit_mode(); + return (AE_OK); +} + +acpi_status acpi_os_terminate(void) +{ + + os_exit_line_edit_mode(); + return (AE_OK); +} + +#ifndef ACPI_USE_NATIVE_RSDP_POINTER +/****************************************************************************** + * + * FUNCTION: acpi_os_get_root_pointer + * + * PARAMETERS: None + * + * RETURN: RSDP physical address + * + * DESCRIPTION: Gets the ACPI root pointer (RSDP) + * + *****************************************************************************/ + +acpi_physical_address acpi_os_get_root_pointer(void) +{ + + return (0); +} +#endif + +/****************************************************************************** + * + * FUNCTION: acpi_os_predefined_override + * + * PARAMETERS: init_val - Initial value of the predefined object + * new_val - The new value for the object + * + * RETURN: Status, pointer to value. Null pointer returned if not + * overriding. + * + * DESCRIPTION: Allow the OS to override predefined names + * + *****************************************************************************/ + +acpi_status +acpi_os_predefined_override(const struct acpi_predefined_names * init_val, + acpi_string * new_val) +{ + + if (!init_val || !new_val) { + return (AE_BAD_PARAMETER); + } + + *new_val = NULL; + return (AE_OK); +} + +/****************************************************************************** + * + * FUNCTION: acpi_os_table_override + * + * PARAMETERS: existing_table - Header of current table (probably + * firmware) + * new_table - Where an entire new table is returned. + * + * RETURN: Status, pointer to new table. Null pointer returned if no + * table is available to override + * + * DESCRIPTION: Return a different version of a table if one is available + * + *****************************************************************************/ + +acpi_status +acpi_os_table_override(struct acpi_table_header * existing_table, + struct acpi_table_header ** new_table) +{ + + if (!existing_table || !new_table) { + return (AE_BAD_PARAMETER); + } + + *new_table = NULL; + +#ifdef ACPI_EXEC_APP + + ae_table_override(existing_table, new_table); + return (AE_OK); +#else + + return (AE_NO_ACPI_TABLES); +#endif +} + +/****************************************************************************** + * + * FUNCTION: acpi_os_physical_table_override + * + * PARAMETERS: existing_table - Header of current table (probably firmware) + * new_address - Where new table address is returned + * (Physical address) + * new_table_length - Where new table length is returned + * + * RETURN: Status, address/length of new table. Null pointer returned + * if no table is available to override. + * + * DESCRIPTION: Returns AE_SUPPORT, function not used in user space. + * + *****************************************************************************/ + +acpi_status +acpi_os_physical_table_override(struct acpi_table_header * existing_table, + acpi_physical_address * new_address, + u32 *new_table_length) +{ + + return (AE_SUPPORT); +} + +/****************************************************************************** + * + * FUNCTION: acpi_os_redirect_output + * + * PARAMETERS: destination - An open file handle/pointer + * + * RETURN: None + * + * DESCRIPTION: Causes redirect of acpi_os_printf and acpi_os_vprintf + * + *****************************************************************************/ + +void acpi_os_redirect_output(void *destination) +{ + + acpi_gbl_output_file = destination; +} + +/****************************************************************************** + * + * FUNCTION: acpi_os_printf + * + * PARAMETERS: fmt, ... - Standard printf format + * + * RETURN: None + * + * DESCRIPTION: Formatted output. Note: very similar to acpi_os_vprintf + * (performance), changes should be tracked in both functions. + * + *****************************************************************************/ + +void ACPI_INTERNAL_VAR_XFACE acpi_os_printf(const char *fmt, ...) +{ + va_list args; + u8 flags; + + flags = acpi_gbl_db_output_flags; + if (flags & ACPI_DB_REDIRECTABLE_OUTPUT) { + + /* Output is directable to either a file (if open) or the console */ + + if (acpi_gbl_debug_file) { + + /* Output file is open, send the output there */ + + va_start(args, fmt); + vfprintf(acpi_gbl_debug_file, fmt, args); + va_end(args); + } else { + /* No redirection, send output to console (once only!) */ + + flags |= ACPI_DB_CONSOLE_OUTPUT; + } + } + + if (flags & ACPI_DB_CONSOLE_OUTPUT) { + va_start(args, fmt); + vfprintf(acpi_gbl_output_file, fmt, args); + va_end(args); + } +} + +/****************************************************************************** + * + * FUNCTION: acpi_os_vprintf + * + * PARAMETERS: fmt - Standard printf format + * args - Argument list + * + * RETURN: None + * + * DESCRIPTION: Formatted output with argument list pointer. Note: very + * similar to acpi_os_printf, changes should be tracked in both + * functions. + * + *****************************************************************************/ + +void acpi_os_vprintf(const char *fmt, va_list args) +{ + u8 flags; + char buffer[ACPI_VPRINTF_BUFFER_SIZE]; + + /* + * We build the output string in a local buffer because we may be + * outputting the buffer twice. Using vfprintf is problematic because + * some implementations modify the args pointer/structure during + * execution. Thus, we use the local buffer for portability. + * + * Note: Since this module is intended for use by the various ACPICA + * utilities/applications, we can safely declare the buffer on the stack. + * Also, This function is used for relatively small error messages only. + */ + vsnprintf(buffer, ACPI_VPRINTF_BUFFER_SIZE, fmt, args); + + flags = acpi_gbl_db_output_flags; + if (flags & ACPI_DB_REDIRECTABLE_OUTPUT) { + + /* Output is directable to either a file (if open) or the console */ + + if (acpi_gbl_debug_file) { + + /* Output file is open, send the output there */ + + fputs(buffer, acpi_gbl_debug_file); + } else { + /* No redirection, send output to console (once only!) */ + + flags |= ACPI_DB_CONSOLE_OUTPUT; + } + } + + if (flags & ACPI_DB_CONSOLE_OUTPUT) { + fputs(buffer, acpi_gbl_output_file); + } +} + +#ifndef ACPI_EXEC_APP +/****************************************************************************** + * + * FUNCTION: acpi_os_get_line + * + * PARAMETERS: buffer - Where to return the command line + * buffer_length - Maximum length of Buffer + * bytes_read - Where the actual byte count is returned + * + * RETURN: Status and actual bytes read + * + * DESCRIPTION: Get the next input line from the terminal. NOTE: For the + * acpi_exec utility, we use the acgetline module instead to + * provide line-editing and history support. + * + *****************************************************************************/ + +acpi_status acpi_os_get_line(char *buffer, u32 buffer_length, u32 *bytes_read) +{ + int input_char; + u32 end_of_line; + + /* Standard acpi_os_get_line for all utilities except acpi_exec */ + + for (end_of_line = 0;; end_of_line++) { + if (end_of_line >= buffer_length) { + return (AE_BUFFER_OVERFLOW); + } + + if ((input_char = getchar()) == EOF) { + return (AE_ERROR); + } + + if (!input_char || input_char == _ASCII_NEWLINE) { + break; + } + + buffer[end_of_line] = (char)input_char; + } + + /* Null terminate the buffer */ + + buffer[end_of_line] = 0; + + /* Return the number of bytes in the string */ + + if (bytes_read) { + *bytes_read = end_of_line; + } + + return (AE_OK); +} +#endif + +#ifndef ACPI_USE_NATIVE_MEMORY_MAPPING +/****************************************************************************** + * + * FUNCTION: acpi_os_map_memory + * + * PARAMETERS: where - Physical address of memory to be mapped + * length - How much memory to map + * + * RETURN: Pointer to mapped memory. Null on error. + * + * DESCRIPTION: Map physical memory into caller's address space + * + *****************************************************************************/ + +void *acpi_os_map_memory(acpi_physical_address where, acpi_size length) +{ + + return (ACPI_TO_POINTER((acpi_size) where)); +} + +/****************************************************************************** + * + * FUNCTION: acpi_os_unmap_memory + * + * PARAMETERS: where - Logical address of memory to be unmapped + * length - How much memory to unmap + * + * RETURN: None. + * + * DESCRIPTION: Delete a previously created mapping. Where and Length must + * correspond to a previous mapping exactly. + * + *****************************************************************************/ + +void acpi_os_unmap_memory(void *where, acpi_size length) +{ + + return; +} +#endif + +/****************************************************************************** + * + * FUNCTION: acpi_os_allocate + * + * PARAMETERS: size - Amount to allocate, in bytes + * + * RETURN: Pointer to the new allocation. Null on error. + * + * DESCRIPTION: Allocate memory. Algorithm is dependent on the OS. + * + *****************************************************************************/ + +void *acpi_os_allocate(acpi_size size) +{ + void *mem; + + mem = (void *)malloc((size_t) size); + return (mem); +} + +#ifdef USE_NATIVE_ALLOCATE_ZEROED +/****************************************************************************** + * + * FUNCTION: acpi_os_allocate_zeroed + * + * PARAMETERS: size - Amount to allocate, in bytes + * + * RETURN: Pointer to the new allocation. Null on error. + * + * DESCRIPTION: Allocate and zero memory. Algorithm is dependent on the OS. + * + *****************************************************************************/ + +void *acpi_os_allocate_zeroed(acpi_size size) +{ + void *mem; + + mem = (void *)calloc(1, (size_t) size); + return (mem); +} +#endif + +/****************************************************************************** + * + * FUNCTION: acpi_os_free + * + * PARAMETERS: mem - Pointer to previously allocated memory + * + * RETURN: None. + * + * DESCRIPTION: Free memory allocated via acpi_os_allocate + * + *****************************************************************************/ + +void acpi_os_free(void *mem) +{ + + free(mem); +} + +#ifdef ACPI_SINGLE_THREADED +/****************************************************************************** + * + * FUNCTION: Semaphore stub functions + * + * DESCRIPTION: Stub functions used for single-thread applications that do + * not require semaphore synchronization. Full implementations + * of these functions appear after the stubs. + * + *****************************************************************************/ + +acpi_status +acpi_os_create_semaphore(u32 max_units, + u32 initial_units, acpi_handle * out_handle) +{ + *out_handle = (acpi_handle) 1; + return (AE_OK); +} + +acpi_status acpi_os_delete_semaphore(acpi_handle handle) +{ + return (AE_OK); +} + +acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout) +{ + return (AE_OK); +} + +acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units) +{ + return (AE_OK); +} + +#else +/****************************************************************************** + * + * FUNCTION: acpi_os_create_semaphore + * + * PARAMETERS: initial_units - Units to be assigned to the new semaphore + * out_handle - Where a handle will be returned + * + * RETURN: Status + * + * DESCRIPTION: Create an OS semaphore + * + *****************************************************************************/ + +acpi_status +acpi_os_create_semaphore(u32 max_units, + u32 initial_units, acpi_handle * out_handle) +{ + sem_t *sem; + + if (!out_handle) { + return (AE_BAD_PARAMETER); + } +#ifdef __APPLE__ + { + char *semaphore_name = tmpnam(NULL); + + sem = + sem_open(semaphore_name, O_EXCL | O_CREAT, 0755, + initial_units); + if (!sem) { + return (AE_NO_MEMORY); + } + sem_unlink(semaphore_name); /* This just deletes the name */ + } + +#else + sem = acpi_os_allocate(sizeof(sem_t)); + if (!sem) { + return (AE_NO_MEMORY); + } + + if (sem_init(sem, 0, initial_units) == -1) { + acpi_os_free(sem); + return (AE_BAD_PARAMETER); + } +#endif + + *out_handle = (acpi_handle) sem; + return (AE_OK); +} + +/****************************************************************************** + * + * FUNCTION: acpi_os_delete_semaphore + * + * PARAMETERS: handle - Handle returned by acpi_os_create_semaphore + * + * RETURN: Status + * + * DESCRIPTION: Delete an OS semaphore + * + *****************************************************************************/ + +acpi_status acpi_os_delete_semaphore(acpi_handle handle) +{ + sem_t *sem = (sem_t *) handle; + + if (!sem) { + return (AE_BAD_PARAMETER); + } + + if (sem_destroy(sem) == -1) { + return (AE_BAD_PARAMETER); + } + + return (AE_OK); +} + +/****************************************************************************** + * + * FUNCTION: acpi_os_wait_semaphore + * + * PARAMETERS: handle - Handle returned by acpi_os_create_semaphore + * units - How many units to wait for + * msec_timeout - How long to wait (milliseconds) + * + * RETURN: Status + * + * DESCRIPTION: Wait for units + * + *****************************************************************************/ + +acpi_status +acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 msec_timeout) +{ + acpi_status status = AE_OK; + sem_t *sem = (sem_t *) handle; +#ifndef ACPI_USE_ALTERNATE_TIMEOUT + struct timespec time; + int ret_val; +#endif + + if (!sem) { + return (AE_BAD_PARAMETER); + } + + switch (msec_timeout) { + /* + * No Wait: + * -------- + * A zero timeout value indicates that we shouldn't wait - just + * acquire the semaphore if available otherwise return AE_TIME + * (a.k.a. 'would block'). + */ + case 0: + + if (sem_trywait(sem) == -1) { + status = (AE_TIME); + } + break; + + /* Wait Indefinitely */ + + case ACPI_WAIT_FOREVER: + + if (sem_wait(sem)) { + status = (AE_TIME); + } + break; + + /* Wait with msec_timeout */ + + default: + +#ifdef ACPI_USE_ALTERNATE_TIMEOUT + /* + * Alternate timeout mechanism for environments where + * sem_timedwait is not available or does not work properly. + */ + while (msec_timeout) { + if (sem_trywait(sem) == 0) { + + /* Got the semaphore */ + return (AE_OK); + } + + if (msec_timeout >= 10) { + msec_timeout -= 10; + usleep(10 * ACPI_USEC_PER_MSEC); /* ten milliseconds */ + } else { + msec_timeout--; + usleep(ACPI_USEC_PER_MSEC); /* one millisecond */ + } + } + status = (AE_TIME); +#else + /* + * The interface to sem_timedwait is an absolute time, so we need to + * get the current time, then add in the millisecond Timeout value. + */ + if (clock_gettime(CLOCK_REALTIME, &time) == -1) { + perror("clock_gettime"); + return (AE_TIME); + } + + time.tv_sec += (msec_timeout / ACPI_MSEC_PER_SEC); + time.tv_nsec += + ((msec_timeout % ACPI_MSEC_PER_SEC) * ACPI_NSEC_PER_MSEC); + + /* Handle nanosecond overflow (field must be less than one second) */ + + if (time.tv_nsec >= ACPI_NSEC_PER_SEC) { + time.tv_sec += (time.tv_nsec / ACPI_NSEC_PER_SEC); + time.tv_nsec = (time.tv_nsec % ACPI_NSEC_PER_SEC); + } + + while (((ret_val = sem_timedwait(sem, &time)) == -1) + && (errno == EINTR)) { + continue; + } + + if (ret_val != 0) { + if (errno != ETIMEDOUT) { + perror("sem_timedwait"); + } + status = (AE_TIME); + } +#endif + break; + } + + return (status); +} + +/****************************************************************************** + * + * FUNCTION: acpi_os_signal_semaphore + * + * PARAMETERS: handle - Handle returned by acpi_os_create_semaphore + * units - Number of units to send + * + * RETURN: Status + * + * DESCRIPTION: Send units + * + *****************************************************************************/ + +acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units) +{ + sem_t *sem = (sem_t *) handle; + + if (!sem) { + return (AE_BAD_PARAMETER); + } + + if (sem_post(sem) == -1) { + return (AE_LIMIT); + } + + return (AE_OK); +} + +#endif /* ACPI_SINGLE_THREADED */ + +/****************************************************************************** + * + * FUNCTION: Spinlock interfaces + * + * DESCRIPTION: Map these interfaces to semaphore interfaces + * + *****************************************************************************/ + +acpi_status acpi_os_create_lock(acpi_spinlock * out_handle) +{ + + return (acpi_os_create_semaphore(1, 1, out_handle)); +} + +void acpi_os_delete_lock(acpi_spinlock handle) +{ + acpi_os_delete_semaphore(handle); +} + +acpi_cpu_flags acpi_os_acquire_lock(acpi_handle handle) +{ + acpi_os_wait_semaphore(handle, 1, 0xFFFF); + return (0); +} + +void acpi_os_release_lock(acpi_spinlock handle, acpi_cpu_flags flags) +{ + acpi_os_signal_semaphore(handle, 1); +} + +/****************************************************************************** + * + * FUNCTION: acpi_os_install_interrupt_handler + * + * PARAMETERS: interrupt_number - Level handler should respond to. + * isr - Address of the ACPI interrupt handler + * except_ptr - Where status is returned + * + * RETURN: Handle to the newly installed handler. + * + * DESCRIPTION: Install an interrupt handler. Used to install the ACPI + * OS-independent handler. + * + *****************************************************************************/ + +u32 +acpi_os_install_interrupt_handler(u32 interrupt_number, + acpi_osd_handler service_routine, + void *context) +{ + + return (AE_OK); +} + +/****************************************************************************** + * + * FUNCTION: acpi_os_remove_interrupt_handler + * + * PARAMETERS: handle - Returned when handler was installed + * + * RETURN: Status + * + * DESCRIPTION: Uninstalls an interrupt handler. + * + *****************************************************************************/ + +acpi_status +acpi_os_remove_interrupt_handler(u32 interrupt_number, + acpi_osd_handler service_routine) +{ + + return (AE_OK); +} + +/****************************************************************************** + * + * FUNCTION: acpi_os_stall + * + * PARAMETERS: microseconds - Time to sleep + * + * RETURN: Blocks until sleep is completed. + * + * DESCRIPTION: Sleep at microsecond granularity + * + *****************************************************************************/ + +void acpi_os_stall(u32 microseconds) +{ + + if (microseconds) { + usleep(microseconds); + } +} + +/****************************************************************************** + * + * FUNCTION: acpi_os_sleep + * + * PARAMETERS: milliseconds - Time to sleep + * + * RETURN: Blocks until sleep is completed. + * + * DESCRIPTION: Sleep at millisecond granularity + * + *****************************************************************************/ + +void acpi_os_sleep(u64 milliseconds) +{ + + /* Sleep for whole seconds */ + + sleep(milliseconds / ACPI_MSEC_PER_SEC); + + /* + * Sleep for remaining microseconds. + * Arg to usleep() is in usecs and must be less than 1,000,000 (1 second). + */ + usleep((milliseconds % ACPI_MSEC_PER_SEC) * ACPI_USEC_PER_MSEC); +} + +/****************************************************************************** + * + * FUNCTION: acpi_os_get_timer + * + * PARAMETERS: None + * + * RETURN: Current time in 100 nanosecond units + * + * DESCRIPTION: Get the current system time + * + *****************************************************************************/ + +u64 acpi_os_get_timer(void) +{ + struct timeval time; + + /* This timer has sufficient resolution for user-space application code */ + + gettimeofday(&time, NULL); + + /* (Seconds * 10^7 = 100ns(10^-7)) + (Microseconds(10^-6) * 10^1 = 100ns) */ + + return (((u64)time.tv_sec * ACPI_100NSEC_PER_SEC) + + ((u64)time.tv_usec * ACPI_100NSEC_PER_USEC)); +} + +/****************************************************************************** + * + * FUNCTION: acpi_os_read_pci_configuration + * + * PARAMETERS: pci_id - Seg/Bus/Dev + * pci_register - Device Register + * value - Buffer where value is placed + * width - Number of bits + * + * RETURN: Status + * + * DESCRIPTION: Read data from PCI configuration space + * + *****************************************************************************/ + +acpi_status +acpi_os_read_pci_configuration(struct acpi_pci_id *pci_id, + u32 pci_register, u64 *value, u32 width) +{ + + *value = 0; + return (AE_OK); +} + +/****************************************************************************** + * + * FUNCTION: acpi_os_write_pci_configuration + * + * PARAMETERS: pci_id - Seg/Bus/Dev + * pci_register - Device Register + * value - Value to be written + * width - Number of bits + * + * RETURN: Status. + * + * DESCRIPTION: Write data to PCI configuration space + * + *****************************************************************************/ + +acpi_status +acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id, + u32 pci_register, u64 value, u32 width) +{ + + return (AE_OK); +} + +/****************************************************************************** + * + * FUNCTION: acpi_os_read_port + * + * PARAMETERS: address - Address of I/O port/register to read + * value - Where value is placed + * width - Number of bits + * + * RETURN: Value read from port + * + * DESCRIPTION: Read data from an I/O port or register + * + *****************************************************************************/ + +acpi_status acpi_os_read_port(acpi_io_address address, u32 *value, u32 width) +{ + + switch (width) { + case 8: + + *value = 0xFF; + break; + + case 16: + + *value = 0xFFFF; + break; + + case 32: + + *value = 0xFFFFFFFF; + break; + + default: + + return (AE_BAD_PARAMETER); + } + + return (AE_OK); +} + +/****************************************************************************** + * + * FUNCTION: acpi_os_write_port + * + * PARAMETERS: address - Address of I/O port/register to write + * value - Value to write + * width - Number of bits + * + * RETURN: None + * + * DESCRIPTION: Write data to an I/O port or register + * + *****************************************************************************/ + +acpi_status acpi_os_write_port(acpi_io_address address, u32 value, u32 width) +{ + + return (AE_OK); +} + +/****************************************************************************** + * + * FUNCTION: acpi_os_read_memory + * + * PARAMETERS: address - Physical Memory Address to read + * value - Where value is placed + * width - Number of bits (8,16,32, or 64) + * + * RETURN: Value read from physical memory address. Always returned + * as a 64-bit integer, regardless of the read width. + * + * DESCRIPTION: Read data from a physical memory address + * + *****************************************************************************/ + +acpi_status +acpi_os_read_memory(acpi_physical_address address, u64 *value, u32 width) +{ + + switch (width) { + case 8: + case 16: + case 32: + case 64: + + *value = 0; + break; + + default: + + return (AE_BAD_PARAMETER); + } + return (AE_OK); +} + +/****************************************************************************** + * + * FUNCTION: acpi_os_write_memory + * + * PARAMETERS: address - Physical Memory Address to write + * value - Value to write + * width - Number of bits (8,16,32, or 64) + * + * RETURN: None + * + * DESCRIPTION: Write data to a physical memory address + * + *****************************************************************************/ + +acpi_status +acpi_os_write_memory(acpi_physical_address address, u64 value, u32 width) +{ + + return (AE_OK); +} + +/****************************************************************************** + * + * FUNCTION: acpi_os_readable + * + * PARAMETERS: pointer - Area to be verified + * length - Size of area + * + * RETURN: TRUE if readable for entire length + * + * DESCRIPTION: Verify that a pointer is valid for reading + * + *****************************************************************************/ + +u8 acpi_os_readable(void *pointer, acpi_size length) +{ + + return (TRUE); +} + +/****************************************************************************** + * + * FUNCTION: acpi_os_writable + * + * PARAMETERS: pointer - Area to be verified + * length - Size of area + * + * RETURN: TRUE if writable for entire length + * + * DESCRIPTION: Verify that a pointer is valid for writing + * + *****************************************************************************/ + +u8 acpi_os_writable(void *pointer, acpi_size length) +{ + + return (TRUE); +} + +/****************************************************************************** + * + * FUNCTION: acpi_os_signal + * + * PARAMETERS: function - ACPI A signal function code + * info - Pointer to function-dependent structure + * + * RETURN: Status + * + * DESCRIPTION: Miscellaneous functions. Example implementation only. + * + *****************************************************************************/ + +acpi_status acpi_os_signal(u32 function, void *info) +{ + + switch (function) { + case ACPI_SIGNAL_FATAL: + + break; + + case ACPI_SIGNAL_BREAKPOINT: + + break; + + default: + + break; + } + + return (AE_OK); +} + +/* Optional multi-thread support */ + +#ifndef ACPI_SINGLE_THREADED +/****************************************************************************** + * + * FUNCTION: acpi_os_get_thread_id + * + * PARAMETERS: None + * + * RETURN: Id of the running thread + * + * DESCRIPTION: Get the ID of the current (running) thread + * + *****************************************************************************/ + +acpi_thread_id acpi_os_get_thread_id(void) +{ + pthread_t thread; + + thread = pthread_self(); + return (ACPI_CAST_PTHREAD_T(thread)); +} + +/****************************************************************************** + * + * FUNCTION: acpi_os_execute + * + * PARAMETERS: type - Type of execution + * function - Address of the function to execute + * context - Passed as a parameter to the function + * + * RETURN: Status. + * + * DESCRIPTION: Execute a new thread + * + *****************************************************************************/ + +acpi_status +acpi_os_execute(acpi_execute_type type, + acpi_osd_exec_callback function, void *context) +{ + pthread_t thread; + int ret; + + ret = + pthread_create(&thread, NULL, (PTHREAD_CALLBACK) function, context); + if (ret) { + acpi_os_printf("Create thread failed"); + } + return (0); +} + +#else /* ACPI_SINGLE_THREADED */ +acpi_thread_id acpi_os_get_thread_id(void) +{ + return (1); +} + +acpi_status +acpi_os_execute(acpi_execute_type type, + acpi_osd_exec_callback function, void *context) +{ + + function(context); + + return (AE_OK); +} + +#endif /* ACPI_SINGLE_THREADED */ + +/****************************************************************************** + * + * FUNCTION: acpi_os_wait_events_complete + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Wait for all asynchronous events to complete. This + * implementation does nothing. + * + *****************************************************************************/ + +void acpi_os_wait_events_complete(void) +{ + return; +} diff --git a/tools/power/acpi/tools/acpidump/apdump.c b/tools/power/acpi/tools/acpidump/apdump.c index 3cac12378366..e8729aa3a60e 100644 --- a/tools/power/acpi/tools/acpidump/apdump.c +++ b/tools/power/acpi/tools/acpidump/apdump.c @@ -427,25 +427,3 @@ exit: free(table); return (table_status); } - -/****************************************************************************** - * - * FUNCTION: acpi_os* print functions - * - * DESCRIPTION: Used for linkage with ACPICA modules - * - ******************************************************************************/ - -void ACPI_INTERNAL_VAR_XFACE acpi_os_printf(const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - vfprintf(stdout, fmt, args); - va_end(args); -} - -void acpi_os_vprintf(const char *fmt, va_list args) -{ - vfprintf(stdout, fmt, args); -} diff --git a/tools/power/acpi/tools/acpidump/apmain.c b/tools/power/acpi/tools/acpidump/apmain.c index 51e8d638db18..c03e4731f099 100644 --- a/tools/power/acpi/tools/acpidump/apmain.c +++ b/tools/power/acpi/tools/acpidump/apmain.c @@ -288,6 +288,7 @@ int ACPI_SYSTEM_XFACE main(int argc, char *argv[]) u32 i; ACPI_DEBUG_INITIALIZE(); /* For debug version only */ + acpi_os_initialize(); /* Process command line options */ -- cgit v1.2.3 From 80a648c12e4bda45c4f1bb93d83184fb3010ac12 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 8 Jul 2014 10:07:00 +0800 Subject: ACPICA: Utilities: Add formatted printing APIs This patch introduces formatted printing APIs to handle ACPICA specific formatted print requirements. Currently only specific OSPMs will use this customized printing support, Linux kernel doesn't use these APIs at this time. It will be enabled for Linux kernel resident ACPICA after being well tested. So currently this patch is a no-op. The specific formatted printing APIs are useful to ACPICA as: 1. Some portable applications do not link standard C library, so they cannot use standard formatted print APIs directly. 2. Platform specific printing format may differ and thus not portable, for example, u64 is %ull for Linux kernel and is %uI64 for some MSVC versions. 3. Platform specific printing format may conflict with ACPICA's usages while it is not possible for ACPICA developers to test their code for all platforms. For example, developers may generate %pRxxx while Linux kernel treats %pR as structured resource printing and decodes variable argument as a "struct resource" pointer. This patch solves above issues by introducing the new APIs. Note that users of such APIs are not introduced in this patch. Users of acpi_os_file_vprintf()/acpi_ut_file_printf() need to invoke acpi_os_initialize(), this should be taken care by the further patches where such users are introduced. Lv Zheng. Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/Makefile | 2 +- drivers/acpi/acpica/acglobal.h | 5 + drivers/acpi/acpica/acutils.h | 19 + drivers/acpi/acpica/utprint.c | 649 +++++++++++++++++++++ include/acpi/actypes.h | 1 + .../acpi/os_specific/service_layers/osunixxf.c | 7 + 6 files changed, 682 insertions(+), 1 deletion(-) create mode 100644 drivers/acpi/acpica/utprint.c (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index 14b851f1a278..6b9ec239d578 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile @@ -175,5 +175,5 @@ acpi-y += \ utxferror.o \ utxfmutex.o -acpi-$(ACPI_FUTURE_USAGE) += utfileio.o uttrack.o utcache.o +acpi-$(ACPI_FUTURE_USAGE) += utfileio.o utprint.o uttrack.o utcache.o diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 78cc366ca878..ebf02cc10a43 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -364,6 +364,11 @@ ACPI_GLOBAL(u32, acpi_gbl_num_objects); ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_debug_file, NULL); ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_output_file, NULL); +/* Print buffer */ + +ACPI_GLOBAL(acpi_spinlock, acpi_gbl_print_lock); /* For print buffer */ +ACPI_GLOBAL(char, acpi_gbl_print_buffer[1024]); + #endif /* ACPI_APPLICATION */ /***************************************************************************** diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index e0adbc1f52ed..85871c639cc2 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -750,4 +750,23 @@ const struct ah_predefined_name *acpi_ah_match_predefined_name(char *nameseg); const struct ah_device_id *acpi_ah_match_hardware_id(char *hid); +/* + * utprint - printf/vprintf output functions + */ +const char *acpi_ut_scan_number(const char *string, u64 *number_ptr); + +const char *acpi_ut_print_number(char *string, u64 number); + +int +acpi_ut_vsnprintf(char *string, + acpi_size size, const char *format, va_list args); + +int acpi_ut_snprintf(char *string, acpi_size size, const char *format, ...); + +#ifdef ACPI_APPLICATION +int acpi_ut_file_vprintf(ACPI_FILE file, const char *format, va_list args); + +int acpi_ut_file_printf(ACPI_FILE file, const char *format, ...); +#endif + #endif /* _ACUTILS_H */ diff --git a/drivers/acpi/acpica/utprint.c b/drivers/acpi/acpica/utprint.c new file mode 100644 index 000000000000..9d5293fd992f --- /dev/null +++ b/drivers/acpi/acpica/utprint.c @@ -0,0 +1,649 @@ +/****************************************************************************** + * + * Module Name: utprint - Formatted printing routines + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2014, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include "accommon.h" + +#define _COMPONENT ACPI_UTILITIES +ACPI_MODULE_NAME("utprint") + +#define ACPI_FORMAT_SIGN 0x01 +#define ACPI_FORMAT_SIGN_PLUS 0x02 +#define ACPI_FORMAT_SIGN_PLUS_SPACE 0x04 +#define ACPI_FORMAT_ZERO 0x08 +#define ACPI_FORMAT_LEFT 0x10 +#define ACPI_FORMAT_UPPER 0x20 +#define ACPI_FORMAT_PREFIX 0x40 +/* Local prototypes */ +static acpi_size +acpi_ut_bound_string_length(const char *string, acpi_size count); + +static char *acpi_ut_bound_string_output(char *string, const char *end, char c); + +static char *acpi_ut_format_number(char *string, + char *end, + u64 number, + u8 base, s32 width, s32 precision, u8 type); + +static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper); + +/******************************************************************************* + * + * FUNCTION: acpi_ut_bound_string_length + * + * PARAMETERS: string - String with boundary + * count - Boundary of the string + * + * RETURN: Length of the string. + * + * DESCRIPTION: Calculate the length of a string with boundary. + * + ******************************************************************************/ + +static acpi_size +acpi_ut_bound_string_length(const char *string, acpi_size count) +{ + u32 length = 0; + + while (*string && count) { + length++; + string++; + count--; + } + + return (length); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_bound_string_output + * + * PARAMETERS: string - String with boundary + * end - Boundary of the string + * c - Character to be output to the string + * + * RETURN: Updated position for next valid character + * + * DESCRIPTION: Output a character into a string with boundary check. + * + ******************************************************************************/ + +static char *acpi_ut_bound_string_output(char *string, const char *end, char c) +{ + + if (string < end) { + *string = c; + } + ++string; + + return (string); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_put_number + * + * PARAMETERS: string - Buffer to hold reverse-ordered string + * number - Integer to be converted + * base - Base of the integer + * upper - Whether or not using upper cased digits + * + * RETURN: Updated position for next valid character + * + * DESCRIPTION: Convert an integer into a string, note that, the string holds a + * reversed ordered number without the trailing zero. + * + ******************************************************************************/ + +static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper) +{ + const char lower_digits[] = "0123456789abcdef"; + const char upper_digits[] = "0123456789ABCDEF"; + const char *digits; + u64 digit_index; + char *pos; + + pos = string; + digits = upper ? upper_digits : lower_digits; + + if (number == 0) { + *(pos++) = '0'; + } else { + while (number) { + (void)acpi_ut_divide(number, base, &number, + &digit_index); + *(pos++) = digits[digit_index]; + } + } + /* *(Pos++) = '0'; */ + + return (pos); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_scan_number + * + * PARAMETERS: string - String buffer + * number_ptr - Where the number is returned + * + * RETURN: Updated position for next valid character + * + * DESCRIPTION: Scan a string for a decimal integer. + * + ******************************************************************************/ + +const char *acpi_ut_scan_number(const char *string, u64 *number_ptr) +{ + u64 number = 0; + + while (ACPI_IS_DIGIT(*string)) { + number *= 10; + number += *(string++) - '0'; + } + *number_ptr = number; + + return (string); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_print_number + * + * PARAMETERS: string - String buffer + * number - The number to be converted + * + * RETURN: Updated position for next valid character + * + * DESCRIPTION: Print a decimal integer into a string. + * + ******************************************************************************/ + +const char *acpi_ut_print_number(char *string, u64 number) +{ + char ascii_string[20]; + const char *pos1; + char *pos2; + + pos1 = acpi_ut_put_number(ascii_string, number, 10, FALSE); + pos2 = string; + + while (pos1 != ascii_string) { + *(pos2++) = *(--pos1); + } + *pos2 = 0; + + return (string); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_format_number + * + * PARAMETERS: string - String buffer with boundary + * end - Boundary of the string + * number - The number to be converted + * base - Base of the integer + * width - Field width + * precision - Precision of the integer + * type - Special printing flags + * + * RETURN: Updated position for next valid character + * + * DESCRIPTION: Print an integer into a string with any base and any precision. + * + ******************************************************************************/ + +static char *acpi_ut_format_number(char *string, + char *end, + u64 number, + u8 base, s32 width, s32 precision, u8 type) +{ + char sign; + char zero; + u8 need_prefix; + u8 upper; + s32 i; + char reversed_string[66]; + + /* Perform sanity checks */ + + if (base < 2 || base > 16) { + return NULL; + } + if (type & ACPI_FORMAT_LEFT) { + type &= ~ACPI_FORMAT_ZERO; + } + + need_prefix = ((type & ACPI_FORMAT_PREFIX) + && base != 10) ? TRUE : FALSE; + upper = (type & ACPI_FORMAT_UPPER) ? TRUE : FALSE; + zero = (type & ACPI_FORMAT_ZERO) ? '0' : ' '; + + /* Calculate size according to sign and prefix */ + + sign = '\0'; + if (type & ACPI_FORMAT_SIGN) { + if ((s64) number < 0) { + sign = '-'; + number = -(s64) number; + width--; + } else if (type & ACPI_FORMAT_SIGN_PLUS) { + sign = '+'; + width--; + } else if (type & ACPI_FORMAT_SIGN_PLUS_SPACE) { + sign = ' '; + width--; + } + } + if (need_prefix) { + width--; + if (base == 16) { + width--; + } + } + + /* Generate full string in reverse order */ + + i = ACPI_PTR_DIFF(acpi_ut_put_number + (reversed_string, number, base, upper), + reversed_string); + + /* Printing 100 using %2d gives "100", not "00" */ + + if (i > precision) { + precision = i; + } + width -= precision; + + /* Output the string */ + + if (!(type & (ACPI_FORMAT_ZERO | ACPI_FORMAT_LEFT))) { + while (--width >= 0) { + string = acpi_ut_bound_string_output(string, end, ' '); + } + } + if (sign) { + string = acpi_ut_bound_string_output(string, end, sign); + } + if (need_prefix) { + string = acpi_ut_bound_string_output(string, end, '0'); + if (base == 16) { + string = acpi_ut_bound_string_output(string, end, + upper ? 'X' : 'x'); + } + } + if (!(type & ACPI_FORMAT_LEFT)) { + while (--width >= 0) { + string = acpi_ut_bound_string_output(string, end, zero); + } + } + while (i <= --precision) { + string = acpi_ut_bound_string_output(string, end, '0'); + } + while (--i >= 0) { + string = acpi_ut_bound_string_output(string, end, + reversed_string[i]); + } + while (--width >= 0) { + string = acpi_ut_bound_string_output(string, end, ' '); + } + + return (string); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_vsnprintf + * + * PARAMETERS: string - String with boundary + * size - Boundary of the string + * format - Standard printf format + * args - Argument list + * + * RETURN: Size of successfully output bytes + * + * DESCRIPTION: Formatted output to a string using argument list pointer. + * + ******************************************************************************/ + +int +acpi_ut_vsnprintf(char *string, + acpi_size size, const char *format, va_list args) +{ + u8 base = 10; + u8 type = 0; + s32 width = -1; + s32 precision = -1; + char qualifier = 0; + u64 number; + char *pos; + char *end; + char c; + const char *s; + const void *p; + s32 length; + int i; + + pos = string; + end = string + size; + + for (; *format; ++format) { + if (*format != '%') { + pos = acpi_ut_bound_string_output(pos, end, *format); + continue; + } + + /* Process sign */ + + do { + ++format; + if (*format == '#') { + type |= ACPI_FORMAT_PREFIX; + } else if (*format == '0') { + type |= ACPI_FORMAT_ZERO; + } else if (*format == '+') { + type |= ACPI_FORMAT_SIGN_PLUS; + } else if (*format == ' ') { + type |= ACPI_FORMAT_SIGN_PLUS_SPACE; + } else if (*format == '-') { + type |= ACPI_FORMAT_LEFT; + } else { + break; + } + } while (1); + + /* Process width */ + + if (ACPI_IS_DIGIT(*format)) { + format = acpi_ut_scan_number(format, &number); + width = (s32) number; + } else if (*format == '*') { + ++format; + width = va_arg(args, int); + if (width < 0) { + width = -width; + type |= ACPI_FORMAT_LEFT; + } + } + + /* Process precision */ + + if (*format == '.') { + ++format; + if (ACPI_IS_DIGIT(*format)) { + format = acpi_ut_scan_number(format, &number); + precision = (s32) number; + } else if (*format == '*') { + ++format; + precision = va_arg(args, int); + } + if (precision < 0) { + precision = 0; + } + } + + /* Process qualifier */ + + if (*format == 'h' || *format == 'l' || *format == 'L') { + qualifier = *format; + ++format; + if (qualifier == 'l' && *format == 'l') { + qualifier = 'L'; + ++format; + } + } + + switch (*format) { + case '%': + + pos = acpi_ut_bound_string_output(pos, end, '%'); + continue; + + case 'c': + + if (!(type & ACPI_FORMAT_LEFT)) { + while (--width > 0) { + pos = + acpi_ut_bound_string_output(pos, + end, + ' '); + } + } + c = (char)va_arg(args, int); + pos = acpi_ut_bound_string_output(pos, end, c); + while (--width > 0) { + pos = + acpi_ut_bound_string_output(pos, end, ' '); + } + continue; + + case 's': + + s = va_arg(args, char *); + if (!s) { + s = ""; + } + length = acpi_ut_bound_string_length(s, precision); + if (!(type & ACPI_FORMAT_LEFT)) { + while (length < width--) { + pos = + acpi_ut_bound_string_output(pos, + end, + ' '); + } + } + for (i = 0; i < length; ++i) { + pos = acpi_ut_bound_string_output(pos, end, *s); + ++s; + } + while (length < width--) { + pos = + acpi_ut_bound_string_output(pos, end, ' '); + } + continue; + + case 'o': + + base = 8; + break; + + case 'X': + + type |= ACPI_FORMAT_UPPER; + + case 'x': + + base = 16; + break; + + case 'd': + case 'i': + + type |= ACPI_FORMAT_SIGN; + + case 'u': + + break; + + case 'p': + + if (width == -1) { + width = 2 * sizeof(void *); + type |= ACPI_FORMAT_ZERO; + } + p = va_arg(args, void *); + pos = acpi_ut_format_number(pos, end, + ACPI_TO_INTEGER(p), + 16, width, precision, type); + continue; + + default: + + pos = acpi_ut_bound_string_output(pos, end, '%'); + if (*format) { + pos = + acpi_ut_bound_string_output(pos, end, + *format); + } else { + --format; + } + continue; + } + + if (qualifier == 'L') { + number = va_arg(args, u64); + if (type & ACPI_FORMAT_SIGN) { + number = (s64) number; + } + } else if (qualifier == 'l') { + number = va_arg(args, unsigned long); + if (type & ACPI_FORMAT_SIGN) { + number = (s32) number; + } + } else if (qualifier == 'h') { + number = (u16)va_arg(args, int); + if (type & ACPI_FORMAT_SIGN) { + number = (s16) number; + } + } else { + number = va_arg(args, unsigned int); + if (type & ACPI_FORMAT_SIGN) { + number = (signed int)number; + } + } + pos = acpi_ut_format_number(pos, end, number, base, + width, precision, type); + } + + if (size > 0) { + if (pos < end) { + *pos = '\0'; + } else { + end[-1] = '\0'; + } + } + + return (ACPI_PTR_DIFF(pos, string)); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_snprintf + * + * PARAMETERS: string - String with boundary + * size - Boundary of the string + * Format, ... - Standard printf format + * + * RETURN: Size of successfully output bytes + * + * DESCRIPTION: Formatted output to a string. + * + ******************************************************************************/ + +int acpi_ut_snprintf(char *string, acpi_size size, const char *format, ...) +{ + va_list args; + int length; + + va_start(args, format); + length = acpi_ut_vsnprintf(string, size, format, args); + va_end(args); + + return (length); +} + +#ifdef ACPI_APPLICATION +/******************************************************************************* + * + * FUNCTION: acpi_ut_file_vprintf + * + * PARAMETERS: file - File descriptor + * format - Standard printf format + * args - Argument list + * + * RETURN: Size of successfully output bytes + * + * DESCRIPTION: Formatted output to a file using argument list pointer. + * + ******************************************************************************/ + +int acpi_ut_file_vprintf(ACPI_FILE file, const char *format, va_list args) +{ + acpi_cpu_flags flags; + int length; + + flags = acpi_os_acquire_lock(acpi_gbl_print_lock); + length = acpi_ut_vsnprintf(acpi_gbl_print_buffer, + sizeof(acpi_gbl_print_buffer), format, args); + (void)acpi_os_write_file(file, acpi_gbl_print_buffer, length, 1); + acpi_os_release_lock(acpi_gbl_print_lock, flags); + + return (length); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_file_printf + * + * PARAMETERS: file - File descriptor + * Format, ... - Standard printf format + * + * RETURN: Size of successfully output bytes + * + * DESCRIPTION: Formatted output to a file. + * + ******************************************************************************/ + +int acpi_ut_file_printf(ACPI_FILE file, const char *format, ...) +{ + va_list args; + int length; + + va_start(args, format); + length = acpi_ut_file_vprintf(file, format, args); + va_end(args); + + return (length); +} +#endif diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 5480209b4254..165abcae5548 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -126,6 +126,7 @@ typedef unsigned char u8; typedef unsigned char u8; typedef unsigned short u16; +typedef short s16; typedef COMPILER_DEPENDENT_UINT64 u64; typedef COMPILER_DEPENDENT_INT64 s64; diff --git a/tools/power/acpi/os_specific/service_layers/osunixxf.c b/tools/power/acpi/os_specific/service_layers/osunixxf.c index 0e6a8a6be441..60b58cd18410 100644 --- a/tools/power/acpi/os_specific/service_layers/osunixxf.c +++ b/tools/power/acpi/os_specific/service_layers/osunixxf.c @@ -182,10 +182,17 @@ static void os_exit_line_edit_mode(void) acpi_status acpi_os_initialize(void) { + acpi_status status; acpi_gbl_output_file = stdout; os_enter_line_edit_mode(); + + status = acpi_os_create_lock(&acpi_gbl_print_lock); + if (ACPI_FAILURE(status)) { + return (status); + } + return (AE_OK); } -- cgit v1.2.3 From 2e70da4c51eb18a4d229aa48763c15f5dbc5b43d Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 8 Jul 2014 10:07:06 +0800 Subject: ACPICA: Utilities: Introduce acpi_log_error() to improve portability Invocations like fprintf(stderr) and perror() are not portable, this patch introduces acpi_log_error() as a replacement, it is implemented using new portable API - acpi_ut_file_vprintf(). Note that though acpi_os_initialize() need to be invoked prior than using this new API, since no users are introduced in this patch, such invocations are not added for applications that link utprint.c in this patch. Futher patches that introduce users of acpi_log_error() should take care of this. This patch is only useful for ACPICA applications, most of which are not shipped in the Linux kernel. Note that follow-up commits will update acpidump to use this new API to improve portability. Lv Zheng. Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/utdebug.c | 26 ++++++++++++++++++++++++++ include/acpi/acpixf.h | 20 ++++++++++++++++++++ include/acpi/platform/acenv.h | 4 ++++ 3 files changed, 50 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c index 21a20ac5b1e1..e516254c63b2 100644 --- a/drivers/acpi/acpica/utdebug.c +++ b/drivers/acpi/acpica/utdebug.c @@ -561,3 +561,29 @@ acpi_ut_ptr_exit(u32 line_number, } #endif + +#ifdef ACPI_APPLICATION +/******************************************************************************* + * + * FUNCTION: acpi_log_error + * + * PARAMETERS: format - Printf format field + * ... - Optional printf arguments + * + * RETURN: None + * + * DESCRIPTION: Print error message to the console, used by applications. + * + ******************************************************************************/ + +void ACPI_INTERNAL_VAR_XFACE acpi_log_error(const char *format, ...) +{ + va_list args; + + va_start(args, format); + (void)acpi_ut_file_vprintf(ACPI_FILE_ERR, format, args); + va_end(args); +} + +ACPI_EXPORT_SYMBOL(acpi_log_error) +#endif diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 35b525c19711..9858551fc84a 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -335,6 +335,23 @@ ACPI_GLOBAL(u8, acpi_gbl_system_awake_and_running); #endif /* ACPI_DEBUG_OUTPUT */ +/* + * Application prototypes + * + * All interfaces used by application will be configured + * out of the ACPICA build unless the ACPI_APPLICATION + * flag is defined. + */ +#ifdef ACPI_APPLICATION +#define ACPI_APP_DEPENDENT_RETURN_VOID(prototype) \ + prototype; + +#else +#define ACPI_APP_DEPENDENT_RETURN_VOID(prototype) \ + static ACPI_INLINE prototype {return;} + +#endif /* ACPI_APPLICATION */ + /***************************************************************************** * * ACPICA public interface prototypes @@ -861,6 +878,9 @@ ACPI_DBG_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(6) const char *module_name, u32 component_id, const char *format, ...)) +ACPI_APP_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(1) + void ACPI_INTERNAL_VAR_XFACE + acpi_log_error(const char *format, ...)) /* * Divergences diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h index b6429e46847a..4390ebd99fda 100644 --- a/include/acpi/platform/acenv.h +++ b/include/acpi/platform/acenv.h @@ -423,8 +423,12 @@ typedef char *va_list; #ifdef ACPI_APPLICATION #include #define ACPI_FILE FILE * +#define ACPI_FILE_OUT stdout +#define ACPI_FILE_ERR stderr #else #define ACPI_FILE void * +#define ACPI_FILE_OUT NULL +#define ACPI_FILE_ERR NULL #endif /* ACPI_APPLICATION */ #endif /* ACPI_FILE */ -- cgit v1.2.3 From d9cf147dbd9cef05fa08bcc1dda9b2d14d9fe567 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 8 Jul 2014 10:07:13 +0800 Subject: ACPICA: Application: Enhance ACPI_USAGE_xxx/ACPI_OPTION with acpi_os_printf() to improve portability This patch enhances ACPI_USAGE_xxx/ACPI_OPTION macros to use portable acpi_os_printf() so that usage functions for applications no longer rely on the printf() API. To use acpi_os_printf() exported by osunixxf.c as a replacement of printf(), applications need to initialize acpi_gbl_output_file to stdout and initialize acpi_gbl_db_output_flags to ACPI_DB_CONSOLE_OUTPUT. The latter is automatically done by ACPI_INIT_GLOBAL(), applications need to link utglobal.o to utilize this mechanism. For GCC, assigning stdout to acpi_gbl_output_file using ACPI_INIT_GLOBAL() is not possible as stdout is not a constant in GCC environment. As an alternative solution, stdout assignment has been put into acpi_os_initialize(). Thus acpi_os_initialize() need to be invoked very early by the applications to initialize the default output of acpi_os_printf() to keep behavior consistency. acpidump has already invoked acpi_os_initialize() in this way. Lv Zheng. Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acapps.h | 7 +++++-- tools/power/acpi/tools/acpidump/apmain.c | 8 ++++---- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acapps.h b/drivers/acpi/acpica/acapps.h index 8698ffba6f39..5bf41f8a4b47 100644 --- a/drivers/acpi/acpica/acapps.h +++ b/drivers/acpi/acpica/acapps.h @@ -79,10 +79,13 @@ /* Macros for usage messages */ #define ACPI_USAGE_HEADER(usage) \ - printf ("Usage: %s\nOptions:\n", usage); + acpi_os_printf ("Usage: %s\nOptions:\n", usage); + +#define ACPI_USAGE_TEXT(description) \ + acpi_os_printf (description); #define ACPI_OPTION(name, description) \ - printf (" %-18s%s\n", name, description); + acpi_os_printf (" %-18s%s\n", name, description); #define FILE_SUFFIX_DISASSEMBLY "dsl" #define ACPI_TABLE_FILE_SUFFIX ".dat" diff --git a/tools/power/acpi/tools/acpidump/apmain.c b/tools/power/acpi/tools/acpidump/apmain.c index c03e4731f099..2a06a864c093 100644 --- a/tools/power/acpi/tools/acpidump/apmain.c +++ b/tools/power/acpi/tools/acpidump/apmain.c @@ -104,7 +104,7 @@ static void ap_display_usage(void) ACPI_OPTION("-v", "Display version information"); ACPI_OPTION("-z", "Verbose mode"); - printf("\nTable Options:\n"); + ACPI_USAGE_TEXT("\nTable Options:\n"); ACPI_OPTION("-a
", "Get table via a physical address"); ACPI_OPTION("-f ", "Get table via a binary file"); @@ -112,9 +112,9 @@ static void ap_display_usage(void) ACPI_OPTION("-x", "Do not use but dump XSDT"); ACPI_OPTION("-x -x", "Do not use or dump XSDT"); - printf("\n" - "Invocation without parameters dumps all available tables\n" - "Multiple mixed instances of -a, -f, and -n are supported\n\n"); + ACPI_USAGE_TEXT("\n" + "Invocation without parameters dumps all available tables\n" + "Multiple mixed instances of -a, -f, and -n are supported\n\n"); } /****************************************************************************** -- cgit v1.2.3 From 3c9349c93712f68dc9fc4caadb2fc1b7c9407316 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 8 Jul 2014 10:07:19 +0800 Subject: ACPICA: Common: Enhance cm_get_file_size() to improve portability This patch uses abstract file IO and acpi_log_error() APIs to enhance cm_get_file_size() so that applications that invoke this API could have portability improved. With actual references added to abstract file IO and acpi_log_error(), the applications need to link oslibcfs.o, utdebug.o, utexcep.o, utmath.o, utprint.o and utxferror.o. It is also required to add acpi_os_initialize() invocations if an application starts to use acpi_log_error(). acpidump has already invoked acpi_os_initialize() in this way. Lv Zheng. Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acapps.h | 2 +- tools/power/acpi/Makefile | 3 +++ tools/power/acpi/common/cmfsize.c | 20 +++++++++++--------- 3 files changed, 15 insertions(+), 10 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acapps.h b/drivers/acpi/acpica/acapps.h index 5bf41f8a4b47..3d2c88289da9 100644 --- a/drivers/acpi/acpica/acapps.h +++ b/drivers/acpi/acpica/acapps.h @@ -105,7 +105,7 @@ extern char *acpi_gbl_optarg; /* * cmfsize - Common get file size function */ -u32 cm_get_file_size(FILE * file); +u32 cm_get_file_size(ACPI_FILE file); #ifndef ACPI_DUMP_APP /* diff --git a/tools/power/acpi/Makefile b/tools/power/acpi/Makefile index f88a251863c5..3d1537b93c64 100644 --- a/tools/power/acpi/Makefile +++ b/tools/power/acpi/Makefile @@ -112,11 +112,14 @@ DUMP_OBJS = \ tbprint.o\ tbxfroot.o\ utbuffer.o\ + utdebug.o\ utexcep.o\ utglobal.o\ utmath.o\ + utprint.o\ utstring.o\ utxferror.o\ + oslibcfs.o\ oslinuxtbl.o\ cmfsize.o\ getopt.o diff --git a/tools/power/acpi/common/cmfsize.c b/tools/power/acpi/common/cmfsize.c index 5140e5edae1f..f4b953354ff7 100644 --- a/tools/power/acpi/common/cmfsize.c +++ b/tools/power/acpi/common/cmfsize.c @@ -58,44 +58,46 @@ ACPI_MODULE_NAME("cmfsize") * RETURN: File Size. On error, -1 (ACPI_UINT32_MAX) * * DESCRIPTION: Get the size of a file. Uses seek-to-EOF. File must be open. - * Does not disturb the current file pointer. Uses perror for - * error messages. + * Does not disturb the current file pointer. * ******************************************************************************/ -u32 cm_get_file_size(FILE * file) +u32 cm_get_file_size(ACPI_FILE file) { long file_size; long current_offset; + acpi_status status; /* Save the current file pointer, seek to EOF to obtain file size */ - current_offset = ftell(file); + current_offset = acpi_os_get_file_offset(file); if (current_offset < 0) { goto offset_error; } - if (fseek(file, 0, SEEK_END)) { + status = acpi_os_set_file_offset(file, 0, ACPI_FILE_END); + if (ACPI_FAILURE(status)) { goto seek_error; } - file_size = ftell(file); + file_size = acpi_os_get_file_offset(file); if (file_size < 0) { goto offset_error; } /* Restore original file pointer */ - if (fseek(file, current_offset, SEEK_SET)) { + status = acpi_os_set_file_offset(file, current_offset, ACPI_FILE_BEGIN); + if (ACPI_FAILURE(status)) { goto seek_error; } return ((u32)file_size); offset_error: - perror("Could not get file offset"); + acpi_log_error("Could not get file offset"); return (ACPI_UINT32_MAX); seek_error: - perror("Could not seek file"); + acpi_log_error("Could not set file offset"); return (ACPI_UINT32_MAX); } -- cgit v1.2.3 From a92e95773d8e2cd58124aea147cb833f33f1e196 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 8 Jul 2014 10:07:26 +0800 Subject: ACPICA: Common: Enhance acpi_getopt() to improve portability This patch enhances acpi_getopt() by converting the standard C library invocations into portable ACPI string APIs and acpi_log_error() to improve portability. Lv Zheng. Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acutils.h | 2 ++ include/acpi/actypes.h | 4 ++++ tools/power/acpi/common/getopt.c | 14 ++++++-------- tools/power/acpi/tools/acpidump/apmain.c | 3 ++- 4 files changed, 14 insertions(+), 9 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 85871c639cc2..035dc29798bb 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -210,6 +210,8 @@ void acpi_ut_subsystem_shutdown(void); acpi_size acpi_ut_strlen(const char *string); +char *acpi_ut_strchr(const char *string, int ch); + char *acpi_ut_strcpy(char *dst_string, const char *src_string); char *acpi_ut_strncpy(char *dst_string, diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 165abcae5548..608a04019372 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -1254,4 +1254,8 @@ struct acpi_memory_list { #define ACPI_FILE_BEGIN 0x01 #define ACPI_FILE_END 0x02 +/* Definitions of getopt */ + +#define ACPI_OPT_END -1 + #endif /* __ACTYPES_H__ */ diff --git a/tools/power/acpi/common/getopt.c b/tools/power/acpi/common/getopt.c index a302f52e4fd3..2f0f34a36db4 100644 --- a/tools/power/acpi/common/getopt.c +++ b/tools/power/acpi/common/getopt.c @@ -51,14 +51,12 @@ * "f|" - Option has required single-char sub-options */ -#include -#include #include #include "accommon.h" #include "acapps.h" #define ACPI_OPTION_ERROR(msg, badchar) \ - if (acpi_gbl_opterr) {fprintf (stderr, "%s%c\n", msg, badchar);} + if (acpi_gbl_opterr) {acpi_log_error ("%s%c\n", msg, badchar);} int acpi_gbl_opterr = 1; int acpi_gbl_optind = 1; @@ -113,7 +111,7 @@ int acpi_getopt_argument(int argc, char **argv) * PARAMETERS: argc, argv - from main * opts - options info list * - * RETURN: Option character or EOF + * RETURN: Option character or ACPI_OPT_END * * DESCRIPTION: Get the next option * @@ -128,10 +126,10 @@ int acpi_getopt(int argc, char **argv, char *opts) if (acpi_gbl_optind >= argc || argv[acpi_gbl_optind][0] != '-' || argv[acpi_gbl_optind][1] == '\0') { - return (EOF); - } else if (strcmp(argv[acpi_gbl_optind], "--") == 0) { + return (ACPI_OPT_END); + } else if (ACPI_STRCMP(argv[acpi_gbl_optind], "--") == 0) { acpi_gbl_optind++; - return (EOF); + return (ACPI_OPT_END); } } @@ -142,7 +140,7 @@ int acpi_getopt(int argc, char **argv, char *opts) /* Make sure that the option is legal */ if (current_char == ':' || - (opts_ptr = strchr(opts, current_char)) == NULL) { + (opts_ptr = ACPI_STRCHR(opts, current_char)) == NULL) { ACPI_OPTION_ERROR("Illegal option: -", current_char); if (argv[acpi_gbl_optind][++current_char_ptr] == '\0') { diff --git a/tools/power/acpi/tools/acpidump/apmain.c b/tools/power/acpi/tools/acpidump/apmain.c index 2a06a864c093..9c3b259aed2c 100644 --- a/tools/power/acpi/tools/acpidump/apmain.c +++ b/tools/power/acpi/tools/acpidump/apmain.c @@ -166,7 +166,8 @@ static int ap_do_options(int argc, char **argv) /* Command line options */ - while ((j = acpi_getopt(argc, argv, AP_SUPPORTED_OPTIONS)) != EOF) + while ((j = + acpi_getopt(argc, argv, AP_SUPPORTED_OPTIONS)) != ACPI_OPT_END) switch (j) { /* * Global options -- cgit v1.2.3 From 846d6ef4d7f0fed114aa1284a245bb1aa96417df Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 8 Jul 2014 10:07:52 +0800 Subject: ACPICA: acpidump: Reduce freopen() invocations to improve portability This patch reduces the requirement of invoking freopen() in acpidump in order to reduce the porting effort of acpidump. This patch achieves this by turning all acpi_os_printf(stdout) into acpi_ut_file_printf(gbl_output_file). Lv Zheng. Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acutils.h | 7 ++ drivers/acpi/acpica/utbuffer.c | 128 ++++++++++++++++++++++++++++++ tools/power/acpi/tools/acpidump/apdump.c | 11 +-- tools/power/acpi/tools/acpidump/apfiles.c | 6 +- tools/power/acpi/tools/acpidump/apmain.c | 3 +- 5 files changed, 146 insertions(+), 9 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 035dc29798bb..ed614f4b2182 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -353,6 +353,13 @@ acpi_ut_debug_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id); void acpi_ut_dump_buffer(u8 *buffer, u32 count, u32 display, u32 offset); +#ifdef ACPI_APPLICATION +void +acpi_ut_dump_buffer_to_file(ACPI_FILE file, + u8 *buffer, + u32 count, u32 display, u32 base_offset); +#endif + void acpi_ut_report_error(char *module_name, u32 line_number); void acpi_ut_report_info(char *module_name, u32 line_number); diff --git a/drivers/acpi/acpica/utbuffer.c b/drivers/acpi/acpica/utbuffer.c index 3c1699740653..038ea887f562 100644 --- a/drivers/acpi/acpica/utbuffer.c +++ b/drivers/acpi/acpica/utbuffer.c @@ -199,3 +199,131 @@ acpi_ut_debug_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id) acpi_ut_dump_buffer(buffer, count, display, 0); } + +#ifdef ACPI_APPLICATION +/******************************************************************************* + * + * FUNCTION: acpi_ut_dump_buffer_to_file + * + * PARAMETERS: file - File descriptor + * buffer - Buffer to dump + * count - Amount to dump, in bytes + * display - BYTE, WORD, DWORD, or QWORD display: + * DB_BYTE_DISPLAY + * DB_WORD_DISPLAY + * DB_DWORD_DISPLAY + * DB_QWORD_DISPLAY + * base_offset - Beginning buffer offset (display only) + * + * RETURN: None + * + * DESCRIPTION: Generic dump buffer in both hex and ascii to a file. + * + ******************************************************************************/ + +void +acpi_ut_dump_buffer_to_file(ACPI_FILE file, + u8 *buffer, u32 count, u32 display, u32 base_offset) +{ + u32 i = 0; + u32 j; + u32 temp32; + u8 buf_char; + + if (!buffer) { + acpi_ut_file_printf(file, + "Null Buffer Pointer in DumpBuffer!\n"); + return; + } + + if ((count < 4) || (count & 0x01)) { + display = DB_BYTE_DISPLAY; + } + + /* Nasty little dump buffer routine! */ + + while (i < count) { + + /* Print current offset */ + + acpi_ut_file_printf(file, "%6.4X: ", (base_offset + i)); + + /* Print 16 hex chars */ + + for (j = 0; j < 16;) { + if (i + j >= count) { + + /* Dump fill spaces */ + + acpi_ut_file_printf(file, "%*s", + ((display * 2) + 1), " "); + j += display; + continue; + } + + switch (display) { + case DB_BYTE_DISPLAY: + default: /* Default is BYTE display */ + + acpi_ut_file_printf(file, "%02X ", + buffer[(acpi_size) i + j]); + break; + + case DB_WORD_DISPLAY: + + ACPI_MOVE_16_TO_32(&temp32, + &buffer[(acpi_size) i + j]); + acpi_ut_file_printf(file, "%04X ", temp32); + break; + + case DB_DWORD_DISPLAY: + + ACPI_MOVE_32_TO_32(&temp32, + &buffer[(acpi_size) i + j]); + acpi_ut_file_printf(file, "%08X ", temp32); + break; + + case DB_QWORD_DISPLAY: + + ACPI_MOVE_32_TO_32(&temp32, + &buffer[(acpi_size) i + j]); + acpi_ut_file_printf(file, "%08X", temp32); + + ACPI_MOVE_32_TO_32(&temp32, + &buffer[(acpi_size) i + j + + 4]); + acpi_ut_file_printf(file, "%08X ", temp32); + break; + } + + j += display; + } + + /* + * Print the ASCII equivalent characters but watch out for the bad + * unprintable ones (printable chars are 0x20 through 0x7E) + */ + acpi_ut_file_printf(file, " "); + for (j = 0; j < 16; j++) { + if (i + j >= count) { + acpi_ut_file_printf(file, "\n"); + return; + } + + buf_char = buffer[(acpi_size) i + j]; + if (ACPI_IS_PRINT(buf_char)) { + acpi_ut_file_printf(file, "%c", buf_char); + } else { + acpi_ut_file_printf(file, "."); + } + } + + /* Done with that line. */ + + acpi_ut_file_printf(file, "\n"); + i += 16; + } + + return; +} +#endif diff --git a/tools/power/acpi/tools/acpidump/apdump.c b/tools/power/acpi/tools/acpidump/apdump.c index 34fa5f25be39..53cee781e24e 100644 --- a/tools/power/acpi/tools/acpidump/apdump.c +++ b/tools/power/acpi/tools/acpidump/apdump.c @@ -195,12 +195,13 @@ ap_dump_table_buffer(struct acpi_table_header *table, * Note: simplest to just always emit a 64-bit address. acpi_xtract * utility can handle this. */ - acpi_os_printf("%4.4s @ 0x%8.8X%8.8X\n", table->signature, - ACPI_FORMAT_UINT64(address)); + acpi_ut_file_printf(gbl_output_file, "%4.4s @ 0x%8.8X%8.8X\n", + table->signature, ACPI_FORMAT_UINT64(address)); - acpi_ut_dump_buffer(ACPI_CAST_PTR(u8, table), table_length, - DB_BYTE_DISPLAY, 0); - acpi_os_printf("\n"); + acpi_ut_dump_buffer_to_file(gbl_output_file, + ACPI_CAST_PTR(u8, table), table_length, + DB_BYTE_DISPLAY, 0); + acpi_ut_file_printf(gbl_output_file, "\n"); return (0); } diff --git a/tools/power/acpi/tools/acpidump/apfiles.c b/tools/power/acpi/tools/acpidump/apfiles.c index 5699ca1d0922..5781c13ae333 100644 --- a/tools/power/acpi/tools/acpidump/apfiles.c +++ b/tools/power/acpi/tools/acpidump/apfiles.c @@ -60,7 +60,7 @@ int ap_open_output_file(char *pathname) { struct stat stat_info; - FILE *file; + ACPI_FILE file; /* If file exists, prompt for overwrite */ @@ -74,9 +74,9 @@ int ap_open_output_file(char *pathname) /* Point stdout to the file */ - file = freopen(pathname, "w", stdout); + file = acpi_os_open_file(pathname, ACPI_FILE_WRITING); if (!file) { - perror("Could not open output file"); + acpi_log_error("Could not open output file: %s\n", pathname); return (-1); } diff --git a/tools/power/acpi/tools/acpidump/apmain.c b/tools/power/acpi/tools/acpidump/apmain.c index 63f7bc9fdf29..35bd6740306e 100644 --- a/tools/power/acpi/tools/acpidump/apmain.c +++ b/tools/power/acpi/tools/acpidump/apmain.c @@ -300,6 +300,7 @@ int ACPI_SYSTEM_XFACE main(int argc, char *argv[]) ACPI_DEBUG_INITIALIZE(); /* For debug version only */ acpi_os_initialize(); + gbl_output_file = ACPI_FILE_OUT; /* Process command line options */ @@ -348,7 +349,7 @@ int ACPI_SYSTEM_XFACE main(int argc, char *argv[]) } } - if (gbl_output_file) { + if (gbl_output_filename) { if (gbl_verbose_mode) { /* Summary for the output file */ -- cgit v1.2.3 From c04691292ff75a3560279bcafb1be0848ae82c23 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 8 Jul 2014 10:08:05 +0800 Subject: ACPICA: Executer: Fix trivial issues in acpi_get_serial_access_bytes() This patch fixes trivial issues in acpi_get_serial_access_bytes(), no real functional bugs. Lv Zheng. Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/exfield.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c index 12878e1982f7..1ff42c07b42b 100644 --- a/drivers/acpi/acpica/exfield.c +++ b/drivers/acpi/acpica/exfield.c @@ -56,7 +56,7 @@ acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length); /******************************************************************************* * - * FUNCTION: acpi_get_serial_access_bytes + * FUNCTION: acpi_ex_get_serial_access_length * * PARAMETERS: accessor_type - The type of the protocol indicated by region * field access attributes @@ -103,7 +103,7 @@ acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length) case AML_FIELD_ATTRIB_BLOCK_CALL: default: - length = ACPI_GSBUS_BUFFER_SIZE; + length = ACPI_GSBUS_BUFFER_SIZE - 2; break; } -- cgit v1.2.3 From ff2389fe662460c71e4ee221cc223b175c231246 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 8 Jul 2014 10:08:13 +0800 Subject: ACPICA: utprint/oslibcfs: cleanup - no functional change Some cleanup and comment update. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/utprint.c | 44 ++++++++++++++-------- .../acpi/os_specific/service_layers/oslibcfs.c | 30 +++++++-------- 2 files changed, 43 insertions(+), 31 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/utprint.c b/drivers/acpi/acpica/utprint.c index 9d5293fd992f..10311648f701 100644 --- a/drivers/acpi/acpica/utprint.c +++ b/drivers/acpi/acpica/utprint.c @@ -67,6 +67,11 @@ static char *acpi_ut_format_number(char *string, static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper); +/* Module globals */ + +static const char acpi_gbl_lower_hex_digits[] = "0123456789abcdef"; +static const char acpi_gbl_upper_hex_digits[] = "0123456789ABCDEF"; + /******************************************************************************* * * FUNCTION: acpi_ut_bound_string_length @@ -74,7 +79,7 @@ static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper); * PARAMETERS: string - String with boundary * count - Boundary of the string * - * RETURN: Length of the string. + * RETURN: Length of the string. Less than or equal to Count. * * DESCRIPTION: Calculate the length of a string with boundary. * @@ -114,8 +119,8 @@ static char *acpi_ut_bound_string_output(char *string, const char *end, char c) if (string < end) { *string = c; } - ++string; + ++string; return (string); } @@ -137,14 +142,12 @@ static char *acpi_ut_bound_string_output(char *string, const char *end, char c) static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper) { - const char lower_digits[] = "0123456789abcdef"; - const char upper_digits[] = "0123456789ABCDEF"; const char *digits; u64 digit_index; char *pos; pos = string; - digits = upper ? upper_digits : lower_digits; + digits = upper ? acpi_gbl_upper_hex_digits : acpi_gbl_lower_hex_digits; if (number == 0) { *(pos++) = '0'; @@ -155,8 +158,8 @@ static char *acpi_ut_put_number(char *string, u64 number, u8 base, u8 upper) *(pos++) = digits[digit_index]; } } - /* *(Pos++) = '0'; */ + /* *(Pos++) = '0'; */ return (pos); } @@ -181,8 +184,8 @@ const char *acpi_ut_scan_number(const char *string, u64 *number_ptr) number *= 10; number += *(string++) - '0'; } - *number_ptr = number; + *number_ptr = number; return (string); } @@ -211,8 +214,8 @@ const char *acpi_ut_print_number(char *string, u64 number) while (pos1 != ascii_string) { *(pos2++) = *(--pos1); } - *pos2 = 0; + *pos2 = 0; return (string); } @@ -246,11 +249,12 @@ static char *acpi_ut_format_number(char *string, s32 i; char reversed_string[66]; - /* Perform sanity checks */ + /* Parameter validation */ if (base < 2 || base > 16) { - return NULL; + return (NULL); } + if (type & ACPI_FORMAT_LEFT) { type &= ~ACPI_FORMAT_ZERO; } @@ -294,6 +298,7 @@ static char *acpi_ut_format_number(char *string, if (i > precision) { precision = i; } + width -= precision; /* Output the string */ @@ -318,6 +323,7 @@ static char *acpi_ut_format_number(char *string, string = acpi_ut_bound_string_output(string, end, zero); } } + while (i <= --precision) { string = acpi_ut_bound_string_output(string, end, '0'); } @@ -341,7 +347,7 @@ static char *acpi_ut_format_number(char *string, * format - Standard printf format * args - Argument list * - * RETURN: Size of successfully output bytes + * RETURN: Number of bytes actually written. * * DESCRIPTION: Formatted output to a string using argument list pointer. * @@ -428,6 +434,7 @@ acpi_ut_vsnprintf(char *string, if (*format == 'h' || *format == 'l' || *format == 'L') { qualifier = *format; ++format; + if (qualifier == 'l' && *format == 'l') { qualifier = 'L'; ++format; @@ -450,8 +457,10 @@ acpi_ut_vsnprintf(char *string, ' '); } } + c = (char)va_arg(args, int); pos = acpi_ut_bound_string_output(pos, end, c); + while (--width > 0) { pos = acpi_ut_bound_string_output(pos, end, ' '); @@ -512,10 +521,11 @@ acpi_ut_vsnprintf(char *string, width = 2 * sizeof(void *); type |= ACPI_FORMAT_ZERO; } + p = va_arg(args, void *); pos = acpi_ut_format_number(pos, end, - ACPI_TO_INTEGER(p), - 16, width, precision, type); + ACPI_TO_INTEGER(p), 16, + width, precision, type); continue; default: @@ -552,6 +562,7 @@ acpi_ut_vsnprintf(char *string, number = (signed int)number; } } + pos = acpi_ut_format_number(pos, end, number, base, width, precision, type); } @@ -575,7 +586,7 @@ acpi_ut_vsnprintf(char *string, * size - Boundary of the string * Format, ... - Standard printf format * - * RETURN: Size of successfully output bytes + * RETURN: Number of bytes actually written. * * DESCRIPTION: Formatted output to a string. * @@ -602,7 +613,7 @@ int acpi_ut_snprintf(char *string, acpi_size size, const char *format, ...) * format - Standard printf format * args - Argument list * - * RETURN: Size of successfully output bytes + * RETURN: Number of bytes actually written. * * DESCRIPTION: Formatted output to a file using argument list pointer. * @@ -616,6 +627,7 @@ int acpi_ut_file_vprintf(ACPI_FILE file, const char *format, va_list args) flags = acpi_os_acquire_lock(acpi_gbl_print_lock); length = acpi_ut_vsnprintf(acpi_gbl_print_buffer, sizeof(acpi_gbl_print_buffer), format, args); + (void)acpi_os_write_file(file, acpi_gbl_print_buffer, length, 1); acpi_os_release_lock(acpi_gbl_print_lock, flags); @@ -629,7 +641,7 @@ int acpi_ut_file_vprintf(ACPI_FILE file, const char *format, va_list args) * PARAMETERS: file - File descriptor * Format, ... - Standard printf format * - * RETURN: Size of successfully output bytes + * RETURN: Number of bytes actually written. * * DESCRIPTION: Formatted output to a file. * diff --git a/tools/power/acpi/os_specific/service_layers/oslibcfs.c b/tools/power/acpi/os_specific/service_layers/oslibcfs.c index 2da0ce885c8c..c13ff9c51d74 100644 --- a/tools/power/acpi/os_specific/service_layers/oslibcfs.c +++ b/tools/power/acpi/os_specific/service_layers/oslibcfs.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Module Name: oslibcfs - C library OSL for file IO + * Module Name: oslibcfs - C library OSL for file I/O * *****************************************************************************/ @@ -64,8 +64,8 @@ ACPI_MODULE_NAME("oslibcfs") ACPI_FILE acpi_os_open_file(const char *path, u8 modes) { ACPI_FILE file; - char modes_str[4]; u32 i = 0; + char modes_str[4]; if (modes & ACPI_FILE_READING) { modes_str[i++] = 'r'; @@ -76,6 +76,7 @@ ACPI_FILE acpi_os_open_file(const char *path, u8 modes) if (modes & ACPI_FILE_BINARY) { modes_str[i++] = 'b'; } + modes_str[i++] = '\0'; file = fopen(path, modes_str); @@ -90,11 +91,11 @@ ACPI_FILE acpi_os_open_file(const char *path, u8 modes) * * FUNCTION: acpi_os_close_file * - * PARAMETERS: file - File descriptor + * PARAMETERS: file - An open file descriptor * * RETURN: None. * - * DESCRIPTION: Close a file. + * DESCRIPTION: Close a file opened via acpi_os_open_file. * ******************************************************************************/ @@ -107,14 +108,14 @@ void acpi_os_close_file(ACPI_FILE file) * * FUNCTION: acpi_os_read_file * - * PARAMETERS: file - File descriptor + * PARAMETERS: file - An open file descriptor * buffer - Data buffer * size - Data block size * count - Number of data blocks * - * RETURN: Size of successfully read buffer. + * RETURN: Number of bytes actually read. * - * DESCRIPTION: Read a file. + * DESCRIPTION: Read from a file. * ******************************************************************************/ @@ -135,14 +136,14 @@ acpi_os_read_file(ACPI_FILE file, void *buffer, acpi_size size, acpi_size count) * * FUNCTION: acpi_os_write_file * - * PARAMETERS: file - File descriptor + * PARAMETERS: file - An open file descriptor * buffer - Data buffer * size - Data block size * count - Number of data blocks * - * RETURN: Size of successfully written buffer. + * RETURN: Number of bytes actually written. * - * DESCRIPTION: Write a file. + * DESCRIPTION: Write to a file. * ******************************************************************************/ @@ -164,9 +165,9 @@ acpi_os_write_file(ACPI_FILE file, * * FUNCTION: acpi_os_get_file_offset * - * PARAMETERS: file - File descriptor + * PARAMETERS: file - An open file descriptor * - * RETURN: Size of current position. + * RETURN: Current file pointer position. * * DESCRIPTION: Get current file offset. * @@ -177,7 +178,6 @@ long acpi_os_get_file_offset(ACPI_FILE file) long offset; offset = ftell(file); - return (offset); } @@ -185,8 +185,8 @@ long acpi_os_get_file_offset(ACPI_FILE file) * * FUNCTION: acpi_os_set_file_offset * - * PARAMETERS: file - File descriptor - * offset - File offset + * PARAMETERS: file - An open file descriptor + * offset - New file offset * from - From begin/end of file * * RETURN: Status -- cgit v1.2.3 From 7d3e83bdb44ce725970253cbefd5e824efc0aab2 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 8 Jul 2014 10:08:19 +0800 Subject: ACPICA: Hardware: back port of a recursive locking fix This patch is a back port result of the following Linux commit: Commit: f7f71cfbf0c276ee3d8d856d0f35a41aed997fa4 Author: Rakib Mullick Subject: ACPI: Fix possible recursive locking in hwregs.c As a result of different coding style rules, the back ported code generates source code differences between the Linux kernel and the ACPICA upstream. This patch reduces such source code differences. Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/hwregs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index e0fd9b4978cd..a4c34d2c556b 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c @@ -278,8 +278,9 @@ acpi_status acpi_hw_clear_acpi_status(void) acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); - if (ACPI_FAILURE(status)) + if (ACPI_FAILURE(status)) { goto exit; + } /* Clear the GPE Bits in all GPE registers in all GPE blocks */ -- cgit v1.2.3 From 7817e265233e4b216aad509fc003cf4face238b9 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 9 Jul 2014 08:25:45 +0800 Subject: ACPICA: Fix a regression for deletion of Alias() objects. Fixes a regression introduced by commit e23d9b829754 (ACPICA: Namespace: Properly null terminate objects detached from a namespace node) In the case of Alias namespace nodes, the node simply points to the aliased node via the Object field; thus we cannot assume that the object is an operand object. Fixes: e23d9b829754 (ACPICA: Namespace: Properly null terminate objects detached from a namespace node) Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/nsobject.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c index f1ea8e56cd87..a42ee9d6970d 100644 --- a/drivers/acpi/acpica/nsobject.c +++ b/drivers/acpi/acpica/nsobject.c @@ -237,17 +237,16 @@ void acpi_ns_detach_object(struct acpi_namespace_node *node) (node->object->common.type != ACPI_TYPE_LOCAL_DATA)) { node->object = node->object->common.next_object; } - } - /* - * Detach the object from any data objects (which are still held by - * the namespace node) - */ - - if (obj_desc->common.next_object && - ((obj_desc->common.next_object)->common.type == - ACPI_TYPE_LOCAL_DATA)) { - obj_desc->common.next_object = NULL; + /* + * Detach the object from any data objects (which are still held by + * the namespace node) + */ + if (obj_desc->common.next_object && + ((obj_desc->common.next_object)->common.type == + ACPI_TYPE_LOCAL_DATA)) { + obj_desc->common.next_object = NULL; + } } /* Reset the node type to untyped */ -- cgit v1.2.3 From ba574dc8563c7c1d1d1c5bf3c1c99ec88513402e Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 15 Jul 2014 22:03:22 +0200 Subject: ACPI / hotplug: Simplify acpi_set_hp_context() Since all of the acpi_set_hp_context() callers pass at least one NULL function pointer and one caller passes NULL function pointers only to it, drop function pointer arguments from acpi_set_hp_context() and make the callers initialize the function pointers in struct acpi_hotplug_context by themselves before passing it to acpi_set_hp_context(). Signed-off-by: Rafael J. Wysocki Acked-by: Bjorn Helgaas --- drivers/acpi/scan.c | 4 +++- drivers/pci/hotplug/acpiphp_glue.c | 7 ++++--- include/acpi/acpi_bus.h | 8 +------- 3 files changed, 8 insertions(+), 11 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index f775fa0d850f..3ffc9306538b 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -77,7 +77,9 @@ void acpi_initialize_hp_context(struct acpi_device *adev, void (*uevent)(struct acpi_device *, u32)) { acpi_lock_hp_context(); - acpi_set_hp_context(adev, hp, notify, uevent, NULL); + hp->notify = notify; + hp->uevent = uevent; + acpi_set_hp_context(adev, hp); acpi_unlock_hp_context(); } EXPORT_SYMBOL_GPL(acpi_initialize_hp_context); diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 08043f9c1dd5..24a43d4e9933 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -80,8 +80,9 @@ static struct acpiphp_context *acpiphp_init_context(struct acpi_device *adev) return NULL; context->refcount = 1; - acpi_set_hp_context(adev, &context->hp, acpiphp_hotplug_notify, NULL, - acpiphp_post_dock_fixup); + context->hp.notify = acpiphp_hotplug_notify; + context->hp.fixup = acpiphp_post_dock_fixup; + acpi_set_hp_context(adev, &context->hp); return context; } @@ -876,7 +877,7 @@ void acpiphp_enumerate_slots(struct pci_bus *bus) goto err; root_context->root_bridge = bridge; - acpi_set_hp_context(adev, &root_context->hp, NULL, NULL, NULL); + acpi_set_hp_context(adev, &root_context->hp); } else { struct acpiphp_context *context; diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index b5714580801a..e0720a569b2c 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -372,15 +372,9 @@ static inline void acpi_set_device_status(struct acpi_device *adev, u32 sta) } static inline void acpi_set_hp_context(struct acpi_device *adev, - struct acpi_hotplug_context *hp, - int (*notify)(struct acpi_device *, u32), - void (*uevent)(struct acpi_device *, u32), - void (*fixup)(struct acpi_device *)) + struct acpi_hotplug_context *hp) { hp->self = adev; - hp->notify = notify; - hp->uevent = uevent; - hp->fixup = fixup; adev->hp = hp; } -- cgit v1.2.3 From a8278efd84f7643d5e44e5e507b657c231b0743b Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Wed, 16 Jul 2014 16:57:52 +0800 Subject: ACPICA: Linux: Add stub support for Linux specific variables and functions. There are global variables and functions not upstreamed to the ACPICA code base. Such symbols still can be referenced by external users as they are listed in the acpixf.h. This patch uses ACPI_GLOBAL and ACPI_EXTERNAL_RETURN_STATUS mechanism to add stub support for such symbols. Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/bus.c | 3 --- include/acpi/acpixf.h | 28 +++++++++++++++++----------- 2 files changed, 17 insertions(+), 14 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index c5bc8cfe09fa..8581f5b84f48 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -477,9 +477,6 @@ static int __init acpi_bus_init_irq(void) return 0; } -u8 acpi_gbl_permanent_mmap; - - void __init acpi_early_init(void) { acpi_status status; diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 35b525c19711..bdbb145b1381 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -53,8 +53,6 @@ #include #include -extern u8 acpi_gbl_permanent_mmap; - /***************************************************************************** * * Macros used for ACPICA globals and configuration @@ -865,17 +863,25 @@ ACPI_DBG_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(6) /* * Divergences */ -acpi_status acpi_get_id(acpi_handle object, acpi_owner_id * out_type); +ACPI_GLOBAL(u8, acpi_gbl_permanent_mmap); + +ACPI_EXTERNAL_RETURN_STATUS(acpi_status + acpi_get_id(acpi_handle object, + acpi_owner_id * out_type)) -acpi_status acpi_unload_table_id(acpi_owner_id id); +ACPI_EXTERNAL_RETURN_STATUS(acpi_status acpi_unload_table_id(acpi_owner_id id)) -acpi_status -acpi_get_table_with_size(acpi_string signature, - u32 instance, struct acpi_table_header **out_table, - acpi_size *tbl_size); +ACPI_EXTERNAL_RETURN_STATUS(acpi_status + acpi_get_table_with_size(acpi_string signature, + u32 instance, + struct acpi_table_header + **out_table, + acpi_size *tbl_size)) -acpi_status -acpi_get_data_full(acpi_handle object, acpi_object_handler handler, void **data, - void (*callback)(void *)); +ACPI_EXTERNAL_RETURN_STATUS(acpi_status + acpi_get_data_full(acpi_handle object, + acpi_object_handler handler, + void **data, + void (*callback)(void *))) #endif /* __ACXFACE_H__ */ -- cgit v1.2.3 From 8ab58e8e7e097bae5fe39cbc67eb93a91f7134b7 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 18 Jul 2014 14:32:51 +0200 Subject: ACPI / video: Fix backlight taking 2 steps on a brightness up/down keypress MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In various scenarious userspace will respond to brightness up/down keypresses by increasing/decreasing the backlight brightness itself. If the kernel then also changes the brightness this results in the brightness having changed 2 steps for a single keypress which is undesirable. See e.g. : https://bugs.launchpad.net/gnome-settings-daemon/+bug/527157 http://askubuntu.com/questions/173921/why-does-my-thinkpad-brightness-control-skip-steps This commit delays responding to brightness up/down keypresses by 100 ms and if userspace in that time responds by changing the backlight itself, cancels the kernels own handling of these keypresses, fixing the 2 steps issue. Link: http://marc.info/?l=linux-kernel&m=140535721100839&w=2 [hdegoede@redhat.com: Move the delayed_work struct into struct acpi_video_device instead of having it as a global] [hdegoede@redhat.com: Keep brightness_switch_enabled as a boolean and always delay the keypress handling] Tested-by: Hans de Goede Tested-by: Bjørn Mork Signed-off-by: Hans de Goede Signed-off-by: Rafael J. Wysocki --- drivers/acpi/video.c | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 350d52a8f781..bfe1fa2fb5d1 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -204,6 +204,8 @@ struct acpi_video_device { struct acpi_video_device_flags flags; struct acpi_video_device_cap cap; struct list_head entry; + struct delayed_work switch_brightness_work; + int switch_brightness_event; struct acpi_video_bus *video; struct acpi_device *dev; struct acpi_video_device_brightness *brightness; @@ -230,8 +232,7 @@ static int acpi_video_device_lcd_get_level_current( unsigned long long *level, bool raw); static int acpi_video_get_next_level(struct acpi_video_device *device, u32 level_current, u32 event); -static int acpi_video_switch_brightness(struct acpi_video_device *device, - int event); +static void acpi_video_switch_brightness(struct work_struct *work); static bool acpi_video_use_native_backlight(void) { @@ -275,6 +276,7 @@ static int acpi_video_set_brightness(struct backlight_device *bd) int request_level = bd->props.brightness + 2; struct acpi_video_device *vd = bl_get_data(bd); + cancel_delayed_work(&vd->switch_brightness_work); return acpi_video_device_lcd_set_level(vd, vd->brightness->levels[request_level]); } @@ -1188,6 +1190,8 @@ acpi_video_bus_get_one_device(struct acpi_device *device, data->device_id = device_id; data->video = video; data->dev = device; + INIT_DELAYED_WORK(&data->switch_brightness_work, + acpi_video_switch_brightness); attribute = acpi_video_get_device_attr(video, device_id); @@ -1410,15 +1414,18 @@ acpi_video_get_next_level(struct acpi_video_device *device, } } -static int -acpi_video_switch_brightness(struct acpi_video_device *device, int event) +static void +acpi_video_switch_brightness(struct work_struct *work) { + struct acpi_video_device *device = container_of(to_delayed_work(work), + struct acpi_video_device, switch_brightness_work); unsigned long long level_current, level_next; + int event = device->switch_brightness_event; int result = -EINVAL; /* no warning message if acpi_backlight=vendor or a quirk is used */ if (!acpi_video_verify_backlight_support()) - return 0; + return; if (!device->brightness) goto out; @@ -1440,8 +1447,6 @@ acpi_video_switch_brightness(struct acpi_video_device *device, int event) out: if (result) printk(KERN_ERR PREFIX "Failed to switch the brightness\n"); - - return result; } int acpi_video_get_edid(struct acpi_device *device, int type, int device_id, @@ -1609,6 +1614,16 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event) return; } +static void brightness_switch_event(struct acpi_video_device *video_device, + u32 event) +{ + if (!brightness_switch_enabled) + return; + + video_device->switch_brightness_event = event; + schedule_delayed_work(&video_device->switch_brightness_work, HZ / 10); +} + static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) { struct acpi_video_device *video_device = data; @@ -1626,28 +1641,23 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) switch (event) { case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */ - if (brightness_switch_enabled) - acpi_video_switch_brightness(video_device, event); + brightness_switch_event(video_device, event); keycode = KEY_BRIGHTNESS_CYCLE; break; case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */ - if (brightness_switch_enabled) - acpi_video_switch_brightness(video_device, event); + brightness_switch_event(video_device, event); keycode = KEY_BRIGHTNESSUP; break; case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */ - if (brightness_switch_enabled) - acpi_video_switch_brightness(video_device, event); + brightness_switch_event(video_device, event); keycode = KEY_BRIGHTNESSDOWN; break; case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightness */ - if (brightness_switch_enabled) - acpi_video_switch_brightness(video_device, event); + brightness_switch_event(video_device, event); keycode = KEY_BRIGHTNESS_ZERO; break; case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */ - if (brightness_switch_enabled) - acpi_video_switch_brightness(video_device, event); + brightness_switch_event(video_device, event); keycode = KEY_DISPLAY_OFF; break; default: -- cgit v1.2.3 From 6d6b20b2e9498371573c3b24a3e6b4ee1343359b Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 14 Jul 2014 14:37:09 +0200 Subject: ACPI: move models with win8 brightness problems from win8 blacklist to use_native_backlight When the windows8 related backlight problems became evident, 2 approaches were follow in parallel, one was to stop claiming to be windows 8 / 2012, the other was to tell acpi_video to stop registering a backlight driver. I've read all the threads and it seems that which approach ended up being applied to which model laptop was never really a concious decision (AFAIK): https://bugzilla.kernel.org/show_bug.cgi?id=51231 https://bugzilla.kernel.org/show_bug.cgi?id=60682 So lets move all the models which are only on the win8 blacklist because of brightness issues to the use_native_backlight list, which is the smaller hammer to use to solve the backlight issues. Making this change is esp. attractive now that 3.16 has video.use_native_brightness=1 by default. If that new default does not get reverted because of regressions, then we can drop all the models with a use_native_backlight quirk, greatly reducing the number of models we've a quirk for. Link: https://bugzilla.kernel.org/show_bug.cgi?id=51231 Link: https://bugzilla.kernel.org/show_bug.cgi?id=60682 Signed-off-by: Hans de Goede Signed-off-by: Rafael J. Wysocki --- drivers/acpi/blacklist.c | 68 ++---------------------------------------------- drivers/acpi/video.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 68 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 3d8413d02a97..36eb42e3b0bb 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c @@ -247,75 +247,11 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { }, /* - * The following machines have broken backlight support when reporting - * the Windows 2012 OSI, so disable it until their support is fixed. + * These machines will power on immediately after shutdown when + * reporting the Windows 2012 OSI. */ { .callback = dmi_disable_osi_win8, - .ident = "ASUS Zenbook Prime UX31A", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "UX31A"), - }, - }, - { - .callback = dmi_disable_osi_win8, - .ident = "ThinkPad Edge E530", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "3259A2G"), - }, - }, - { - .callback = dmi_disable_osi_win8, - .ident = "ThinkPad Edge E530", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "3259CTO"), - }, - }, - { - .callback = dmi_disable_osi_win8, - .ident = "ThinkPad Edge E530", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "3259HJG"), - }, - }, - { - .callback = dmi_disable_osi_win8, - .ident = "Acer Aspire V5-573G", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer Aspire"), - DMI_MATCH(DMI_PRODUCT_VERSION, "V5-573G/Dazzle_HW"), - }, - }, - { - .callback = dmi_disable_osi_win8, - .ident = "Acer Aspire V5-572G", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer Aspire"), - DMI_MATCH(DMI_PRODUCT_VERSION, "V5-572G/Dazzle_CX"), - }, - }, - { - .callback = dmi_disable_osi_win8, - .ident = "ThinkPad T431s", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "20AACTO1WW"), - }, - }, - { - .callback = dmi_disable_osi_win8, - .ident = "ThinkPad T430", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "2349D15"), - }, - }, - { - .callback = dmi_disable_osi_win8, .ident = "Dell Inspiron 7737", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index bfe1fa2fb5d1..18c0e6920eb4 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -461,6 +461,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = { DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720"), }, }, + { + .callback = video_set_use_native_backlight, + .ident = "ThinkPad X230", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X230"), + }, + }, { .callback = video_set_use_native_backlight, .ident = "ThinkPad T430 and T430s", @@ -471,10 +479,42 @@ static struct dmi_system_id video_dmi_table[] __initdata = { }, { .callback = video_set_use_native_backlight, - .ident = "ThinkPad X230", + .ident = "ThinkPad T430", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X230"), + DMI_MATCH(DMI_PRODUCT_VERSION, "2349D15"), + }, + }, + { + .callback = video_set_use_native_backlight, + .ident = "ThinkPad T431s", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "20AACTO1WW"), + }, + }, + { + .callback = video_set_use_native_backlight, + .ident = "ThinkPad Edge E530", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "3259A2G"), + }, + }, + { + .callback = video_set_use_native_backlight, + .ident = "ThinkPad Edge E530", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "3259CTO"), + }, + }, + { + .callback = video_set_use_native_backlight, + .ident = "ThinkPad Edge E530", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "3259HJG"), }, }, { @@ -573,6 +613,30 @@ static struct dmi_system_id video_dmi_table[] __initdata = { DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate B113"), }, }, + { + .callback = video_set_use_native_backlight, + .ident = "Acer Aspire V5-572G", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer Aspire"), + DMI_MATCH(DMI_PRODUCT_VERSION, "V5-572G/Dazzle_CX"), + }, + }, + { + .callback = video_set_use_native_backlight, + .ident = "Acer Aspire V5-573G", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer Aspire"), + DMI_MATCH(DMI_PRODUCT_VERSION, "V5-573G/Dazzle_HW"), + }, + }, + { + .callback = video_set_use_native_backlight, + .ident = "ASUS Zenbook Prime UX31A", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "UX31A"), + }, + }, { .callback = video_set_use_native_backlight, .ident = "HP ProBook 4340s", -- cgit v1.2.3 From 8a1664be0b922dd6afd60eca96a992ef5ec22c40 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Fri, 18 Jul 2014 18:02:52 +0800 Subject: ACPI: add config for BIOS table scan With the addition of ARM64 that does not have a traditional BIOS to scan, add a config option which is selected on x86 (ia64 doesn't need it either, it is EFI/UEFI based system) to do the traditional BIOS scanning for tables. Signed-off-by: Graeme Gregory Signed-off-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- arch/x86/Kconfig | 1 + drivers/acpi/Kconfig | 3 +++ drivers/acpi/osl.c | 4 +++- 3 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index d24887b645dc..5617750262db 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -132,6 +132,7 @@ config X86 select GENERIC_CPU_AUTOPROBE select HAVE_ARCH_AUDITSYSCALL select ARCH_SUPPORTS_ATOMIC_RMW + select ACPI_LEGACY_TABLES_LOOKUP if ACPI config INSTRUCTION_DECODER def_bool y diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index a34a22841002..970524c54bfa 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -42,6 +42,9 @@ menuconfig ACPI if ACPI +config ACPI_LEGACY_TABLES_LOOKUP + bool + config ACPI_SLEEP bool depends on SUSPEND || HIBERNATION diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index bad25b070fe0..3abe9b223ba7 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -259,12 +259,14 @@ acpi_physical_address __init acpi_os_get_root_pointer(void) "System description tables not found\n"); return 0; } - } else { + } else if (IS_ENABLED(CONFIG_ACPI_LEGACY_TABLES_LOOKUP)) { acpi_physical_address pa = 0; acpi_find_root_pointer(&pa); return pa; } + + return 0; } /* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */ -- cgit v1.2.3 From b50154d53e668314542ef9a592accc37137a8f65 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Fri, 18 Jul 2014 18:02:53 +0800 Subject: ACPI: Don't use acpi_lapic in ACPI core code Now ARM64 support is being added to ACPI so architecture specific values can not be used in core ACPI code. Following on the patch "ACPI / processor: Check if LAPIC is present during initialization" which uses acpi_lapic in acpi_processor.c, on ARM64 platform, GIC is used instead of local APIC, so acpi_lapic is not a suitable value for ARM64. What is actually important at this point is if there is/are CPU entry/entries (Local APIC/SAPIC, GICC) in MADT, so introduce acpi_has_cpu_in_madt() to be arch specific and generic. Signed-off-by: Graeme Gregory Signed-off-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- arch/ia64/include/asm/acpi.h | 5 +++++ arch/x86/include/asm/acpi.h | 5 +++++ drivers/acpi/acpi_processor.c | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/arch/ia64/include/asm/acpi.h b/arch/ia64/include/asm/acpi.h index 75dc59a793d6..a1d91ab4c5ef 100644 --- a/arch/ia64/include/asm/acpi.h +++ b/arch/ia64/include/asm/acpi.h @@ -40,6 +40,11 @@ extern int acpi_lapic; #define acpi_noirq 0 /* ACPI always enabled on IA64 */ #define acpi_pci_disabled 0 /* ACPI PCI always enabled on IA64 */ #define acpi_strict 1 /* no ACPI spec workarounds on IA64 */ + +static inline bool acpi_has_cpu_in_madt(void) +{ + return !!acpi_lapic; +} #endif #define acpi_processor_cstate_check(x) (x) /* no idle limits on IA64 :) */ static inline void disable_acpi(void) { } diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index e06225eda635..0ab4f9fd2687 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -121,6 +121,11 @@ static inline void arch_acpi_set_pdc_bits(u32 *buf) buf[2] &= ~(ACPI_PDC_C_C2C3_FFH); } +static inline bool acpi_has_cpu_in_madt(void) +{ + return !!acpi_lapic; +} + #else /* !CONFIG_ACPI */ #define acpi_lapic 0 diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index 1c085742644f..1fdf5e07a1c7 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c @@ -268,7 +268,7 @@ static int acpi_processor_get_info(struct acpi_device *device) pr->apic_id = apic_id; cpu_index = acpi_map_cpuid(pr->apic_id, pr->acpi_id); - if (!cpu0_initialized && !acpi_lapic) { + if (!cpu0_initialized && !acpi_has_cpu_in_madt()) { cpu0_initialized = 1; /* Handle UP system running SMP kernel, with no LAPIC in MADT */ if ((cpu_index == -1) && (num_online_cpus() == 1)) -- cgit v1.2.3 From 46ba51ea8f8639da32c55744b35479fdfb4e7232 Mon Sep 17 00:00:00 2001 From: Hanjun Guo Date: Fri, 18 Jul 2014 18:02:54 +0800 Subject: ACPI / processor: Introduce ARCH_MIGHT_HAVE_ACPI_PDC The use of _PDC is deprecated in ACPI 3.0 in favor of _OSC, as ARM platform is supported only in ACPI 5.0 or higher version, _PDC will not be used in ARM platform, so make Make _PDC only for platforms with Intel CPUs. Introduce ARCH_MIGHT_HAVE_ACPI_PDC and move _PDC related code in ACPI processor driver into a single file processor_pdc.c, make x86 and ia64 select it when ACPI is enabled. This patch also use pr_* to replace printk to fix the checkpatch warning and factor acpi_processor_alloc_pdc() a little bit to avoid duplicate pr_err() code. Suggested-by: Robert Richter Signed-off-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- arch/ia64/Kconfig | 1 + arch/x86/Kconfig | 1 + drivers/acpi/Kconfig | 3 + drivers/acpi/Makefile | 1 + drivers/acpi/internal.h | 5 + drivers/acpi/processor_core.c | 198 ---------------------------------------- drivers/acpi/processor_pdc.c | 206 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 217 insertions(+), 198 deletions(-) create mode 100644 drivers/acpi/processor_pdc.c (limited to 'drivers/acpi') diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 2f3abcf8f6bc..44a6915ab13d 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -10,6 +10,7 @@ config IA64 select ARCH_MIGHT_HAVE_PC_SERIO select PCI if (!IA64_HP_SIM) select ACPI if (!IA64_HP_SIM) + select ARCH_MIGHT_HAVE_ACPI_PDC if ACPI select PM if (!IA64_HP_SIM) select HAVE_UNSTABLE_SCHED_CLOCK select HAVE_IDE diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 5617750262db..70c43b5371bb 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -21,6 +21,7 @@ config X86_64 ### Arch settings config X86 def_bool y + select ARCH_MIGHT_HAVE_ACPI_PDC if ACPI select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS select ARCH_MIGHT_HAVE_PC_PARPORT select ARCH_MIGHT_HAVE_PC_SERIO diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 970524c54bfa..3f5f745bbbea 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -45,6 +45,9 @@ if ACPI config ACPI_LEGACY_TABLES_LOOKUP bool +config ARCH_MIGHT_HAVE_ACPI_PDC + bool + config ACPI_SLEEP bool depends on SUSPEND || HIBERNATION diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index ea55e0179f81..505d4d79fe3e 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -36,6 +36,7 @@ acpi-y += scan.o acpi-y += resource.o acpi-y += acpi_processor.o acpi-y += processor_core.o +acpi-$(CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC) += processor_pdc.o acpi-y += ec.o acpi-$(CONFIG_ACPI_DOCK) += dock.o acpi-y += pci_root.o pci_link.o pci_irq.o diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 7de5b603f272..64ee3eed18de 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -108,7 +108,12 @@ int acpi_power_transition(struct acpi_device *device, int state); int acpi_device_update_power(struct acpi_device *device, int *state_p); int acpi_wakeup_device_init(void); + +#ifdef CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC void acpi_early_processor_set_pdc(void); +#else +static inline void acpi_early_processor_set_pdc(void) {} +#endif /* -------------------------------------------------------------------------- Embedded Controller diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 71e2065639a6..00f48d13a516 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -4,17 +4,11 @@ * * Alex Chiang * - Unified x86/ia64 implementations - * Venkatesh Pallipadi - * - Added _PDC for platforms with Intel CPUs */ #include -#include -#include #include #include -#include "internal.h" - #define _COMPONENT ACPI_PROCESSOR_COMPONENT ACPI_MODULE_NAME("processor_core"); @@ -208,195 +202,3 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) return acpi_map_cpuid(apic_id, acpi_id); } EXPORT_SYMBOL_GPL(acpi_get_cpuid); - -static bool __init processor_physically_present(acpi_handle handle) -{ - int cpuid, type; - u32 acpi_id; - acpi_status status; - acpi_object_type acpi_type; - unsigned long long tmp; - union acpi_object object = { 0 }; - struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; - - status = acpi_get_type(handle, &acpi_type); - if (ACPI_FAILURE(status)) - return false; - - switch (acpi_type) { - case ACPI_TYPE_PROCESSOR: - status = acpi_evaluate_object(handle, NULL, NULL, &buffer); - if (ACPI_FAILURE(status)) - return false; - acpi_id = object.processor.proc_id; - break; - case ACPI_TYPE_DEVICE: - status = acpi_evaluate_integer(handle, "_UID", NULL, &tmp); - if (ACPI_FAILURE(status)) - return false; - acpi_id = tmp; - break; - default: - return false; - } - - type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0; - cpuid = acpi_get_cpuid(handle, type, acpi_id); - - if (cpuid == -1) - return false; - - return true; -} - -static void acpi_set_pdc_bits(u32 *buf) -{ - buf[0] = ACPI_PDC_REVISION_ID; - buf[1] = 1; - - /* Enable coordination with firmware's _TSD info */ - buf[2] = ACPI_PDC_SMP_T_SWCOORD; - - /* Twiddle arch-specific bits needed for _PDC */ - arch_acpi_set_pdc_bits(buf); -} - -static struct acpi_object_list *acpi_processor_alloc_pdc(void) -{ - struct acpi_object_list *obj_list; - union acpi_object *obj; - u32 *buf; - - /* allocate and initialize pdc. It will be used later. */ - obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL); - if (!obj_list) { - printk(KERN_ERR "Memory allocation error\n"); - return NULL; - } - - obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL); - if (!obj) { - printk(KERN_ERR "Memory allocation error\n"); - kfree(obj_list); - return NULL; - } - - buf = kmalloc(12, GFP_KERNEL); - if (!buf) { - printk(KERN_ERR "Memory allocation error\n"); - kfree(obj); - kfree(obj_list); - return NULL; - } - - acpi_set_pdc_bits(buf); - - obj->type = ACPI_TYPE_BUFFER; - obj->buffer.length = 12; - obj->buffer.pointer = (u8 *) buf; - obj_list->count = 1; - obj_list->pointer = obj; - - return obj_list; -} - -/* - * _PDC is required for a BIOS-OS handshake for most of the newer - * ACPI processor features. - */ -static acpi_status -acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in) -{ - acpi_status status = AE_OK; - - if (boot_option_idle_override == IDLE_NOMWAIT) { - /* - * If mwait is disabled for CPU C-states, the C2C3_FFH access - * mode will be disabled in the parameter of _PDC object. - * Of course C1_FFH access mode will also be disabled. - */ - union acpi_object *obj; - u32 *buffer = NULL; - - obj = pdc_in->pointer; - buffer = (u32 *)(obj->buffer.pointer); - buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH); - - } - status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL); - - if (ACPI_FAILURE(status)) - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Could not evaluate _PDC, using legacy perf. control.\n")); - - return status; -} - -void acpi_processor_set_pdc(acpi_handle handle) -{ - struct acpi_object_list *obj_list; - - if (arch_has_acpi_pdc() == false) - return; - - obj_list = acpi_processor_alloc_pdc(); - if (!obj_list) - return; - - acpi_processor_eval_pdc(handle, obj_list); - - kfree(obj_list->pointer->buffer.pointer); - kfree(obj_list->pointer); - kfree(obj_list); -} - -static acpi_status __init -early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv) -{ - if (processor_physically_present(handle) == false) - return AE_OK; - - acpi_processor_set_pdc(handle); - return AE_OK; -} - -#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(ACPI_PROCESSOR_DEVICE_HID, early_init_pdc, NULL, NULL); -} diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c new file mode 100644 index 000000000000..e5dd80800930 --- /dev/null +++ b/drivers/acpi/processor_pdc.c @@ -0,0 +1,206 @@ +/* + * Copyright (C) 2005 Intel Corporation + * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. + * + * Venkatesh Pallipadi + * - Added _PDC for platforms with Intel CPUs + */ + +#define pr_fmt(fmt) "ACPI: " fmt + +#include +#include +#include +#include + +#include "internal.h" + +#define _COMPONENT ACPI_PROCESSOR_COMPONENT +ACPI_MODULE_NAME("processor_pdc"); + +static bool __init processor_physically_present(acpi_handle handle) +{ + int cpuid, type; + u32 acpi_id; + acpi_status status; + acpi_object_type acpi_type; + unsigned long long tmp; + union acpi_object object = { 0 }; + struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; + + status = acpi_get_type(handle, &acpi_type); + if (ACPI_FAILURE(status)) + return false; + + switch (acpi_type) { + case ACPI_TYPE_PROCESSOR: + status = acpi_evaluate_object(handle, NULL, NULL, &buffer); + if (ACPI_FAILURE(status)) + return false; + acpi_id = object.processor.proc_id; + break; + case ACPI_TYPE_DEVICE: + status = acpi_evaluate_integer(handle, "_UID", NULL, &tmp); + if (ACPI_FAILURE(status)) + return false; + acpi_id = tmp; + break; + default: + return false; + } + + type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0; + cpuid = acpi_get_cpuid(handle, type, acpi_id); + + if (cpuid == -1) + return false; + + return true; +} + +static void acpi_set_pdc_bits(u32 *buf) +{ + buf[0] = ACPI_PDC_REVISION_ID; + buf[1] = 1; + + /* Enable coordination with firmware's _TSD info */ + buf[2] = ACPI_PDC_SMP_T_SWCOORD; + + /* Twiddle arch-specific bits needed for _PDC */ + arch_acpi_set_pdc_bits(buf); +} + +static struct acpi_object_list *acpi_processor_alloc_pdc(void) +{ + struct acpi_object_list *obj_list; + union acpi_object *obj; + u32 *buf; + + /* allocate and initialize pdc. It will be used later. */ + obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL); + if (!obj_list) + goto out; + + obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL); + if (!obj) { + kfree(obj_list); + goto out; + } + + buf = kmalloc(12, GFP_KERNEL); + if (!buf) { + kfree(obj); + kfree(obj_list); + goto out; + } + + acpi_set_pdc_bits(buf); + + obj->type = ACPI_TYPE_BUFFER; + obj->buffer.length = 12; + obj->buffer.pointer = (u8 *) buf; + obj_list->count = 1; + obj_list->pointer = obj; + + return obj_list; +out: + pr_err("Memory allocation error\n"); + return NULL; +} + +/* + * _PDC is required for a BIOS-OS handshake for most of the newer + * ACPI processor features. + */ +static acpi_status +acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in) +{ + acpi_status status = AE_OK; + + if (boot_option_idle_override == IDLE_NOMWAIT) { + /* + * If mwait is disabled for CPU C-states, the C2C3_FFH access + * mode will be disabled in the parameter of _PDC object. + * Of course C1_FFH access mode will also be disabled. + */ + union acpi_object *obj; + u32 *buffer = NULL; + + obj = pdc_in->pointer; + buffer = (u32 *)(obj->buffer.pointer); + buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH); + + } + status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL); + + if (ACPI_FAILURE(status)) + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Could not evaluate _PDC, using legacy perf. control.\n")); + + return status; +} + +void acpi_processor_set_pdc(acpi_handle handle) +{ + struct acpi_object_list *obj_list; + + if (arch_has_acpi_pdc() == false) + return; + + obj_list = acpi_processor_alloc_pdc(); + if (!obj_list) + return; + + acpi_processor_eval_pdc(handle, obj_list); + + kfree(obj_list->pointer->buffer.pointer); + kfree(obj_list->pointer); + kfree(obj_list); +} + +static acpi_status __init +early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv) +{ + if (processor_physically_present(handle) == false) + return AE_OK; + + acpi_processor_set_pdc(handle); + return AE_OK; +} + +static int __init set_no_mwait(const struct dmi_system_id *id) +{ + pr_notice("%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); +} + +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(ACPI_PROCESSOR_DEVICE_HID, early_init_pdc, NULL, NULL); +} -- cgit v1.2.3 From e71eeb2a6bcc6282b95215eb353a3ac9ce3e0de3 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 23 Jul 2014 00:59:04 +0200 Subject: ACPI / button: Do not propagate wakeup-from-suspend events During system suspend mark ACPI buttons (other than the lid) as "suspended" and if in that state, report wakeup events on button events, but do not propagate those events up the stack. This prevents systems from being turned off after a button-triggered wakeup from the "freeze" sleep state. Link: https://bugzilla.kernel.org/show_bug.cgi?id=77611 Tested-on: Acer Aspire S5, Toshiba Portege R500 Signed-off-by: Rafael J. Wysocki --- drivers/acpi/button.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index db35594d4df7..6d5d1832a588 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -79,11 +79,13 @@ static int acpi_button_remove(struct acpi_device *device); static void acpi_button_notify(struct acpi_device *device, u32 event); #ifdef CONFIG_PM_SLEEP +static int acpi_button_suspend(struct device *dev); static int acpi_button_resume(struct device *dev); #else +#define acpi_button_suspend NULL #define acpi_button_resume NULL #endif -static SIMPLE_DEV_PM_OPS(acpi_button_pm, NULL, acpi_button_resume); +static SIMPLE_DEV_PM_OPS(acpi_button_pm, acpi_button_suspend, acpi_button_resume); static struct acpi_driver acpi_button_driver = { .name = "button", @@ -102,6 +104,7 @@ struct acpi_button { struct input_dev *input; char phys[32]; /* for input device */ unsigned long pushed; + bool suspended; }; static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier); @@ -293,15 +296,19 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) if (button->type == ACPI_BUTTON_TYPE_LID) { acpi_lid_send_state(device); } else { - int keycode = test_bit(KEY_SLEEP, input->keybit) ? - KEY_SLEEP : KEY_POWER; + int keycode; + + pm_wakeup_event(&device->dev, 0); + if (button->suspended) + break; + keycode = test_bit(KEY_SLEEP, input->keybit) ? + KEY_SLEEP : KEY_POWER; input_report_key(input, keycode, 1); input_sync(input); input_report_key(input, keycode, 0); input_sync(input); - pm_wakeup_event(&device->dev, 0); acpi_bus_generate_netlink_event( device->pnp.device_class, dev_name(&device->dev), @@ -316,11 +323,21 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) } #ifdef CONFIG_PM_SLEEP +static int acpi_button_suspend(struct device *dev) +{ + struct acpi_device *device = to_acpi_device(dev); + struct acpi_button *button = acpi_driver_data(device); + + button->suspended = true; + return 0; +} + static int acpi_button_resume(struct device *dev) { struct acpi_device *device = to_acpi_device(dev); struct acpi_button *button = acpi_driver_data(device); + button->suspended = false; if (button->type == ACPI_BUTTON_TYPE_LID) return acpi_lid_send_state(device); return 0; -- cgit v1.2.3 From c072530f391e33bd22ed0638c08f07528f154493 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 23 Jul 2014 01:00:45 +0200 Subject: ACPI / PM: Revork the handling of ACPI device wakeup notifications Since ACPI wakeup GPEs are going to be enabled during system suspend as well as for runtime wakeup by a subsequent patch and the same notify handlers will be used in both cases, rework the ACPI device wakeup notification framework so that the part specific to physical devices is always run asynchronously from the PM workqueue. This prevents runtime resume callbacks for those devices from being run during system suspend and resume which may not be appropriate, among other things. Also make ACPI device wakeup notification handling a bit more robust agaist subsequent removal of ACPI device objects, whould that ever happen, and create a wakeup source object for each ACPI device configured for wakeup so that wakeup notifications for those devices can wake up the system from the "freeze" sleep state. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/device_pm.c | 80 +++++++++++++++++++++++++++++++++++------------- drivers/acpi/pci_root.c | 2 +- drivers/pci/pci-acpi.c | 60 ++++++++++++------------------------ include/acpi/acpi_bus.h | 21 ++++++++----- include/linux/pci-acpi.h | 13 +++++--- 5 files changed, 101 insertions(+), 75 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 49a51277f81d..366de0b0c39b 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -367,29 +367,61 @@ EXPORT_SYMBOL(acpi_bus_power_manageable); #ifdef CONFIG_PM static DEFINE_MUTEX(acpi_pm_notifier_lock); +static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used) +{ + struct acpi_device *adev; + + if (val != ACPI_NOTIFY_DEVICE_WAKE) + return; + + adev = acpi_bus_get_acpi_device(handle); + if (!adev) + return; + + mutex_lock(&acpi_pm_notifier_lock); + + if (adev->wakeup.flags.notifier_present) { + __pm_wakeup_event(adev->wakeup.ws, 0); + if (adev->wakeup.context.work.func) + queue_pm_work(&adev->wakeup.context.work); + } + + mutex_unlock(&acpi_pm_notifier_lock); + + acpi_bus_put_acpi_device(adev); +} + /** - * acpi_add_pm_notifier - Register PM notifier for given ACPI device. - * @adev: ACPI device to add the notifier for. - * @context: Context information to pass to the notifier routine. + * acpi_add_pm_notifier - Register PM notify handler for given ACPI device. + * @adev: ACPI device to add the notify handler for. + * @dev: Device to generate a wakeup event for while handling the notification. + * @work_func: Work function to execute when handling the notification. * * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of * PM wakeup events. For example, wakeup events may be generated for bridges * if one of the devices below the bridge is signaling wakeup, even if the * bridge itself doesn't have a wakeup GPE associated with it. */ -acpi_status acpi_add_pm_notifier(struct acpi_device *adev, - acpi_notify_handler handler, void *context) +acpi_status acpi_add_pm_notifier(struct acpi_device *adev, struct device *dev, + void (*work_func)(struct work_struct *work)) { acpi_status status = AE_ALREADY_EXISTS; + if (!dev && !work_func) + return AE_BAD_PARAMETER; + mutex_lock(&acpi_pm_notifier_lock); if (adev->wakeup.flags.notifier_present) goto out; - status = acpi_install_notify_handler(adev->handle, - ACPI_SYSTEM_NOTIFY, - handler, context); + adev->wakeup.ws = wakeup_source_register(dev_name(&adev->dev)); + adev->wakeup.context.dev = dev; + if (work_func) + INIT_WORK(&adev->wakeup.context.work, work_func); + + status = acpi_install_notify_handler(adev->handle, ACPI_SYSTEM_NOTIFY, + acpi_pm_notify_handler, NULL); if (ACPI_FAILURE(status)) goto out; @@ -404,8 +436,7 @@ acpi_status acpi_add_pm_notifier(struct acpi_device *adev, * acpi_remove_pm_notifier - Unregister PM notifier from given ACPI device. * @adev: ACPI device to remove the notifier from. */ -acpi_status acpi_remove_pm_notifier(struct acpi_device *adev, - acpi_notify_handler handler) +acpi_status acpi_remove_pm_notifier(struct acpi_device *adev) { acpi_status status = AE_BAD_PARAMETER; @@ -416,10 +447,17 @@ acpi_status acpi_remove_pm_notifier(struct acpi_device *adev, status = acpi_remove_notify_handler(adev->handle, ACPI_SYSTEM_NOTIFY, - handler); + acpi_pm_notify_handler); if (ACPI_FAILURE(status)) goto out; + if (adev->wakeup.context.work.func) { + cancel_work_sync(&adev->wakeup.context.work); + adev->wakeup.context.work.func = NULL; + } + adev->wakeup.context.dev = NULL; + wakeup_source_unregister(adev->wakeup.ws); + adev->wakeup.flags.notifier_present = false; out: @@ -602,16 +640,15 @@ EXPORT_SYMBOL(acpi_pm_device_sleep_state); #ifdef CONFIG_PM_RUNTIME /** - * acpi_wakeup_device - Wakeup notification handler for ACPI devices. - * @handle: ACPI handle of the device the notification is for. - * @event: Type of the signaled event. - * @context: Device corresponding to @handle. + * acpi_pm_notify_work_func - ACPI devices wakeup notification work function. + * @work: Work item to handle. */ -static void acpi_wakeup_device(acpi_handle handle, u32 event, void *context) +static void acpi_pm_notify_work_func(struct work_struct *work) { - struct device *dev = context; + struct device *dev; - if (event == ACPI_NOTIFY_DEVICE_WAKE && dev) { + dev = container_of(work, struct acpi_device_wakeup_context, work)->dev; + if (dev) { pm_wakeup_event(dev, 0); pm_runtime_resume(dev); } @@ -677,8 +714,7 @@ int acpi_pm_device_run_wake(struct device *phys_dev, bool enable) } EXPORT_SYMBOL(acpi_pm_device_run_wake); #else -static inline void acpi_wakeup_device(acpi_handle handle, u32 event, - void *context) {} +static inline void acpi_pm_notify_work_func(struct work_struct *work) {} #endif /* CONFIG_PM_RUNTIME */ #ifdef CONFIG_PM_SLEEP @@ -1048,7 +1084,7 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on) if (dev->pm_domain) return -EEXIST; - acpi_add_pm_notifier(adev, acpi_wakeup_device, dev); + acpi_add_pm_notifier(adev, dev, acpi_pm_notify_work_func); dev->pm_domain = &acpi_general_pm_domain; if (power_on) { acpi_dev_pm_full_power(adev); @@ -1076,7 +1112,7 @@ void acpi_dev_pm_detach(struct device *dev, bool power_off) if (adev && dev->pm_domain == &acpi_general_pm_domain) { dev->pm_domain = NULL; - acpi_remove_pm_notifier(adev, acpi_wakeup_device); + acpi_remove_pm_notifier(adev); if (power_off) { /* * If the device's PM QoS resume latency limit or flags diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index d388f13d48b4..e6ae603ed1a1 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -593,7 +593,7 @@ static int acpi_pci_root_add(struct acpi_device *device, if (no_aspm) pcie_no_aspm(); - pci_acpi_add_bus_pm_notifier(device, root->bus); + pci_acpi_add_bus_pm_notifier(device); if (device->wakeup.flags.run_wake) device_set_run_wake(root->bus->bridge, true); diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index ca4927ba8433..7b8b2298840a 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -18,31 +18,31 @@ #include "pci.h" /** - * pci_acpi_wake_bus - Wake-up notification handler for root buses. - * @handle: ACPI handle of a device the notification is for. - * @event: Type of the signaled event. - * @context: PCI root bus to wake up devices on. + * pci_acpi_wake_bus - Root bus wakeup notification fork function. + * @work: Work item to handle. */ -static void pci_acpi_wake_bus(acpi_handle handle, u32 event, void *context) +static void pci_acpi_wake_bus(struct work_struct *work) { - struct pci_bus *pci_bus = context; + struct acpi_device *adev; + struct acpi_pci_root *root; - if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_bus) - pci_pme_wakeup_bus(pci_bus); + adev = container_of(work, struct acpi_device, wakeup.context.work); + root = acpi_driver_data(adev); + pci_pme_wakeup_bus(root->bus); } /** - * pci_acpi_wake_dev - Wake-up notification handler for PCI devices. + * pci_acpi_wake_dev - PCI device wakeup notification work function. * @handle: ACPI handle of a device the notification is for. - * @event: Type of the signaled event. - * @context: PCI device object to wake up. + * @work: Work item to handle. */ -static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context) +static void pci_acpi_wake_dev(struct work_struct *work) { - struct pci_dev *pci_dev = context; + struct acpi_device_wakeup_context *context; + struct pci_dev *pci_dev; - if (event != ACPI_NOTIFY_DEVICE_WAKE || !pci_dev) - return; + context = container_of(work, struct acpi_device_wakeup_context, work); + pci_dev = to_pci_dev(context->dev); if (pci_dev->pme_poll) pci_dev->pme_poll = false; @@ -65,23 +65,12 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context) } /** - * pci_acpi_add_bus_pm_notifier - Register PM notifier for given PCI bus. - * @dev: ACPI device to add the notifier for. - * @pci_bus: PCI bus to walk checking for PME status if an event is signaled. + * pci_acpi_add_bus_pm_notifier - Register PM notifier for root PCI bus. + * @dev: PCI root bridge ACPI device. */ -acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev, - struct pci_bus *pci_bus) +acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev) { - return acpi_add_pm_notifier(dev, pci_acpi_wake_bus, pci_bus); -} - -/** - * pci_acpi_remove_bus_pm_notifier - Unregister PCI bus PM notifier. - * @dev: ACPI device to remove the notifier from. - */ -acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev) -{ - return acpi_remove_pm_notifier(dev, pci_acpi_wake_bus); + return acpi_add_pm_notifier(dev, NULL, pci_acpi_wake_bus); } /** @@ -92,16 +81,7 @@ acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev) acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev, struct pci_dev *pci_dev) { - return acpi_add_pm_notifier(dev, pci_acpi_wake_dev, pci_dev); -} - -/** - * pci_acpi_remove_pm_notifier - Unregister PCI device PM notifier. - * @dev: ACPI device to remove the notifier from. - */ -acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev) -{ - return acpi_remove_pm_notifier(dev, pci_acpi_wake_dev); + return acpi_add_pm_notifier(dev, &pci_dev->dev, pci_acpi_wake_dev); } phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle) diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index b5714580801a..99780d46abb6 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -315,12 +315,19 @@ struct acpi_device_wakeup_flags { u8 notifier_present:1; /* Wake-up notify handler has been installed */ }; +struct acpi_device_wakeup_context { + struct work_struct work; + struct device *dev; +}; + struct acpi_device_wakeup { acpi_handle gpe_device; u64 gpe_number; u64 sleep_state; struct list_head resources; struct acpi_device_wakeup_flags flags; + struct acpi_device_wakeup_context context; + struct wakeup_source *ws; int prepare_count; }; @@ -510,20 +517,18 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int state); int acpi_disable_wakeup_device_power(struct acpi_device *dev); #ifdef CONFIG_PM -acpi_status acpi_add_pm_notifier(struct acpi_device *adev, - acpi_notify_handler handler, void *context); -acpi_status acpi_remove_pm_notifier(struct acpi_device *adev, - acpi_notify_handler handler); +acpi_status acpi_add_pm_notifier(struct acpi_device *adev, struct device *dev, + void (*work_func)(struct work_struct *work)); +acpi_status acpi_remove_pm_notifier(struct acpi_device *adev); int acpi_pm_device_sleep_state(struct device *, int *, int); #else static inline acpi_status acpi_add_pm_notifier(struct acpi_device *adev, - acpi_notify_handler handler, - void *context) + struct device *dev, + void (*work_func)(struct work_struct *work)) { return AE_SUPPORT; } -static inline acpi_status acpi_remove_pm_notifier(struct acpi_device *adev, - acpi_notify_handler handler) +static inline acpi_status acpi_remove_pm_notifier(struct acpi_device *adev) { return AE_SUPPORT; } diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h index 637a608ded0b..64dacb7288a6 100644 --- a/include/linux/pci-acpi.h +++ b/include/linux/pci-acpi.h @@ -11,12 +11,17 @@ #include #ifdef CONFIG_ACPI -extern acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev, - struct pci_bus *pci_bus); -extern acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev); +extern acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev); +static inline acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev) +{ + return acpi_remove_pm_notifier(dev); +} extern acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev, struct pci_dev *pci_dev); -extern acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev); +static inline acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev) +{ + return acpi_remove_pm_notifier(dev); +} extern phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle); static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev) -- cgit v1.2.3 From f35cec255557d1037ff0d772edfd6e7b1e92cdc0 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 23 Jul 2014 01:00:53 +0200 Subject: ACPI / PM: Always enable wakeup GPEs when enabling device wakeup Wakeup GPEs are currently only enabled when setting up devices for remote wakeup at run time. During system-wide transitions they are enabled by ACPICA at the very last stage of suspend (before asking the BIOS to take over). Of course, that only works for system sleep states supported by ACPI, so in particular it doesn't work for the "freeze" sleep state. For this reason, modify the ACPI core device PM code to enable wakeup GPEs for devices when setting them up for wakeup regardless of whether that is remote wakeup at runtime or system wakeup. That allows the same device wakeup setup routine to be used for both runtime PM and system-wide PM and makes it possible to reduce code size quite a bit. This make ACPI-based PCI Wake-on-LAN work with the "freeze" sleep state on my venerable Toshiba Portege R500 and should help other systems too. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/device_pm.c | 49 +++++++++++++++++------------------------------- include/acpi/acpi_bus.h | 11 ----------- 2 files changed, 17 insertions(+), 43 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 366de0b0c39b..ad2810900799 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -638,7 +638,6 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in) } EXPORT_SYMBOL(acpi_pm_device_sleep_state); -#ifdef CONFIG_PM_RUNTIME /** * acpi_pm_notify_work_func - ACPI devices wakeup notification work function. * @work: Work item to handle. @@ -655,8 +654,9 @@ static void acpi_pm_notify_work_func(struct work_struct *work) } /** - * __acpi_device_run_wake - Enable/disable runtime remote wakeup for device. - * @adev: ACPI device to enable/disable the remote wakeup for. + * acpi_device_wakeup - Enable/disable wakeup functionality for device. + * @adev: ACPI device to enable/disable wakeup functionality for. + * @target_state: State the system is transitioning into. * @enable: Whether to enable or disable the wakeup functionality. * * Enable/disable the GPE associated with @adev so that it can generate @@ -666,7 +666,8 @@ static void acpi_pm_notify_work_func(struct work_struct *work) * Callers must ensure that @adev is a valid ACPI device node before executing * this function. */ -int __acpi_device_run_wake(struct acpi_device *adev, bool enable) +static int acpi_device_wakeup(struct acpi_device *adev, u32 target_state, + bool enable) { struct acpi_device_wakeup *wakeup = &adev->wakeup; @@ -674,7 +675,7 @@ int __acpi_device_run_wake(struct acpi_device *adev, bool enable) acpi_status res; int error; - error = acpi_enable_wakeup_device_power(adev, ACPI_STATE_S0); + error = acpi_enable_wakeup_device_power(adev, target_state); if (error) return error; @@ -690,6 +691,7 @@ int __acpi_device_run_wake(struct acpi_device *adev, bool enable) return 0; } +#ifdef CONFIG_PM_RUNTIME /** * acpi_pm_device_run_wake - Enable/disable remote wakeup for given device. * @dev: Device to enable/disable the platform to wake up. @@ -710,28 +712,12 @@ int acpi_pm_device_run_wake(struct device *phys_dev, bool enable) return -ENODEV; } - return __acpi_device_run_wake(adev, enable); + return acpi_device_wakeup(adev, enable, ACPI_STATE_S0); } EXPORT_SYMBOL(acpi_pm_device_run_wake); -#else -static inline void acpi_pm_notify_work_func(struct work_struct *work) {} #endif /* CONFIG_PM_RUNTIME */ #ifdef CONFIG_PM_SLEEP -/** - * __acpi_device_sleep_wake - Enable or disable device to wake up the system. - * @dev: Device to enable/desible to wake up the system. - * @target_state: System state the device is supposed to wake up from. - * @enable: Whether to enable or disable @dev to wake up the system. - */ -int __acpi_device_sleep_wake(struct acpi_device *adev, u32 target_state, - bool enable) -{ - return enable ? - acpi_enable_wakeup_device_power(adev, target_state) : - acpi_disable_wakeup_device_power(adev); -} - /** * acpi_pm_device_sleep_wake - Enable or disable device to wake up the system. * @dev: Device to enable/desible to wake up the system from sleep states. @@ -752,8 +738,7 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable) return -ENODEV; } - error = __acpi_device_sleep_wake(adev, acpi_target_system_state(), - enable); + error = acpi_device_wakeup(adev, acpi_target_system_state(), enable); if (!error) dev_info(dev, "System wakeup %s by ACPI\n", enable ? "enabled" : "disabled"); @@ -811,13 +796,13 @@ int acpi_dev_runtime_suspend(struct device *dev) remote_wakeup = dev_pm_qos_flags(dev, PM_QOS_FLAG_REMOTE_WAKEUP) > PM_QOS_FLAGS_NONE; - error = __acpi_device_run_wake(adev, remote_wakeup); + error = acpi_device_wakeup(adev, ACPI_STATE_S0, remote_wakeup); if (remote_wakeup && error) return -EAGAIN; error = acpi_dev_pm_low_power(dev, adev, ACPI_STATE_S0); if (error) - __acpi_device_run_wake(adev, false); + acpi_device_wakeup(adev, ACPI_STATE_S0, false); return error; } @@ -840,7 +825,7 @@ int acpi_dev_runtime_resume(struct device *dev) return 0; error = acpi_dev_pm_full_power(adev); - __acpi_device_run_wake(adev, false); + acpi_device_wakeup(adev, ACPI_STATE_S0, false); return error; } EXPORT_SYMBOL_GPL(acpi_dev_runtime_resume); @@ -896,13 +881,13 @@ int acpi_dev_suspend_late(struct device *dev) target_state = acpi_target_system_state(); wakeup = device_may_wakeup(dev); - error = __acpi_device_sleep_wake(adev, target_state, wakeup); + error = acpi_device_wakeup(adev, target_state, wakeup); if (wakeup && error) return error; error = acpi_dev_pm_low_power(dev, adev, target_state); if (error) - __acpi_device_sleep_wake(adev, ACPI_STATE_UNKNOWN, false); + acpi_device_wakeup(adev, ACPI_STATE_UNKNOWN, false); return error; } @@ -925,7 +910,7 @@ int acpi_dev_resume_early(struct device *dev) return 0; error = acpi_dev_pm_full_power(adev); - __acpi_device_sleep_wake(adev, ACPI_STATE_UNKNOWN, false); + acpi_device_wakeup(adev, ACPI_STATE_UNKNOWN, false); return error; } EXPORT_SYMBOL_GPL(acpi_dev_resume_early); @@ -1088,7 +1073,7 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on) dev->pm_domain = &acpi_general_pm_domain; if (power_on) { acpi_dev_pm_full_power(adev); - __acpi_device_run_wake(adev, false); + acpi_device_wakeup(adev, ACPI_STATE_S0, false); } return 0; } @@ -1122,7 +1107,7 @@ void acpi_dev_pm_detach(struct device *dev, bool power_off) */ dev_pm_qos_hide_latency_limit(dev); dev_pm_qos_hide_flags(dev); - __acpi_device_run_wake(adev, false); + acpi_device_wakeup(adev, ACPI_STATE_S0, false); acpi_dev_pm_low_power(dev, adev, ACPI_STATE_S0); } } diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 99780d46abb6..a0b08457452d 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -543,13 +543,8 @@ static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m) #endif #ifdef CONFIG_PM_RUNTIME -int __acpi_device_run_wake(struct acpi_device *, bool); int acpi_pm_device_run_wake(struct device *, bool); #else -static inline int __acpi_device_run_wake(struct acpi_device *adev, bool en) -{ - return -ENODEV; -} static inline int acpi_pm_device_run_wake(struct device *dev, bool enable) { return -ENODEV; @@ -557,14 +552,8 @@ static inline int acpi_pm_device_run_wake(struct device *dev, bool enable) #endif #ifdef CONFIG_PM_SLEEP -int __acpi_device_sleep_wake(struct acpi_device *, u32, bool); int acpi_pm_device_sleep_wake(struct device *, bool); #else -static inline int __acpi_device_sleep_wake(struct acpi_device *adev, - u32 target_state, bool enable) -{ - return -ENODEV; -} static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable) { return -ENODEV; -- cgit v1.2.3 From 17653a3e098dc20ae1db7459344a81c386625696 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 23 Jul 2014 01:01:41 +0200 Subject: ACPI / PM: Use ACPI_COMPANION() instead of ACPI_HANDLE() The ACPI_HANDLE() macro evaluates ACPI_COMPANION() internally to return the handle of the device's ACPI companion, so it is much more straightforward and efficient to use ACPI_COMPANION() directly to obtain the device's ACPI companion object instead of using ACPI_HANDLE() and acpi_bus_get_device() on the returned handle for the same thing. Do that in three places in the ACPI device PM code. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/device_pm.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index ad2810900799..67075f800e34 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -596,7 +596,6 @@ static int acpi_dev_pm_get_state(struct device *dev, struct acpi_device *adev, */ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in) { - acpi_handle handle = ACPI_HANDLE(dev); struct acpi_device *adev; int ret, d_min, d_max; @@ -611,8 +610,9 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in) d_max_in = ACPI_STATE_D3_HOT; } - if (!handle || acpi_bus_get_device(handle, &adev)) { - dev_dbg(dev, "ACPI handle without context in %s!\n", __func__); + adev = ACPI_COMPANION(dev); + if (!adev) { + dev_dbg(dev, "ACPI companion missing in %s!\n", __func__); return -ENODEV; } @@ -700,15 +700,13 @@ static int acpi_device_wakeup(struct acpi_device *adev, u32 target_state, int acpi_pm_device_run_wake(struct device *phys_dev, bool enable) { struct acpi_device *adev; - acpi_handle handle; if (!device_run_wake(phys_dev)) return -EINVAL; - handle = ACPI_HANDLE(phys_dev); - if (!handle || acpi_bus_get_device(handle, &adev)) { - dev_dbg(phys_dev, "ACPI handle without context in %s!\n", - __func__); + adev = ACPI_COMPANION(phys_dev); + if (!adev) { + dev_dbg(phys_dev, "ACPI companion missing in %s!\n", __func__); return -ENODEV; } @@ -725,16 +723,15 @@ EXPORT_SYMBOL(acpi_pm_device_run_wake); */ int acpi_pm_device_sleep_wake(struct device *dev, bool enable) { - acpi_handle handle; struct acpi_device *adev; int error; if (!device_can_wakeup(dev)) return -EINVAL; - handle = ACPI_HANDLE(dev); - if (!handle || acpi_bus_get_device(handle, &adev)) { - dev_dbg(dev, "ACPI handle without context in %s!\n", __func__); + adev = ACPI_COMPANION(dev); + if (!adev) { + dev_dbg(dev, "ACPI companion missing in %s!\n", __func__); return -ENODEV; } -- cgit v1.2.3 From 417b4a73b62760db67512892c32f8acc008ab54e Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Wed, 16 Jul 2014 16:58:53 +0800 Subject: ACPI: Add support to force header inclusion rules for . As there is only CONFIG_ACPI=n processing in the , it is not safe to include directly for source out of Linux ACPI subsystems. This patch adds error messaging to warn developers of such wrong inclusions. In order not to be bisected and reverted as a wrong commit, warning messages are carefully split into a seperate patch other than the wrong inclusion cleanups. Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/Makefile | 2 +- include/acpi/platform/aclinux.h | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index 8bb43f06e11f..87a24ac21363 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile @@ -2,7 +2,7 @@ # Makefile for ACPICA Core interpreter # -ccflags-y := -Os +ccflags-y := -Os -DBUILDING_ACPICA ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT # use acpi.o to put all files here into acpi.o modparam namespace diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h index dfba35476b8a..1ba7c190c2cc 100644 --- a/include/acpi/platform/aclinux.h +++ b/include/acpi/platform/aclinux.h @@ -44,6 +44,16 @@ #ifndef __ACLINUX_H__ #define __ACLINUX_H__ +#ifdef __KERNEL__ + +/* ACPICA external files should not include ACPICA headers directly. */ + +#if !defined(BUILDING_ACPICA) && !defined(_LINUX_ACPI_H) +#error "Please don't include directly, include instead." +#endif + +#endif + /* Common (in-kernel/user-space) ACPICA configuration */ #define ACPI_USE_SYSTEM_CLIBRARY -- cgit v1.2.3 From b9ca3d7b513a9824dc97d5dc7c4eb9e30ab776b5 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 23 Jul 2014 13:11:59 +0800 Subject: ACPICA: GPEs: Do not allow enable for GPEs that have no handler(s). ACPICA commit 23b5a8542283af28c3a3a4e3f81096d6e2569faa There is no point in enabling a GPE that has no handler or GPE method. At worst, it can cause GPE floods. Rafael Wysocki. Signed-off-by: Rafael J. Wysocki Signed-off-by: Bob Moore Signed-off-by: Lv Zheng --- drivers/acpi/acpica/evxfgpe.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c index cb534faf5369..82e5c146bdd4 100644 --- a/drivers/acpi/acpica/evxfgpe.c +++ b/drivers/acpi/acpica/evxfgpe.c @@ -126,11 +126,19 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); - /* Ensure that we have a valid GPE number */ - + /* + * Ensure that we have a valid GPE number and that there is some way + * of handling the GPE (handler or a GPE method). In other words, we + * won't allow a valid GPE to be enabled if there is no way to handle it. + */ gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); if (gpe_event_info) { - status = acpi_ev_add_gpe_reference(gpe_event_info); + if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) != + ACPI_GPE_DISPATCH_NONE) { + status = acpi_ev_add_gpe_reference(gpe_event_info); + } else { + status = AE_NO_HANDLER; + } } acpi_os_release_lock(acpi_gbl_gpe_lock, flags); -- cgit v1.2.3 From c12f07d17c12193256a99e20c9a0f130fb8f7be8 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 23 Jul 2014 13:12:16 +0800 Subject: ACPICA: Add new GPE public interface - acpi_mark_gpe_for_wake. ACPICA commit c49dbfed2bc069d0038ea7e1294409bfde7c2c8c Some potential callers of acpi_setup_gpe_for_wake may know in advance that there won't be any notify handlers installed for device wake notifications from the given GPE (one example is a button GPE in Linux). For these cases, acpi_mark_gpe_for_wake should be used instead of acpi_setup_gpe_for_wake. This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to setup implicit wake notification for it (since there's no handler method). Rafael Wysocki. Signed-off-by: Rafael J. Wysocki Signed-off-by: Bob Moore Signed-off-by: Lv Zheng --- drivers/acpi/acpica/evxfgpe.c | 47 +++++++++++++++++++++++++++++++++++++++++++ include/acpi/acpixf.h | 4 ++++ 2 files changed, 51 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c index 82e5c146bdd4..0cf159cc6e6d 100644 --- a/drivers/acpi/acpica/evxfgpe.c +++ b/drivers/acpi/acpica/evxfgpe.c @@ -185,6 +185,53 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) ACPI_EXPORT_SYMBOL(acpi_disable_gpe) +/******************************************************************************* + * + * FUNCTION: acpi_mark_gpe_for_wake + * + * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 + * gpe_number - GPE level within the GPE block + * + * RETURN: Status + * + * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply + * sets the ACPI_GPE_CAN_WAKE flag. + * + * Some potential callers of acpi_setup_gpe_for_wake may know in advance that + * there won't be any notify handlers installed for device wake notifications + * from the given GPE (one example is a button GPE in Linux). For these cases, + * acpi_mark_gpe_for_wake should be used instead of acpi_setup_gpe_for_wake. + * This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to + * setup implicit wake notification for it (since there's no handler method). + * + ******************************************************************************/ +acpi_status acpi_mark_gpe_for_wake(acpi_handle gpe_device, u32 gpe_number) +{ + struct acpi_gpe_event_info *gpe_event_info; + acpi_status status = AE_BAD_PARAMETER; + acpi_cpu_flags flags; + + ACPI_FUNCTION_TRACE(acpi_mark_gpe_for_wake); + + flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); + + /* Ensure that we have a valid GPE number */ + + gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); + if (gpe_event_info) { + + /* Mark the GPE as a possible wake event */ + + gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; + status = AE_OK; + } + + acpi_os_release_lock(acpi_gbl_gpe_lock, flags); + return_ACPI_STATUS(status); +} + +ACPI_EXPORT_SYMBOL(acpi_mark_gpe_for_wake) + /******************************************************************************* * * FUNCTION: acpi_setup_gpe_for_wake diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 3f6e14ff24b1..508e5649dda9 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -674,6 +674,10 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_finish_gpe(acpi_handle gpe_device, u32 gpe_number)) +ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status + acpi_mark_gpe_for_wake(acpi_handle gpe_device, + u32 gpe_number)) + ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_setup_gpe_for_wake(acpi_handle parent_device, -- cgit v1.2.3 From bd9b2f9aff26c185c1f8e0cd08a850ee4ace391a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 14 Jul 2014 22:41:41 +0200 Subject: ACPI / scan: No implicit wake notification for buttons The ACPI device enumeration code in Linux assumes that buttons always are wakeup devices, so it calls acpi_setup_gpe_for_wake() for them which leads to undesirable side effects. Namely, that function sets up implicit device wake notification mechanism for a given GPE if there is no handler method in the ACPI namespace, which from the ACPICA's perspective means that there always is a way to handle that GPE if enabled. However, we don't handle wake notify events for buttons, so if there are no handler methods for their GPEs in the namespace, enabling a button GPE at run time leads to a GPE storm in some cases (the GPE triggers, ACPICA carries out the implicit wake notification for it which isn't handled, so the GPE triggers again and so on). To prevent that from happening use acpi_mark_gpe_for_wake() instead of acpi_setup_gpe_for_wake() for buttons which will cause ACPICA to only enable button GPEs if there are handler methods for the in the namespace. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index f775fa0d850f..0afa66050370 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1421,14 +1421,13 @@ static int acpi_bus_extract_wakeup_device_power_package(acpi_handle handle, wakeup->sleep_state = sleep_state; } } - acpi_setup_gpe_for_wake(handle, wakeup->gpe_device, wakeup->gpe_number); out: kfree(buffer.pointer); return err; } -static void acpi_bus_set_run_wake_flags(struct acpi_device *device) +static void acpi_wakeup_gpe_init(struct acpi_device *device) { struct acpi_device_id button_device_ids[] = { {"PNP0C0C", 0}, @@ -1436,29 +1435,33 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device) {"PNP0C0E", 0}, {"", 0}, }; + struct acpi_device_wakeup *wakeup = &device->wakeup; acpi_status status; acpi_event_status event_status; - device->wakeup.flags.notifier_present = 0; + wakeup->flags.notifier_present = 0; /* Power button, Lid switch always enable wakeup */ if (!acpi_match_device_ids(device, button_device_ids)) { - device->wakeup.flags.run_wake = 1; + wakeup->flags.run_wake = 1; if (!acpi_match_device_ids(device, &button_device_ids[1])) { /* Do not use Lid/sleep button for S5 wakeup */ - if (device->wakeup.sleep_state == ACPI_STATE_S5) - device->wakeup.sleep_state = ACPI_STATE_S4; + if (wakeup->sleep_state == ACPI_STATE_S5) + wakeup->sleep_state = ACPI_STATE_S4; } + acpi_mark_gpe_for_wake(wakeup->gpe_device, wakeup->gpe_number); device_set_wakeup_capable(&device->dev, true); return; } - status = acpi_get_gpe_status(device->wakeup.gpe_device, - device->wakeup.gpe_number, - &event_status); - if (status == AE_OK) - device->wakeup.flags.run_wake = - !!(event_status & ACPI_EVENT_FLAG_HANDLE); + acpi_setup_gpe_for_wake(device->handle, wakeup->gpe_device, + wakeup->gpe_number); + status = acpi_get_gpe_status(wakeup->gpe_device, wakeup->gpe_number, + &event_status); + if (ACPI_FAILURE(status)) + return; + + wakeup->flags.run_wake = !!(event_status & ACPI_EVENT_FLAG_HANDLE); } static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device) @@ -1478,7 +1481,7 @@ static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device) device->wakeup.flags.valid = 1; device->wakeup.prepare_count = 0; - acpi_bus_set_run_wake_flags(device); + acpi_wakeup_gpe_init(device); /* Call _PSW/_DSW object to disable its ability to wake the sleeping * system for the ACPI device with the _PRW object. * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW. -- cgit v1.2.3 From 821d6f0359b0614792ab8e2fb93b503e25a65079 Mon Sep 17 00:00:00 2001 From: Lan Tianyu Date: Wed, 23 Jul 2014 14:42:33 +0800 Subject: ACPI / sleep: Do not save NVS for new machines to accelerate S3 NVS region is saved and restored unconditionally for machines without nvs_nosave quirk during S3. Tested some new machines and the operation is not necessary. Saving NVS region also affects S2RAM speed. The time of NVS saving and restoring depends on the size of NVS region and it consumes 7~10ms normally. This patch is to make machines produced from 2012 to now not saving NVS region to accelerate S3. Signed-off-by: Lan Tianyu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/sleep.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index b3e3cc73ba79..54da4a3fe65e 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -322,6 +322,11 @@ static struct dmi_system_id acpisleep_dmi_table[] __initdata = { static void acpi_sleep_dmi_check(void) { + int year; + + if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year >= 2012) + acpi_nvs_nosave_s3(); + dmi_check_system(acpisleep_dmi_table); } -- cgit v1.2.3 From 7f94fde6e738b4492d6923fe8ece459441a6a2ec Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 28 Jul 2014 17:37:33 +0200 Subject: ACPI / video: Add use_native_backlight quirk for HP EliteBook 2014 models Link: https://bugzilla.redhat.com/show_bug.cgi?id=1123565 Signed-off-by: Hans de Goede Signed-off-by: Rafael J. Wysocki --- drivers/acpi/video.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 18c0e6920eb4..826884392e6b 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -673,6 +673,15 @@ static struct dmi_system_id video_dmi_table[] __initdata = { }, { .callback = video_set_use_native_backlight, + .ident = "HP EliteBook 2014 models", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook "), + DMI_MATCH(DMI_PRODUCT_NAME, " G2"), + }, + }, + { + .callback = video_set_use_native_backlight, .ident = "HP ZBook 14", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), -- cgit v1.2.3 From 3a54a57dceed78f7f3c35991d6d4a064a0c2e343 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 28 Jul 2014 21:22:55 +0800 Subject: ACPI / battery: remove duplicated include from battery.c Remove duplicated include. Signed-off-by: Wei Yongjun Signed-off-by: Rafael J. Wysocki --- drivers/acpi/battery.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 130f513e08c9..48bcf38a0ea8 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #ifdef CONFIG_ACPI_PROCFS_POWER -- cgit v1.2.3 From 515afdcba0880528fa8ae6fa63a14de6b9018770 Mon Sep 17 00:00:00 2001 From: Hanjun Guo Date: Tue, 29 Jul 2014 11:27:50 +0800 Subject: ACPI / processor: Make it possible to get local x2apic id via _MAT Logical processors with APIC ID values of 255 and greater are required to have a Processor Device object and must convey the processor's APIC information to OSPM using the Processor Local X2APIC structure, but not until ACPI 5.1, X2APIC structure was not supported in _MAT method. _MAT is needed for CPU hotplug and system with more than 255 CPUs will definitely need X2APIC structure, so add its support in map_mat_entry() to make it possible to get local x2apic id via _MAT based on ACPI 5.1. Signed-off-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- drivers/acpi/processor_core.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 71e2065639a6..afe4201c5c7b 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -135,6 +135,8 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) map_lapic_id(header, acpi_id, &apic_id); } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { map_lsapic_id(header, type, acpi_id, &apic_id); + } else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) { + map_x2apic_id(header, type, acpi_id, &apic_id); } exit: -- cgit v1.2.3 From 8884de6a47dda88f8fdf4efa9960149fb5a8a46f Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 30 Jul 2014 12:20:26 +0800 Subject: ACPICA: Work around an ancient GCC bug. warning: cast from function call of type 'char *' to non-matching type 'long unsigned int' Since acpi_ut_format_number() hasn't been enabled for the Linux kernel, this patch doesn't affect the Linux kernel. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/utprint.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/utprint.c b/drivers/acpi/acpica/utprint.c index 10311648f701..080e22aaba15 100644 --- a/drivers/acpi/acpica/utprint.c +++ b/drivers/acpi/acpica/utprint.c @@ -242,6 +242,7 @@ static char *acpi_ut_format_number(char *string, u64 number, u8 base, s32 width, s32 precision, u8 type) { + char *pos; char sign; char zero; u8 need_prefix; @@ -289,9 +290,8 @@ static char *acpi_ut_format_number(char *string, /* Generate full string in reverse order */ - i = ACPI_PTR_DIFF(acpi_ut_put_number - (reversed_string, number, base, upper), - reversed_string); + pos = acpi_ut_put_number(reversed_string, number, base, upper); + i = ACPI_PTR_DIFF(pos, reversed_string); /* Printing 100 using %2d gives "100", not "00" */ -- cgit v1.2.3 From 90da690bc488bdc6333fe7565e6ab8daa5540327 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 30 Jul 2014 12:20:39 +0800 Subject: ACPICA: Disassembler: Add support for the ToUUID opererator (macro). This change adds support to disassemble a UUID back to the original ToUUID operator. It will detect a UUID within a standard AML Buffer. Also, a description of the UUID is emitted for "known" UUIDs, defined as UUIDs that are defined in the ACPI specification. Since this is a change for disassembler which is not shipped in the Linux kernel, the Linux kernel is not affected. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/aclocal.h | 13 +++++++------ include/acpi/acconfig.h | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 6 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 91f801a2e689..4c9fd7ceeb24 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -730,12 +730,13 @@ union acpi_parse_value { #define ACPI_DASM_STRING 0x02 /* Buffer is a ASCII string */ #define ACPI_DASM_UNICODE 0x03 /* Buffer is a Unicode string */ #define ACPI_DASM_PLD_METHOD 0x04 /* Buffer is a _PLD method bit-packed buffer */ -#define ACPI_DASM_EISAID 0x05 /* Integer is an EISAID */ -#define ACPI_DASM_MATCHOP 0x06 /* Parent opcode is a Match() operator */ -#define ACPI_DASM_LNOT_PREFIX 0x07 /* Start of a Lnot_equal (etc.) pair of opcodes */ -#define ACPI_DASM_LNOT_SUFFIX 0x08 /* End of a Lnot_equal (etc.) pair of opcodes */ -#define ACPI_DASM_HID_STRING 0x09 /* String is a _HID or _CID */ -#define ACPI_DASM_IGNORE 0x0A /* Not used at this time */ +#define ACPI_DASM_UUID 0x05 /* Buffer is a UUID/GUID */ +#define ACPI_DASM_EISAID 0x06 /* Integer is an EISAID */ +#define ACPI_DASM_MATCHOP 0x07 /* Parent opcode is a Match() operator */ +#define ACPI_DASM_LNOT_PREFIX 0x08 /* Start of a Lnot_equal (etc.) pair of opcodes */ +#define ACPI_DASM_LNOT_SUFFIX 0x09 /* End of a Lnot_equal (etc.) pair of opcodes */ +#define ACPI_DASM_HID_STRING 0x0A /* String is a _HID or _CID */ +#define ACPI_DASM_IGNORE 0x0B /* Not used at this time */ /* * Generic operation (for example: If, While, Store) diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h index 932a60d6ed82..5a0a3e5daf85 100644 --- a/include/acpi/acconfig.h +++ b/include/acpi/acconfig.h @@ -217,6 +217,24 @@ #define ACPI_NUM_sx_d_METHODS 4 #define ACPI_NUM_sx_w_METHODS 5 +/****************************************************************************** + * + * Miscellaneous constants + * + *****************************************************************************/ + +/* UUID constants */ + +#define UUID_BUFFER_LENGTH 16 /* Length of UUID in memory */ +#define UUID_STRING_LENGTH 36 /* Total length of a UUID string */ + +/* Positions for required hyphens (dashes) in UUID strings */ + +#define UUID_HYPHEN1_OFFSET 8 +#define UUID_HYPHEN2_OFFSET 13 +#define UUID_HYPHEN3_OFFSET 18 +#define UUID_HYPHEN4_OFFSET 23 + /****************************************************************************** * * ACPI AML Debugger -- cgit v1.2.3 From d38bb0020452bb28579e3ade8537e9e32b41d607 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 30 Jul 2014 12:20:46 +0800 Subject: ACPICA: Update for comments/formatting. No functional changes. Fix some issues detected by acpisrc utility. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/exfield.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c index 1ff42c07b42b..6907ce0c704c 100644 --- a/drivers/acpi/acpica/exfield.c +++ b/drivers/acpi/acpica/exfield.c @@ -186,12 +186,11 @@ acpi_ex_read_data_from_field(struct acpi_walk_state * walk_state, access_length); /* - * Add additional 2 bytes for modeled generic_serial_bus data buffer: - * typedef struct { - * BYTEStatus; // Byte 0 of the data buffer - * BYTELength; // Byte 1 of the data buffer - * BYTE[x-1]Data; // Bytes 2-x of the arbitrary length data buffer, - * } + * Add additional 2 bytes for the generic_serial_bus data buffer: + * + * Status; (Byte 0 of the data buffer) + * Length; (Byte 1 of the data buffer) + * Data[x-1]; (Bytes 2-x of the arbitrary length data buffer) */ length += 2; function = ACPI_READ | (accessor_type << 16); @@ -368,12 +367,11 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, access_length); /* - * Add additional 2 bytes for modeled generic_serial_bus data buffer: - * typedef struct { - * BYTEStatus; // Byte 0 of the data buffer - * BYTELength; // Byte 1 of the data buffer - * BYTE[x-1]Data; // Bytes 2-x of the arbitrary length data buffer, - * } + * Add additional 2 bytes for the generic_serial_bus data buffer: + * + * Status; (Byte 0 of the data buffer) + * Length; (Byte 1 of the data buffer) + * Data[x-1]; (Bytes 2-x of the arbitrary length data buffer) */ length += 2; function = ACPI_WRITE | (accessor_type << 16); -- cgit v1.2.3 From b95dd1753123071fcfe34457ed4f9429c75d5ec9 Mon Sep 17 00:00:00 2001 From: Sascha Wildner Date: Wed, 30 Jul 2014 12:20:53 +0800 Subject: ACPICA: Remove some extraneous printf arguments. Arguments that have no associated % format specifier. Apparently these are not caught by any current compilers. ACPICA BZ 1090. Sascha Wildner. Currently, this patch only affects applications under the toos/power/acpi folder. Link: https://bugs.acpica.org/show_bug.cgi?id=1090 Signed-off-by: Sascha Wildner Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/exdump.c | 6 +++--- drivers/acpi/acpica/utfileio.c | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index 925202acc3e4..0f23c3f2678e 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c @@ -494,7 +494,7 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, } } - acpi_os_printf("\n", next); + acpi_os_printf("\n"); break; case ACPI_EXD_HDLR_LIST: @@ -528,7 +528,7 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, } } - acpi_os_printf("\n", next); + acpi_os_printf("\n"); break; case ACPI_EXD_RGN_LIST: @@ -562,7 +562,7 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, } } - acpi_os_printf("\n", next); + acpi_os_printf("\n"); break; case ACPI_EXD_NODE: diff --git a/drivers/acpi/acpica/utfileio.c b/drivers/acpi/acpica/utfileio.c index bdf9914733cb..4e263a8cc6f0 100644 --- a/drivers/acpi/acpica/utfileio.c +++ b/drivers/acpi/acpica/utfileio.c @@ -201,8 +201,7 @@ acpi_ut_read_table(FILE * fp, status = fl_check_for_ascii(fp, NULL, FALSE); if (ACPI_SUCCESS(status)) { acpi_os_printf - ("File appears to be ASCII only, must be binary\n", - table_header.length, file_size); + ("File appears to be ASCII only, must be binary\n"); } #endif return (AE_BAD_HEADER); -- cgit v1.2.3 From 3589b8b8af6bdc3aafe520d76a73b77d965006b6 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Wed, 30 Jul 2014 12:21:07 +0800 Subject: ACPICA: Utilities: Fix local printf issue. The bug can be reproduced by using a format that do not have the width.prec specified after a format that have the width.prec specified. The second formatted output will be wrong. The root cause is acpi_ut_vsnprintf() doesn't reset the specifiers to the default values. This patch fixes this issue. BZ 1094. Reported by Yizhe Wang, fixed by Lv Zheng. Since acpi_ut_vprintf() is only enabled for specific OSPM now, this patch doesn't affect Linux kernel. Link: https://bugs.acpica.org/show_bug.cgi?id=1094 Reported-and-tested-by: Yizhe Wang Signed-off-by: Lv Zheng Signed-off-by: Bob Moore Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/utprint.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/utprint.c b/drivers/acpi/acpica/utprint.c index 080e22aaba15..0ce3f5a0dd67 100644 --- a/drivers/acpi/acpica/utprint.c +++ b/drivers/acpi/acpica/utprint.c @@ -401,6 +401,7 @@ acpi_ut_vsnprintf(char *string, /* Process width */ + width = -1; if (ACPI_IS_DIGIT(*format)) { format = acpi_ut_scan_number(format, &number); width = (s32) number; @@ -415,6 +416,7 @@ acpi_ut_vsnprintf(char *string, /* Process precision */ + precision = -1; if (*format == '.') { ++format; if (ACPI_IS_DIGIT(*format)) { @@ -431,6 +433,7 @@ acpi_ut_vsnprintf(char *string, /* Process qualifier */ + qualifier = -1; if (*format == 'h' || *format == 'l' || *format == 'L') { qualifier = *format; ++format; -- cgit v1.2.3 From 73bbca04867d2f75443cc7dadcf115258f06b25e Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 30 Jul 2014 12:21:13 +0800 Subject: ACPICA: acpihelp: Add UUID support, restructure some existing files. This adds a -u option to acpi_help to display all known ACPI UUIDs. Some existing files in the core code have been restructured. Three new files. [zetalog: changing drivers/acpi/acpica/Makefile accordingly] Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/Makefile | 8 +++- drivers/acpi/acpica/aclocal.h | 5 +++ drivers/acpi/acpica/acutils.h | 9 ++++ drivers/acpi/acpica/utdecode.c | 27 ----------- drivers/acpi/acpica/uthex.c | 100 +++++++++++++++++++++++++++++++++++++++++ drivers/acpi/acpica/utuuid.c | 96 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 217 insertions(+), 28 deletions(-) create mode 100644 drivers/acpi/acpica/uthex.c create mode 100644 drivers/acpi/acpica/utuuid.c (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index 6b9ec239d578..f2bb97812dd6 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile @@ -157,6 +157,7 @@ acpi-y += \ uterror.o \ uteval.o \ utglobal.o \ + uthex.o \ utids.o \ utinit.o \ utlock.o \ @@ -175,5 +176,10 @@ acpi-y += \ utxferror.o \ utxfmutex.o -acpi-$(ACPI_FUTURE_USAGE) += utfileio.o utprint.o uttrack.o utcache.o +acpi-$(ACPI_FUTURE_USAGE) += \ + utcache.o \ + utfileio.o \ + utprint.o \ + uttrack.o \ + utuuid.o diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 4c9fd7ceeb24..1f9aba5fb81f 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -1155,4 +1155,9 @@ struct ah_device_id { char *description; }; +struct ah_uuid { + char *description; + char *string; +}; + #endif /* __ACLOCAL_H__ */ diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index ed614f4b2182..486d342e74b6 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -194,6 +194,8 @@ char *acpi_ut_get_event_name(u32 event_id); char acpi_ut_hex_to_ascii_char(u64 integer, u32 position); +u8 acpi_ut_ascii_char_to_hex(int hex_char); + u8 acpi_ut_valid_object_type(acpi_object_type type); /* @@ -759,6 +761,8 @@ const struct ah_predefined_name *acpi_ah_match_predefined_name(char *nameseg); const struct ah_device_id *acpi_ah_match_hardware_id(char *hid); +const char *acpi_ah_match_uuid(u8 *data); + /* * utprint - printf/vprintf output functions */ @@ -778,4 +782,9 @@ int acpi_ut_file_vprintf(ACPI_FILE file, const char *format, va_list args); int acpi_ut_file_printf(ACPI_FILE file, const char *format, ...); #endif +/* + * utuuid -- UUID support functions + */ +void acpi_ut_convert_string_to_uuid(char *in_string, u8 *uuid_buffer); + #endif /* _ACUTILS_H */ diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c index 90ec37c473c6..98f541873810 100644 --- a/drivers/acpi/acpica/utdecode.c +++ b/drivers/acpi/acpica/utdecode.c @@ -86,33 +86,6 @@ const u8 acpi_gbl_ns_properties[ACPI_NUM_NS_TYPES] = { ACPI_NS_NORMAL /* 30 Invalid */ }; -/******************************************************************************* - * - * FUNCTION: acpi_ut_hex_to_ascii_char - * - * PARAMETERS: integer - Contains the hex digit - * position - bit position of the digit within the - * integer (multiple of 4) - * - * RETURN: The converted Ascii character - * - * DESCRIPTION: Convert a hex digit to an Ascii character - * - ******************************************************************************/ - -/* Hex to ASCII conversion table */ - -static const char acpi_gbl_hex_to_ascii[] = { - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' -}; - -char acpi_ut_hex_to_ascii_char(u64 integer, u32 position) -{ - - return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]); -} - /******************************************************************************* * * FUNCTION: acpi_ut_get_region_name diff --git a/drivers/acpi/acpica/uthex.c b/drivers/acpi/acpica/uthex.c new file mode 100644 index 000000000000..9afa9441b183 --- /dev/null +++ b/drivers/acpi/acpica/uthex.c @@ -0,0 +1,100 @@ +/****************************************************************************** + * + * Module Name: uthex -- Hex/ASCII support functions + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2014, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include "accommon.h" + +#define _COMPONENT ACPI_COMPILER +ACPI_MODULE_NAME("uthex") + +/* Hex to ASCII conversion table */ +static char acpi_gbl_hex_to_ascii[] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', + 'E', 'F' +}; + +/******************************************************************************* + * + * FUNCTION: acpi_ut_hex_to_ascii_char + * + * PARAMETERS: integer - Contains the hex digit + * position - bit position of the digit within the + * integer (multiple of 4) + * + * RETURN: The converted Ascii character + * + * DESCRIPTION: Convert a hex digit to an Ascii character + * + ******************************************************************************/ + +char acpi_ut_hex_to_ascii_char(u64 integer, u32 position) +{ + + return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_hex_char_to_value + * + * PARAMETERS: ascii_char - Hex character in Ascii + * + * RETURN: The binary value of the ascii/hex character + * + * DESCRIPTION: Perform ascii-to-hex translation + * + ******************************************************************************/ + +u8 acpi_ut_ascii_char_to_hex(int hex_char) +{ + + if (hex_char <= 0x39) { + return ((u8)(hex_char - 0x30)); + } + + if (hex_char <= 0x46) { + return ((u8)(hex_char - 0x37)); + } + + return ((u8)(hex_char - 0x57)); +} diff --git a/drivers/acpi/acpica/utuuid.c b/drivers/acpi/acpica/utuuid.c new file mode 100644 index 000000000000..4dc33130f134 --- /dev/null +++ b/drivers/acpi/acpica/utuuid.c @@ -0,0 +1,96 @@ +/****************************************************************************** + * + * Module Name: utuuid -- UUID support functions + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2014, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include "accommon.h" + +#define _COMPONENT ACPI_COMPILER +ACPI_MODULE_NAME("utuuid") + +/* + * UUID support functions. + * + * This table is used to convert an input UUID ascii string to a 16 byte + * buffer and the reverse. The table maps a UUID buffer index 0-15 to + * the index within the 36-byte UUID string where the associated 2-byte + * hex value can be found. + * + * 36-byte UUID strings are of the form: + * aabbccdd-eeff-gghh-iijj-kkllmmnnoopp + * Where aa-pp are one byte hex numbers, made up of two hex digits + * + * Note: This table is basically the inverse of the string-to-offset table + * found in the ACPI spec in the description of the to_UUID macro. + */ +const u8 acpi_gbl_map_to_uuid_offset[UUID_BUFFER_LENGTH] = { + 6, 4, 2, 0, 11, 9, 16, 14, 19, 21, 24, 26, 28, 30, 32, 34 +}; + +/******************************************************************************* + * + * FUNCTION: acpi_ut_convert_string_to_uuid + * + * PARAMETERS: in_string - 36-byte formatted UUID string + * uuid_buffer - Where the 16-byte UUID buffer is returned + * + * RETURN: None. Output data is returned in the uuid_buffer + * + * DESCRIPTION: Convert a 36-byte formatted UUID string to 16-byte UUID buffer + * + ******************************************************************************/ + +void acpi_ut_convert_string_to_uuid(char *in_string, u8 *uuid_buffer) +{ + u32 i; + + for (i = 0; i < UUID_BUFFER_LENGTH; i++) { + uuid_buffer[i] = + (acpi_ut_ascii_char_to_hex + (in_string[acpi_gbl_map_to_uuid_offset[i]]) << 4); + + uuid_buffer[i] |= + acpi_ut_ascii_char_to_hex(in_string + [acpi_gbl_map_to_uuid_offset[i] + + 1]); + } +} -- cgit v1.2.3 From 1aae3b97cee2f4904771d61040c19693e7b1a530 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 30 Jul 2014 12:21:19 +0800 Subject: ACPICA: Debug object: Add current value of Timer() to debug line prefix. Simplifies timing of things like control method execution. [zetalog: fixing 64-bit division link error] Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/exdebug.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/exdebug.c b/drivers/acpi/acpica/exdebug.c index 4cfc3d3b5c97..6fbfad47518c 100644 --- a/drivers/acpi/acpica/exdebug.c +++ b/drivers/acpi/acpica/exdebug.c @@ -75,6 +75,7 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, u32 level, u32 index) { u32 i; + u32 timer; ACPI_FUNCTION_TRACE_PTR(ex_do_debug_object, source_desc); @@ -85,12 +86,20 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, return_VOID; } + /* + * We will emit the current timer value (in microseconds) with each + * debug output. Only need the lower 26 bits. This allows for 67 + * million microseconds or 67 seconds before rollover. + */ + timer = ((u32)acpi_os_get_timer() / 10); /* (100 nanoseconds to microseconds) */ + timer &= 0x03FFFFFF; + /* * Print line header as long as we are not in the middle of an * object display */ if (!((level > 0) && index == 0)) { - acpi_os_printf("[ACPI Debug] %*s", level, " "); + acpi_os_printf("[ACPI Debug %.8u] %*s", timer, level, " "); } /* Display the index for package output only */ -- cgit v1.2.3 From a9f65e01aa52692756ac5e6357502921a55f8a0e Mon Sep 17 00:00:00 2001 From: "David E. Box" Date: Wed, 30 Jul 2014 12:21:26 +0800 Subject: ACPICA: ACPI 5.1: Support for the _DSD predefined name. Adds full support for _DSD. David Box. Signed-off-by: David E. Box Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acpredef.h | 13 ++++++++++++- include/acpi/acnames.h | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h index bd08817cafd8..c5bfadf5294a 100644 --- a/drivers/acpi/acpica/acpredef.h +++ b/drivers/acpi/acpica/acpredef.h @@ -105,6 +105,11 @@ * count = 0 (optional) * (Used for _DLM) * + * ACPI_PTYPE2_UUID_PAIR: Each subpackage is preceded by a UUID Buffer. The UUID + * defines the format of the package. Zero-length parent package is + * allowed. + * (Used for _DSD) + * *****************************************************************************/ enum acpi_return_package_types { @@ -117,7 +122,8 @@ enum acpi_return_package_types { ACPI_PTYPE2_FIXED = 7, ACPI_PTYPE2_MIN = 8, ACPI_PTYPE2_REV_FIXED = 9, - ACPI_PTYPE2_FIX_VAR = 10 + ACPI_PTYPE2_FIX_VAR = 10, + ACPI_PTYPE2_UUID_PAIR = 11 }; /* Support macros for users of the predefined info table */ @@ -436,6 +442,11 @@ const union acpi_predefined_info acpi_gbl_predefined_methods[] = { {{"_DOS", METHOD_1ARGS(ACPI_TYPE_INTEGER), METHOD_NO_RETURN_VALUE}}, + {{"_DSD", METHOD_0ARGS, + METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Pkgs) each: 1 Buf, 1 Pkg */ + PACKAGE_INFO(ACPI_PTYPE2_UUID_PAIR, ACPI_RTYPE_BUFFER, 1, + ACPI_RTYPE_PACKAGE, 1, 0), + {{"_DSM", METHOD_4ARGS(ACPI_TYPE_BUFFER, ACPI_TYPE_INTEGER, ACPI_TYPE_INTEGER, ACPI_TYPE_PACKAGE), diff --git a/include/acpi/acnames.h b/include/acpi/acnames.h index 3dd6e838dc30..c728113374f5 100644 --- a/include/acpi/acnames.h +++ b/include/acpi/acnames.h @@ -55,6 +55,7 @@ #define METHOD_NAME__HID "_HID" #define METHOD_NAME__INI "_INI" #define METHOD_NAME__PLD "_PLD" +#define METHOD_NAME__DSD "_DSD" #define METHOD_NAME__PRS "_PRS" #define METHOD_NAME__PRT "_PRT" #define METHOD_NAME__PRW "_PRW" -- cgit v1.2.3 From b3cc1356a6bd5c1b1269f2201e7ae65a458b662d Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 30 Jul 2014 12:21:31 +0800 Subject: ACPICA: ACPI 5.1: New notify value for System Affinity Update. New value for the Notify() operator. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/utdecode.c | 5 +++-- include/acpi/actypes.h | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c index 98f541873810..40e923e675fc 100644 --- a/drivers/acpi/acpica/utdecode.c +++ b/drivers/acpi/acpica/utdecode.c @@ -448,7 +448,8 @@ static const char *acpi_gbl_generic_notify[ACPI_NOTIFY_MAX + 1] = { /* 09 */ "Device PLD Check", /* 0A */ "Reserved", /* 0B */ "System Locality Update", - /* 0C */ "Shutdown Request" + /* 0C */ "Shutdown Request", + /* 0D */ "System Resource Affinity Update" }; static const char *acpi_gbl_device_notify[4] = { @@ -475,7 +476,7 @@ static const char *acpi_gbl_thermal_notify[4] = { const char *acpi_ut_get_notify_name(u32 notify_value, acpi_object_type type) { - /* 00 - 0C are common to all object types */ + /* 00 - 0D are common to all object types */ if (notify_value <= ACPI_NOTIFY_MAX) { return (acpi_gbl_generic_notify[notify_value]); diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 4d9b29c436b2..ac03ec81d342 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -612,8 +612,9 @@ typedef u64 acpi_integer; #define ACPI_NOTIFY_RESERVED (u8) 0x0A #define ACPI_NOTIFY_LOCALITY_UPDATE (u8) 0x0B #define ACPI_NOTIFY_SHUTDOWN_REQUEST (u8) 0x0C +#define ACPI_NOTIFY_AFFINITY_UPDATE (u8) 0x0D -#define ACPI_NOTIFY_MAX 0x0C +#define ACPI_NOTIFY_MAX 0x0D /* * Types associated with ACPI names and objects. The first group of -- cgit v1.2.3 From bdc9b755778dd3c75d6d777b094e6906b28999c3 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 30 Jul 2014 12:21:38 +0800 Subject: ACPICA: ACPI 5.1: Support for the _CCA predifined name. Full support for _CCA. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acpredef.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h index c5bfadf5294a..bd3908d26c4f 100644 --- a/drivers/acpi/acpica/acpredef.h +++ b/drivers/acpi/acpica/acpredef.h @@ -370,6 +370,9 @@ const union acpi_predefined_info acpi_gbl_predefined_methods[] = { {{"_CBA", METHOD_0ARGS, METHOD_RETURNS(ACPI_RTYPE_INTEGER)}}, /* See PCI firmware spec 3.0 */ + {{"_CCA", METHOD_0ARGS, + METHOD_RETURNS(ACPI_RTYPE_INTEGER)}}, /* ACPI 5.1 */ + {{"_CDM", METHOD_0ARGS, METHOD_RETURNS(ACPI_RTYPE_INTEGER)}}, -- cgit v1.2.3 From a5f95da9fb2a0b228b3bab19d35850af3e9a74b2 Mon Sep 17 00:00:00 2001 From: Arjun Sreedharan Date: Thu, 31 Jul 2014 14:34:49 +0530 Subject: ACPI / PNP: Replace faulty is_hex_digit() by isxdigit() 0 is ascii for NULL. Hex digit matching should be from '0'. Faulty version returns true for #,$,%,& etc. Signed-off-by: Arjun Sreedharan Acked-by: Randy Dunlap Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_pnp.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpi_pnp.c b/drivers/acpi/acpi_pnp.c index 4ddb0dca56f6..996fa1959eea 100644 --- a/drivers/acpi/acpi_pnp.c +++ b/drivers/acpi/acpi_pnp.c @@ -12,6 +12,7 @@ #include #include +#include static const struct acpi_device_id acpi_pnp_device_ids[] = { /* soc_button_array */ @@ -320,11 +321,6 @@ static const struct acpi_device_id acpi_pnp_device_ids[] = { {""}, }; -static bool is_hex_digit(char c) -{ - return (c >= 0 && c <= '9') || (c >= 'A' && c <= 'F'); -} - static bool matching_id(char *idstr, char *list_id) { int i; @@ -335,7 +331,7 @@ static bool matching_id(char *idstr, char *list_id) for (i = 3; i < 7; i++) { char c = toupper(idstr[i]); - if (!is_hex_digit(c) + if (!isxdigit(c) || (list_id[i] != 'X' && c != toupper(list_id[i]))) return false; } -- cgit v1.2.3 From 43218a1b3ba7c8e39d88b5c0a43841f0e3e17470 Mon Sep 17 00:00:00 2001 From: Jie Yang Date: Fri, 1 Aug 2014 09:06:35 +0800 Subject: ACPI / LPSS: add LPSS device for Wildcat Point PCH INT3438 is the ADSP device on Wildcat Point platform with 2 DW DMA engines built In. The DMA engines are used for DSP FW loading and audio data transferring. These DMA engine probing need the clock, without it, probing may failed and can't go forward. Add LPSS device "INT3438" for Wildcat Point PCH, to provide clock for its ADSP DMA engine probing. Signed-off-by: Jie Yang Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_lpss.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index 9cb65b0e7597..ce06149088c5 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -113,6 +113,14 @@ static void lpss_i2c_setup(struct lpss_private_data *pdata) writel(val, pdata->mmio_base + offset); } +static struct lpss_device_desc wpt_dev_desc = { + .clk_required = true, + .prv_offset = 0x800, + .ltr_required = true, + .clk_divider = true, + .clk_gate = true, +}; + static struct lpss_device_desc lpt_dev_desc = { .clk_required = true, .prv_offset = 0x800, @@ -226,6 +234,8 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = { { "INT3436", LPSS_ADDR(lpt_sdio_dev_desc) }, { "INT3437", }, + { "INT3438", LPSS_ADDR(wpt_dev_desc) }, + { } }; -- cgit v1.2.3