diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-13 23:08:22 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-13 23:08:22 -0500 |
commit | 04ed510988f278a69872b4cdb426e565e3236215 (patch) | |
tree | 25bae36a6562c0fa7743851404d3bdd867bb468a | |
parent | bd2cd7d5a8f83ddc761025f42a3ca8e56351a6cc (diff) | |
parent | eb5fcc3134b5375593de5325ddf4b1404b36b602 (diff) |
Merge tag 'acpi-4.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI updates from Rafael Wysocki:
"These update ACPICA to upstream revision 20170831, fix APEI to use the
fixmap instead of ioremap_page_range(), add an operation region driver
for TI PMIC TPS68470, add support for PCC subspace IDs to the ACPI
CPPC driver, fix a few assorted issues and clean up some code.
Specifics:
- Update the ACPICA code to upstream revision 20170831 including
* PDTT table header support (Bob Moore).
* Cleanup and extension of internal string-to-integer conversion
functions (Bob Moore).
* Support for 64-bit hardware accesses (Lv Zheng).
* ACPI PM Timer code adjustment to deal with 64-bit return values
of acpi_hw_read() (Bob Moore).
* Support for deferred table verification in acpiexec (Lv Zheng).
- Fix APEI to use the fixmap instead of ioremap_page_range() which
cannot work correctly the way the code in there attempted to use it
and drop some code that's not necessary any more after that change
(James Morse).
- Clean up the APEI support code and make it use 64-bit timestamps
(Arnd Bergmann, Dongjiu Geng, Jan Beulich).
- Add operation region driver for TI PMIC TPS68470 (Rajmohan Mani).
- Add support for PCC subspace IDs to the ACPI CPPC driver (George
Cherian).
- Fix an ACPI EC driver regression related to the handling of EC
events during the "noirq" phases of system suspend/resume (Lv
Zheng).
- Delay the initialization of the lid state in the ACPI button driver
to fix issues appearing on some systems (Hans de Goede).
- Extend the KIOX000A "device always present" quirk to cover all
affected BIOS versions (Hans de Goede).
- Clean up some code in the ACPI core and drivers (Colin Ian King,
Gustavo Silva)"
* tag 'acpi-4.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (24 commits)
ACPI: Mark expected switch fall-throughs
ACPI / LPSS: Remove redundant initialization of clk
ACPI / CPPC: Make CPPC ACPI driver aware of PCC subspace IDs
mailbox: PCC: Move the MAX_PCC_SUBSPACES definition to header file
ACPI / sysfs: Make function param_set_trace_method_name() static
ACPI / button: Delay acpi_lid_initialize_state() until first user space open
ACPI / EC: Fix regression related to triggering source of EC event handling
APEI / ERST: use 64-bit timestamps
ACPI / APEI: Remove arch_apei_flush_tlb_one()
arm64: mm: Remove arch_apei_flush_tlb_one()
ACPI / APEI: Remove ghes_ioremap_area
ACPI / APEI: Replace ioremap_page_range() with fixmap
ACPI / APEI: remove the unused dead-code for SEA/NMI notification type
ACPI / x86: Extend KIOX000A quirk to cover all affected BIOS versions
ACPI / APEI: adjust a local variable type in ghes_ioremap_pfn_irq()
ACPICA: Update version to 20170831
ACPICA: Update acpi_get_timer for 64-bit interface to acpi_hw_read
ACPICA: String conversions: Update to add new behaviors
ACPICA: String conversions: Cleanup/format comments. No functional changes
ACPICA: Restructure/cleanup all string-to-integer conversion functions
...
48 files changed, 1551 insertions, 629 deletions
diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h index 59cca1d6ec54..32f465a80e4e 100644 --- a/arch/arm64/include/asm/acpi.h +++ b/arch/arm64/include/asm/acpi.h | |||
@@ -126,18 +126,6 @@ static inline const char *acpi_get_enable_method(int cpu) | |||
126 | */ | 126 | */ |
127 | #define acpi_disable_cmcff 1 | 127 | #define acpi_disable_cmcff 1 |
128 | pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr); | 128 | pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr); |
129 | |||
130 | /* | ||
131 | * Despite its name, this function must still broadcast the TLB | ||
132 | * invalidation in order to ensure other CPUs don't end up with junk | ||
133 | * entries as a result of speculation. Unusually, its also called in | ||
134 | * IRQ context (ghes_iounmap_irq) so if we ever need to use IPIs for | ||
135 | * TLB broadcasting, then we're in trouble here. | ||
136 | */ | ||
137 | static inline void arch_apei_flush_tlb_one(unsigned long addr) | ||
138 | { | ||
139 | flush_tlb_kernel_range(addr, addr + PAGE_SIZE); | ||
140 | } | ||
141 | #endif /* CONFIG_ACPI_APEI */ | 129 | #endif /* CONFIG_ACPI_APEI */ |
142 | 130 | ||
143 | #ifdef CONFIG_ACPI_NUMA | 131 | #ifdef CONFIG_ACPI_NUMA |
diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h index caf86be815ba..4052ec39e8db 100644 --- a/arch/arm64/include/asm/fixmap.h +++ b/arch/arm64/include/asm/fixmap.h | |||
@@ -51,6 +51,13 @@ enum fixed_addresses { | |||
51 | 51 | ||
52 | FIX_EARLYCON_MEM_BASE, | 52 | FIX_EARLYCON_MEM_BASE, |
53 | FIX_TEXT_POKE0, | 53 | FIX_TEXT_POKE0, |
54 | |||
55 | #ifdef CONFIG_ACPI_APEI_GHES | ||
56 | /* Used for GHES mapping from assorted contexts */ | ||
57 | FIX_APEI_GHES_IRQ, | ||
58 | FIX_APEI_GHES_NMI, | ||
59 | #endif /* CONFIG_ACPI_APEI_GHES */ | ||
60 | |||
54 | __end_of_permanent_fixed_addresses, | 61 | __end_of_permanent_fixed_addresses, |
55 | 62 | ||
56 | /* | 63 | /* |
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index f1eb15e0e864..267d2b79d52d 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c | |||
@@ -778,6 +778,10 @@ void __init early_fixmap_init(void) | |||
778 | } | 778 | } |
779 | } | 779 | } |
780 | 780 | ||
781 | /* | ||
782 | * Unusually, this is also called in IRQ context (ghes_iounmap_irq) so if we | ||
783 | * ever need to use IPIs for TLB broadcasting, then we're in trouble here. | ||
784 | */ | ||
781 | void __set_fixmap(enum fixed_addresses idx, | 785 | void __set_fixmap(enum fixed_addresses idx, |
782 | phys_addr_t phys, pgprot_t flags) | 786 | phys_addr_t phys, pgprot_t flags) |
783 | { | 787 | { |
diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h index dcd9fb55e679..b0c505fe9a95 100644 --- a/arch/x86/include/asm/fixmap.h +++ b/arch/x86/include/asm/fixmap.h | |||
@@ -104,6 +104,12 @@ enum fixed_addresses { | |||
104 | FIX_GDT_REMAP_BEGIN, | 104 | FIX_GDT_REMAP_BEGIN, |
105 | FIX_GDT_REMAP_END = FIX_GDT_REMAP_BEGIN + NR_CPUS - 1, | 105 | FIX_GDT_REMAP_END = FIX_GDT_REMAP_BEGIN + NR_CPUS - 1, |
106 | 106 | ||
107 | #ifdef CONFIG_ACPI_APEI_GHES | ||
108 | /* Used for GHES mapping from assorted contexts */ | ||
109 | FIX_APEI_GHES_IRQ, | ||
110 | FIX_APEI_GHES_NMI, | ||
111 | #endif | ||
112 | |||
107 | __end_of_permanent_fixed_addresses, | 113 | __end_of_permanent_fixed_addresses, |
108 | 114 | ||
109 | /* | 115 | /* |
diff --git a/arch/x86/kernel/acpi/apei.c b/arch/x86/kernel/acpi/apei.c index ea3046e0b0cf..bb8d300fecbd 100644 --- a/arch/x86/kernel/acpi/apei.c +++ b/arch/x86/kernel/acpi/apei.c | |||
@@ -52,8 +52,3 @@ void arch_apei_report_mem_error(int sev, struct cper_sec_mem_err *mem_err) | |||
52 | apei_mce_report_mem_error(sev, mem_err); | 52 | apei_mce_report_mem_error(sev, mem_err); |
53 | #endif | 53 | #endif |
54 | } | 54 | } |
55 | |||
56 | void arch_apei_flush_tlb_one(unsigned long addr) | ||
57 | { | ||
58 | __flush_tlb_one(addr); | ||
59 | } | ||
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 4cb763a01f4d..91477d5ab422 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -541,4 +541,20 @@ if ARM64 | |||
541 | source "drivers/acpi/arm64/Kconfig" | 541 | source "drivers/acpi/arm64/Kconfig" |
542 | endif | 542 | endif |
543 | 543 | ||
544 | config TPS68470_PMIC_OPREGION | ||
545 | bool "ACPI operation region support for TPS68470 PMIC" | ||
546 | depends on MFD_TPS68470 | ||
547 | help | ||
548 | This config adds ACPI operation region support for TI TPS68470 PMIC. | ||
549 | TPS68470 device is an advanced power management unit that powers | ||
550 | a Compact Camera Module (CCM), generates clocks for image sensors, | ||
551 | drives a dual LED for flash and incorporates two LED drivers for | ||
552 | general purpose indicators. | ||
553 | This driver enables ACPI operation region support control voltage | ||
554 | regulators and clocks. | ||
555 | |||
556 | This option is a bool as it provides an ACPI operation | ||
557 | region, which must be available before any of the devices | ||
558 | using this, are probed. | ||
559 | |||
544 | endif # ACPI | 560 | endif # ACPI |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 168e14d29d31..31c15d84a8d0 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -109,6 +109,8 @@ obj-$(CONFIG_CHT_WC_PMIC_OPREGION) += pmic/intel_pmic_chtwc.o | |||
109 | 109 | ||
110 | obj-$(CONFIG_ACPI_CONFIGFS) += acpi_configfs.o | 110 | obj-$(CONFIG_ACPI_CONFIGFS) += acpi_configfs.o |
111 | 111 | ||
112 | obj-$(CONFIG_TPS68470_PMIC_OPREGION) += pmic/tps68470_pmic.o | ||
113 | |||
112 | video-objs += acpi_video.o video_detect.o | 114 | video-objs += acpi_video.o video_detect.o |
113 | obj-y += dptf/ | 115 | obj-y += dptf/ |
114 | 116 | ||
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 8f52483219ba..47a7ed557bd6 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
@@ -265,6 +265,7 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event) | |||
265 | default: | 265 | default: |
266 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 266 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
267 | "Unsupported event [0x%x]\n", event)); | 267 | "Unsupported event [0x%x]\n", event)); |
268 | /* fall through */ | ||
268 | case ACPI_AC_NOTIFY_STATUS: | 269 | case ACPI_AC_NOTIFY_STATUS: |
269 | case ACPI_NOTIFY_BUS_CHECK: | 270 | case ACPI_NOTIFY_BUS_CHECK: |
270 | case ACPI_NOTIFY_DEVICE_CHECK: | 271 | case ACPI_NOTIFY_DEVICE_CHECK: |
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index de7385b824e1..7f2b02cc8ea1 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c | |||
@@ -362,7 +362,7 @@ static int register_device_clock(struct acpi_device *adev, | |||
362 | { | 362 | { |
363 | const struct lpss_device_desc *dev_desc = pdata->dev_desc; | 363 | const struct lpss_device_desc *dev_desc = pdata->dev_desc; |
364 | const char *devname = dev_name(&adev->dev); | 364 | const char *devname = dev_name(&adev->dev); |
365 | struct clk *clk = ERR_PTR(-ENODEV); | 365 | struct clk *clk; |
366 | struct lpss_clk_data *clk_data; | 366 | struct lpss_clk_data *clk_data; |
367 | const char *parent, *clk_name; | 367 | const char *parent, *clk_name; |
368 | void __iomem *prv_base; | 368 | void __iomem *prv_base; |
diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index 86c10599d9f8..449d86d39965 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c | |||
@@ -82,6 +82,7 @@ static int acpi_processor_errata_piix4(struct pci_dev *dev) | |||
82 | * PIIX4 models. | 82 | * PIIX4 models. |
83 | */ | 83 | */ |
84 | errata.piix4.throttle = 1; | 84 | errata.piix4.throttle = 1; |
85 | /* fall through*/ | ||
85 | 86 | ||
86 | case 2: /* PIIX4E */ | 87 | case 2: /* PIIX4E */ |
87 | case 3: /* PIIX4M */ | 88 | case 3: /* PIIX4M */ |
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index e05232da0588..71f6f2624deb 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile | |||
@@ -178,6 +178,7 @@ acpi-y += \ | |||
178 | utresrc.o \ | 178 | utresrc.o \ |
179 | utstate.o \ | 179 | utstate.o \ |
180 | utstring.o \ | 180 | utstring.o \ |
181 | utstrsuppt.o \ | ||
181 | utstrtoul64.o \ | 182 | utstrtoul64.o \ |
182 | utxface.o \ | 183 | utxface.o \ |
183 | utxfinit.o \ | 184 | utxfinit.o \ |
diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index fd4f3cacb356..cd722d8edacb 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h | |||
@@ -66,9 +66,9 @@ acpi_status | |||
66 | acpi_hw_validate_register(struct acpi_generic_address *reg, | 66 | acpi_hw_validate_register(struct acpi_generic_address *reg, |
67 | u8 max_bit_width, u64 *address); | 67 | u8 max_bit_width, u64 *address); |
68 | 68 | ||
69 | acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg); | 69 | acpi_status acpi_hw_read(u64 *value, struct acpi_generic_address *reg); |
70 | 70 | ||
71 | acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg); | 71 | acpi_status acpi_hw_write(u64 value, struct acpi_generic_address *reg); |
72 | 72 | ||
73 | struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id); | 73 | struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id); |
74 | 74 | ||
diff --git a/drivers/acpi/acpica/acinterp.h b/drivers/acpi/acpica/acinterp.h index 29a863c85318..29555c8789a3 100644 --- a/drivers/acpi/acpica/acinterp.h +++ b/drivers/acpi/acpica/acinterp.h | |||
@@ -101,7 +101,8 @@ typedef const struct acpi_exdump_info { | |||
101 | */ | 101 | */ |
102 | acpi_status | 102 | acpi_status |
103 | acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc, | 103 | acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc, |
104 | union acpi_operand_object **result_desc, u32 flags); | 104 | union acpi_operand_object **result_desc, |
105 | u32 implicit_conversion); | ||
105 | 106 | ||
106 | acpi_status | 107 | acpi_status |
107 | acpi_ex_convert_to_buffer(union acpi_operand_object *obj_desc, | 108 | acpi_ex_convert_to_buffer(union acpi_operand_object *obj_desc, |
@@ -424,9 +425,6 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc, | |||
424 | struct acpi_walk_state *walk_state, | 425 | struct acpi_walk_state *walk_state, |
425 | u8 implicit_conversion); | 426 | u8 implicit_conversion); |
426 | 427 | ||
427 | #define ACPI_IMPLICIT_CONVERSION TRUE | ||
428 | #define ACPI_NO_IMPLICIT_CONVERSION FALSE | ||
429 | |||
430 | /* | 428 | /* |
431 | * exstoren - resolve/store object | 429 | * exstoren - resolve/store object |
432 | */ | 430 | */ |
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 745134ade35f..83b75e9db7ef 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h | |||
@@ -141,6 +141,11 @@ extern const char *acpi_gbl_ptyp_decode[]; | |||
141 | #define ACPI_MSG_SUFFIX \ | 141 | #define ACPI_MSG_SUFFIX \ |
142 | acpi_os_printf (" (%8.8X/%s-%u)\n", ACPI_CA_VERSION, module_name, line_number) | 142 | acpi_os_printf (" (%8.8X/%s-%u)\n", ACPI_CA_VERSION, module_name, line_number) |
143 | 143 | ||
144 | /* Flags to indicate implicit or explicit string-to-integer conversion */ | ||
145 | |||
146 | #define ACPI_IMPLICIT_CONVERSION TRUE | ||
147 | #define ACPI_NO_IMPLICIT_CONVERSION FALSE | ||
148 | |||
144 | /* Types for Resource descriptor entries */ | 149 | /* Types for Resource descriptor entries */ |
145 | 150 | ||
146 | #define ACPI_INVALID_RESOURCE 0 | 151 | #define ACPI_INVALID_RESOURCE 0 |
@@ -197,15 +202,31 @@ void acpi_ut_strlwr(char *src_string); | |||
197 | 202 | ||
198 | int acpi_ut_stricmp(char *string1, char *string2); | 203 | int acpi_ut_stricmp(char *string1, char *string2); |
199 | 204 | ||
200 | acpi_status acpi_ut_strtoul64(char *string, u32 flags, u64 *ret_integer); | 205 | /* |
206 | * utstrsuppt - string-to-integer conversion support functions | ||
207 | */ | ||
208 | acpi_status acpi_ut_convert_octal_string(char *string, u64 *return_value); | ||
209 | |||
210 | acpi_status acpi_ut_convert_decimal_string(char *string, u64 *return_value_ptr); | ||
211 | |||
212 | acpi_status acpi_ut_convert_hex_string(char *string, u64 *return_value_ptr); | ||
213 | |||
214 | char acpi_ut_remove_whitespace(char **string); | ||
215 | |||
216 | char acpi_ut_remove_leading_zeros(char **string); | ||
217 | |||
218 | u8 acpi_ut_detect_hex_prefix(char **string); | ||
219 | |||
220 | u8 acpi_ut_detect_octal_prefix(char **string); | ||
201 | 221 | ||
202 | /* | 222 | /* |
203 | * Values for Flags above | 223 | * utstrtoul64 - string-to-integer conversion functions |
204 | * Note: LIMIT values correspond to acpi_gbl_integer_byte_width values (4/8) | ||
205 | */ | 224 | */ |
206 | #define ACPI_STRTOUL_32BIT 0x04 /* 4 bytes */ | 225 | acpi_status acpi_ut_strtoul64(char *string, u64 *ret_integer); |
207 | #define ACPI_STRTOUL_64BIT 0x08 /* 8 bytes */ | 226 | |
208 | #define ACPI_STRTOUL_BASE16 0x10 /* Default: Base10/16 */ | 227 | u64 acpi_ut_explicit_strtoul64(char *string); |
228 | |||
229 | u64 acpi_ut_implicit_strtoul64(char *string); | ||
209 | 230 | ||
210 | /* | 231 | /* |
211 | * utglobal - Global data structures and procedures | 232 | * utglobal - Global data structures and procedures |
diff --git a/drivers/acpi/acpica/dbconvert.c b/drivers/acpi/acpica/dbconvert.c index 857dbc43a9b1..32d546f0db2f 100644 --- a/drivers/acpi/acpica/dbconvert.c +++ b/drivers/acpi/acpica/dbconvert.c | |||
@@ -277,10 +277,7 @@ acpi_db_convert_to_object(acpi_object_type type, | |||
277 | default: | 277 | default: |
278 | 278 | ||
279 | object->type = ACPI_TYPE_INTEGER; | 279 | object->type = ACPI_TYPE_INTEGER; |
280 | status = acpi_ut_strtoul64(string, | 280 | status = acpi_ut_strtoul64(string, &object->integer.value); |
281 | (acpi_gbl_integer_byte_width | | ||
282 | ACPI_STRTOUL_BASE16), | ||
283 | &object->integer.value); | ||
284 | break; | 281 | break; |
285 | } | 282 | } |
286 | 283 | ||
diff --git a/drivers/acpi/acpica/dswexec.c b/drivers/acpi/acpica/dswexec.c index 20d7744b06ae..22f45d090733 100644 --- a/drivers/acpi/acpica/dswexec.c +++ b/drivers/acpi/acpica/dswexec.c | |||
@@ -134,7 +134,7 @@ acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state, | |||
134 | * object. Implicitly convert the argument if necessary. | 134 | * object. Implicitly convert the argument if necessary. |
135 | */ | 135 | */ |
136 | status = acpi_ex_convert_to_integer(obj_desc, &local_obj_desc, | 136 | status = acpi_ex_convert_to_integer(obj_desc, &local_obj_desc, |
137 | ACPI_STRTOUL_BASE16); | 137 | ACPI_IMPLICIT_CONVERSION); |
138 | if (ACPI_FAILURE(status)) { | 138 | if (ACPI_FAILURE(status)) { |
139 | goto cleanup; | 139 | goto cleanup; |
140 | } | 140 | } |
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 229382035550..263d8fc4a9e2 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c | |||
@@ -390,8 +390,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list) | |||
390 | struct acpi_gpe_handler_info *gpe_handler_info; | 390 | struct acpi_gpe_handler_info *gpe_handler_info; |
391 | u32 int_status = ACPI_INTERRUPT_NOT_HANDLED; | 391 | u32 int_status = ACPI_INTERRUPT_NOT_HANDLED; |
392 | u8 enabled_status_byte; | 392 | u8 enabled_status_byte; |
393 | u32 status_reg; | 393 | u64 status_reg; |
394 | u32 enable_reg; | 394 | u64 enable_reg; |
395 | acpi_cpu_flags flags; | 395 | acpi_cpu_flags flags; |
396 | u32 i; | 396 | u32 i; |
397 | u32 j; | 397 | u32 j; |
@@ -472,7 +472,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list) | |||
472 | gpe_register_info->base_gpe_number, | 472 | gpe_register_info->base_gpe_number, |
473 | gpe_register_info->base_gpe_number + | 473 | gpe_register_info->base_gpe_number + |
474 | (ACPI_GPE_REGISTER_WIDTH - 1), | 474 | (ACPI_GPE_REGISTER_WIDTH - 1), |
475 | status_reg, enable_reg, | 475 | (u32)status_reg, (u32)enable_reg, |
476 | gpe_register_info->enable_for_run, | 476 | gpe_register_info->enable_for_run, |
477 | gpe_register_info->enable_for_wake)); | 477 | gpe_register_info->enable_for_wake)); |
478 | 478 | ||
diff --git a/drivers/acpi/acpica/exconcat.c b/drivers/acpi/acpica/exconcat.c index 76bfb7dcae2f..59b8de2f07d3 100644 --- a/drivers/acpi/acpica/exconcat.c +++ b/drivers/acpi/acpica/exconcat.c | |||
@@ -156,7 +156,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, | |||
156 | 156 | ||
157 | status = | 157 | status = |
158 | acpi_ex_convert_to_integer(local_operand1, &temp_operand1, | 158 | acpi_ex_convert_to_integer(local_operand1, &temp_operand1, |
159 | ACPI_STRTOUL_BASE16); | 159 | ACPI_IMPLICIT_CONVERSION); |
160 | break; | 160 | break; |
161 | 161 | ||
162 | case ACPI_TYPE_BUFFER: | 162 | case ACPI_TYPE_BUFFER: |
diff --git a/drivers/acpi/acpica/exconvrt.c b/drivers/acpi/acpica/exconvrt.c index f71028e334ee..23ebadb06a95 100644 --- a/drivers/acpi/acpica/exconvrt.c +++ b/drivers/acpi/acpica/exconvrt.c | |||
@@ -57,10 +57,10 @@ acpi_ex_convert_to_ascii(u64 integer, u16 base, u8 *string, u8 max_length); | |||
57 | * | 57 | * |
58 | * FUNCTION: acpi_ex_convert_to_integer | 58 | * FUNCTION: acpi_ex_convert_to_integer |
59 | * | 59 | * |
60 | * PARAMETERS: obj_desc - Object to be converted. Must be an | 60 | * PARAMETERS: obj_desc - Object to be converted. Must be an |
61 | * Integer, Buffer, or String | 61 | * Integer, Buffer, or String |
62 | * result_desc - Where the new Integer object is returned | 62 | * result_desc - Where the new Integer object is returned |
63 | * flags - Used for string conversion | 63 | * implicit_conversion - Used for string conversion |
64 | * | 64 | * |
65 | * RETURN: Status | 65 | * RETURN: Status |
66 | * | 66 | * |
@@ -70,14 +70,14 @@ acpi_ex_convert_to_ascii(u64 integer, u16 base, u8 *string, u8 max_length); | |||
70 | 70 | ||
71 | acpi_status | 71 | acpi_status |
72 | acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc, | 72 | acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc, |
73 | union acpi_operand_object **result_desc, u32 flags) | 73 | union acpi_operand_object **result_desc, |
74 | u32 implicit_conversion) | ||
74 | { | 75 | { |
75 | union acpi_operand_object *return_desc; | 76 | union acpi_operand_object *return_desc; |
76 | u8 *pointer; | 77 | u8 *pointer; |
77 | u64 result; | 78 | u64 result; |
78 | u32 i; | 79 | u32 i; |
79 | u32 count; | 80 | u32 count; |
80 | acpi_status status; | ||
81 | 81 | ||
82 | ACPI_FUNCTION_TRACE_PTR(ex_convert_to_integer, obj_desc); | 82 | ACPI_FUNCTION_TRACE_PTR(ex_convert_to_integer, obj_desc); |
83 | 83 | ||
@@ -123,12 +123,18 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc, | |||
123 | * hexadecimal as per the ACPI specification. The only exception (as | 123 | * hexadecimal as per the ACPI specification. The only exception (as |
124 | * of ACPI 3.0) is that the to_integer() operator allows both decimal | 124 | * of ACPI 3.0) is that the to_integer() operator allows both decimal |
125 | * and hexadecimal strings (hex prefixed with "0x"). | 125 | * and hexadecimal strings (hex prefixed with "0x"). |
126 | * | ||
127 | * Explicit conversion is used only by to_integer. | ||
128 | * All other string-to-integer conversions are implicit conversions. | ||
126 | */ | 129 | */ |
127 | status = acpi_ut_strtoul64(ACPI_CAST_PTR(char, pointer), | 130 | if (implicit_conversion) { |
128 | (acpi_gbl_integer_byte_width | | 131 | result = |
129 | flags), &result); | 132 | acpi_ut_implicit_strtoul64(ACPI_CAST_PTR |
130 | if (ACPI_FAILURE(status)) { | 133 | (char, pointer)); |
131 | return_ACPI_STATUS(status); | 134 | } else { |
135 | result = | ||
136 | acpi_ut_explicit_strtoul64(ACPI_CAST_PTR | ||
137 | (char, pointer)); | ||
132 | } | 138 | } |
133 | break; | 139 | break; |
134 | 140 | ||
@@ -631,7 +637,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type, | |||
631 | */ | 637 | */ |
632 | status = | 638 | status = |
633 | acpi_ex_convert_to_integer(source_desc, result_desc, | 639 | acpi_ex_convert_to_integer(source_desc, result_desc, |
634 | ACPI_STRTOUL_BASE16); | 640 | ACPI_IMPLICIT_CONVERSION); |
635 | break; | 641 | break; |
636 | 642 | ||
637 | case ACPI_TYPE_STRING: | 643 | case ACPI_TYPE_STRING: |
diff --git a/drivers/acpi/acpica/exmisc.c b/drivers/acpi/acpica/exmisc.c index 1e7649ce0a7b..dbad3ebd7df5 100644 --- a/drivers/acpi/acpica/exmisc.c +++ b/drivers/acpi/acpica/exmisc.c | |||
@@ -330,7 +330,7 @@ acpi_ex_do_logical_op(u16 opcode, | |||
330 | case ACPI_TYPE_INTEGER: | 330 | case ACPI_TYPE_INTEGER: |
331 | 331 | ||
332 | status = acpi_ex_convert_to_integer(operand1, &local_operand1, | 332 | status = acpi_ex_convert_to_integer(operand1, &local_operand1, |
333 | ACPI_STRTOUL_BASE16); | 333 | ACPI_IMPLICIT_CONVERSION); |
334 | break; | 334 | break; |
335 | 335 | ||
336 | case ACPI_TYPE_STRING: | 336 | case ACPI_TYPE_STRING: |
diff --git a/drivers/acpi/acpica/exresop.c b/drivers/acpi/acpica/exresop.c index c4852429e2ff..1c7c9962b0de 100644 --- a/drivers/acpi/acpica/exresop.c +++ b/drivers/acpi/acpica/exresop.c | |||
@@ -415,7 +415,7 @@ acpi_ex_resolve_operands(u16 opcode, | |||
415 | * Known as "Implicit Source Operand Conversion" | 415 | * Known as "Implicit Source Operand Conversion" |
416 | */ | 416 | */ |
417 | status = acpi_ex_convert_to_integer(obj_desc, stack_ptr, | 417 | status = acpi_ex_convert_to_integer(obj_desc, stack_ptr, |
418 | ACPI_STRTOUL_BASE16); | 418 | ACPI_IMPLICIT_CONVERSION); |
419 | if (ACPI_FAILURE(status)) { | 419 | if (ACPI_FAILURE(status)) { |
420 | if (status == AE_TYPE) { | 420 | if (status == AE_TYPE) { |
421 | ACPI_ERROR((AE_INFO, | 421 | ACPI_ERROR((AE_INFO, |
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index 5eb11b30a79e..09b6822aa5cc 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c | |||
@@ -99,7 +99,7 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action) | |||
99 | { | 99 | { |
100 | struct acpi_gpe_register_info *gpe_register_info; | 100 | struct acpi_gpe_register_info *gpe_register_info; |
101 | acpi_status status = AE_OK; | 101 | acpi_status status = AE_OK; |
102 | u32 enable_mask; | 102 | u64 enable_mask; |
103 | u32 register_bit; | 103 | u32 register_bit; |
104 | 104 | ||
105 | ACPI_FUNCTION_ENTRY(); | 105 | ACPI_FUNCTION_ENTRY(); |
@@ -214,7 +214,7 @@ acpi_status | |||
214 | acpi_hw_get_gpe_status(struct acpi_gpe_event_info *gpe_event_info, | 214 | acpi_hw_get_gpe_status(struct acpi_gpe_event_info *gpe_event_info, |
215 | acpi_event_status *event_status) | 215 | acpi_event_status *event_status) |
216 | { | 216 | { |
217 | u32 in_byte; | 217 | u64 in_byte; |
218 | u32 register_bit; | 218 | u32 register_bit; |
219 | struct acpi_gpe_register_info *gpe_register_info; | 219 | struct acpi_gpe_register_info *gpe_register_info; |
220 | acpi_event_status local_event_status = 0; | 220 | acpi_event_status local_event_status = 0; |
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index acb417b58bbb..aa6e00081915 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c | |||
@@ -220,16 +220,15 @@ acpi_hw_validate_register(struct acpi_generic_address *reg, | |||
220 | * | 220 | * |
221 | * RETURN: Status | 221 | * RETURN: Status |
222 | * | 222 | * |
223 | * DESCRIPTION: Read from either memory or IO space. This is a 32-bit max | 223 | * DESCRIPTION: Read from either memory or IO space. This is a 64-bit max |
224 | * version of acpi_read, used internally since the overhead of | 224 | * version of acpi_read. |
225 | * 64-bit values is not needed. | ||
226 | * | 225 | * |
227 | * LIMITATIONS: <These limitations also apply to acpi_hw_write> | 226 | * LIMITATIONS: <These limitations also apply to acpi_hw_write> |
228 | * space_ID must be system_memory or system_IO. | 227 | * space_ID must be system_memory or system_IO. |
229 | * | 228 | * |
230 | ******************************************************************************/ | 229 | ******************************************************************************/ |
231 | 230 | ||
232 | acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) | 231 | acpi_status acpi_hw_read(u64 *value, struct acpi_generic_address *reg) |
233 | { | 232 | { |
234 | u64 address; | 233 | u64 address; |
235 | u8 access_width; | 234 | u8 access_width; |
@@ -244,17 +243,17 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) | |||
244 | 243 | ||
245 | /* Validate contents of the GAS register */ | 244 | /* Validate contents of the GAS register */ |
246 | 245 | ||
247 | status = acpi_hw_validate_register(reg, 32, &address); | 246 | status = acpi_hw_validate_register(reg, 64, &address); |
248 | if (ACPI_FAILURE(status)) { | 247 | if (ACPI_FAILURE(status)) { |
249 | return (status); | 248 | return (status); |
250 | } | 249 | } |
251 | 250 | ||
252 | /* | 251 | /* |
253 | * Initialize entire 32-bit return value to zero, convert access_width | 252 | * Initialize entire 64-bit return value to zero, convert access_width |
254 | * into number of bits based | 253 | * into number of bits based |
255 | */ | 254 | */ |
256 | *value = 0; | 255 | *value = 0; |
257 | access_width = acpi_hw_get_access_bit_width(address, reg, 32); | 256 | access_width = acpi_hw_get_access_bit_width(address, reg, 64); |
258 | bit_width = reg->bit_offset + reg->bit_width; | 257 | bit_width = reg->bit_offset + reg->bit_width; |
259 | bit_offset = reg->bit_offset; | 258 | bit_offset = reg->bit_offset; |
260 | 259 | ||
@@ -265,7 +264,7 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) | |||
265 | index = 0; | 264 | index = 0; |
266 | while (bit_width) { | 265 | while (bit_width) { |
267 | if (bit_offset >= access_width) { | 266 | if (bit_offset >= access_width) { |
268 | value32 = 0; | 267 | value64 = 0; |
269 | bit_offset -= access_width; | 268 | bit_offset -= access_width; |
270 | } else { | 269 | } else { |
271 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { | 270 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { |
@@ -276,7 +275,6 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) | |||
276 | ACPI_DIV_8 | 275 | ACPI_DIV_8 |
277 | (access_width), | 276 | (access_width), |
278 | &value64, access_width); | 277 | &value64, access_width); |
279 | value32 = (u32)value64; | ||
280 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ | 278 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ |
281 | 279 | ||
282 | status = acpi_hw_read_port((acpi_io_address) | 280 | status = acpi_hw_read_port((acpi_io_address) |
@@ -286,15 +284,16 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) | |||
286 | (access_width), | 284 | (access_width), |
287 | &value32, | 285 | &value32, |
288 | access_width); | 286 | access_width); |
287 | value64 = (u64)value32; | ||
289 | } | 288 | } |
290 | } | 289 | } |
291 | 290 | ||
292 | /* | 291 | /* |
293 | * Use offset style bit writes because "Index * AccessWidth" is | 292 | * Use offset style bit writes because "Index * AccessWidth" is |
294 | * ensured to be less than 32-bits by acpi_hw_validate_register(). | 293 | * ensured to be less than 64-bits by acpi_hw_validate_register(). |
295 | */ | 294 | */ |
296 | ACPI_SET_BITS(value, index * access_width, | 295 | ACPI_SET_BITS(value, index * access_width, |
297 | ACPI_MASK_BITS_ABOVE_32(access_width), value32); | 296 | ACPI_MASK_BITS_ABOVE_64(access_width), value64); |
298 | 297 | ||
299 | bit_width -= | 298 | bit_width -= |
300 | bit_width > access_width ? access_width : bit_width; | 299 | bit_width > access_width ? access_width : bit_width; |
@@ -302,8 +301,9 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) | |||
302 | } | 301 | } |
303 | 302 | ||
304 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | 303 | ACPI_DEBUG_PRINT((ACPI_DB_IO, |
305 | "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", | 304 | "Read: %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n", |
306 | *value, access_width, ACPI_FORMAT_UINT64(address), | 305 | ACPI_FORMAT_UINT64(*value), access_width, |
306 | ACPI_FORMAT_UINT64(address), | ||
307 | acpi_ut_get_region_name(reg->space_id))); | 307 | acpi_ut_get_region_name(reg->space_id))); |
308 | 308 | ||
309 | return (status); | 309 | return (status); |
@@ -318,20 +318,18 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) | |||
318 | * | 318 | * |
319 | * RETURN: Status | 319 | * RETURN: Status |
320 | * | 320 | * |
321 | * DESCRIPTION: Write to either memory or IO space. This is a 32-bit max | 321 | * DESCRIPTION: Write to either memory or IO space. This is a 64-bit max |
322 | * version of acpi_write, used internally since the overhead of | 322 | * version of acpi_write. |
323 | * 64-bit values is not needed. | ||
324 | * | 323 | * |
325 | ******************************************************************************/ | 324 | ******************************************************************************/ |
326 | 325 | ||
327 | acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) | 326 | acpi_status acpi_hw_write(u64 value, struct acpi_generic_address *reg) |
328 | { | 327 | { |
329 | u64 address; | 328 | u64 address; |
330 | u8 access_width; | 329 | u8 access_width; |
331 | u32 bit_width; | 330 | u32 bit_width; |
332 | u8 bit_offset; | 331 | u8 bit_offset; |
333 | u64 value64; | 332 | u64 value64; |
334 | u32 value32; | ||
335 | u8 index; | 333 | u8 index; |
336 | acpi_status status; | 334 | acpi_status status; |
337 | 335 | ||
@@ -339,14 +337,14 @@ acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) | |||
339 | 337 | ||
340 | /* Validate contents of the GAS register */ | 338 | /* Validate contents of the GAS register */ |
341 | 339 | ||
342 | status = acpi_hw_validate_register(reg, 32, &address); | 340 | status = acpi_hw_validate_register(reg, 64, &address); |
343 | if (ACPI_FAILURE(status)) { | 341 | if (ACPI_FAILURE(status)) { |
344 | return (status); | 342 | return (status); |
345 | } | 343 | } |
346 | 344 | ||
347 | /* Convert access_width into number of bits based */ | 345 | /* Convert access_width into number of bits based */ |
348 | 346 | ||
349 | access_width = acpi_hw_get_access_bit_width(address, reg, 32); | 347 | access_width = acpi_hw_get_access_bit_width(address, reg, 64); |
350 | bit_width = reg->bit_offset + reg->bit_width; | 348 | bit_width = reg->bit_offset + reg->bit_width; |
351 | bit_offset = reg->bit_offset; | 349 | bit_offset = reg->bit_offset; |
352 | 350 | ||
@@ -358,16 +356,15 @@ acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) | |||
358 | while (bit_width) { | 356 | while (bit_width) { |
359 | /* | 357 | /* |
360 | * Use offset style bit reads because "Index * AccessWidth" is | 358 | * Use offset style bit reads because "Index * AccessWidth" is |
361 | * ensured to be less than 32-bits by acpi_hw_validate_register(). | 359 | * ensured to be less than 64-bits by acpi_hw_validate_register(). |
362 | */ | 360 | */ |
363 | value32 = ACPI_GET_BITS(&value, index * access_width, | 361 | value64 = ACPI_GET_BITS(&value, index * access_width, |
364 | ACPI_MASK_BITS_ABOVE_32(access_width)); | 362 | ACPI_MASK_BITS_ABOVE_64(access_width)); |
365 | 363 | ||
366 | if (bit_offset >= access_width) { | 364 | if (bit_offset >= access_width) { |
367 | bit_offset -= access_width; | 365 | bit_offset -= access_width; |
368 | } else { | 366 | } else { |
369 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { | 367 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { |
370 | value64 = (u64)value32; | ||
371 | status = | 368 | status = |
372 | acpi_os_write_memory((acpi_physical_address) | 369 | acpi_os_write_memory((acpi_physical_address) |
373 | address + | 370 | address + |
@@ -382,7 +379,7 @@ acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) | |||
382 | index * | 379 | index * |
383 | ACPI_DIV_8 | 380 | ACPI_DIV_8 |
384 | (access_width), | 381 | (access_width), |
385 | value32, | 382 | (u32)value64, |
386 | access_width); | 383 | access_width); |
387 | } | 384 | } |
388 | } | 385 | } |
@@ -397,8 +394,9 @@ acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) | |||
397 | } | 394 | } |
398 | 395 | ||
399 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | 396 | ACPI_DEBUG_PRINT((ACPI_DB_IO, |
400 | "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", | 397 | "Wrote: %8.8X%8.8X width %2d to %8.8X%8.8X (%s)\n", |
401 | value, access_width, ACPI_FORMAT_UINT64(address), | 398 | ACPI_FORMAT_UINT64(value), access_width, |
399 | ACPI_FORMAT_UINT64(address), | ||
402 | acpi_ut_get_region_name(reg->space_id))); | 400 | acpi_ut_get_region_name(reg->space_id))); |
403 | 401 | ||
404 | return (status); | 402 | return (status); |
@@ -526,6 +524,7 @@ acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control) | |||
526 | acpi_status acpi_hw_register_read(u32 register_id, u32 *return_value) | 524 | acpi_status acpi_hw_register_read(u32 register_id, u32 *return_value) |
527 | { | 525 | { |
528 | u32 value = 0; | 526 | u32 value = 0; |
527 | u64 value64; | ||
529 | acpi_status status; | 528 | acpi_status status; |
530 | 529 | ||
531 | ACPI_FUNCTION_TRACE(hw_register_read); | 530 | ACPI_FUNCTION_TRACE(hw_register_read); |
@@ -564,12 +563,14 @@ acpi_status acpi_hw_register_read(u32 register_id, u32 *return_value) | |||
564 | case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ | 563 | case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ |
565 | 564 | ||
566 | status = | 565 | status = |
567 | acpi_hw_read(&value, &acpi_gbl_FADT.xpm2_control_block); | 566 | acpi_hw_read(&value64, &acpi_gbl_FADT.xpm2_control_block); |
567 | value = (u32)value64; | ||
568 | break; | 568 | break; |
569 | 569 | ||
570 | case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ | 570 | case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ |
571 | 571 | ||
572 | status = acpi_hw_read(&value, &acpi_gbl_FADT.xpm_timer_block); | 572 | status = acpi_hw_read(&value64, &acpi_gbl_FADT.xpm_timer_block); |
573 | value = (u32)value64; | ||
573 | break; | 574 | break; |
574 | 575 | ||
575 | case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ | 576 | case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ |
@@ -586,7 +587,7 @@ acpi_status acpi_hw_register_read(u32 register_id, u32 *return_value) | |||
586 | } | 587 | } |
587 | 588 | ||
588 | if (ACPI_SUCCESS(status)) { | 589 | if (ACPI_SUCCESS(status)) { |
589 | *return_value = value; | 590 | *return_value = (u32)value; |
590 | } | 591 | } |
591 | 592 | ||
592 | return_ACPI_STATUS(status); | 593 | return_ACPI_STATUS(status); |
@@ -622,6 +623,7 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value) | |||
622 | { | 623 | { |
623 | acpi_status status; | 624 | acpi_status status; |
624 | u32 read_value; | 625 | u32 read_value; |
626 | u64 read_value64; | ||
625 | 627 | ||
626 | ACPI_FUNCTION_TRACE(hw_register_write); | 628 | ACPI_FUNCTION_TRACE(hw_register_write); |
627 | 629 | ||
@@ -685,11 +687,12 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value) | |||
685 | * as per the ACPI spec. | 687 | * as per the ACPI spec. |
686 | */ | 688 | */ |
687 | status = | 689 | status = |
688 | acpi_hw_read(&read_value, | 690 | acpi_hw_read(&read_value64, |
689 | &acpi_gbl_FADT.xpm2_control_block); | 691 | &acpi_gbl_FADT.xpm2_control_block); |
690 | if (ACPI_FAILURE(status)) { | 692 | if (ACPI_FAILURE(status)) { |
691 | goto exit; | 693 | goto exit; |
692 | } | 694 | } |
695 | read_value = (u32)read_value64; | ||
693 | 696 | ||
694 | /* Insert the bits to be preserved */ | 697 | /* Insert the bits to be preserved */ |
695 | 698 | ||
@@ -745,22 +748,25 @@ acpi_hw_read_multiple(u32 *value, | |||
745 | { | 748 | { |
746 | u32 value_a = 0; | 749 | u32 value_a = 0; |
747 | u32 value_b = 0; | 750 | u32 value_b = 0; |
751 | u64 value64; | ||
748 | acpi_status status; | 752 | acpi_status status; |
749 | 753 | ||
750 | /* The first register is always required */ | 754 | /* The first register is always required */ |
751 | 755 | ||
752 | status = acpi_hw_read(&value_a, register_a); | 756 | status = acpi_hw_read(&value64, register_a); |
753 | if (ACPI_FAILURE(status)) { | 757 | if (ACPI_FAILURE(status)) { |
754 | return (status); | 758 | return (status); |
755 | } | 759 | } |
760 | value_a = (u32)value64; | ||
756 | 761 | ||
757 | /* Second register is optional */ | 762 | /* Second register is optional */ |
758 | 763 | ||
759 | if (register_b->address) { | 764 | if (register_b->address) { |
760 | status = acpi_hw_read(&value_b, register_b); | 765 | status = acpi_hw_read(&value64, register_b); |
761 | if (ACPI_FAILURE(status)) { | 766 | if (ACPI_FAILURE(status)) { |
762 | return (status); | 767 | return (status); |
763 | } | 768 | } |
769 | value_b = (u32)value64; | ||
764 | } | 770 | } |
765 | 771 | ||
766 | /* | 772 | /* |
diff --git a/drivers/acpi/acpica/hwtimer.c b/drivers/acpi/acpica/hwtimer.c index b3c5d8c754bb..a2f4e25d45b1 100644 --- a/drivers/acpi/acpica/hwtimer.c +++ b/drivers/acpi/acpica/hwtimer.c | |||
@@ -94,6 +94,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_timer_resolution) | |||
94 | acpi_status acpi_get_timer(u32 * ticks) | 94 | acpi_status acpi_get_timer(u32 * ticks) |
95 | { | 95 | { |
96 | acpi_status status; | 96 | acpi_status status; |
97 | u64 timer_value; | ||
97 | 98 | ||
98 | ACPI_FUNCTION_TRACE(acpi_get_timer); | 99 | ACPI_FUNCTION_TRACE(acpi_get_timer); |
99 | 100 | ||
@@ -107,7 +108,14 @@ acpi_status acpi_get_timer(u32 * ticks) | |||
107 | return_ACPI_STATUS(AE_SUPPORT); | 108 | return_ACPI_STATUS(AE_SUPPORT); |
108 | } | 109 | } |
109 | 110 | ||
110 | status = acpi_hw_read(ticks, &acpi_gbl_FADT.xpm_timer_block); | 111 | status = acpi_hw_read(&timer_value, &acpi_gbl_FADT.xpm_timer_block); |
112 | if (ACPI_SUCCESS(status)) { | ||
113 | |||
114 | /* ACPI PM Timer is defined to be 32 bits (PM_TMR_LEN) */ | ||
115 | |||
116 | *ticks = (u32)timer_value; | ||
117 | } | ||
118 | |||
111 | return_ACPI_STATUS(status); | 119 | return_ACPI_STATUS(status); |
112 | } | 120 | } |
113 | 121 | ||
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c index 34684ae89981..b3c6e439933c 100644 --- a/drivers/acpi/acpica/hwxface.c +++ b/drivers/acpi/acpica/hwxface.c | |||
@@ -125,76 +125,12 @@ ACPI_EXPORT_SYMBOL(acpi_reset) | |||
125 | ******************************************************************************/ | 125 | ******************************************************************************/ |
126 | acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) | 126 | acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) |
127 | { | 127 | { |
128 | u32 value_lo; | ||
129 | u32 value_hi; | ||
130 | u32 width; | ||
131 | u64 address; | ||
132 | acpi_status status; | 128 | acpi_status status; |
133 | 129 | ||
134 | ACPI_FUNCTION_NAME(acpi_read); | 130 | ACPI_FUNCTION_NAME(acpi_read); |
135 | 131 | ||
136 | if (!return_value) { | 132 | status = acpi_hw_read(return_value, reg); |
137 | return (AE_BAD_PARAMETER); | 133 | return (status); |
138 | } | ||
139 | |||
140 | /* Validate contents of the GAS register. Allow 64-bit transfers */ | ||
141 | |||
142 | status = acpi_hw_validate_register(reg, 64, &address); | ||
143 | if (ACPI_FAILURE(status)) { | ||
144 | return (status); | ||
145 | } | ||
146 | |||
147 | /* | ||
148 | * Two address spaces supported: Memory or I/O. PCI_Config is | ||
149 | * not supported here because the GAS structure is insufficient | ||
150 | */ | ||
151 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { | ||
152 | status = acpi_os_read_memory((acpi_physical_address) | ||
153 | address, return_value, | ||
154 | reg->bit_width); | ||
155 | if (ACPI_FAILURE(status)) { | ||
156 | return (status); | ||
157 | } | ||
158 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ | ||
159 | |||
160 | value_lo = 0; | ||
161 | value_hi = 0; | ||
162 | |||
163 | width = reg->bit_width; | ||
164 | if (width == 64) { | ||
165 | width = 32; /* Break into two 32-bit transfers */ | ||
166 | } | ||
167 | |||
168 | status = acpi_hw_read_port((acpi_io_address) | ||
169 | address, &value_lo, width); | ||
170 | if (ACPI_FAILURE(status)) { | ||
171 | return (status); | ||
172 | } | ||
173 | |||
174 | if (reg->bit_width == 64) { | ||
175 | |||
176 | /* Read the top 32 bits */ | ||
177 | |||
178 | status = acpi_hw_read_port((acpi_io_address) | ||
179 | (address + 4), &value_hi, | ||
180 | 32); | ||
181 | if (ACPI_FAILURE(status)) { | ||
182 | return (status); | ||
183 | } | ||
184 | } | ||
185 | |||
186 | /* Set the return value only if status is AE_OK */ | ||
187 | |||
188 | *return_value = (value_lo | ((u64)value_hi << 32)); | ||
189 | } | ||
190 | |||
191 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | ||
192 | "Read: %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n", | ||
193 | ACPI_FORMAT_UINT64(*return_value), reg->bit_width, | ||
194 | ACPI_FORMAT_UINT64(address), | ||
195 | acpi_ut_get_region_name(reg->space_id))); | ||
196 | |||
197 | return (AE_OK); | ||
198 | } | 134 | } |
199 | 135 | ||
200 | ACPI_EXPORT_SYMBOL(acpi_read) | 136 | ACPI_EXPORT_SYMBOL(acpi_read) |
@@ -213,59 +149,11 @@ ACPI_EXPORT_SYMBOL(acpi_read) | |||
213 | ******************************************************************************/ | 149 | ******************************************************************************/ |
214 | acpi_status acpi_write(u64 value, struct acpi_generic_address *reg) | 150 | acpi_status acpi_write(u64 value, struct acpi_generic_address *reg) |
215 | { | 151 | { |
216 | u32 width; | ||
217 | u64 address; | ||
218 | acpi_status status; | 152 | acpi_status status; |
219 | 153 | ||
220 | ACPI_FUNCTION_NAME(acpi_write); | 154 | ACPI_FUNCTION_NAME(acpi_write); |
221 | 155 | ||
222 | /* Validate contents of the GAS register. Allow 64-bit transfers */ | 156 | status = acpi_hw_write(value, reg); |
223 | |||
224 | status = acpi_hw_validate_register(reg, 64, &address); | ||
225 | if (ACPI_FAILURE(status)) { | ||
226 | return (status); | ||
227 | } | ||
228 | |||
229 | /* | ||
230 | * Two address spaces supported: Memory or IO. PCI_Config is | ||
231 | * not supported here because the GAS structure is insufficient | ||
232 | */ | ||
233 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { | ||
234 | status = acpi_os_write_memory((acpi_physical_address) | ||
235 | address, value, reg->bit_width); | ||
236 | if (ACPI_FAILURE(status)) { | ||
237 | return (status); | ||
238 | } | ||
239 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ | ||
240 | |||
241 | width = reg->bit_width; | ||
242 | if (width == 64) { | ||
243 | width = 32; /* Break into two 32-bit transfers */ | ||
244 | } | ||
245 | |||
246 | status = acpi_hw_write_port((acpi_io_address) | ||
247 | address, ACPI_LODWORD(value), | ||
248 | width); | ||
249 | if (ACPI_FAILURE(status)) { | ||
250 | return (status); | ||
251 | } | ||
252 | |||
253 | if (reg->bit_width == 64) { | ||
254 | status = acpi_hw_write_port((acpi_io_address) | ||
255 | (address + 4), | ||
256 | ACPI_HIDWORD(value), 32); | ||
257 | if (ACPI_FAILURE(status)) { | ||
258 | return (status); | ||
259 | } | ||
260 | } | ||
261 | } | ||
262 | |||
263 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | ||
264 | "Wrote: %8.8X%8.8X width %2d to %8.8X%8.8X (%s)\n", | ||
265 | ACPI_FORMAT_UINT64(value), reg->bit_width, | ||
266 | ACPI_FORMAT_UINT64(address), | ||
267 | acpi_ut_get_region_name(reg->space_id))); | ||
268 | |||
269 | return (status); | 157 | return (status); |
270 | } | 158 | } |
271 | 159 | ||
diff --git a/drivers/acpi/acpica/nsconvert.c b/drivers/acpi/acpica/nsconvert.c index e4a7da8a11f0..539d775bbc92 100644 --- a/drivers/acpi/acpica/nsconvert.c +++ b/drivers/acpi/acpica/nsconvert.c | |||
@@ -78,8 +78,8 @@ acpi_ns_convert_to_integer(union acpi_operand_object *original_object, | |||
78 | 78 | ||
79 | /* String-to-Integer conversion */ | 79 | /* String-to-Integer conversion */ |
80 | 80 | ||
81 | status = acpi_ut_strtoul64(original_object->string.pointer, | 81 | status = |
82 | acpi_gbl_integer_byte_width, &value); | 82 | acpi_ut_strtoul64(original_object->string.pointer, &value); |
83 | if (ACPI_FAILURE(status)) { | 83 | if (ACPI_FAILURE(status)) { |
84 | return (status); | 84 | return (status); |
85 | } | 85 | } |
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c index 26ad596c973e..5ecb8d2e6834 100644 --- a/drivers/acpi/acpica/tbxface.c +++ b/drivers/acpi/acpica/tbxface.c | |||
@@ -173,10 +173,13 @@ acpi_status ACPI_INIT_FUNCTION acpi_reallocate_root_table(void) | |||
173 | ACPI_FUNCTION_TRACE(acpi_reallocate_root_table); | 173 | ACPI_FUNCTION_TRACE(acpi_reallocate_root_table); |
174 | 174 | ||
175 | /* | 175 | /* |
176 | * Only reallocate the root table if the host provided a static buffer | 176 | * If there are tables unverified, it is required to reallocate the |
177 | * for the table array in the call to acpi_initialize_tables. | 177 | * root table list to clean up invalid table entries. Otherwise only |
178 | * reallocate the root table list if the host provided a static buffer | ||
179 | * for the table array in the call to acpi_initialize_tables(). | ||
178 | */ | 180 | */ |
179 | if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { | 181 | if ((acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) && |
182 | acpi_gbl_enable_table_validation) { | ||
180 | return_ACPI_STATUS(AE_SUPPORT); | 183 | return_ACPI_STATUS(AE_SUPPORT); |
181 | } | 184 | } |
182 | 185 | ||
diff --git a/drivers/acpi/acpica/utstrsuppt.c b/drivers/acpi/acpica/utstrsuppt.c new file mode 100644 index 000000000000..965fb5cec94f --- /dev/null +++ b/drivers/acpi/acpica/utstrsuppt.c | |||
@@ -0,0 +1,438 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Module Name: utstrsuppt - Support functions for string-to-integer conversion | ||
4 | * | ||
5 | ******************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2017, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | |||
47 | #define _COMPONENT ACPI_UTILITIES | ||
48 | ACPI_MODULE_NAME("utstrsuppt") | ||
49 | |||
50 | /* Local prototypes */ | ||
51 | static acpi_status | ||
52 | acpi_ut_insert_digit(u64 *accumulated_value, u32 base, int ascii_digit); | ||
53 | |||
54 | static acpi_status | ||
55 | acpi_ut_strtoul_multiply64(u64 multiplicand, u64 multiplier, u64 *out_product); | ||
56 | |||
57 | static acpi_status | ||
58 | acpi_ut_strtoul_add64(u64 addend1, u64 addend2, u64 *out_sum); | ||
59 | |||
60 | /******************************************************************************* | ||
61 | * | ||
62 | * FUNCTION: acpi_ut_convert_octal_string | ||
63 | * | ||
64 | * PARAMETERS: string - Null terminated input string | ||
65 | * return_value_ptr - Where the converted value is returned | ||
66 | * | ||
67 | * RETURN: Status and 64-bit converted integer | ||
68 | * | ||
69 | * DESCRIPTION: Performs a base 8 conversion of the input string to an | ||
70 | * integer value, either 32 or 64 bits. | ||
71 | * | ||
72 | * NOTE: Maximum 64-bit unsigned octal value is 01777777777777777777777 | ||
73 | * Maximum 32-bit unsigned octal value is 037777777777 | ||
74 | * | ||
75 | ******************************************************************************/ | ||
76 | |||
77 | acpi_status acpi_ut_convert_octal_string(char *string, u64 *return_value_ptr) | ||
78 | { | ||
79 | u64 accumulated_value = 0; | ||
80 | acpi_status status = AE_OK; | ||
81 | |||
82 | /* Convert each ASCII byte in the input string */ | ||
83 | |||
84 | while (*string) { | ||
85 | |||
86 | /* Character must be ASCII 0-7, otherwise terminate with no error */ | ||
87 | |||
88 | if (!(ACPI_IS_OCTAL_DIGIT(*string))) { | ||
89 | break; | ||
90 | } | ||
91 | |||
92 | /* Convert and insert this octal digit into the accumulator */ | ||
93 | |||
94 | status = acpi_ut_insert_digit(&accumulated_value, 8, *string); | ||
95 | if (ACPI_FAILURE(status)) { | ||
96 | status = AE_OCTAL_OVERFLOW; | ||
97 | break; | ||
98 | } | ||
99 | |||
100 | string++; | ||
101 | } | ||
102 | |||
103 | /* Always return the value that has been accumulated */ | ||
104 | |||
105 | *return_value_ptr = accumulated_value; | ||
106 | return (status); | ||
107 | } | ||
108 | |||
109 | /******************************************************************************* | ||
110 | * | ||
111 | * FUNCTION: acpi_ut_convert_decimal_string | ||
112 | * | ||
113 | * PARAMETERS: string - Null terminated input string | ||
114 | * return_value_ptr - Where the converted value is returned | ||
115 | * | ||
116 | * RETURN: Status and 64-bit converted integer | ||
117 | * | ||
118 | * DESCRIPTION: Performs a base 10 conversion of the input string to an | ||
119 | * integer value, either 32 or 64 bits. | ||
120 | * | ||
121 | * NOTE: Maximum 64-bit unsigned decimal value is 18446744073709551615 | ||
122 | * Maximum 32-bit unsigned decimal value is 4294967295 | ||
123 | * | ||
124 | ******************************************************************************/ | ||
125 | |||
126 | acpi_status acpi_ut_convert_decimal_string(char *string, u64 *return_value_ptr) | ||
127 | { | ||
128 | u64 accumulated_value = 0; | ||
129 | acpi_status status = AE_OK; | ||
130 | |||
131 | /* Convert each ASCII byte in the input string */ | ||
132 | |||
133 | while (*string) { | ||
134 | |||
135 | /* Character must be ASCII 0-9, otherwise terminate with no error */ | ||
136 | |||
137 | if (!isdigit(*string)) { | ||
138 | break; | ||
139 | } | ||
140 | |||
141 | /* Convert and insert this decimal digit into the accumulator */ | ||
142 | |||
143 | status = acpi_ut_insert_digit(&accumulated_value, 10, *string); | ||
144 | if (ACPI_FAILURE(status)) { | ||
145 | status = AE_DECIMAL_OVERFLOW; | ||
146 | break; | ||
147 | } | ||
148 | |||
149 | string++; | ||
150 | } | ||
151 | |||
152 | /* Always return the value that has been accumulated */ | ||
153 | |||
154 | *return_value_ptr = accumulated_value; | ||
155 | return (status); | ||
156 | } | ||
157 | |||
158 | /******************************************************************************* | ||
159 | * | ||
160 | * FUNCTION: acpi_ut_convert_hex_string | ||
161 | * | ||
162 | * PARAMETERS: string - Null terminated input string | ||
163 | * return_value_ptr - Where the converted value is returned | ||
164 | * | ||
165 | * RETURN: Status and 64-bit converted integer | ||
166 | * | ||
167 | * DESCRIPTION: Performs a base 16 conversion of the input string to an | ||
168 | * integer value, either 32 or 64 bits. | ||
169 | * | ||
170 | * NOTE: Maximum 64-bit unsigned hex value is 0xFFFFFFFFFFFFFFFF | ||
171 | * Maximum 32-bit unsigned hex value is 0xFFFFFFFF | ||
172 | * | ||
173 | ******************************************************************************/ | ||
174 | |||
175 | acpi_status acpi_ut_convert_hex_string(char *string, u64 *return_value_ptr) | ||
176 | { | ||
177 | u64 accumulated_value = 0; | ||
178 | acpi_status status = AE_OK; | ||
179 | |||
180 | /* Convert each ASCII byte in the input string */ | ||
181 | |||
182 | while (*string) { | ||
183 | |||
184 | /* Must be ASCII A-F, a-f, or 0-9, otherwise terminate with no error */ | ||
185 | |||
186 | if (!isxdigit(*string)) { | ||
187 | break; | ||
188 | } | ||
189 | |||
190 | /* Convert and insert this hex digit into the accumulator */ | ||
191 | |||
192 | status = acpi_ut_insert_digit(&accumulated_value, 16, *string); | ||
193 | if (ACPI_FAILURE(status)) { | ||
194 | status = AE_HEX_OVERFLOW; | ||
195 | break; | ||
196 | } | ||
197 | |||
198 | string++; | ||
199 | } | ||
200 | |||
201 | /* Always return the value that has been accumulated */ | ||
202 | |||
203 | *return_value_ptr = accumulated_value; | ||
204 | return (status); | ||
205 | } | ||
206 | |||
207 | /******************************************************************************* | ||
208 | * | ||
209 | * FUNCTION: acpi_ut_remove_leading_zeros | ||
210 | * | ||
211 | * PARAMETERS: string - Pointer to input ASCII string | ||
212 | * | ||
213 | * RETURN: Next character after any leading zeros. This character may be | ||
214 | * used by the caller to detect end-of-string. | ||
215 | * | ||
216 | * DESCRIPTION: Remove any leading zeros in the input string. Return the | ||
217 | * next character after the final ASCII zero to enable the caller | ||
218 | * to check for the end of the string (NULL terminator). | ||
219 | * | ||
220 | ******************************************************************************/ | ||
221 | |||
222 | char acpi_ut_remove_leading_zeros(char **string) | ||
223 | { | ||
224 | |||
225 | while (**string == ACPI_ASCII_ZERO) { | ||
226 | *string += 1; | ||
227 | } | ||
228 | |||
229 | return (**string); | ||
230 | } | ||
231 | |||
232 | /******************************************************************************* | ||
233 | * | ||
234 | * FUNCTION: acpi_ut_remove_whitespace | ||
235 | * | ||
236 | * PARAMETERS: string - Pointer to input ASCII string | ||
237 | * | ||
238 | * RETURN: Next character after any whitespace. This character may be | ||
239 | * used by the caller to detect end-of-string. | ||
240 | * | ||
241 | * DESCRIPTION: Remove any leading whitespace in the input string. Return the | ||
242 | * next character after the final ASCII zero to enable the caller | ||
243 | * to check for the end of the string (NULL terminator). | ||
244 | * | ||
245 | ******************************************************************************/ | ||
246 | |||
247 | char acpi_ut_remove_whitespace(char **string) | ||
248 | { | ||
249 | |||
250 | while (isspace((u8)**string)) { | ||
251 | *string += 1; | ||
252 | } | ||
253 | |||
254 | return (**string); | ||
255 | } | ||
256 | |||
257 | /******************************************************************************* | ||
258 | * | ||
259 | * FUNCTION: acpi_ut_detect_hex_prefix | ||
260 | * | ||
261 | * PARAMETERS: string - Pointer to input ASCII string | ||
262 | * | ||
263 | * RETURN: TRUE if a "0x" prefix was found at the start of the string | ||
264 | * | ||
265 | * DESCRIPTION: Detect and remove a hex "0x" prefix | ||
266 | * | ||
267 | ******************************************************************************/ | ||
268 | |||
269 | u8 acpi_ut_detect_hex_prefix(char **string) | ||
270 | { | ||
271 | |||
272 | if ((**string == ACPI_ASCII_ZERO) && | ||
273 | (tolower((int)*(*string + 1)) == 'x')) { | ||
274 | *string += 2; /* Go past the leading 0x */ | ||
275 | return (TRUE); | ||
276 | } | ||
277 | |||
278 | return (FALSE); /* Not a hex string */ | ||
279 | } | ||
280 | |||
281 | /******************************************************************************* | ||
282 | * | ||
283 | * FUNCTION: acpi_ut_detect_octal_prefix | ||
284 | * | ||
285 | * PARAMETERS: string - Pointer to input ASCII string | ||
286 | * | ||
287 | * RETURN: True if an octal "0" prefix was found at the start of the | ||
288 | * string | ||
289 | * | ||
290 | * DESCRIPTION: Detect and remove an octal prefix (zero) | ||
291 | * | ||
292 | ******************************************************************************/ | ||
293 | |||
294 | u8 acpi_ut_detect_octal_prefix(char **string) | ||
295 | { | ||
296 | |||
297 | if (**string == ACPI_ASCII_ZERO) { | ||
298 | *string += 1; /* Go past the leading 0 */ | ||
299 | return (TRUE); | ||
300 | } | ||
301 | |||
302 | return (FALSE); /* Not an octal string */ | ||
303 | } | ||
304 | |||
305 | /******************************************************************************* | ||
306 | * | ||
307 | * FUNCTION: acpi_ut_insert_digit | ||
308 | * | ||
309 | * PARAMETERS: accumulated_value - Current value of the integer value | ||
310 | * accumulator. The new value is | ||
311 | * returned here. | ||
312 | * base - Radix, either 8/10/16 | ||
313 | * ascii_digit - ASCII single digit to be inserted | ||
314 | * | ||
315 | * RETURN: Status and result of the convert/insert operation. The only | ||
316 | * possible returned exception code is numeric overflow of | ||
317 | * either the multiply or add conversion operations. | ||
318 | * | ||
319 | * DESCRIPTION: Generic conversion and insertion function for all bases: | ||
320 | * | ||
321 | * 1) Multiply the current accumulated/converted value by the | ||
322 | * base in order to make room for the new character. | ||
323 | * | ||
324 | * 2) Convert the new character to binary and add it to the | ||
325 | * current accumulated value. | ||
326 | * | ||
327 | * Note: The only possible exception indicates an integer | ||
328 | * overflow (AE_NUMERIC_OVERFLOW) | ||
329 | * | ||
330 | ******************************************************************************/ | ||
331 | |||
332 | static acpi_status | ||
333 | acpi_ut_insert_digit(u64 *accumulated_value, u32 base, int ascii_digit) | ||
334 | { | ||
335 | acpi_status status; | ||
336 | u64 product; | ||
337 | |||
338 | /* Make room in the accumulated value for the incoming digit */ | ||
339 | |||
340 | status = acpi_ut_strtoul_multiply64(*accumulated_value, base, &product); | ||
341 | if (ACPI_FAILURE(status)) { | ||
342 | return (status); | ||
343 | } | ||
344 | |||
345 | /* Add in the new digit, and store the sum to the accumulated value */ | ||
346 | |||
347 | status = | ||
348 | acpi_ut_strtoul_add64(product, | ||
349 | acpi_ut_ascii_char_to_hex(ascii_digit), | ||
350 | accumulated_value); | ||
351 | |||
352 | return (status); | ||
353 | } | ||
354 | |||
355 | /******************************************************************************* | ||
356 | * | ||
357 | * FUNCTION: acpi_ut_strtoul_multiply64 | ||
358 | * | ||
359 | * PARAMETERS: multiplicand - Current accumulated converted integer | ||
360 | * multiplier - Base/Radix | ||
361 | * out_product - Where the product is returned | ||
362 | * | ||
363 | * RETURN: Status and 64-bit product | ||
364 | * | ||
365 | * DESCRIPTION: Multiply two 64-bit values, with checking for 64-bit overflow as | ||
366 | * well as 32-bit overflow if necessary (if the current global | ||
367 | * integer width is 32). | ||
368 | * | ||
369 | ******************************************************************************/ | ||
370 | |||
371 | static acpi_status | ||
372 | acpi_ut_strtoul_multiply64(u64 multiplicand, u64 multiplier, u64 *out_product) | ||
373 | { | ||
374 | u64 val; | ||
375 | |||
376 | /* Exit if either operand is zero */ | ||
377 | |||
378 | *out_product = 0; | ||
379 | if (!multiplicand || !multiplier) { | ||
380 | return (AE_OK); | ||
381 | } | ||
382 | |||
383 | /* Check for 64-bit overflow before the actual multiplication */ | ||
384 | |||
385 | acpi_ut_short_divide(ACPI_UINT64_MAX, (u32)multiplier, &val, NULL); | ||
386 | if (multiplicand > val) { | ||
387 | return (AE_NUMERIC_OVERFLOW); | ||
388 | } | ||
389 | |||
390 | val = multiplicand * multiplier; | ||
391 | |||
392 | /* Check for 32-bit overflow if necessary */ | ||
393 | |||
394 | if ((acpi_gbl_integer_bit_width == 32) && (val > ACPI_UINT32_MAX)) { | ||
395 | return (AE_NUMERIC_OVERFLOW); | ||
396 | } | ||
397 | |||
398 | *out_product = val; | ||
399 | return (AE_OK); | ||
400 | } | ||
401 | |||
402 | /******************************************************************************* | ||
403 | * | ||
404 | * FUNCTION: acpi_ut_strtoul_add64 | ||
405 | * | ||
406 | * PARAMETERS: addend1 - Current accumulated converted integer | ||
407 | * addend2 - New hex value/char | ||
408 | * out_sum - Where sum is returned (Accumulator) | ||
409 | * | ||
410 | * RETURN: Status and 64-bit sum | ||
411 | * | ||
412 | * DESCRIPTION: Add two 64-bit values, with checking for 64-bit overflow as | ||
413 | * well as 32-bit overflow if necessary (if the current global | ||
414 | * integer width is 32). | ||
415 | * | ||
416 | ******************************************************************************/ | ||
417 | |||
418 | static acpi_status acpi_ut_strtoul_add64(u64 addend1, u64 addend2, u64 *out_sum) | ||
419 | { | ||
420 | u64 sum; | ||
421 | |||
422 | /* Check for 64-bit overflow before the actual addition */ | ||
423 | |||
424 | if ((addend1 > 0) && (addend2 > (ACPI_UINT64_MAX - addend1))) { | ||
425 | return (AE_NUMERIC_OVERFLOW); | ||
426 | } | ||
427 | |||
428 | sum = addend1 + addend2; | ||
429 | |||
430 | /* Check for 32-bit overflow if necessary */ | ||
431 | |||
432 | if ((acpi_gbl_integer_bit_width == 32) && (sum > ACPI_UINT32_MAX)) { | ||
433 | return (AE_NUMERIC_OVERFLOW); | ||
434 | } | ||
435 | |||
436 | *out_sum = sum; | ||
437 | return (AE_OK); | ||
438 | } | ||
diff --git a/drivers/acpi/acpica/utstrtoul64.c b/drivers/acpi/acpica/utstrtoul64.c index 9633ee142855..e2067dcb9389 100644 --- a/drivers/acpi/acpica/utstrtoul64.c +++ b/drivers/acpi/acpica/utstrtoul64.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | * | 2 | * |
3 | * Module Name: utstrtoul64 - string to 64-bit integer support | 3 | * Module Name: utstrtoul64 - String-to-integer conversion support for both |
4 | * 64-bit and 32-bit integers | ||
4 | * | 5 | * |
5 | ******************************************************************************/ | 6 | ******************************************************************************/ |
6 | 7 | ||
@@ -44,304 +45,319 @@ | |||
44 | #include <acpi/acpi.h> | 45 | #include <acpi/acpi.h> |
45 | #include "accommon.h" | 46 | #include "accommon.h" |
46 | 47 | ||
47 | /******************************************************************************* | ||
48 | * | ||
49 | * The functions in this module satisfy the need for 64-bit string-to-integer | ||
50 | * conversions on both 32-bit and 64-bit platforms. | ||
51 | * | ||
52 | ******************************************************************************/ | ||
53 | |||
54 | #define _COMPONENT ACPI_UTILITIES | 48 | #define _COMPONENT ACPI_UTILITIES |
55 | ACPI_MODULE_NAME("utstrtoul64") | 49 | ACPI_MODULE_NAME("utstrtoul64") |
56 | 50 | ||
57 | /* Local prototypes */ | ||
58 | static u64 acpi_ut_strtoul_base10(char *string, u32 flags); | ||
59 | |||
60 | static u64 acpi_ut_strtoul_base16(char *string, u32 flags); | ||
61 | |||
62 | /******************************************************************************* | 51 | /******************************************************************************* |
63 | * | 52 | * |
64 | * String conversion rules as written in the ACPI specification. The error | 53 | * This module contains the top-level string to 64/32-bit unsigned integer |
65 | * conditions and behavior are different depending on the type of conversion. | 54 | * conversion functions: |
66 | * | ||
67 | * | ||
68 | * Implicit data type conversion: string-to-integer | ||
69 | * -------------------------------------------------- | ||
70 | * | ||
71 | * Base is always 16. This is the ACPI_STRTOUL_BASE16 case. | ||
72 | * | ||
73 | * Example: | ||
74 | * Add ("BA98", Arg0, Local0) | ||
75 | * | ||
76 | * The integer is initialized to the value zero. | ||
77 | * The ASCII string is interpreted as a hexadecimal constant. | ||
78 | * | 55 | * |
79 | * 1) A "0x" prefix is not allowed. However, ACPICA allows this for | 56 | * 1) A standard strtoul() function that supports 64-bit integers, base |
80 | * compatibility with previous ACPICA. (NO ERROR) | 57 | * 8/10/16, with integer overflow support. This is used mainly by the |
58 | * iASL compiler, which implements tighter constraints on integer | ||
59 | * constants than the runtime (interpreter) integer-to-string conversions. | ||
60 | * 2) Runtime "Explicit conversion" as defined in the ACPI specification. | ||
61 | * 3) Runtime "Implicit conversion" as defined in the ACPI specification. | ||
81 | * | 62 | * |
82 | * 2) Terminates when the size of an integer is reached (32 or 64 bits). | 63 | * Current users of this module: |
83 | * (NO ERROR) | ||
84 | * | 64 | * |
85 | * 3) The first non-hex character terminates the conversion without error. | 65 | * iASL - Preprocessor (constants and math expressions) |
86 | * (NO ERROR) | 66 | * iASL - Main parser, conversion of constants to integers |
87 | * | 67 | * iASL - Data Table Compiler parser (constants and math expressions) |
88 | * 4) Conversion of a null (zero-length) string to an integer is not | 68 | * interpreter - Implicit and explicit conversions, GPE method names |
89 | * allowed. However, ACPICA allows this for compatibility with previous | 69 | * interpreter - Repair code for return values from predefined names |
90 | * ACPICA. This conversion returns the value 0. (NO ERROR) | 70 | * debugger - Command line input string conversion |
91 | * | 71 | * acpi_dump - ACPI table physical addresses |
92 | * | 72 | * acpi_exec - Support for namespace overrides |
93 | * Explicit data type conversion: to_integer() with string operand | ||
94 | * --------------------------------------------------------------- | ||
95 | * | ||
96 | * Base is either 10 (default) or 16 (with 0x prefix) | ||
97 | * | ||
98 | * Examples: | ||
99 | * to_integer ("1000") | ||
100 | * to_integer ("0xABCD") | ||
101 | * | ||
102 | * 1) Can be (must be) either a decimal or hexadecimal numeric string. | ||
103 | * A hex value must be prefixed by "0x" or it is interpreted as a decimal. | ||
104 | * | 73 | * |
105 | * 2) The value must not exceed the maximum of an integer value. ACPI spec | 74 | * Notes concerning users of these interfaces: |
106 | * states the behavior is "unpredictable", so ACPICA matches the behavior | ||
107 | * of the implicit conversion case.(NO ERROR) | ||
108 | * | 75 | * |
109 | * 3) Behavior on the first non-hex character is not specified by the ACPI | 76 | * acpi_gbl_integer_byte_width is used to set the 32/64 bit limit for explicit |
110 | * spec, so ACPICA matches the behavior of the implicit conversion case | 77 | * and implicit conversions. This global must be set to the proper width. |
111 | * and terminates. (NO ERROR) | 78 | * For the core ACPICA code, the width depends on the DSDT version. For the |
79 | * acpi_ut_strtoul64 interface, all conversions are 64 bits. This interface is | ||
80 | * used primarily for iASL, where the default width is 64 bits for all parsers, | ||
81 | * but error checking is performed later to flag cases where a 64-bit constant | ||
82 | * is wrongly defined in a 32-bit DSDT/SSDT. | ||
112 | * | 83 | * |
113 | * 4) A null (zero-length) string is illegal. | 84 | * In ACPI, the only place where octal numbers are supported is within |
114 | * However, ACPICA allows this for compatibility with previous ACPICA. | 85 | * the ASL language itself. This is implemented via the main acpi_ut_strtoul64 |
115 | * This conversion returns the value 0. (NO ERROR) | 86 | * interface. According the ACPI specification, there is no ACPI runtime |
87 | * support (explicit/implicit) for octal string conversions. | ||
116 | * | 88 | * |
117 | ******************************************************************************/ | 89 | ******************************************************************************/ |
118 | |||
119 | /******************************************************************************* | 90 | /******************************************************************************* |
120 | * | 91 | * |
121 | * FUNCTION: acpi_ut_strtoul64 | 92 | * FUNCTION: acpi_ut_strtoul64 |
122 | * | 93 | * |
123 | * PARAMETERS: string - Null terminated input string | 94 | * PARAMETERS: string - Null terminated input string, |
124 | * flags - Conversion info, see below | 95 | * must be a valid pointer |
125 | * return_value - Where the converted integer is | 96 | * return_value - Where the converted integer is |
126 | * returned | 97 | * returned. Must be a valid pointer |
127 | * | ||
128 | * RETURN: Status and Converted value | ||
129 | * | 98 | * |
130 | * DESCRIPTION: Convert a string into an unsigned value. Performs either a | 99 | * RETURN: Status and converted integer. Returns an exception on a |
131 | * 32-bit or 64-bit conversion, depending on the input integer | 100 | * 64-bit numeric overflow |
132 | * size in Flags (often the current mode of the interpreter). | ||
133 | * | 101 | * |
134 | * Values for Flags: | 102 | * DESCRIPTION: Convert a string into an unsigned integer. Always performs a |
135 | * ACPI_STRTOUL_32BIT - Max integer value is 32 bits | 103 | * full 64-bit conversion, regardless of the current global |
136 | * ACPI_STRTOUL_64BIT - Max integer value is 64 bits | 104 | * integer width. Supports Decimal, Hex, and Octal strings. |
137 | * ACPI_STRTOUL_BASE16 - Input string is hexadecimal. Default | ||
138 | * is 10/16 based on string prefix (0x). | ||
139 | * | 105 | * |
140 | * NOTES: | 106 | * Current users of this function: |
141 | * Negative numbers are not supported, as they are not supported by ACPI. | ||
142 | * | 107 | * |
143 | * Supports only base 16 or base 10 strings/values. Does not | 108 | * iASL - Preprocessor (constants and math expressions) |
144 | * support Octal strings, as these are not supported by ACPI. | 109 | * iASL - Main ASL parser, conversion of ASL constants to integers |
145 | * | 110 | * iASL - Data Table Compiler parser (constants and math expressions) |
146 | * Current users of this support: | 111 | * interpreter - Repair code for return values from predefined names |
147 | * | 112 | * acpi_dump - ACPI table physical addresses |
148 | * interpreter - Implicit and explicit conversions, GPE method names | 113 | * acpi_exec - Support for namespace overrides |
149 | * debugger - Command line input string conversion | ||
150 | * iASL - Main parser, conversion of constants to integers | ||
151 | * iASL - Data Table Compiler parser (constant math expressions) | ||
152 | * iASL - Preprocessor (constant math expressions) | ||
153 | * acpi_dump - Input table addresses | ||
154 | * acpi_exec - Testing of the acpi_ut_strtoul64 function | ||
155 | * | ||
156 | * Note concerning callers: | ||
157 | * acpi_gbl_integer_byte_width can be used to set the 32/64 limit. If used, | ||
158 | * this global should be set to the proper width. For the core ACPICA code, | ||
159 | * this width depends on the DSDT version. For iASL, the default byte | ||
160 | * width is always 8 for the parser, but error checking is performed later | ||
161 | * to flag cases where a 64-bit constant is defined in a 32-bit DSDT/SSDT. | ||
162 | * | 114 | * |
163 | ******************************************************************************/ | 115 | ******************************************************************************/ |
164 | 116 | acpi_status acpi_ut_strtoul64(char *string, u64 *return_value) | |
165 | acpi_status acpi_ut_strtoul64(char *string, u32 flags, u64 *return_value) | ||
166 | { | 117 | { |
167 | acpi_status status = AE_OK; | 118 | acpi_status status = AE_OK; |
168 | u32 base; | 119 | u8 original_bit_width; |
120 | u32 base = 10; /* Default is decimal */ | ||
169 | 121 | ||
170 | ACPI_FUNCTION_TRACE_STR(ut_strtoul64, string); | 122 | ACPI_FUNCTION_TRACE_STR(ut_strtoul64, string); |
171 | 123 | ||
172 | /* Parameter validation */ | ||
173 | |||
174 | if (!string || !return_value) { | ||
175 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
176 | } | ||
177 | |||
178 | *return_value = 0; | 124 | *return_value = 0; |
179 | 125 | ||
180 | /* Check for zero-length string, returns 0 */ | 126 | /* A NULL return string returns a value of zero */ |
181 | 127 | ||
182 | if (*string == 0) { | 128 | if (*string == 0) { |
183 | return_ACPI_STATUS(AE_OK); | 129 | return_ACPI_STATUS(AE_OK); |
184 | } | 130 | } |
185 | 131 | ||
186 | /* Skip over any white space at start of string */ | 132 | if (!acpi_ut_remove_whitespace(&string)) { |
187 | |||
188 | while (isspace((int)*string)) { | ||
189 | string++; | ||
190 | } | ||
191 | |||
192 | /* End of string? return 0 */ | ||
193 | |||
194 | if (*string == 0) { | ||
195 | return_ACPI_STATUS(AE_OK); | 133 | return_ACPI_STATUS(AE_OK); |
196 | } | 134 | } |
197 | 135 | ||
198 | /* | 136 | /* |
199 | * 1) The "0x" prefix indicates base 16. Per the ACPI specification, | 137 | * 1) Check for a hex constant. A "0x" prefix indicates base 16. |
200 | * the "0x" prefix is only allowed for implicit (non-strict) conversions. | ||
201 | * However, we always allow it for compatibility with older ACPICA. | ||
202 | */ | 138 | */ |
203 | if ((*string == ACPI_ASCII_ZERO) && | 139 | if (acpi_ut_detect_hex_prefix(&string)) { |
204 | (tolower((int)*(string + 1)) == 'x')) { | ||
205 | string += 2; /* Go past the 0x */ | ||
206 | if (*string == 0) { | ||
207 | return_ACPI_STATUS(AE_OK); /* Return value 0 */ | ||
208 | } | ||
209 | |||
210 | base = 16; | 140 | base = 16; |
211 | } | 141 | } |
212 | 142 | ||
213 | /* 2) Force to base 16 (implicit conversion case) */ | 143 | /* |
214 | 144 | * 2) Check for an octal constant, defined to be a leading zero | |
215 | else if (flags & ACPI_STRTOUL_BASE16) { | 145 | * followed by sequence of octal digits (0-7) |
216 | base = 16; | 146 | */ |
147 | else if (acpi_ut_detect_octal_prefix(&string)) { | ||
148 | base = 8; | ||
217 | } | 149 | } |
218 | 150 | ||
219 | /* 3) Default fallback is to Base 10 */ | 151 | if (!acpi_ut_remove_leading_zeros(&string)) { |
220 | 152 | return_ACPI_STATUS(AE_OK); /* Return value 0 */ | |
221 | else { | ||
222 | base = 10; | ||
223 | } | 153 | } |
224 | 154 | ||
225 | /* Skip all leading zeros */ | 155 | /* |
156 | * Force a full 64-bit conversion. The caller (usually iASL) must | ||
157 | * check for a 32-bit overflow later as necessary (If current mode | ||
158 | * is 32-bit, meaning a 32-bit DSDT). | ||
159 | */ | ||
160 | original_bit_width = acpi_gbl_integer_bit_width; | ||
161 | acpi_gbl_integer_bit_width = 64; | ||
226 | 162 | ||
227 | while (*string == ACPI_ASCII_ZERO) { | 163 | /* |
228 | string++; | 164 | * Perform the base 8, 10, or 16 conversion. A 64-bit numeric overflow |
229 | if (*string == 0) { | 165 | * will return an exception (to allow iASL to flag the statement). |
230 | return_ACPI_STATUS(AE_OK); /* Return value 0 */ | 166 | */ |
231 | } | 167 | switch (base) { |
168 | case 8: | ||
169 | status = acpi_ut_convert_octal_string(string, return_value); | ||
170 | break; | ||
171 | |||
172 | case 10: | ||
173 | status = acpi_ut_convert_decimal_string(string, return_value); | ||
174 | break; | ||
175 | |||
176 | case 16: | ||
177 | default: | ||
178 | status = acpi_ut_convert_hex_string(string, return_value); | ||
179 | break; | ||
232 | } | 180 | } |
233 | 181 | ||
234 | /* Perform the base 16 or 10 conversion */ | 182 | /* Only possible exception from above is a 64-bit overflow */ |
235 | |||
236 | if (base == 16) { | ||
237 | *return_value = acpi_ut_strtoul_base16(string, flags); | ||
238 | } else { | ||
239 | *return_value = acpi_ut_strtoul_base10(string, flags); | ||
240 | } | ||
241 | 183 | ||
184 | acpi_gbl_integer_bit_width = original_bit_width; | ||
242 | return_ACPI_STATUS(status); | 185 | return_ACPI_STATUS(status); |
243 | } | 186 | } |
244 | 187 | ||
245 | /******************************************************************************* | 188 | /******************************************************************************* |
246 | * | 189 | * |
247 | * FUNCTION: acpi_ut_strtoul_base10 | 190 | * FUNCTION: acpi_ut_implicit_strtoul64 |
191 | * | ||
192 | * PARAMETERS: string - Null terminated input string, | ||
193 | * must be a valid pointer | ||
194 | * | ||
195 | * RETURN: Converted integer | ||
196 | * | ||
197 | * DESCRIPTION: Perform a 64-bit conversion with restrictions placed upon | ||
198 | * an "implicit conversion" by the ACPI specification. Used by | ||
199 | * many ASL operators that require an integer operand, and support | ||
200 | * an automatic (implicit) conversion from a string operand | ||
201 | * to the final integer operand. The major restriction is that | ||
202 | * only hex strings are supported. | ||
203 | * | ||
204 | * ----------------------------------------------------------------------------- | ||
205 | * | ||
206 | * Base is always 16, either with or without the 0x prefix. Decimal and | ||
207 | * Octal strings are not supported, as per the ACPI specification. | ||
208 | * | ||
209 | * Examples (both are hex values): | ||
210 | * Add ("BA98", Arg0, Local0) | ||
211 | * Subtract ("0x12345678", Arg1, Local1) | ||
212 | * | ||
213 | * Conversion rules as extracted from the ACPI specification: | ||
214 | * | ||
215 | * The converted integer is initialized to the value zero. | ||
216 | * The ASCII string is always interpreted as a hexadecimal constant. | ||
217 | * | ||
218 | * 1) According to the ACPI specification, a "0x" prefix is not allowed. | ||
219 | * However, ACPICA allows this as an ACPI extension on general | ||
220 | * principle. (NO ERROR) | ||
221 | * | ||
222 | * 2) The conversion terminates when the size of an integer is reached | ||
223 | * (32 or 64 bits). There are no numeric overflow conditions. (NO ERROR) | ||
224 | * | ||
225 | * 3) The first non-hex character terminates the conversion and returns | ||
226 | * the current accumulated value of the converted integer (NO ERROR). | ||
248 | * | 227 | * |
249 | * PARAMETERS: string - Null terminated input string | 228 | * 4) Conversion of a null (zero-length) string to an integer is |
250 | * flags - Conversion info | 229 | * technically not allowed. However, ACPICA allows this as an ACPI |
230 | * extension. The conversion returns the value 0. (NO ERROR) | ||
251 | * | 231 | * |
252 | * RETURN: 64-bit converted integer | 232 | * NOTE: There are no error conditions returned by this function. At |
233 | * the minimum, a value of zero is returned. | ||
253 | * | 234 | * |
254 | * DESCRIPTION: Performs a base 10 conversion of the input string to an | 235 | * Current users of this function: |
255 | * integer value, either 32 or 64 bits. | 236 | * |
256 | * Note: String must be valid and non-null. | 237 | * interpreter - All runtime implicit conversions, as per ACPI specification |
238 | * iASL - Data Table Compiler parser (constants and math expressions) | ||
257 | * | 239 | * |
258 | ******************************************************************************/ | 240 | ******************************************************************************/ |
259 | 241 | ||
260 | static u64 acpi_ut_strtoul_base10(char *string, u32 flags) | 242 | u64 acpi_ut_implicit_strtoul64(char *string) |
261 | { | 243 | { |
262 | int ascii_digit; | 244 | u64 converted_integer = 0; |
263 | u64 next_value; | ||
264 | u64 return_value = 0; | ||
265 | |||
266 | /* Main loop: convert each ASCII byte in the input string */ | ||
267 | |||
268 | while (*string) { | ||
269 | ascii_digit = *string; | ||
270 | if (!isdigit(ascii_digit)) { | ||
271 | |||
272 | /* Not ASCII 0-9, terminate */ | ||
273 | |||
274 | goto exit; | ||
275 | } | ||
276 | |||
277 | /* Convert and insert (add) the decimal digit */ | ||
278 | 245 | ||
279 | acpi_ut_short_multiply(return_value, 10, &next_value); | 246 | ACPI_FUNCTION_TRACE_STR(ut_implicit_strtoul64, string); |
280 | next_value += (ascii_digit - ACPI_ASCII_ZERO); | ||
281 | 247 | ||
282 | /* Check for overflow (32 or 64 bit) - return current converted value */ | 248 | if (!acpi_ut_remove_whitespace(&string)) { |
249 | return_VALUE(0); | ||
250 | } | ||
283 | 251 | ||
284 | if (((flags & ACPI_STRTOUL_32BIT) && (next_value > ACPI_UINT32_MAX)) || (next_value < return_value)) { /* 64-bit overflow case */ | 252 | /* |
285 | goto exit; | 253 | * Per the ACPI specification, only hexadecimal is supported for |
286 | } | 254 | * implicit conversions, and the "0x" prefix is "not allowed". |
255 | * However, allow a "0x" prefix as an ACPI extension. | ||
256 | */ | ||
257 | acpi_ut_detect_hex_prefix(&string); | ||
287 | 258 | ||
288 | return_value = next_value; | 259 | if (!acpi_ut_remove_leading_zeros(&string)) { |
289 | string++; | 260 | return_VALUE(0); |
290 | } | 261 | } |
291 | 262 | ||
292 | exit: | 263 | /* |
293 | return (return_value); | 264 | * Ignore overflow as per the ACPI specification. This is implemented by |
265 | * ignoring the return status from the conversion function called below. | ||
266 | * On overflow, the input string is simply truncated. | ||
267 | */ | ||
268 | acpi_ut_convert_hex_string(string, &converted_integer); | ||
269 | return_VALUE(converted_integer); | ||
294 | } | 270 | } |
295 | 271 | ||
296 | /******************************************************************************* | 272 | /******************************************************************************* |
297 | * | 273 | * |
298 | * FUNCTION: acpi_ut_strtoul_base16 | 274 | * FUNCTION: acpi_ut_explicit_strtoul64 |
275 | * | ||
276 | * PARAMETERS: string - Null terminated input string, | ||
277 | * must be a valid pointer | ||
299 | * | 278 | * |
300 | * PARAMETERS: string - Null terminated input string | 279 | * RETURN: Converted integer |
301 | * flags - conversion info | ||
302 | * | 280 | * |
303 | * RETURN: 64-bit converted integer | 281 | * DESCRIPTION: Perform a 64-bit conversion with the restrictions placed upon |
282 | * an "explicit conversion" by the ACPI specification. The | ||
283 | * main restriction is that only hex and decimal are supported. | ||
304 | * | 284 | * |
305 | * DESCRIPTION: Performs a base 16 conversion of the input string to an | 285 | * ----------------------------------------------------------------------------- |
306 | * integer value, either 32 or 64 bits. | 286 | * |
307 | * Note: String must be valid and non-null. | 287 | * Base is either 10 (default) or 16 (with 0x prefix). Octal (base 8) strings |
288 | * are not supported, as per the ACPI specification. | ||
289 | * | ||
290 | * Examples: | ||
291 | * to_integer ("1000") Decimal | ||
292 | * to_integer ("0xABCD") Hex | ||
293 | * | ||
294 | * Conversion rules as extracted from the ACPI specification: | ||
295 | * | ||
296 | * 1) The input string is either a decimal or hexadecimal numeric string. | ||
297 | * A hex value must be prefixed by "0x" or it is interpreted as decimal. | ||
298 | * | ||
299 | * 2) The value must not exceed the maximum of an integer value | ||
300 | * (32 or 64 bits). The ACPI specification states the behavior is | ||
301 | * "unpredictable", so ACPICA matches the behavior of the implicit | ||
302 | * conversion case. There are no numeric overflow conditions. (NO ERROR) | ||
303 | * | ||
304 | * 3) Behavior on the first non-hex character is not defined by the ACPI | ||
305 | * specification (for the to_integer operator), so ACPICA matches the | ||
306 | * behavior of the implicit conversion case. It terminates the | ||
307 | * conversion and returns the current accumulated value of the converted | ||
308 | * integer. (NO ERROR) | ||
309 | * | ||
310 | * 4) Conversion of a null (zero-length) string to an integer is | ||
311 | * technically not allowed. However, ACPICA allows this as an ACPI | ||
312 | * extension. The conversion returns the value 0. (NO ERROR) | ||
313 | * | ||
314 | * NOTE: There are no error conditions returned by this function. At the | ||
315 | * minimum, a value of zero is returned. | ||
316 | * | ||
317 | * Current users of this function: | ||
318 | * | ||
319 | * interpreter - Runtime ASL to_integer operator, as per the ACPI specification | ||
308 | * | 320 | * |
309 | ******************************************************************************/ | 321 | ******************************************************************************/ |
310 | 322 | ||
311 | static u64 acpi_ut_strtoul_base16(char *string, u32 flags) | 323 | u64 acpi_ut_explicit_strtoul64(char *string) |
312 | { | 324 | { |
313 | int ascii_digit; | 325 | u64 converted_integer = 0; |
314 | u32 valid_digits = 1; | 326 | u32 base = 10; /* Default is decimal */ |
315 | u64 return_value = 0; | ||
316 | |||
317 | /* Main loop: convert each ASCII byte in the input string */ | ||
318 | 327 | ||
319 | while (*string) { | 328 | ACPI_FUNCTION_TRACE_STR(ut_explicit_strtoul64, string); |
320 | 329 | ||
321 | /* Check for overflow (32 or 64 bit) - return current converted value */ | 330 | if (!acpi_ut_remove_whitespace(&string)) { |
322 | 331 | return_VALUE(0); | |
323 | if ((valid_digits > 16) || | 332 | } |
324 | ((valid_digits > 8) && (flags & ACPI_STRTOUL_32BIT))) { | ||
325 | goto exit; | ||
326 | } | ||
327 | |||
328 | ascii_digit = *string; | ||
329 | if (!isxdigit(ascii_digit)) { | ||
330 | |||
331 | /* Not Hex ASCII A-F, a-f, or 0-9, terminate */ | ||
332 | |||
333 | goto exit; | ||
334 | } | ||
335 | 333 | ||
336 | /* Convert and insert the hex digit */ | 334 | /* |
335 | * Only Hex and Decimal are supported, as per the ACPI specification. | ||
336 | * A "0x" prefix indicates hex; otherwise decimal is assumed. | ||
337 | */ | ||
338 | if (acpi_ut_detect_hex_prefix(&string)) { | ||
339 | base = 16; | ||
340 | } | ||
337 | 341 | ||
338 | acpi_ut_short_shift_left(return_value, 4, &return_value); | 342 | if (!acpi_ut_remove_leading_zeros(&string)) { |
339 | return_value |= acpi_ut_ascii_char_to_hex(ascii_digit); | 343 | return_VALUE(0); |
344 | } | ||
340 | 345 | ||
341 | string++; | 346 | /* |
342 | valid_digits++; | 347 | * Ignore overflow as per the ACPI specification. This is implemented by |
348 | * ignoring the return status from the conversion functions called below. | ||
349 | * On overflow, the input string is simply truncated. | ||
350 | */ | ||
351 | switch (base) { | ||
352 | case 10: | ||
353 | default: | ||
354 | acpi_ut_convert_decimal_string(string, &converted_integer); | ||
355 | break; | ||
356 | |||
357 | case 16: | ||
358 | acpi_ut_convert_hex_string(string, &converted_integer); | ||
359 | break; | ||
343 | } | 360 | } |
344 | 361 | ||
345 | exit: | 362 | return_VALUE(converted_integer); |
346 | return (return_value); | ||
347 | } | 363 | } |
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index 2c462beee551..6742f6c68034 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c | |||
@@ -1061,7 +1061,7 @@ static int erst_writer(struct pstore_record *record) | |||
1061 | rcd->hdr.error_severity = CPER_SEV_FATAL; | 1061 | rcd->hdr.error_severity = CPER_SEV_FATAL; |
1062 | /* timestamp valid. platform_id, partition_id are invalid */ | 1062 | /* timestamp valid. platform_id, partition_id are invalid */ |
1063 | rcd->hdr.validation_bits = CPER_VALID_TIMESTAMP; | 1063 | rcd->hdr.validation_bits = CPER_VALID_TIMESTAMP; |
1064 | rcd->hdr.timestamp = get_seconds(); | 1064 | rcd->hdr.timestamp = ktime_get_real_seconds(); |
1065 | rcd->hdr.record_length = sizeof(*rcd) + record->size; | 1065 | rcd->hdr.record_length = sizeof(*rcd) + record->size; |
1066 | rcd->hdr.creator_id = CPER_CREATOR_PSTORE; | 1066 | rcd->hdr.creator_id = CPER_CREATOR_PSTORE; |
1067 | rcd->hdr.notification_type = CPER_NOTIFY_MCE; | 1067 | rcd->hdr.notification_type = CPER_NOTIFY_MCE; |
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index ebaa51ba8a22..6402f7fad3bb 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <acpi/actbl1.h> | 51 | #include <acpi/actbl1.h> |
52 | #include <acpi/ghes.h> | 52 | #include <acpi/ghes.h> |
53 | #include <acpi/apei.h> | 53 | #include <acpi/apei.h> |
54 | #include <asm/fixmap.h> | ||
54 | #include <asm/tlbflush.h> | 55 | #include <asm/tlbflush.h> |
55 | #include <ras/ras_event.h> | 56 | #include <ras/ras_event.h> |
56 | 57 | ||
@@ -112,22 +113,10 @@ static DEFINE_MUTEX(ghes_list_mutex); | |||
112 | * Because the memory area used to transfer hardware error information | 113 | * Because the memory area used to transfer hardware error information |
113 | * from BIOS to Linux can be determined only in NMI, IRQ or timer | 114 | * from BIOS to Linux can be determined only in NMI, IRQ or timer |
114 | * handler, but general ioremap can not be used in atomic context, so | 115 | * handler, but general ioremap can not be used in atomic context, so |
115 | * a special version of atomic ioremap is implemented for that. | 116 | * the fixmap is used instead. |
116 | */ | 117 | * |
117 | 118 | * These 2 spinlocks are used to prevent the fixmap entries from being used | |
118 | /* | 119 | * simultaneously. |
119 | * Two virtual pages are used, one for IRQ/PROCESS context, the other for | ||
120 | * NMI context (optionally). | ||
121 | */ | ||
122 | #define GHES_IOREMAP_PAGES 2 | ||
123 | #define GHES_IOREMAP_IRQ_PAGE(base) (base) | ||
124 | #define GHES_IOREMAP_NMI_PAGE(base) ((base) + PAGE_SIZE) | ||
125 | |||
126 | /* virtual memory area for atomic ioremap */ | ||
127 | static struct vm_struct *ghes_ioremap_area; | ||
128 | /* | ||
129 | * These 2 spinlock is used to prevent atomic ioremap virtual memory | ||
130 | * area from being mapped simultaneously. | ||
131 | */ | 120 | */ |
132 | static DEFINE_RAW_SPINLOCK(ghes_ioremap_lock_nmi); | 121 | static DEFINE_RAW_SPINLOCK(ghes_ioremap_lock_nmi); |
133 | static DEFINE_SPINLOCK(ghes_ioremap_lock_irq); | 122 | static DEFINE_SPINLOCK(ghes_ioremap_lock_irq); |
@@ -140,71 +129,38 @@ static atomic_t ghes_estatus_cache_alloced; | |||
140 | 129 | ||
141 | static int ghes_panic_timeout __read_mostly = 30; | 130 | static int ghes_panic_timeout __read_mostly = 30; |
142 | 131 | ||
143 | static int ghes_ioremap_init(void) | ||
144 | { | ||
145 | ghes_ioremap_area = __get_vm_area(PAGE_SIZE * GHES_IOREMAP_PAGES, | ||
146 | VM_IOREMAP, VMALLOC_START, VMALLOC_END); | ||
147 | if (!ghes_ioremap_area) { | ||
148 | pr_err(GHES_PFX "Failed to allocate virtual memory area for atomic ioremap.\n"); | ||
149 | return -ENOMEM; | ||
150 | } | ||
151 | |||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | static void ghes_ioremap_exit(void) | ||
156 | { | ||
157 | free_vm_area(ghes_ioremap_area); | ||
158 | } | ||
159 | |||
160 | static void __iomem *ghes_ioremap_pfn_nmi(u64 pfn) | 132 | static void __iomem *ghes_ioremap_pfn_nmi(u64 pfn) |
161 | { | 133 | { |
162 | unsigned long vaddr; | ||
163 | phys_addr_t paddr; | 134 | phys_addr_t paddr; |
164 | pgprot_t prot; | 135 | pgprot_t prot; |
165 | 136 | ||
166 | vaddr = (unsigned long)GHES_IOREMAP_NMI_PAGE(ghes_ioremap_area->addr); | ||
167 | |||
168 | paddr = pfn << PAGE_SHIFT; | 137 | paddr = pfn << PAGE_SHIFT; |
169 | prot = arch_apei_get_mem_attribute(paddr); | 138 | prot = arch_apei_get_mem_attribute(paddr); |
170 | ioremap_page_range(vaddr, vaddr + PAGE_SIZE, paddr, prot); | 139 | __set_fixmap(FIX_APEI_GHES_NMI, paddr, prot); |
171 | 140 | ||
172 | return (void __iomem *)vaddr; | 141 | return (void __iomem *) fix_to_virt(FIX_APEI_GHES_NMI); |
173 | } | 142 | } |
174 | 143 | ||
175 | static void __iomem *ghes_ioremap_pfn_irq(u64 pfn) | 144 | static void __iomem *ghes_ioremap_pfn_irq(u64 pfn) |
176 | { | 145 | { |
177 | unsigned long vaddr, paddr; | 146 | phys_addr_t paddr; |
178 | pgprot_t prot; | 147 | pgprot_t prot; |
179 | 148 | ||
180 | vaddr = (unsigned long)GHES_IOREMAP_IRQ_PAGE(ghes_ioremap_area->addr); | ||
181 | |||
182 | paddr = pfn << PAGE_SHIFT; | 149 | paddr = pfn << PAGE_SHIFT; |
183 | prot = arch_apei_get_mem_attribute(paddr); | 150 | prot = arch_apei_get_mem_attribute(paddr); |
151 | __set_fixmap(FIX_APEI_GHES_IRQ, paddr, prot); | ||
184 | 152 | ||
185 | ioremap_page_range(vaddr, vaddr + PAGE_SIZE, paddr, prot); | 153 | return (void __iomem *) fix_to_virt(FIX_APEI_GHES_IRQ); |
186 | |||
187 | return (void __iomem *)vaddr; | ||
188 | } | 154 | } |
189 | 155 | ||
190 | static void ghes_iounmap_nmi(void __iomem *vaddr_ptr) | 156 | static void ghes_iounmap_nmi(void) |
191 | { | 157 | { |
192 | unsigned long vaddr = (unsigned long __force)vaddr_ptr; | 158 | clear_fixmap(FIX_APEI_GHES_NMI); |
193 | void *base = ghes_ioremap_area->addr; | ||
194 | |||
195 | BUG_ON(vaddr != (unsigned long)GHES_IOREMAP_NMI_PAGE(base)); | ||
196 | unmap_kernel_range_noflush(vaddr, PAGE_SIZE); | ||
197 | arch_apei_flush_tlb_one(vaddr); | ||
198 | } | 159 | } |
199 | 160 | ||
200 | static void ghes_iounmap_irq(void __iomem *vaddr_ptr) | 161 | static void ghes_iounmap_irq(void) |
201 | { | 162 | { |
202 | unsigned long vaddr = (unsigned long __force)vaddr_ptr; | 163 | clear_fixmap(FIX_APEI_GHES_IRQ); |
203 | void *base = ghes_ioremap_area->addr; | ||
204 | |||
205 | BUG_ON(vaddr != (unsigned long)GHES_IOREMAP_IRQ_PAGE(base)); | ||
206 | unmap_kernel_range_noflush(vaddr, PAGE_SIZE); | ||
207 | arch_apei_flush_tlb_one(vaddr); | ||
208 | } | 164 | } |
209 | 165 | ||
210 | static int ghes_estatus_pool_init(void) | 166 | static int ghes_estatus_pool_init(void) |
@@ -360,10 +316,10 @@ static void ghes_copy_tofrom_phys(void *buffer, u64 paddr, u32 len, | |||
360 | paddr += trunk; | 316 | paddr += trunk; |
361 | buffer += trunk; | 317 | buffer += trunk; |
362 | if (in_nmi) { | 318 | if (in_nmi) { |
363 | ghes_iounmap_nmi(vaddr); | 319 | ghes_iounmap_nmi(); |
364 | raw_spin_unlock(&ghes_ioremap_lock_nmi); | 320 | raw_spin_unlock(&ghes_ioremap_lock_nmi); |
365 | } else { | 321 | } else { |
366 | ghes_iounmap_irq(vaddr); | 322 | ghes_iounmap_irq(); |
367 | spin_unlock_irqrestore(&ghes_ioremap_lock_irq, flags); | 323 | spin_unlock_irqrestore(&ghes_ioremap_lock_irq, flags); |
368 | } | 324 | } |
369 | } | 325 | } |
@@ -851,17 +807,8 @@ static void ghes_sea_remove(struct ghes *ghes) | |||
851 | synchronize_rcu(); | 807 | synchronize_rcu(); |
852 | } | 808 | } |
853 | #else /* CONFIG_ACPI_APEI_SEA */ | 809 | #else /* CONFIG_ACPI_APEI_SEA */ |
854 | static inline void ghes_sea_add(struct ghes *ghes) | 810 | static inline void ghes_sea_add(struct ghes *ghes) { } |
855 | { | 811 | static inline void ghes_sea_remove(struct ghes *ghes) { } |
856 | pr_err(GHES_PFX "ID: %d, trying to add SEA notification which is not supported\n", | ||
857 | ghes->generic->header.source_id); | ||
858 | } | ||
859 | |||
860 | static inline void ghes_sea_remove(struct ghes *ghes) | ||
861 | { | ||
862 | pr_err(GHES_PFX "ID: %d, trying to remove SEA notification which is not supported\n", | ||
863 | ghes->generic->header.source_id); | ||
864 | } | ||
865 | #endif /* CONFIG_ACPI_APEI_SEA */ | 812 | #endif /* CONFIG_ACPI_APEI_SEA */ |
866 | 813 | ||
867 | #ifdef CONFIG_HAVE_ACPI_APEI_NMI | 814 | #ifdef CONFIG_HAVE_ACPI_APEI_NMI |
@@ -1063,23 +1010,9 @@ static void ghes_nmi_init_cxt(void) | |||
1063 | init_irq_work(&ghes_proc_irq_work, ghes_proc_in_irq); | 1010 | init_irq_work(&ghes_proc_irq_work, ghes_proc_in_irq); |
1064 | } | 1011 | } |
1065 | #else /* CONFIG_HAVE_ACPI_APEI_NMI */ | 1012 | #else /* CONFIG_HAVE_ACPI_APEI_NMI */ |
1066 | static inline void ghes_nmi_add(struct ghes *ghes) | 1013 | static inline void ghes_nmi_add(struct ghes *ghes) { } |
1067 | { | 1014 | static inline void ghes_nmi_remove(struct ghes *ghes) { } |
1068 | pr_err(GHES_PFX "ID: %d, trying to add NMI notification which is not supported!\n", | 1015 | static inline void ghes_nmi_init_cxt(void) { } |
1069 | ghes->generic->header.source_id); | ||
1070 | BUG(); | ||
1071 | } | ||
1072 | |||
1073 | static inline void ghes_nmi_remove(struct ghes *ghes) | ||
1074 | { | ||
1075 | pr_err(GHES_PFX "ID: %d, trying to remove NMI notification which is not supported!\n", | ||
1076 | ghes->generic->header.source_id); | ||
1077 | BUG(); | ||
1078 | } | ||
1079 | |||
1080 | static inline void ghes_nmi_init_cxt(void) | ||
1081 | { | ||
1082 | } | ||
1083 | #endif /* CONFIG_HAVE_ACPI_APEI_NMI */ | 1016 | #endif /* CONFIG_HAVE_ACPI_APEI_NMI */ |
1084 | 1017 | ||
1085 | static int ghes_probe(struct platform_device *ghes_dev) | 1018 | static int ghes_probe(struct platform_device *ghes_dev) |
@@ -1284,13 +1217,9 @@ static int __init ghes_init(void) | |||
1284 | 1217 | ||
1285 | ghes_nmi_init_cxt(); | 1218 | ghes_nmi_init_cxt(); |
1286 | 1219 | ||
1287 | rc = ghes_ioremap_init(); | ||
1288 | if (rc) | ||
1289 | goto err; | ||
1290 | |||
1291 | rc = ghes_estatus_pool_init(); | 1220 | rc = ghes_estatus_pool_init(); |
1292 | if (rc) | 1221 | if (rc) |
1293 | goto err_ioremap_exit; | 1222 | goto err; |
1294 | 1223 | ||
1295 | rc = ghes_estatus_pool_expand(GHES_ESTATUS_CACHE_AVG_SIZE * | 1224 | rc = ghes_estatus_pool_expand(GHES_ESTATUS_CACHE_AVG_SIZE * |
1296 | GHES_ESTATUS_CACHE_ALLOCED_MAX); | 1225 | GHES_ESTATUS_CACHE_ALLOCED_MAX); |
@@ -1314,8 +1243,6 @@ static int __init ghes_init(void) | |||
1314 | return 0; | 1243 | return 0; |
1315 | err_pool_exit: | 1244 | err_pool_exit: |
1316 | ghes_estatus_pool_exit(); | 1245 | ghes_estatus_pool_exit(); |
1317 | err_ioremap_exit: | ||
1318 | ghes_ioremap_exit(); | ||
1319 | err: | 1246 | err: |
1320 | return rc; | 1247 | return rc; |
1321 | } | 1248 | } |
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index ef1856b15488..c391898b483c 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -390,6 +390,7 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) | |||
390 | { | 390 | { |
391 | struct acpi_button *button = acpi_driver_data(device); | 391 | struct acpi_button *button = acpi_driver_data(device); |
392 | struct input_dev *input; | 392 | struct input_dev *input; |
393 | int users; | ||
393 | 394 | ||
394 | switch (event) { | 395 | switch (event) { |
395 | case ACPI_FIXED_HARDWARE_EVENT: | 396 | case ACPI_FIXED_HARDWARE_EVENT: |
@@ -398,7 +399,11 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) | |||
398 | case ACPI_BUTTON_NOTIFY_STATUS: | 399 | case ACPI_BUTTON_NOTIFY_STATUS: |
399 | input = button->input; | 400 | input = button->input; |
400 | if (button->type == ACPI_BUTTON_TYPE_LID) { | 401 | if (button->type == ACPI_BUTTON_TYPE_LID) { |
401 | acpi_lid_update_state(device); | 402 | mutex_lock(&button->input->mutex); |
403 | users = button->input->users; | ||
404 | mutex_unlock(&button->input->mutex); | ||
405 | if (users) | ||
406 | acpi_lid_update_state(device); | ||
402 | } else { | 407 | } else { |
403 | int keycode; | 408 | int keycode; |
404 | 409 | ||
@@ -442,12 +447,24 @@ static int acpi_button_resume(struct device *dev) | |||
442 | struct acpi_button *button = acpi_driver_data(device); | 447 | struct acpi_button *button = acpi_driver_data(device); |
443 | 448 | ||
444 | button->suspended = false; | 449 | button->suspended = false; |
445 | if (button->type == ACPI_BUTTON_TYPE_LID) | 450 | if (button->type == ACPI_BUTTON_TYPE_LID && button->input->users) |
446 | acpi_lid_initialize_state(device); | 451 | acpi_lid_initialize_state(device); |
447 | return 0; | 452 | return 0; |
448 | } | 453 | } |
449 | #endif | 454 | #endif |
450 | 455 | ||
456 | static int acpi_lid_input_open(struct input_dev *input) | ||
457 | { | ||
458 | struct acpi_device *device = input_get_drvdata(input); | ||
459 | struct acpi_button *button = acpi_driver_data(device); | ||
460 | |||
461 | button->last_state = !!acpi_lid_evaluate_state(device); | ||
462 | button->last_time = ktime_get(); | ||
463 | acpi_lid_initialize_state(device); | ||
464 | |||
465 | return 0; | ||
466 | } | ||
467 | |||
451 | static int acpi_button_add(struct acpi_device *device) | 468 | static int acpi_button_add(struct acpi_device *device) |
452 | { | 469 | { |
453 | struct acpi_button *button; | 470 | struct acpi_button *button; |
@@ -488,8 +505,7 @@ static int acpi_button_add(struct acpi_device *device) | |||
488 | strcpy(name, ACPI_BUTTON_DEVICE_NAME_LID); | 505 | strcpy(name, ACPI_BUTTON_DEVICE_NAME_LID); |
489 | sprintf(class, "%s/%s", | 506 | sprintf(class, "%s/%s", |
490 | ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_LID); | 507 | ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_LID); |
491 | button->last_state = !!acpi_lid_evaluate_state(device); | 508 | input->open = acpi_lid_input_open; |
492 | button->last_time = ktime_get(); | ||
493 | } else { | 509 | } else { |
494 | printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", hid); | 510 | printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", hid); |
495 | error = -ENODEV; | 511 | error = -ENODEV; |
@@ -522,11 +538,11 @@ static int acpi_button_add(struct acpi_device *device) | |||
522 | break; | 538 | break; |
523 | } | 539 | } |
524 | 540 | ||
541 | input_set_drvdata(input, device); | ||
525 | error = input_register_device(input); | 542 | error = input_register_device(input); |
526 | if (error) | 543 | if (error) |
527 | goto err_remove_fs; | 544 | goto err_remove_fs; |
528 | if (button->type == ACPI_BUTTON_TYPE_LID) { | 545 | if (button->type == ACPI_BUTTON_TYPE_LID) { |
529 | acpi_lid_initialize_state(device); | ||
530 | /* | 546 | /* |
531 | * This assumes there's only one lid device, or if there are | 547 | * This assumes there's only one lid device, or if there are |
532 | * more we only care about the last one... | 548 | * more we only care about the last one... |
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index e5b47f032d9a..21c28433c590 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c | |||
@@ -48,7 +48,6 @@ | |||
48 | struct cppc_pcc_data { | 48 | struct cppc_pcc_data { |
49 | struct mbox_chan *pcc_channel; | 49 | struct mbox_chan *pcc_channel; |
50 | void __iomem *pcc_comm_addr; | 50 | void __iomem *pcc_comm_addr; |
51 | int pcc_subspace_idx; | ||
52 | bool pcc_channel_acquired; | 51 | bool pcc_channel_acquired; |
53 | ktime_t deadline; | 52 | ktime_t deadline; |
54 | unsigned int pcc_mpar, pcc_mrtt, pcc_nominal; | 53 | unsigned int pcc_mpar, pcc_mrtt, pcc_nominal; |
@@ -75,13 +74,16 @@ struct cppc_pcc_data { | |||
75 | 74 | ||
76 | /* Wait queue for CPUs whose requests were batched */ | 75 | /* Wait queue for CPUs whose requests were batched */ |
77 | wait_queue_head_t pcc_write_wait_q; | 76 | wait_queue_head_t pcc_write_wait_q; |
77 | ktime_t last_cmd_cmpl_time; | ||
78 | ktime_t last_mpar_reset; | ||
79 | int mpar_count; | ||
80 | int refcount; | ||
78 | }; | 81 | }; |
79 | 82 | ||
80 | /* Structure to represent the single PCC channel */ | 83 | /* Array to represent the PCC channel per subspace id */ |
81 | static struct cppc_pcc_data pcc_data = { | 84 | static struct cppc_pcc_data *pcc_data[MAX_PCC_SUBSPACES]; |
82 | .pcc_subspace_idx = -1, | 85 | /* The cpu_pcc_subspace_idx containsper CPU subspace id */ |
83 | .platform_owns_pcc = true, | 86 | static DEFINE_PER_CPU(int, cpu_pcc_subspace_idx); |
84 | }; | ||
85 | 87 | ||
86 | /* | 88 | /* |
87 | * The cpc_desc structure contains the ACPI register details | 89 | * The cpc_desc structure contains the ACPI register details |
@@ -93,7 +95,8 @@ static struct cppc_pcc_data pcc_data = { | |||
93 | static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr); | 95 | static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr); |
94 | 96 | ||
95 | /* pcc mapped address + header size + offset within PCC subspace */ | 97 | /* pcc mapped address + header size + offset within PCC subspace */ |
96 | #define GET_PCC_VADDR(offs) (pcc_data.pcc_comm_addr + 0x8 + (offs)) | 98 | #define GET_PCC_VADDR(offs, pcc_ss_id) (pcc_data[pcc_ss_id]->pcc_comm_addr + \ |
99 | 0x8 + (offs)) | ||
97 | 100 | ||
98 | /* Check if a CPC register is in PCC */ | 101 | /* Check if a CPC register is in PCC */ |
99 | #define CPC_IN_PCC(cpc) ((cpc)->type == ACPI_TYPE_BUFFER && \ | 102 | #define CPC_IN_PCC(cpc) ((cpc)->type == ACPI_TYPE_BUFFER && \ |
@@ -188,13 +191,16 @@ static struct kobj_type cppc_ktype = { | |||
188 | .default_attrs = cppc_attrs, | 191 | .default_attrs = cppc_attrs, |
189 | }; | 192 | }; |
190 | 193 | ||
191 | static int check_pcc_chan(bool chk_err_bit) | 194 | static int check_pcc_chan(int pcc_ss_id, bool chk_err_bit) |
192 | { | 195 | { |
193 | int ret = -EIO, status = 0; | 196 | int ret = -EIO, status = 0; |
194 | struct acpi_pcct_shared_memory __iomem *generic_comm_base = pcc_data.pcc_comm_addr; | 197 | struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id]; |
195 | ktime_t next_deadline = ktime_add(ktime_get(), pcc_data.deadline); | 198 | struct acpi_pcct_shared_memory __iomem *generic_comm_base = |
199 | pcc_ss_data->pcc_comm_addr; | ||
200 | ktime_t next_deadline = ktime_add(ktime_get(), | ||
201 | pcc_ss_data->deadline); | ||
196 | 202 | ||
197 | if (!pcc_data.platform_owns_pcc) | 203 | if (!pcc_ss_data->platform_owns_pcc) |
198 | return 0; | 204 | return 0; |
199 | 205 | ||
200 | /* Retry in case the remote processor was too slow to catch up. */ | 206 | /* Retry in case the remote processor was too slow to catch up. */ |
@@ -219,7 +225,7 @@ static int check_pcc_chan(bool chk_err_bit) | |||
219 | } | 225 | } |
220 | 226 | ||
221 | if (likely(!ret)) | 227 | if (likely(!ret)) |
222 | pcc_data.platform_owns_pcc = false; | 228 | pcc_ss_data->platform_owns_pcc = false; |
223 | else | 229 | else |
224 | pr_err("PCC check channel failed. Status=%x\n", status); | 230 | pr_err("PCC check channel failed. Status=%x\n", status); |
225 | 231 | ||
@@ -230,13 +236,12 @@ static int check_pcc_chan(bool chk_err_bit) | |||
230 | * This function transfers the ownership of the PCC to the platform | 236 | * This function transfers the ownership of the PCC to the platform |
231 | * So it must be called while holding write_lock(pcc_lock) | 237 | * So it must be called while holding write_lock(pcc_lock) |
232 | */ | 238 | */ |
233 | static int send_pcc_cmd(u16 cmd) | 239 | static int send_pcc_cmd(int pcc_ss_id, u16 cmd) |
234 | { | 240 | { |
235 | int ret = -EIO, i; | 241 | int ret = -EIO, i; |
242 | struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id]; | ||
236 | struct acpi_pcct_shared_memory *generic_comm_base = | 243 | struct acpi_pcct_shared_memory *generic_comm_base = |
237 | (struct acpi_pcct_shared_memory *) pcc_data.pcc_comm_addr; | 244 | (struct acpi_pcct_shared_memory *)pcc_ss_data->pcc_comm_addr; |
238 | static ktime_t last_cmd_cmpl_time, last_mpar_reset; | ||
239 | static int mpar_count; | ||
240 | unsigned int time_delta; | 245 | unsigned int time_delta; |
241 | 246 | ||
242 | /* | 247 | /* |
@@ -249,24 +254,25 @@ static int send_pcc_cmd(u16 cmd) | |||
249 | * before write completion, so first send a WRITE command to | 254 | * before write completion, so first send a WRITE command to |
250 | * platform | 255 | * platform |
251 | */ | 256 | */ |
252 | if (pcc_data.pending_pcc_write_cmd) | 257 | if (pcc_ss_data->pending_pcc_write_cmd) |
253 | send_pcc_cmd(CMD_WRITE); | 258 | send_pcc_cmd(pcc_ss_id, CMD_WRITE); |
254 | 259 | ||
255 | ret = check_pcc_chan(false); | 260 | ret = check_pcc_chan(pcc_ss_id, false); |
256 | if (ret) | 261 | if (ret) |
257 | goto end; | 262 | goto end; |
258 | } else /* CMD_WRITE */ | 263 | } else /* CMD_WRITE */ |
259 | pcc_data.pending_pcc_write_cmd = FALSE; | 264 | pcc_ss_data->pending_pcc_write_cmd = FALSE; |
260 | 265 | ||
261 | /* | 266 | /* |
262 | * Handle the Minimum Request Turnaround Time(MRTT) | 267 | * Handle the Minimum Request Turnaround Time(MRTT) |
263 | * "The minimum amount of time that OSPM must wait after the completion | 268 | * "The minimum amount of time that OSPM must wait after the completion |
264 | * of a command before issuing the next command, in microseconds" | 269 | * of a command before issuing the next command, in microseconds" |
265 | */ | 270 | */ |
266 | if (pcc_data.pcc_mrtt) { | 271 | if (pcc_ss_data->pcc_mrtt) { |
267 | time_delta = ktime_us_delta(ktime_get(), last_cmd_cmpl_time); | 272 | time_delta = ktime_us_delta(ktime_get(), |
268 | if (pcc_data.pcc_mrtt > time_delta) | 273 | pcc_ss_data->last_cmd_cmpl_time); |
269 | udelay(pcc_data.pcc_mrtt - time_delta); | 274 | if (pcc_ss_data->pcc_mrtt > time_delta) |
275 | udelay(pcc_ss_data->pcc_mrtt - time_delta); | ||
270 | } | 276 | } |
271 | 277 | ||
272 | /* | 278 | /* |
@@ -280,18 +286,19 @@ static int send_pcc_cmd(u16 cmd) | |||
280 | * not send the request to the platform after hitting the MPAR limit in | 286 | * not send the request to the platform after hitting the MPAR limit in |
281 | * any 60s window | 287 | * any 60s window |
282 | */ | 288 | */ |
283 | if (pcc_data.pcc_mpar) { | 289 | if (pcc_ss_data->pcc_mpar) { |
284 | if (mpar_count == 0) { | 290 | if (pcc_ss_data->mpar_count == 0) { |
285 | time_delta = ktime_ms_delta(ktime_get(), last_mpar_reset); | 291 | time_delta = ktime_ms_delta(ktime_get(), |
286 | if (time_delta < 60 * MSEC_PER_SEC) { | 292 | pcc_ss_data->last_mpar_reset); |
293 | if ((time_delta < 60 * MSEC_PER_SEC) && pcc_ss_data->last_mpar_reset) { | ||
287 | pr_debug("PCC cmd not sent due to MPAR limit"); | 294 | pr_debug("PCC cmd not sent due to MPAR limit"); |
288 | ret = -EIO; | 295 | ret = -EIO; |
289 | goto end; | 296 | goto end; |
290 | } | 297 | } |
291 | last_mpar_reset = ktime_get(); | 298 | pcc_ss_data->last_mpar_reset = ktime_get(); |
292 | mpar_count = pcc_data.pcc_mpar; | 299 | pcc_ss_data->mpar_count = pcc_ss_data->pcc_mpar; |
293 | } | 300 | } |
294 | mpar_count--; | 301 | pcc_ss_data->mpar_count--; |
295 | } | 302 | } |
296 | 303 | ||
297 | /* Write to the shared comm region. */ | 304 | /* Write to the shared comm region. */ |
@@ -300,10 +307,10 @@ static int send_pcc_cmd(u16 cmd) | |||
300 | /* Flip CMD COMPLETE bit */ | 307 | /* Flip CMD COMPLETE bit */ |
301 | writew_relaxed(0, &generic_comm_base->status); | 308 | writew_relaxed(0, &generic_comm_base->status); |
302 | 309 | ||
303 | pcc_data.platform_owns_pcc = true; | 310 | pcc_ss_data->platform_owns_pcc = true; |
304 | 311 | ||
305 | /* Ring doorbell */ | 312 | /* Ring doorbell */ |
306 | ret = mbox_send_message(pcc_data.pcc_channel, &cmd); | 313 | ret = mbox_send_message(pcc_ss_data->pcc_channel, &cmd); |
307 | if (ret < 0) { | 314 | if (ret < 0) { |
308 | pr_err("Err sending PCC mbox message. cmd:%d, ret:%d\n", | 315 | pr_err("Err sending PCC mbox message. cmd:%d, ret:%d\n", |
309 | cmd, ret); | 316 | cmd, ret); |
@@ -311,15 +318,15 @@ static int send_pcc_cmd(u16 cmd) | |||
311 | } | 318 | } |
312 | 319 | ||
313 | /* wait for completion and check for PCC errro bit */ | 320 | /* wait for completion and check for PCC errro bit */ |
314 | ret = check_pcc_chan(true); | 321 | ret = check_pcc_chan(pcc_ss_id, true); |
315 | 322 | ||
316 | if (pcc_data.pcc_mrtt) | 323 | if (pcc_ss_data->pcc_mrtt) |
317 | last_cmd_cmpl_time = ktime_get(); | 324 | pcc_ss_data->last_cmd_cmpl_time = ktime_get(); |
318 | 325 | ||
319 | if (pcc_data.pcc_channel->mbox->txdone_irq) | 326 | if (pcc_ss_data->pcc_channel->mbox->txdone_irq) |
320 | mbox_chan_txdone(pcc_data.pcc_channel, ret); | 327 | mbox_chan_txdone(pcc_ss_data->pcc_channel, ret); |
321 | else | 328 | else |
322 | mbox_client_txdone(pcc_data.pcc_channel, ret); | 329 | mbox_client_txdone(pcc_ss_data->pcc_channel, ret); |
323 | 330 | ||
324 | end: | 331 | end: |
325 | if (cmd == CMD_WRITE) { | 332 | if (cmd == CMD_WRITE) { |
@@ -329,12 +336,12 @@ end: | |||
329 | if (!desc) | 336 | if (!desc) |
330 | continue; | 337 | continue; |
331 | 338 | ||
332 | if (desc->write_cmd_id == pcc_data.pcc_write_cnt) | 339 | if (desc->write_cmd_id == pcc_ss_data->pcc_write_cnt) |
333 | desc->write_cmd_status = ret; | 340 | desc->write_cmd_status = ret; |
334 | } | 341 | } |
335 | } | 342 | } |
336 | pcc_data.pcc_write_cnt++; | 343 | pcc_ss_data->pcc_write_cnt++; |
337 | wake_up_all(&pcc_data.pcc_write_wait_q); | 344 | wake_up_all(&pcc_ss_data->pcc_write_wait_q); |
338 | } | 345 | } |
339 | 346 | ||
340 | return ret; | 347 | return ret; |
@@ -536,16 +543,16 @@ err_ret: | |||
536 | } | 543 | } |
537 | EXPORT_SYMBOL_GPL(acpi_get_psd_map); | 544 | EXPORT_SYMBOL_GPL(acpi_get_psd_map); |
538 | 545 | ||
539 | static int register_pcc_channel(int pcc_subspace_idx) | 546 | static int register_pcc_channel(int pcc_ss_idx) |
540 | { | 547 | { |
541 | struct acpi_pcct_hw_reduced *cppc_ss; | 548 | struct acpi_pcct_hw_reduced *cppc_ss; |
542 | u64 usecs_lat; | 549 | u64 usecs_lat; |
543 | 550 | ||
544 | if (pcc_subspace_idx >= 0) { | 551 | if (pcc_ss_idx >= 0) { |
545 | pcc_data.pcc_channel = pcc_mbox_request_channel(&cppc_mbox_cl, | 552 | pcc_data[pcc_ss_idx]->pcc_channel = |
546 | pcc_subspace_idx); | 553 | pcc_mbox_request_channel(&cppc_mbox_cl, pcc_ss_idx); |
547 | 554 | ||
548 | if (IS_ERR(pcc_data.pcc_channel)) { | 555 | if (IS_ERR(pcc_data[pcc_ss_idx]->pcc_channel)) { |
549 | pr_err("Failed to find PCC communication channel\n"); | 556 | pr_err("Failed to find PCC communication channel\n"); |
550 | return -ENODEV; | 557 | return -ENODEV; |
551 | } | 558 | } |
@@ -556,7 +563,7 @@ static int register_pcc_channel(int pcc_subspace_idx) | |||
556 | * PCC channels) and stored pointers to the | 563 | * PCC channels) and stored pointers to the |
557 | * subspace communication region in con_priv. | 564 | * subspace communication region in con_priv. |
558 | */ | 565 | */ |
559 | cppc_ss = (pcc_data.pcc_channel)->con_priv; | 566 | cppc_ss = (pcc_data[pcc_ss_idx]->pcc_channel)->con_priv; |
560 | 567 | ||
561 | if (!cppc_ss) { | 568 | if (!cppc_ss) { |
562 | pr_err("No PCC subspace found for CPPC\n"); | 569 | pr_err("No PCC subspace found for CPPC\n"); |
@@ -569,19 +576,20 @@ static int register_pcc_channel(int pcc_subspace_idx) | |||
569 | * So add an arbitrary amount of wait on top of Nominal. | 576 | * So add an arbitrary amount of wait on top of Nominal. |
570 | */ | 577 | */ |
571 | usecs_lat = NUM_RETRIES * cppc_ss->latency; | 578 | usecs_lat = NUM_RETRIES * cppc_ss->latency; |
572 | pcc_data.deadline = ns_to_ktime(usecs_lat * NSEC_PER_USEC); | 579 | pcc_data[pcc_ss_idx]->deadline = ns_to_ktime(usecs_lat * NSEC_PER_USEC); |
573 | pcc_data.pcc_mrtt = cppc_ss->min_turnaround_time; | 580 | pcc_data[pcc_ss_idx]->pcc_mrtt = cppc_ss->min_turnaround_time; |
574 | pcc_data.pcc_mpar = cppc_ss->max_access_rate; | 581 | pcc_data[pcc_ss_idx]->pcc_mpar = cppc_ss->max_access_rate; |
575 | pcc_data.pcc_nominal = cppc_ss->latency; | 582 | pcc_data[pcc_ss_idx]->pcc_nominal = cppc_ss->latency; |
576 | 583 | ||
577 | pcc_data.pcc_comm_addr = acpi_os_ioremap(cppc_ss->base_address, cppc_ss->length); | 584 | pcc_data[pcc_ss_idx]->pcc_comm_addr = |
578 | if (!pcc_data.pcc_comm_addr) { | 585 | acpi_os_ioremap(cppc_ss->base_address, cppc_ss->length); |
586 | if (!pcc_data[pcc_ss_idx]->pcc_comm_addr) { | ||
579 | pr_err("Failed to ioremap PCC comm region mem\n"); | 587 | pr_err("Failed to ioremap PCC comm region mem\n"); |
580 | return -ENOMEM; | 588 | return -ENOMEM; |
581 | } | 589 | } |
582 | 590 | ||
583 | /* Set flag so that we dont come here for each CPU. */ | 591 | /* Set flag so that we dont come here for each CPU. */ |
584 | pcc_data.pcc_channel_acquired = true; | 592 | pcc_data[pcc_ss_idx]->pcc_channel_acquired = true; |
585 | } | 593 | } |
586 | 594 | ||
587 | return 0; | 595 | return 0; |
@@ -600,6 +608,34 @@ bool __weak cpc_ffh_supported(void) | |||
600 | return false; | 608 | return false; |
601 | } | 609 | } |
602 | 610 | ||
611 | |||
612 | /** | ||
613 | * pcc_data_alloc() - Allocate the pcc_data memory for pcc subspace | ||
614 | * | ||
615 | * Check and allocate the cppc_pcc_data memory. | ||
616 | * In some processor configurations it is possible that same subspace | ||
617 | * is shared between multiple CPU's. This is seen especially in CPU's | ||
618 | * with hardware multi-threading support. | ||
619 | * | ||
620 | * Return: 0 for success, errno for failure | ||
621 | */ | ||
622 | int pcc_data_alloc(int pcc_ss_id) | ||
623 | { | ||
624 | if (pcc_ss_id < 0 || pcc_ss_id >= MAX_PCC_SUBSPACES) | ||
625 | return -EINVAL; | ||
626 | |||
627 | if (pcc_data[pcc_ss_id]) { | ||
628 | pcc_data[pcc_ss_id]->refcount++; | ||
629 | } else { | ||
630 | pcc_data[pcc_ss_id] = kzalloc(sizeof(struct cppc_pcc_data), | ||
631 | GFP_KERNEL); | ||
632 | if (!pcc_data[pcc_ss_id]) | ||
633 | return -ENOMEM; | ||
634 | pcc_data[pcc_ss_id]->refcount++; | ||
635 | } | ||
636 | |||
637 | return 0; | ||
638 | } | ||
603 | /* | 639 | /* |
604 | * An example CPC table looks like the following. | 640 | * An example CPC table looks like the following. |
605 | * | 641 | * |
@@ -661,6 +697,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) | |||
661 | struct device *cpu_dev; | 697 | struct device *cpu_dev; |
662 | acpi_handle handle = pr->handle; | 698 | acpi_handle handle = pr->handle; |
663 | unsigned int num_ent, i, cpc_rev; | 699 | unsigned int num_ent, i, cpc_rev; |
700 | int pcc_subspace_id = -1; | ||
664 | acpi_status status; | 701 | acpi_status status; |
665 | int ret = -EFAULT; | 702 | int ret = -EFAULT; |
666 | 703 | ||
@@ -733,9 +770,11 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) | |||
733 | * so extract it only once. | 770 | * so extract it only once. |
734 | */ | 771 | */ |
735 | if (gas_t->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { | 772 | if (gas_t->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { |
736 | if (pcc_data.pcc_subspace_idx < 0) | 773 | if (pcc_subspace_id < 0) { |
737 | pcc_data.pcc_subspace_idx = gas_t->access_width; | 774 | pcc_subspace_id = gas_t->access_width; |
738 | else if (pcc_data.pcc_subspace_idx != gas_t->access_width) { | 775 | if (pcc_data_alloc(pcc_subspace_id)) |
776 | goto out_free; | ||
777 | } else if (pcc_subspace_id != gas_t->access_width) { | ||
739 | pr_debug("Mismatched PCC ids.\n"); | 778 | pr_debug("Mismatched PCC ids.\n"); |
740 | goto out_free; | 779 | goto out_free; |
741 | } | 780 | } |
@@ -763,6 +802,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) | |||
763 | goto out_free; | 802 | goto out_free; |
764 | } | 803 | } |
765 | } | 804 | } |
805 | per_cpu(cpu_pcc_subspace_idx, pr->id) = pcc_subspace_id; | ||
766 | /* Store CPU Logical ID */ | 806 | /* Store CPU Logical ID */ |
767 | cpc_ptr->cpu_id = pr->id; | 807 | cpc_ptr->cpu_id = pr->id; |
768 | 808 | ||
@@ -771,14 +811,14 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) | |||
771 | if (ret) | 811 | if (ret) |
772 | goto out_free; | 812 | goto out_free; |
773 | 813 | ||
774 | /* Register PCC channel once for all CPUs. */ | 814 | /* Register PCC channel once for all PCC subspace id. */ |
775 | if (!pcc_data.pcc_channel_acquired) { | 815 | if (pcc_subspace_id >= 0 && !pcc_data[pcc_subspace_id]->pcc_channel_acquired) { |
776 | ret = register_pcc_channel(pcc_data.pcc_subspace_idx); | 816 | ret = register_pcc_channel(pcc_subspace_id); |
777 | if (ret) | 817 | if (ret) |
778 | goto out_free; | 818 | goto out_free; |
779 | 819 | ||
780 | init_rwsem(&pcc_data.pcc_lock); | 820 | init_rwsem(&pcc_data[pcc_subspace_id]->pcc_lock); |
781 | init_waitqueue_head(&pcc_data.pcc_write_wait_q); | 821 | init_waitqueue_head(&pcc_data[pcc_subspace_id]->pcc_write_wait_q); |
782 | } | 822 | } |
783 | 823 | ||
784 | /* Everything looks okay */ | 824 | /* Everything looks okay */ |
@@ -831,6 +871,18 @@ void acpi_cppc_processor_exit(struct acpi_processor *pr) | |||
831 | struct cpc_desc *cpc_ptr; | 871 | struct cpc_desc *cpc_ptr; |
832 | unsigned int i; | 872 | unsigned int i; |
833 | void __iomem *addr; | 873 | void __iomem *addr; |
874 | int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, pr->id); | ||
875 | |||
876 | if (pcc_ss_id >=0 && pcc_data[pcc_ss_id]) { | ||
877 | if (pcc_data[pcc_ss_id]->pcc_channel_acquired) { | ||
878 | pcc_data[pcc_ss_id]->refcount--; | ||
879 | if (!pcc_data[pcc_ss_id]->refcount) { | ||
880 | pcc_mbox_free_channel(pcc_data[pcc_ss_id]->pcc_channel); | ||
881 | pcc_data[pcc_ss_id]->pcc_channel_acquired = 0; | ||
882 | kfree(pcc_data[pcc_ss_id]); | ||
883 | } | ||
884 | } | ||
885 | } | ||
834 | 886 | ||
835 | cpc_ptr = per_cpu(cpc_desc_ptr, pr->id); | 887 | cpc_ptr = per_cpu(cpc_desc_ptr, pr->id); |
836 | if (!cpc_ptr) | 888 | if (!cpc_ptr) |
@@ -888,6 +940,7 @@ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val) | |||
888 | { | 940 | { |
889 | int ret_val = 0; | 941 | int ret_val = 0; |
890 | void __iomem *vaddr = 0; | 942 | void __iomem *vaddr = 0; |
943 | int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); | ||
891 | struct cpc_reg *reg = ®_res->cpc_entry.reg; | 944 | struct cpc_reg *reg = ®_res->cpc_entry.reg; |
892 | 945 | ||
893 | if (reg_res->type == ACPI_TYPE_INTEGER) { | 946 | if (reg_res->type == ACPI_TYPE_INTEGER) { |
@@ -897,7 +950,7 @@ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val) | |||
897 | 950 | ||
898 | *val = 0; | 951 | *val = 0; |
899 | if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) | 952 | if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) |
900 | vaddr = GET_PCC_VADDR(reg->address); | 953 | vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id); |
901 | else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) | 954 | else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) |
902 | vaddr = reg_res->sys_mem_vaddr; | 955 | vaddr = reg_res->sys_mem_vaddr; |
903 | else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) | 956 | else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) |
@@ -932,10 +985,11 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) | |||
932 | { | 985 | { |
933 | int ret_val = 0; | 986 | int ret_val = 0; |
934 | void __iomem *vaddr = 0; | 987 | void __iomem *vaddr = 0; |
988 | int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); | ||
935 | struct cpc_reg *reg = ®_res->cpc_entry.reg; | 989 | struct cpc_reg *reg = ®_res->cpc_entry.reg; |
936 | 990 | ||
937 | if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) | 991 | if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) |
938 | vaddr = GET_PCC_VADDR(reg->address); | 992 | vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id); |
939 | else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) | 993 | else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) |
940 | vaddr = reg_res->sys_mem_vaddr; | 994 | vaddr = reg_res->sys_mem_vaddr; |
941 | else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) | 995 | else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) |
@@ -980,6 +1034,8 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps) | |||
980 | struct cpc_register_resource *highest_reg, *lowest_reg, | 1034 | struct cpc_register_resource *highest_reg, *lowest_reg, |
981 | *lowest_non_linear_reg, *nominal_reg; | 1035 | *lowest_non_linear_reg, *nominal_reg; |
982 | u64 high, low, nom, min_nonlinear; | 1036 | u64 high, low, nom, min_nonlinear; |
1037 | int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum); | ||
1038 | struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id]; | ||
983 | int ret = 0, regs_in_pcc = 0; | 1039 | int ret = 0, regs_in_pcc = 0; |
984 | 1040 | ||
985 | if (!cpc_desc) { | 1041 | if (!cpc_desc) { |
@@ -996,9 +1052,9 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps) | |||
996 | if (CPC_IN_PCC(highest_reg) || CPC_IN_PCC(lowest_reg) || | 1052 | if (CPC_IN_PCC(highest_reg) || CPC_IN_PCC(lowest_reg) || |
997 | CPC_IN_PCC(lowest_non_linear_reg) || CPC_IN_PCC(nominal_reg)) { | 1053 | CPC_IN_PCC(lowest_non_linear_reg) || CPC_IN_PCC(nominal_reg)) { |
998 | regs_in_pcc = 1; | 1054 | regs_in_pcc = 1; |
999 | down_write(&pcc_data.pcc_lock); | 1055 | down_write(&pcc_ss_data->pcc_lock); |
1000 | /* Ring doorbell once to update PCC subspace */ | 1056 | /* Ring doorbell once to update PCC subspace */ |
1001 | if (send_pcc_cmd(CMD_READ) < 0) { | 1057 | if (send_pcc_cmd(pcc_ss_id, CMD_READ) < 0) { |
1002 | ret = -EIO; | 1058 | ret = -EIO; |
1003 | goto out_err; | 1059 | goto out_err; |
1004 | } | 1060 | } |
@@ -1021,7 +1077,7 @@ int cppc_get_perf_caps(int cpunum, struct cppc_perf_caps *perf_caps) | |||
1021 | 1077 | ||
1022 | out_err: | 1078 | out_err: |
1023 | if (regs_in_pcc) | 1079 | if (regs_in_pcc) |
1024 | up_write(&pcc_data.pcc_lock); | 1080 | up_write(&pcc_ss_data->pcc_lock); |
1025 | return ret; | 1081 | return ret; |
1026 | } | 1082 | } |
1027 | EXPORT_SYMBOL_GPL(cppc_get_perf_caps); | 1083 | EXPORT_SYMBOL_GPL(cppc_get_perf_caps); |
@@ -1038,6 +1094,8 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs) | |||
1038 | struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum); | 1094 | struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum); |
1039 | struct cpc_register_resource *delivered_reg, *reference_reg, | 1095 | struct cpc_register_resource *delivered_reg, *reference_reg, |
1040 | *ref_perf_reg, *ctr_wrap_reg; | 1096 | *ref_perf_reg, *ctr_wrap_reg; |
1097 | int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum); | ||
1098 | struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id]; | ||
1041 | u64 delivered, reference, ref_perf, ctr_wrap_time; | 1099 | u64 delivered, reference, ref_perf, ctr_wrap_time; |
1042 | int ret = 0, regs_in_pcc = 0; | 1100 | int ret = 0, regs_in_pcc = 0; |
1043 | 1101 | ||
@@ -1061,10 +1119,10 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs) | |||
1061 | /* Are any of the regs PCC ?*/ | 1119 | /* Are any of the regs PCC ?*/ |
1062 | if (CPC_IN_PCC(delivered_reg) || CPC_IN_PCC(reference_reg) || | 1120 | if (CPC_IN_PCC(delivered_reg) || CPC_IN_PCC(reference_reg) || |
1063 | CPC_IN_PCC(ctr_wrap_reg) || CPC_IN_PCC(ref_perf_reg)) { | 1121 | CPC_IN_PCC(ctr_wrap_reg) || CPC_IN_PCC(ref_perf_reg)) { |
1064 | down_write(&pcc_data.pcc_lock); | 1122 | down_write(&pcc_ss_data->pcc_lock); |
1065 | regs_in_pcc = 1; | 1123 | regs_in_pcc = 1; |
1066 | /* Ring doorbell once to update PCC subspace */ | 1124 | /* Ring doorbell once to update PCC subspace */ |
1067 | if (send_pcc_cmd(CMD_READ) < 0) { | 1125 | if (send_pcc_cmd(pcc_ss_id, CMD_READ) < 0) { |
1068 | ret = -EIO; | 1126 | ret = -EIO; |
1069 | goto out_err; | 1127 | goto out_err; |
1070 | } | 1128 | } |
@@ -1094,7 +1152,7 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs) | |||
1094 | perf_fb_ctrs->wraparound_time = ctr_wrap_time; | 1152 | perf_fb_ctrs->wraparound_time = ctr_wrap_time; |
1095 | out_err: | 1153 | out_err: |
1096 | if (regs_in_pcc) | 1154 | if (regs_in_pcc) |
1097 | up_write(&pcc_data.pcc_lock); | 1155 | up_write(&pcc_ss_data->pcc_lock); |
1098 | return ret; | 1156 | return ret; |
1099 | } | 1157 | } |
1100 | EXPORT_SYMBOL_GPL(cppc_get_perf_ctrs); | 1158 | EXPORT_SYMBOL_GPL(cppc_get_perf_ctrs); |
@@ -1110,6 +1168,8 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) | |||
1110 | { | 1168 | { |
1111 | struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu); | 1169 | struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu); |
1112 | struct cpc_register_resource *desired_reg; | 1170 | struct cpc_register_resource *desired_reg; |
1171 | int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); | ||
1172 | struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id]; | ||
1113 | int ret = 0; | 1173 | int ret = 0; |
1114 | 1174 | ||
1115 | if (!cpc_desc) { | 1175 | if (!cpc_desc) { |
@@ -1127,11 +1187,11 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) | |||
1127 | * achieve that goal here | 1187 | * achieve that goal here |
1128 | */ | 1188 | */ |
1129 | if (CPC_IN_PCC(desired_reg)) { | 1189 | if (CPC_IN_PCC(desired_reg)) { |
1130 | down_read(&pcc_data.pcc_lock); /* BEGIN Phase-I */ | 1190 | down_read(&pcc_ss_data->pcc_lock); /* BEGIN Phase-I */ |
1131 | if (pcc_data.platform_owns_pcc) { | 1191 | if (pcc_ss_data->platform_owns_pcc) { |
1132 | ret = check_pcc_chan(false); | 1192 | ret = check_pcc_chan(pcc_ss_id, false); |
1133 | if (ret) { | 1193 | if (ret) { |
1134 | up_read(&pcc_data.pcc_lock); | 1194 | up_read(&pcc_ss_data->pcc_lock); |
1135 | return ret; | 1195 | return ret; |
1136 | } | 1196 | } |
1137 | } | 1197 | } |
@@ -1139,8 +1199,8 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) | |||
1139 | * Update the pending_write to make sure a PCC CMD_READ will not | 1199 | * Update the pending_write to make sure a PCC CMD_READ will not |
1140 | * arrive and steal the channel during the switch to write lock | 1200 | * arrive and steal the channel during the switch to write lock |
1141 | */ | 1201 | */ |
1142 | pcc_data.pending_pcc_write_cmd = true; | 1202 | pcc_ss_data->pending_pcc_write_cmd = true; |
1143 | cpc_desc->write_cmd_id = pcc_data.pcc_write_cnt; | 1203 | cpc_desc->write_cmd_id = pcc_ss_data->pcc_write_cnt; |
1144 | cpc_desc->write_cmd_status = 0; | 1204 | cpc_desc->write_cmd_status = 0; |
1145 | } | 1205 | } |
1146 | 1206 | ||
@@ -1151,7 +1211,7 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) | |||
1151 | cpc_write(cpu, desired_reg, perf_ctrls->desired_perf); | 1211 | cpc_write(cpu, desired_reg, perf_ctrls->desired_perf); |
1152 | 1212 | ||
1153 | if (CPC_IN_PCC(desired_reg)) | 1213 | if (CPC_IN_PCC(desired_reg)) |
1154 | up_read(&pcc_data.pcc_lock); /* END Phase-I */ | 1214 | up_read(&pcc_ss_data->pcc_lock); /* END Phase-I */ |
1155 | /* | 1215 | /* |
1156 | * This is Phase-II where we transfer the ownership of PCC to Platform | 1216 | * This is Phase-II where we transfer the ownership of PCC to Platform |
1157 | * | 1217 | * |
@@ -1199,15 +1259,15 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) | |||
1199 | * the write command before servicing the read command | 1259 | * the write command before servicing the read command |
1200 | */ | 1260 | */ |
1201 | if (CPC_IN_PCC(desired_reg)) { | 1261 | if (CPC_IN_PCC(desired_reg)) { |
1202 | if (down_write_trylock(&pcc_data.pcc_lock)) { /* BEGIN Phase-II */ | 1262 | if (down_write_trylock(&pcc_ss_data->pcc_lock)) {/* BEGIN Phase-II */ |
1203 | /* Update only if there are pending write commands */ | 1263 | /* Update only if there are pending write commands */ |
1204 | if (pcc_data.pending_pcc_write_cmd) | 1264 | if (pcc_ss_data->pending_pcc_write_cmd) |
1205 | send_pcc_cmd(CMD_WRITE); | 1265 | send_pcc_cmd(pcc_ss_id, CMD_WRITE); |
1206 | up_write(&pcc_data.pcc_lock); /* END Phase-II */ | 1266 | up_write(&pcc_ss_data->pcc_lock); /* END Phase-II */ |
1207 | } else | 1267 | } else |
1208 | /* Wait until pcc_write_cnt is updated by send_pcc_cmd */ | 1268 | /* Wait until pcc_write_cnt is updated by send_pcc_cmd */ |
1209 | wait_event(pcc_data.pcc_write_wait_q, | 1269 | wait_event(pcc_ss_data->pcc_write_wait_q, |
1210 | cpc_desc->write_cmd_id != pcc_data.pcc_write_cnt); | 1270 | cpc_desc->write_cmd_id != pcc_ss_data->pcc_write_cnt); |
1211 | 1271 | ||
1212 | /* send_pcc_cmd updates the status in case of failure */ | 1272 | /* send_pcc_cmd updates the status in case of failure */ |
1213 | ret = cpc_desc->write_cmd_status; | 1273 | ret = cpc_desc->write_cmd_status; |
@@ -1240,6 +1300,8 @@ unsigned int cppc_get_transition_latency(int cpu_num) | |||
1240 | unsigned int latency_ns = 0; | 1300 | unsigned int latency_ns = 0; |
1241 | struct cpc_desc *cpc_desc; | 1301 | struct cpc_desc *cpc_desc; |
1242 | struct cpc_register_resource *desired_reg; | 1302 | struct cpc_register_resource *desired_reg; |
1303 | int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu_num); | ||
1304 | struct cppc_pcc_data *pcc_ss_data = pcc_data[pcc_ss_id]; | ||
1243 | 1305 | ||
1244 | cpc_desc = per_cpu(cpc_desc_ptr, cpu_num); | 1306 | cpc_desc = per_cpu(cpc_desc_ptr, cpu_num); |
1245 | if (!cpc_desc) | 1307 | if (!cpc_desc) |
@@ -1249,11 +1311,11 @@ unsigned int cppc_get_transition_latency(int cpu_num) | |||
1249 | if (!CPC_IN_PCC(desired_reg)) | 1311 | if (!CPC_IN_PCC(desired_reg)) |
1250 | return CPUFREQ_ETERNAL; | 1312 | return CPUFREQ_ETERNAL; |
1251 | 1313 | ||
1252 | if (pcc_data.pcc_mpar) | 1314 | if (pcc_ss_data->pcc_mpar) |
1253 | latency_ns = 60 * (1000 * 1000 * 1000 / pcc_data.pcc_mpar); | 1315 | latency_ns = 60 * (1000 * 1000 * 1000 / pcc_ss_data->pcc_mpar); |
1254 | 1316 | ||
1255 | latency_ns = max(latency_ns, pcc_data.pcc_nominal * 1000); | 1317 | latency_ns = max(latency_ns, pcc_ss_data->pcc_nominal * 1000); |
1256 | latency_ns = max(latency_ns, pcc_data.pcc_mrtt * 1000); | 1318 | latency_ns = max(latency_ns, pcc_ss_data->pcc_mrtt * 1000); |
1257 | 1319 | ||
1258 | return latency_ns; | 1320 | return latency_ns; |
1259 | } | 1321 | } |
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 2305e1ab978e..e3fc1f045e1c 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -482,6 +482,7 @@ int dock_notify(struct acpi_device *adev, u32 event) | |||
482 | surprise_removal = 1; | 482 | surprise_removal = 1; |
483 | event = ACPI_NOTIFY_EJECT_REQUEST; | 483 | event = ACPI_NOTIFY_EJECT_REQUEST; |
484 | /* Fall back */ | 484 | /* Fall back */ |
485 | /* fall through */ | ||
485 | case ACPI_NOTIFY_EJECT_REQUEST: | 486 | case ACPI_NOTIFY_EJECT_REQUEST: |
486 | begin_undock(ds); | 487 | begin_undock(ds); |
487 | if ((immediate_undock && !(ds->flags & DOCK_IS_ATA)) | 488 | if ((immediate_undock && !(ds->flags & DOCK_IS_ATA)) |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 236b14324780..82b3ce5e937e 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -486,8 +486,11 @@ static inline void __acpi_ec_enable_event(struct acpi_ec *ec) | |||
486 | { | 486 | { |
487 | if (!test_and_set_bit(EC_FLAGS_QUERY_ENABLED, &ec->flags)) | 487 | if (!test_and_set_bit(EC_FLAGS_QUERY_ENABLED, &ec->flags)) |
488 | ec_log_drv("event unblocked"); | 488 | ec_log_drv("event unblocked"); |
489 | if (!test_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) | 489 | /* |
490 | advance_transaction(ec); | 490 | * Unconditionally invoke this once after enabling the event |
491 | * handling mechanism to detect the pending events. | ||
492 | */ | ||
493 | advance_transaction(ec); | ||
491 | } | 494 | } |
492 | 495 | ||
493 | static inline void __acpi_ec_disable_event(struct acpi_ec *ec) | 496 | static inline void __acpi_ec_disable_event(struct acpi_ec *ec) |
@@ -1456,11 +1459,10 @@ static int ec_install_handlers(struct acpi_ec *ec, bool handle_events) | |||
1456 | if (test_bit(EC_FLAGS_STARTED, &ec->flags) && | 1459 | if (test_bit(EC_FLAGS_STARTED, &ec->flags) && |
1457 | ec->reference_count >= 1) | 1460 | ec->reference_count >= 1) |
1458 | acpi_ec_enable_gpe(ec, true); | 1461 | acpi_ec_enable_gpe(ec, true); |
1459 | |||
1460 | /* EC is fully operational, allow queries */ | ||
1461 | acpi_ec_enable_event(ec); | ||
1462 | } | 1462 | } |
1463 | } | 1463 | } |
1464 | /* EC is fully operational, allow queries */ | ||
1465 | acpi_ec_enable_event(ec); | ||
1464 | 1466 | ||
1465 | return 0; | 1467 | return 0; |
1466 | } | 1468 | } |
diff --git a/drivers/acpi/pmic/tps68470_pmic.c b/drivers/acpi/pmic/tps68470_pmic.c new file mode 100644 index 000000000000..7f3c567e8168 --- /dev/null +++ b/drivers/acpi/pmic/tps68470_pmic.c | |||
@@ -0,0 +1,455 @@ | |||
1 | /* | ||
2 | * TI TPS68470 PMIC operation region driver | ||
3 | * | ||
4 | * Copyright (C) 2017 Intel Corporation. All rights reserved. | ||
5 | * | ||
6 | * Author: Rajmohan Mani <rajmohan.mani@intel.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License version | ||
10 | * 2 as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
13 | * kind, whether express or implied; without even the implied warranty | ||
14 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * Based on drivers/acpi/pmic/intel_pmic* drivers | ||
18 | */ | ||
19 | |||
20 | #include <linux/acpi.h> | ||
21 | #include <linux/mfd/tps68470.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/regmap.h> | ||
25 | |||
26 | struct tps68470_pmic_table { | ||
27 | u32 address; /* operation region address */ | ||
28 | u32 reg; /* corresponding register */ | ||
29 | u32 bitmask; /* bit mask for power, clock */ | ||
30 | }; | ||
31 | |||
32 | #define TI_PMIC_POWER_OPREGION_ID 0xB0 | ||
33 | #define TI_PMIC_VR_VAL_OPREGION_ID 0xB1 | ||
34 | #define TI_PMIC_CLOCK_OPREGION_ID 0xB2 | ||
35 | #define TI_PMIC_CLKFREQ_OPREGION_ID 0xB3 | ||
36 | |||
37 | struct tps68470_pmic_opregion { | ||
38 | struct mutex lock; | ||
39 | struct regmap *regmap; | ||
40 | }; | ||
41 | |||
42 | #define S_IO_I2C_EN (BIT(0) | BIT(1)) | ||
43 | |||
44 | static const struct tps68470_pmic_table power_table[] = { | ||
45 | { | ||
46 | .address = 0x00, | ||
47 | .reg = TPS68470_REG_S_I2C_CTL, | ||
48 | .bitmask = S_IO_I2C_EN, | ||
49 | /* S_I2C_CTL */ | ||
50 | }, | ||
51 | { | ||
52 | .address = 0x04, | ||
53 | .reg = TPS68470_REG_VCMCTL, | ||
54 | .bitmask = BIT(0), | ||
55 | /* VCMCTL */ | ||
56 | }, | ||
57 | { | ||
58 | .address = 0x08, | ||
59 | .reg = TPS68470_REG_VAUX1CTL, | ||
60 | .bitmask = BIT(0), | ||
61 | /* VAUX1_CTL */ | ||
62 | }, | ||
63 | { | ||
64 | .address = 0x0C, | ||
65 | .reg = TPS68470_REG_VAUX2CTL, | ||
66 | .bitmask = BIT(0), | ||
67 | /* VAUX2CTL */ | ||
68 | }, | ||
69 | { | ||
70 | .address = 0x10, | ||
71 | .reg = TPS68470_REG_VACTL, | ||
72 | .bitmask = BIT(0), | ||
73 | /* VACTL */ | ||
74 | }, | ||
75 | { | ||
76 | .address = 0x14, | ||
77 | .reg = TPS68470_REG_VDCTL, | ||
78 | .bitmask = BIT(0), | ||
79 | /* VDCTL */ | ||
80 | }, | ||
81 | }; | ||
82 | |||
83 | /* Table to set voltage regulator value */ | ||
84 | static const struct tps68470_pmic_table vr_val_table[] = { | ||
85 | { | ||
86 | .address = 0x00, | ||
87 | .reg = TPS68470_REG_VSIOVAL, | ||
88 | .bitmask = TPS68470_VSIOVAL_IOVOLT_MASK, | ||
89 | /* TPS68470_REG_VSIOVAL */ | ||
90 | }, | ||
91 | { | ||
92 | .address = 0x04, | ||
93 | .reg = TPS68470_REG_VIOVAL, | ||
94 | .bitmask = TPS68470_VIOVAL_IOVOLT_MASK, | ||
95 | /* TPS68470_REG_VIOVAL */ | ||
96 | }, | ||
97 | { | ||
98 | .address = 0x08, | ||
99 | .reg = TPS68470_REG_VCMVAL, | ||
100 | .bitmask = TPS68470_VCMVAL_VCVOLT_MASK, | ||
101 | /* TPS68470_REG_VCMVAL */ | ||
102 | }, | ||
103 | { | ||
104 | .address = 0x0C, | ||
105 | .reg = TPS68470_REG_VAUX1VAL, | ||
106 | .bitmask = TPS68470_VAUX1VAL_AUX1VOLT_MASK, | ||
107 | /* TPS68470_REG_VAUX1VAL */ | ||
108 | }, | ||
109 | { | ||
110 | .address = 0x10, | ||
111 | .reg = TPS68470_REG_VAUX2VAL, | ||
112 | .bitmask = TPS68470_VAUX2VAL_AUX2VOLT_MASK, | ||
113 | /* TPS68470_REG_VAUX2VAL */ | ||
114 | }, | ||
115 | { | ||
116 | .address = 0x14, | ||
117 | .reg = TPS68470_REG_VAVAL, | ||
118 | .bitmask = TPS68470_VAVAL_AVOLT_MASK, | ||
119 | /* TPS68470_REG_VAVAL */ | ||
120 | }, | ||
121 | { | ||
122 | .address = 0x18, | ||
123 | .reg = TPS68470_REG_VDVAL, | ||
124 | .bitmask = TPS68470_VDVAL_DVOLT_MASK, | ||
125 | /* TPS68470_REG_VDVAL */ | ||
126 | }, | ||
127 | }; | ||
128 | |||
129 | /* Table to configure clock frequency */ | ||
130 | static const struct tps68470_pmic_table clk_freq_table[] = { | ||
131 | { | ||
132 | .address = 0x00, | ||
133 | .reg = TPS68470_REG_POSTDIV2, | ||
134 | .bitmask = BIT(0) | BIT(1), | ||
135 | /* TPS68470_REG_POSTDIV2 */ | ||
136 | }, | ||
137 | { | ||
138 | .address = 0x04, | ||
139 | .reg = TPS68470_REG_BOOSTDIV, | ||
140 | .bitmask = 0x1F, | ||
141 | /* TPS68470_REG_BOOSTDIV */ | ||
142 | }, | ||
143 | { | ||
144 | .address = 0x08, | ||
145 | .reg = TPS68470_REG_BUCKDIV, | ||
146 | .bitmask = 0x0F, | ||
147 | /* TPS68470_REG_BUCKDIV */ | ||
148 | }, | ||
149 | { | ||
150 | .address = 0x0C, | ||
151 | .reg = TPS68470_REG_PLLSWR, | ||
152 | .bitmask = 0x13, | ||
153 | /* TPS68470_REG_PLLSWR */ | ||
154 | }, | ||
155 | { | ||
156 | .address = 0x10, | ||
157 | .reg = TPS68470_REG_XTALDIV, | ||
158 | .bitmask = 0xFF, | ||
159 | /* TPS68470_REG_XTALDIV */ | ||
160 | }, | ||
161 | { | ||
162 | .address = 0x14, | ||
163 | .reg = TPS68470_REG_PLLDIV, | ||
164 | .bitmask = 0xFF, | ||
165 | /* TPS68470_REG_PLLDIV */ | ||
166 | }, | ||
167 | { | ||
168 | .address = 0x18, | ||
169 | .reg = TPS68470_REG_POSTDIV, | ||
170 | .bitmask = 0x83, | ||
171 | /* TPS68470_REG_POSTDIV */ | ||
172 | }, | ||
173 | }; | ||
174 | |||
175 | /* Table to configure and enable clocks */ | ||
176 | static const struct tps68470_pmic_table clk_table[] = { | ||
177 | { | ||
178 | .address = 0x00, | ||
179 | .reg = TPS68470_REG_PLLCTL, | ||
180 | .bitmask = 0xF5, | ||
181 | /* TPS68470_REG_PLLCTL */ | ||
182 | }, | ||
183 | { | ||
184 | .address = 0x04, | ||
185 | .reg = TPS68470_REG_PLLCTL2, | ||
186 | .bitmask = BIT(0), | ||
187 | /* TPS68470_REG_PLLCTL2 */ | ||
188 | }, | ||
189 | { | ||
190 | .address = 0x08, | ||
191 | .reg = TPS68470_REG_CLKCFG1, | ||
192 | .bitmask = TPS68470_CLKCFG1_MODE_A_MASK | | ||
193 | TPS68470_CLKCFG1_MODE_B_MASK, | ||
194 | /* TPS68470_REG_CLKCFG1 */ | ||
195 | }, | ||
196 | { | ||
197 | .address = 0x0C, | ||
198 | .reg = TPS68470_REG_CLKCFG2, | ||
199 | .bitmask = TPS68470_CLKCFG1_MODE_A_MASK | | ||
200 | TPS68470_CLKCFG1_MODE_B_MASK, | ||
201 | /* TPS68470_REG_CLKCFG2 */ | ||
202 | }, | ||
203 | }; | ||
204 | |||
205 | static int pmic_get_reg_bit(u64 address, | ||
206 | const struct tps68470_pmic_table *table, | ||
207 | const unsigned int table_size, int *reg, | ||
208 | int *bitmask) | ||
209 | { | ||
210 | u64 i; | ||
211 | |||
212 | i = address / 4; | ||
213 | if (i >= table_size) | ||
214 | return -ENOENT; | ||
215 | |||
216 | if (!reg || !bitmask) | ||
217 | return -EINVAL; | ||
218 | |||
219 | *reg = table[i].reg; | ||
220 | *bitmask = table[i].bitmask; | ||
221 | |||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | static int tps68470_pmic_get_power(struct regmap *regmap, int reg, | ||
226 | int bitmask, u64 *value) | ||
227 | { | ||
228 | unsigned int data; | ||
229 | |||
230 | if (regmap_read(regmap, reg, &data)) | ||
231 | return -EIO; | ||
232 | |||
233 | *value = (data & bitmask) ? 1 : 0; | ||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | static int tps68470_pmic_get_vr_val(struct regmap *regmap, int reg, | ||
238 | int bitmask, u64 *value) | ||
239 | { | ||
240 | unsigned int data; | ||
241 | |||
242 | if (regmap_read(regmap, reg, &data)) | ||
243 | return -EIO; | ||
244 | |||
245 | *value = data & bitmask; | ||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | static int tps68470_pmic_get_clk(struct regmap *regmap, int reg, | ||
250 | int bitmask, u64 *value) | ||
251 | { | ||
252 | unsigned int data; | ||
253 | |||
254 | if (regmap_read(regmap, reg, &data)) | ||
255 | return -EIO; | ||
256 | |||
257 | *value = (data & bitmask) ? 1 : 0; | ||
258 | return 0; | ||
259 | } | ||
260 | |||
261 | static int tps68470_pmic_get_clk_freq(struct regmap *regmap, int reg, | ||
262 | int bitmask, u64 *value) | ||
263 | { | ||
264 | unsigned int data; | ||
265 | |||
266 | if (regmap_read(regmap, reg, &data)) | ||
267 | return -EIO; | ||
268 | |||
269 | *value = data & bitmask; | ||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | static int ti_tps68470_regmap_update_bits(struct regmap *regmap, int reg, | ||
274 | int bitmask, u64 value) | ||
275 | { | ||
276 | return regmap_update_bits(regmap, reg, bitmask, value); | ||
277 | } | ||
278 | |||
279 | static acpi_status tps68470_pmic_common_handler(u32 function, | ||
280 | acpi_physical_address address, | ||
281 | u32 bits, u64 *value, | ||
282 | void *region_context, | ||
283 | int (*get)(struct regmap *, | ||
284 | int, int, u64 *), | ||
285 | int (*update)(struct regmap *, | ||
286 | int, int, u64), | ||
287 | const struct tps68470_pmic_table *tbl, | ||
288 | unsigned int tbl_size) | ||
289 | { | ||
290 | struct tps68470_pmic_opregion *opregion = region_context; | ||
291 | struct regmap *regmap = opregion->regmap; | ||
292 | int reg, ret, bitmask; | ||
293 | |||
294 | if (bits != 32) | ||
295 | return AE_BAD_PARAMETER; | ||
296 | |||
297 | ret = pmic_get_reg_bit(address, tbl, tbl_size, ®, &bitmask); | ||
298 | if (ret < 0) | ||
299 | return AE_BAD_PARAMETER; | ||
300 | |||
301 | if (function == ACPI_WRITE && *value > bitmask) | ||
302 | return AE_BAD_PARAMETER; | ||
303 | |||
304 | mutex_lock(&opregion->lock); | ||
305 | |||
306 | ret = (function == ACPI_READ) ? | ||
307 | get(regmap, reg, bitmask, value) : | ||
308 | update(regmap, reg, bitmask, *value); | ||
309 | |||
310 | mutex_unlock(&opregion->lock); | ||
311 | |||
312 | return ret ? AE_ERROR : AE_OK; | ||
313 | } | ||
314 | |||
315 | static acpi_status tps68470_pmic_cfreq_handler(u32 function, | ||
316 | acpi_physical_address address, | ||
317 | u32 bits, u64 *value, | ||
318 | void *handler_context, | ||
319 | void *region_context) | ||
320 | { | ||
321 | return tps68470_pmic_common_handler(function, address, bits, value, | ||
322 | region_context, | ||
323 | tps68470_pmic_get_clk_freq, | ||
324 | ti_tps68470_regmap_update_bits, | ||
325 | clk_freq_table, | ||
326 | ARRAY_SIZE(clk_freq_table)); | ||
327 | } | ||
328 | |||
329 | static acpi_status tps68470_pmic_clk_handler(u32 function, | ||
330 | acpi_physical_address address, u32 bits, | ||
331 | u64 *value, void *handler_context, | ||
332 | void *region_context) | ||
333 | { | ||
334 | return tps68470_pmic_common_handler(function, address, bits, value, | ||
335 | region_context, | ||
336 | tps68470_pmic_get_clk, | ||
337 | ti_tps68470_regmap_update_bits, | ||
338 | clk_table, | ||
339 | ARRAY_SIZE(clk_table)); | ||
340 | } | ||
341 | |||
342 | static acpi_status tps68470_pmic_vrval_handler(u32 function, | ||
343 | acpi_physical_address address, | ||
344 | u32 bits, u64 *value, | ||
345 | void *handler_context, | ||
346 | void *region_context) | ||
347 | { | ||
348 | return tps68470_pmic_common_handler(function, address, bits, value, | ||
349 | region_context, | ||
350 | tps68470_pmic_get_vr_val, | ||
351 | ti_tps68470_regmap_update_bits, | ||
352 | vr_val_table, | ||
353 | ARRAY_SIZE(vr_val_table)); | ||
354 | } | ||
355 | |||
356 | static acpi_status tps68470_pmic_pwr_handler(u32 function, | ||
357 | acpi_physical_address address, | ||
358 | u32 bits, u64 *value, | ||
359 | void *handler_context, | ||
360 | void *region_context) | ||
361 | { | ||
362 | if (bits != 32) | ||
363 | return AE_BAD_PARAMETER; | ||
364 | |||
365 | /* set/clear for bit 0, bits 0 and 1 together */ | ||
366 | if (function == ACPI_WRITE && | ||
367 | !(*value == 0 || *value == 1 || *value == 3)) { | ||
368 | return AE_BAD_PARAMETER; | ||
369 | } | ||
370 | |||
371 | return tps68470_pmic_common_handler(function, address, bits, value, | ||
372 | region_context, | ||
373 | tps68470_pmic_get_power, | ||
374 | ti_tps68470_regmap_update_bits, | ||
375 | power_table, | ||
376 | ARRAY_SIZE(power_table)); | ||
377 | } | ||
378 | |||
379 | static int tps68470_pmic_opregion_probe(struct platform_device *pdev) | ||
380 | { | ||
381 | struct regmap *tps68470_regmap = dev_get_drvdata(pdev->dev.parent); | ||
382 | acpi_handle handle = ACPI_HANDLE(pdev->dev.parent); | ||
383 | struct device *dev = &pdev->dev; | ||
384 | struct tps68470_pmic_opregion *opregion; | ||
385 | acpi_status status; | ||
386 | |||
387 | if (!dev || !tps68470_regmap) { | ||
388 | dev_warn(dev, "dev or regmap is NULL\n"); | ||
389 | return -EINVAL; | ||
390 | } | ||
391 | |||
392 | if (!handle) { | ||
393 | dev_warn(dev, "acpi handle is NULL\n"); | ||
394 | return -ENODEV; | ||
395 | } | ||
396 | |||
397 | opregion = devm_kzalloc(dev, sizeof(*opregion), GFP_KERNEL); | ||
398 | if (!opregion) | ||
399 | return -ENOMEM; | ||
400 | |||
401 | mutex_init(&opregion->lock); | ||
402 | opregion->regmap = tps68470_regmap; | ||
403 | |||
404 | status = acpi_install_address_space_handler(handle, | ||
405 | TI_PMIC_POWER_OPREGION_ID, | ||
406 | tps68470_pmic_pwr_handler, | ||
407 | NULL, opregion); | ||
408 | if (ACPI_FAILURE(status)) | ||
409 | goto out_mutex_destroy; | ||
410 | |||
411 | status = acpi_install_address_space_handler(handle, | ||
412 | TI_PMIC_VR_VAL_OPREGION_ID, | ||
413 | tps68470_pmic_vrval_handler, | ||
414 | NULL, opregion); | ||
415 | if (ACPI_FAILURE(status)) | ||
416 | goto out_remove_power_handler; | ||
417 | |||
418 | status = acpi_install_address_space_handler(handle, | ||
419 | TI_PMIC_CLOCK_OPREGION_ID, | ||
420 | tps68470_pmic_clk_handler, | ||
421 | NULL, opregion); | ||
422 | if (ACPI_FAILURE(status)) | ||
423 | goto out_remove_vr_val_handler; | ||
424 | |||
425 | status = acpi_install_address_space_handler(handle, | ||
426 | TI_PMIC_CLKFREQ_OPREGION_ID, | ||
427 | tps68470_pmic_cfreq_handler, | ||
428 | NULL, opregion); | ||
429 | if (ACPI_FAILURE(status)) | ||
430 | goto out_remove_clk_handler; | ||
431 | |||
432 | return 0; | ||
433 | |||
434 | out_remove_clk_handler: | ||
435 | acpi_remove_address_space_handler(handle, TI_PMIC_CLOCK_OPREGION_ID, | ||
436 | tps68470_pmic_clk_handler); | ||
437 | out_remove_vr_val_handler: | ||
438 | acpi_remove_address_space_handler(handle, TI_PMIC_VR_VAL_OPREGION_ID, | ||
439 | tps68470_pmic_vrval_handler); | ||
440 | out_remove_power_handler: | ||
441 | acpi_remove_address_space_handler(handle, TI_PMIC_POWER_OPREGION_ID, | ||
442 | tps68470_pmic_pwr_handler); | ||
443 | out_mutex_destroy: | ||
444 | mutex_destroy(&opregion->lock); | ||
445 | return -ENODEV; | ||
446 | } | ||
447 | |||
448 | static struct platform_driver tps68470_pmic_opregion_driver = { | ||
449 | .probe = tps68470_pmic_opregion_probe, | ||
450 | .driver = { | ||
451 | .name = "tps68470_pmic_opregion", | ||
452 | }, | ||
453 | }; | ||
454 | |||
455 | builtin_platform_driver(tps68470_pmic_opregion_driver) | ||
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index d85e010ee2cc..316a0fc785e3 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c | |||
@@ -381,6 +381,7 @@ unsigned int acpi_dev_get_irq_type(int triggering, int polarity) | |||
381 | case ACPI_ACTIVE_BOTH: | 381 | case ACPI_ACTIVE_BOTH: |
382 | if (triggering == ACPI_EDGE_SENSITIVE) | 382 | if (triggering == ACPI_EDGE_SENSITIVE) |
383 | return IRQ_TYPE_EDGE_BOTH; | 383 | return IRQ_TYPE_EDGE_BOTH; |
384 | /* fall through */ | ||
384 | default: | 385 | default: |
385 | return IRQ_TYPE_NONE; | 386 | return IRQ_TYPE_NONE; |
386 | } | 387 | } |
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 0fd57bf33524..bc303df60d5d 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c | |||
@@ -169,7 +169,8 @@ module_param_cb(debug_level, ¶m_ops_debug_level, &acpi_dbg_level, 0644); | |||
169 | 169 | ||
170 | static char trace_method_name[1024]; | 170 | static char trace_method_name[1024]; |
171 | 171 | ||
172 | int param_set_trace_method_name(const char *val, const struct kernel_param *kp) | 172 | static int param_set_trace_method_name(const char *val, |
173 | const struct kernel_param *kp) | ||
173 | { | 174 | { |
174 | u32 saved_flags = 0; | 175 | u32 saved_flags = 0; |
175 | bool is_abs_path = true; | 176 | bool is_abs_path = true; |
diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c index b4fbb9929482..ec5b0f190231 100644 --- a/drivers/acpi/x86/utils.c +++ b/drivers/acpi/x86/utils.c | |||
@@ -71,18 +71,34 @@ static const struct always_present_id always_present_ids[] = { | |||
71 | DMI_MATCH(DMI_PRODUCT_NAME, "Venue 11 Pro 7130"), | 71 | DMI_MATCH(DMI_PRODUCT_NAME, "Venue 11 Pro 7130"), |
72 | }), | 72 | }), |
73 | /* | 73 | /* |
74 | * The GPD win BIOS dated 20170320 has disabled the accelerometer, the | 74 | * The GPD win BIOS dated 20170221 has disabled the accelerometer, the |
75 | * drivers sometimes cause crashes under Windows and this is how the | 75 | * drivers sometimes cause crashes under Windows and this is how the |
76 | * manufacturer has solved this :| Note that the the DMI data is less | 76 | * manufacturer has solved this :| Note that the the DMI data is less |
77 | * generic then it seems, a board_vendor of "AMI Corporation" is quite | 77 | * generic then it seems, a board_vendor of "AMI Corporation" is quite |
78 | * rare and a board_name of "Default String" also is rare. | 78 | * rare and a board_name of "Default String" also is rare. |
79 | * | ||
80 | * Unfortunately the GPD pocket also uses these strings and its BIOS | ||
81 | * was copy-pasted from the GPD win, so it has a disabled KIOX000A | ||
82 | * node which we should not enable, thus we also check the BIOS date. | ||
79 | */ | 83 | */ |
80 | ENTRY("KIOX000A", "1", ICPU(INTEL_FAM6_ATOM_AIRMONT), { | 84 | ENTRY("KIOX000A", "1", ICPU(INTEL_FAM6_ATOM_AIRMONT), { |
81 | DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), | 85 | DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), |
82 | DMI_MATCH(DMI_BOARD_NAME, "Default string"), | 86 | DMI_MATCH(DMI_BOARD_NAME, "Default string"), |
83 | DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), | 87 | DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), |
88 | DMI_MATCH(DMI_BIOS_DATE, "02/21/2017") | ||
89 | }), | ||
90 | ENTRY("KIOX000A", "1", ICPU(INTEL_FAM6_ATOM_AIRMONT), { | ||
91 | DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), | ||
92 | DMI_MATCH(DMI_BOARD_NAME, "Default string"), | ||
93 | DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), | ||
84 | DMI_MATCH(DMI_BIOS_DATE, "03/20/2017") | 94 | DMI_MATCH(DMI_BIOS_DATE, "03/20/2017") |
85 | }), | 95 | }), |
96 | ENTRY("KIOX000A", "1", ICPU(INTEL_FAM6_ATOM_AIRMONT), { | ||
97 | DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), | ||
98 | DMI_MATCH(DMI_BOARD_NAME, "Default string"), | ||
99 | DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), | ||
100 | DMI_MATCH(DMI_BIOS_DATE, "05/25/2017") | ||
101 | }), | ||
86 | }; | 102 | }; |
87 | 103 | ||
88 | bool acpi_device_always_present(struct acpi_device *adev) | 104 | bool acpi_device_always_present(struct acpi_device *adev) |
diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c index 9b7005e1345e..e5a69679cfa2 100644 --- a/drivers/mailbox/pcc.c +++ b/drivers/mailbox/pcc.c | |||
@@ -69,7 +69,6 @@ | |||
69 | 69 | ||
70 | #include "mailbox.h" | 70 | #include "mailbox.h" |
71 | 71 | ||
72 | #define MAX_PCC_SUBSPACES 256 | ||
73 | #define MBOX_IRQ_NAME "pcc-mbox" | 72 | #define MBOX_IRQ_NAME "pcc-mbox" |
74 | 73 | ||
75 | static struct mbox_chan *pcc_mbox_channels; | 74 | static struct mbox_chan *pcc_mbox_channels; |
diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h index ad54610ea6cd..17d61b1f2511 100644 --- a/include/acpi/acexcep.h +++ b/include/acpi/acexcep.h | |||
@@ -126,8 +126,12 @@ struct acpi_exception_info { | |||
126 | #define AE_NOT_CONFIGURED EXCEP_ENV (0x001C) | 126 | #define AE_NOT_CONFIGURED EXCEP_ENV (0x001C) |
127 | #define AE_ACCESS EXCEP_ENV (0x001D) | 127 | #define AE_ACCESS EXCEP_ENV (0x001D) |
128 | #define AE_IO_ERROR EXCEP_ENV (0x001E) | 128 | #define AE_IO_ERROR EXCEP_ENV (0x001E) |
129 | #define AE_NUMERIC_OVERFLOW EXCEP_ENV (0x001F) | ||
130 | #define AE_HEX_OVERFLOW EXCEP_ENV (0x0020) | ||
131 | #define AE_DECIMAL_OVERFLOW EXCEP_ENV (0x0021) | ||
132 | #define AE_OCTAL_OVERFLOW EXCEP_ENV (0x0022) | ||
129 | 133 | ||
130 | #define AE_CODE_ENV_MAX 0x001E | 134 | #define AE_CODE_ENV_MAX 0x0022 |
131 | 135 | ||
132 | /* | 136 | /* |
133 | * Programmer exceptions | 137 | * Programmer exceptions |
@@ -263,7 +267,15 @@ static const struct acpi_exception_info acpi_gbl_exception_names_env[] = { | |||
263 | EXCEP_TXT("AE_NOT_CONFIGURED", | 267 | EXCEP_TXT("AE_NOT_CONFIGURED", |
264 | "The interface is not part of the current subsystem configuration"), | 268 | "The interface is not part of the current subsystem configuration"), |
265 | EXCEP_TXT("AE_ACCESS", "Permission denied for the requested operation"), | 269 | EXCEP_TXT("AE_ACCESS", "Permission denied for the requested operation"), |
266 | EXCEP_TXT("AE_IO_ERROR", "An I/O error occurred") | 270 | EXCEP_TXT("AE_IO_ERROR", "An I/O error occurred"), |
271 | EXCEP_TXT("AE_NUMERIC_OVERFLOW", | ||
272 | "Overflow during string-to-integer conversion"), | ||
273 | EXCEP_TXT("AE_HEX_OVERFLOW", | ||
274 | "Overflow during ASCII hex-to-binary conversion"), | ||
275 | EXCEP_TXT("AE_DECIMAL_OVERFLOW", | ||
276 | "Overflow during ASCII decimal-to-binary conversion"), | ||
277 | EXCEP_TXT("AE_OCTAL_OVERFLOW", | ||
278 | "Overflow during ASCII octal-to-binary conversion") | ||
267 | }; | 279 | }; |
268 | 280 | ||
269 | static const struct acpi_exception_info acpi_gbl_exception_names_pgm[] = { | 281 | static const struct acpi_exception_info acpi_gbl_exception_names_pgm[] = { |
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 53c5e2f7bcec..e1dd1a8d42b6 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h | |||
@@ -46,7 +46,7 @@ | |||
46 | 46 | ||
47 | /* Current ACPICA subsystem version in YYYYMMDD format */ | 47 | /* Current ACPICA subsystem version in YYYYMMDD format */ |
48 | 48 | ||
49 | #define ACPI_CA_VERSION 0x20170728 | 49 | #define ACPI_CA_VERSION 0x20170831 |
50 | 50 | ||
51 | #include <acpi/acconfig.h> | 51 | #include <acpi/acconfig.h> |
52 | #include <acpi/actypes.h> | 52 | #include <acpi/actypes.h> |
diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h index 6b8714a428b6..7a89e6de94da 100644 --- a/include/acpi/actbl1.h +++ b/include/acpi/actbl1.h | |||
@@ -69,6 +69,7 @@ | |||
69 | #define ACPI_SIG_HEST "HEST" /* Hardware Error Source Table */ | 69 | #define ACPI_SIG_HEST "HEST" /* Hardware Error Source Table */ |
70 | #define ACPI_SIG_MADT "APIC" /* Multiple APIC Description Table */ | 70 | #define ACPI_SIG_MADT "APIC" /* Multiple APIC Description Table */ |
71 | #define ACPI_SIG_MSCT "MSCT" /* Maximum System Characteristics Table */ | 71 | #define ACPI_SIG_MSCT "MSCT" /* Maximum System Characteristics Table */ |
72 | #define ACPI_SIG_PDTT "PDTT" /* Processor Debug Trigger Table */ | ||
72 | #define ACPI_SIG_PPTT "PPTT" /* Processor Properties Topology Table */ | 73 | #define ACPI_SIG_PPTT "PPTT" /* Processor Properties Topology Table */ |
73 | #define ACPI_SIG_SBST "SBST" /* Smart Battery Specification Table */ | 74 | #define ACPI_SIG_SBST "SBST" /* Smart Battery Specification Table */ |
74 | #define ACPI_SIG_SLIT "SLIT" /* System Locality Distance Information Table */ | 75 | #define ACPI_SIG_SLIT "SLIT" /* System Locality Distance Information Table */ |
@@ -1282,6 +1283,35 @@ struct acpi_nfit_flush_address { | |||
1282 | 1283 | ||
1283 | /******************************************************************************* | 1284 | /******************************************************************************* |
1284 | * | 1285 | * |
1286 | * PDTT - Processor Debug Trigger Table (ACPI 6.2) | ||
1287 | * Version 0 | ||
1288 | * | ||
1289 | ******************************************************************************/ | ||
1290 | |||
1291 | struct acpi_table_pdtt { | ||
1292 | struct acpi_table_header header; /* Common ACPI table header */ | ||
1293 | u8 trigger_count; | ||
1294 | u8 reserved[3]; | ||
1295 | u32 array_offset; | ||
1296 | }; | ||
1297 | |||
1298 | /* | ||
1299 | * PDTT Communication Channel Identifier Structure. | ||
1300 | * The number of these structures is defined by trigger_count above, | ||
1301 | * starting at array_offset. | ||
1302 | */ | ||
1303 | struct acpi_pdtt_channel { | ||
1304 | u16 sub_channel_id; | ||
1305 | }; | ||
1306 | |||
1307 | /* Mask and Flags for above */ | ||
1308 | |||
1309 | #define ACPI_PDTT_SUBCHANNEL_ID_MASK 0x00FF | ||
1310 | #define ACPI_PDTT_RUNTIME_TRIGGER (1<<8) | ||
1311 | #define ACPI_PPTT_WAIT_COMPLETION (1<<9) | ||
1312 | |||
1313 | /******************************************************************************* | ||
1314 | * | ||
1285 | * PPTT - Processor Properties Topology Table (ACPI 6.2) | 1315 | * PPTT - Processor Properties Topology Table (ACPI 6.2) |
1286 | * Version 1 | 1316 | * Version 1 |
1287 | * | 1317 | * |
diff --git a/include/acpi/apei.h b/include/acpi/apei.h index 1797e81a3204..680f80960c3d 100644 --- a/include/acpi/apei.h +++ b/include/acpi/apei.h | |||
@@ -51,7 +51,6 @@ int erst_clear(u64 record_id); | |||
51 | 51 | ||
52 | int arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr, void *data); | 52 | int arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr, void *data); |
53 | void arch_apei_report_mem_error(int sev, struct cper_sec_mem_err *mem_err); | 53 | void arch_apei_report_mem_error(int sev, struct cper_sec_mem_err *mem_err); |
54 | void arch_apei_flush_tlb_one(unsigned long addr); | ||
55 | 54 | ||
56 | #endif | 55 | #endif |
57 | #endif | 56 | #endif |
diff --git a/include/acpi/pcc.h b/include/acpi/pcc.h index 8caa79c61703..cd6ef45e614e 100644 --- a/include/acpi/pcc.h +++ b/include/acpi/pcc.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/mailbox_controller.h> | 13 | #include <linux/mailbox_controller.h> |
14 | #include <linux/mailbox_client.h> | 14 | #include <linux/mailbox_client.h> |
15 | 15 | ||
16 | #define MAX_PCC_SUBSPACES 256 | ||
16 | #ifdef CONFIG_PCC | 17 | #ifdef CONFIG_PCC |
17 | extern struct mbox_chan *pcc_mbox_request_channel(struct mbox_client *cl, | 18 | extern struct mbox_chan *pcc_mbox_request_channel(struct mbox_client *cl, |
18 | int subspace_id); | 19 | int subspace_id); |
diff --git a/tools/power/acpi/tools/acpidump/Makefile b/tools/power/acpi/tools/acpidump/Makefile index f7c7af1f9258..b436f8675f6a 100644 --- a/tools/power/acpi/tools/acpidump/Makefile +++ b/tools/power/acpi/tools/acpidump/Makefile | |||
@@ -39,6 +39,7 @@ TOOL_OBJS = \ | |||
39 | utnonansi.o\ | 39 | utnonansi.o\ |
40 | utprint.o\ | 40 | utprint.o\ |
41 | utstring.o\ | 41 | utstring.o\ |
42 | utstrsuppt.o\ | ||
42 | utstrtoul64.o\ | 43 | utstrtoul64.o\ |
43 | utxferror.o\ | 44 | utxferror.o\ |
44 | oslinuxtbl.o\ | 45 | oslinuxtbl.o\ |
diff --git a/tools/power/acpi/tools/acpidump/apdump.c b/tools/power/acpi/tools/acpidump/apdump.c index 60df1fbd4a77..0634449156d8 100644 --- a/tools/power/acpi/tools/acpidump/apdump.c +++ b/tools/power/acpi/tools/acpidump/apdump.c | |||
@@ -287,8 +287,7 @@ int ap_dump_table_by_address(char *ascii_address) | |||
287 | 287 | ||
288 | /* Convert argument to an integer physical address */ | 288 | /* Convert argument to an integer physical address */ |
289 | 289 | ||
290 | status = acpi_ut_strtoul64(ascii_address, ACPI_STRTOUL_64BIT, | 290 | status = acpi_ut_strtoul64(ascii_address, &long_address); |
291 | &long_address); | ||
292 | if (ACPI_FAILURE(status)) { | 291 | if (ACPI_FAILURE(status)) { |
293 | fprintf(stderr, "%s: Could not convert to a physical address\n", | 292 | fprintf(stderr, "%s: Could not convert to a physical address\n", |
294 | ascii_address); | 293 | ascii_address); |
diff --git a/tools/power/acpi/tools/acpidump/apmain.c b/tools/power/acpi/tools/acpidump/apmain.c index 943b6b614683..22c3b4ee1617 100644 --- a/tools/power/acpi/tools/acpidump/apmain.c +++ b/tools/power/acpi/tools/acpidump/apmain.c | |||
@@ -208,9 +208,7 @@ static int ap_do_options(int argc, char **argv) | |||
208 | case 'r': /* Dump tables from specified RSDP */ | 208 | case 'r': /* Dump tables from specified RSDP */ |
209 | 209 | ||
210 | status = | 210 | status = |
211 | acpi_ut_strtoul64(acpi_gbl_optarg, | 211 | acpi_ut_strtoul64(acpi_gbl_optarg, &gbl_rsdp_base); |
212 | ACPI_STRTOUL_64BIT, | ||
213 | &gbl_rsdp_base); | ||
214 | if (ACPI_FAILURE(status)) { | 212 | if (ACPI_FAILURE(status)) { |
215 | fprintf(stderr, | 213 | fprintf(stderr, |
216 | "%s: Could not convert to a physical address\n", | 214 | "%s: Could not convert to a physical address\n", |