6057 lines
197 KiB
Diff
6057 lines
197 KiB
Diff
diff --git a/Documentation/power/basic-pm-debugging.txt b/Documentation/power/basic-pm-debugging.txt
|
||
index b96098c..708f87f 100644
|
||
--- a/Documentation/power/basic-pm-debugging.txt
|
||
+++ b/Documentation/power/basic-pm-debugging.txt
|
||
@@ -164,7 +164,32 @@ load n/2 modules more and try again.
|
||
Again, if you find the offending module(s), it(they) must be unloaded every time
|
||
before hibernation, and please report the problem with it(them).
|
||
|
||
-c) Advanced debugging
|
||
+c) Using the "test_resume" hibernation option
|
||
+
|
||
+/sys/power/disk generally tells the kernel what to do after creating a
|
||
+hibernation image. One of the available options is "test_resume" which
|
||
+causes the just created image to be used for immediate restoration. Namely,
|
||
+after doing:
|
||
+
|
||
+# echo test_resume > /sys/power/disk
|
||
+# echo disk > /sys/power/state
|
||
+
|
||
+a hibernation image will be created and a resume from it will be triggered
|
||
+immediately without involving the platform firmware in any way.
|
||
+
|
||
+That test can be used to check if failures to resume from hibernation are
|
||
+related to bad interactions with the platform firmware. That is, if the above
|
||
+works every time, but resume from actual hibernation does not work or is
|
||
+unreliable, the platform firmware may be responsible for the failures.
|
||
+
|
||
+On architectures and platforms that support using different kernels to restore
|
||
+hibernation images (that is, the kernel used to read the image from storage and
|
||
+load it into memory is different from the one included in the image) or support
|
||
+kernel address space randomization, it also can be used to check if failures
|
||
+to resume may be related to the differences between the restore and image
|
||
+kernels.
|
||
+
|
||
+d) Advanced debugging
|
||
|
||
In case that hibernation does not work on your system even in the minimal
|
||
configuration and compiling more drivers as modules is not practical or some
|
||
diff --git a/Documentation/power/interface.txt b/Documentation/power/interface.txt
|
||
index f1f0f59a..974916f 100644
|
||
--- a/Documentation/power/interface.txt
|
||
+++ b/Documentation/power/interface.txt
|
||
@@ -1,75 +1,76 @@
|
||
-Power Management Interface
|
||
-
|
||
-
|
||
-The power management subsystem provides a unified sysfs interface to
|
||
-userspace, regardless of what architecture or platform one is
|
||
-running. The interface exists in /sys/power/ directory (assuming sysfs
|
||
-is mounted at /sys).
|
||
-
|
||
-/sys/power/state controls system power state. Reading from this file
|
||
-returns what states are supported, which is hard-coded to 'freeze',
|
||
-'standby' (Power-On Suspend), 'mem' (Suspend-to-RAM), and 'disk'
|
||
-(Suspend-to-Disk).
|
||
-
|
||
-Writing to this file one of those strings causes the system to
|
||
-transition into that state. Please see the file
|
||
-Documentation/power/states.txt for a description of each of those
|
||
-states.
|
||
-
|
||
-
|
||
-/sys/power/disk controls the operating mode of the suspend-to-disk
|
||
-mechanism. Suspend-to-disk can be handled in several ways. We have a
|
||
-few options for putting the system to sleep - using the platform driver
|
||
-(e.g. ACPI or other suspend_ops), powering off the system or rebooting the
|
||
-system (for testing).
|
||
-
|
||
-Additionally, /sys/power/disk can be used to turn on one of the two testing
|
||
-modes of the suspend-to-disk mechanism: 'testproc' or 'test'. If the
|
||
-suspend-to-disk mechanism is in the 'testproc' mode, writing 'disk' to
|
||
-/sys/power/state will cause the kernel to disable nonboot CPUs and freeze
|
||
-tasks, wait for 5 seconds, unfreeze tasks and enable nonboot CPUs. If it is
|
||
-in the 'test' mode, writing 'disk' to /sys/power/state will cause the kernel
|
||
-to disable nonboot CPUs and freeze tasks, shrink memory, suspend devices, wait
|
||
-for 5 seconds, resume devices, unfreeze tasks and enable nonboot CPUs. Then,
|
||
-we are able to look in the log messages and work out, for example, which code
|
||
-is being slow and which device drivers are misbehaving.
|
||
-
|
||
-Reading from this file will display all supported modes and the currently
|
||
-selected one in brackets, for example
|
||
-
|
||
- [shutdown] reboot test testproc
|
||
-
|
||
-Writing to this file will accept one of
|
||
-
|
||
- 'platform' (only if the platform supports it)
|
||
- 'shutdown'
|
||
- 'reboot'
|
||
- 'testproc'
|
||
- 'test'
|
||
-
|
||
-/sys/power/image_size controls the size of the image created by
|
||
-the suspend-to-disk mechanism. It can be written a string
|
||
-representing a non-negative integer that will be used as an upper
|
||
-limit of the image size, in bytes. The suspend-to-disk mechanism will
|
||
-do its best to ensure the image size will not exceed that number. However,
|
||
-if this turns out to be impossible, it will try to suspend anyway using the
|
||
-smallest image possible. In particular, if "0" is written to this file, the
|
||
-suspend image will be as small as possible.
|
||
-
|
||
-Reading from this file will display the current image size limit, which
|
||
-is set to 2/5 of available RAM by default.
|
||
-
|
||
-/sys/power/pm_trace controls the code which saves the last PM event point in
|
||
-the RTC across reboots, so that you can debug a machine that just hangs
|
||
-during suspend (or more commonly, during resume). Namely, the RTC is only
|
||
-used to save the last PM event point if this file contains '1'. Initially it
|
||
-contains '0' which may be changed to '1' by writing a string representing a
|
||
-nonzero integer into it.
|
||
-
|
||
-To use this debugging feature you should attempt to suspend the machine, then
|
||
-reboot it and run
|
||
-
|
||
- dmesg -s 1000000 | grep 'hash matches'
|
||
-
|
||
-CAUTION: Using it will cause your machine's real-time (CMOS) clock to be
|
||
-set to a random invalid time after a resume.
|
||
+Power Management Interface for System Sleep
|
||
+
|
||
+Copyright (c) 2016 Intel Corp., Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||
+
|
||
+The power management subsystem provides userspace with a unified sysfs interface
|
||
+for system sleep regardless of the underlying system architecture or platform.
|
||
+The interface is located in the /sys/power/ directory (assuming that sysfs is
|
||
+mounted at /sys).
|
||
+
|
||
+/sys/power/state is the system sleep state control file.
|
||
+
|
||
+Reading from it returns a list of supported sleep states, encoded as:
|
||
+
|
||
+'freeze' (Suspend-to-Idle)
|
||
+'standby' (Power-On Suspend)
|
||
+'mem' (Suspend-to-RAM)
|
||
+'disk' (Suspend-to-Disk)
|
||
+
|
||
+Suspend-to-Idle is always supported. Suspend-to-Disk is always supported
|
||
+too as long the kernel has been configured to support hibernation at all
|
||
+(ie. CONFIG_HIBERNATION is set in the kernel configuration file). Support
|
||
+for Suspend-to-RAM and Power-On Suspend depends on the capabilities of the
|
||
+platform.
|
||
+
|
||
+If one of the strings listed in /sys/power/state is written to it, the system
|
||
+will attempt to transition into the corresponding sleep state. Refer to
|
||
+Documentation/power/states.txt for a description of each of those states.
|
||
+
|
||
+/sys/power/disk controls the operating mode of hibernation (Suspend-to-Disk).
|
||
+Specifically, it tells the kernel what to do after creating a hibernation image.
|
||
+
|
||
+Reading from it returns a list of supported options encoded as:
|
||
+
|
||
+'platform' (put the system into sleep using a platform-provided method)
|
||
+'shutdown' (shut the system down)
|
||
+'reboot' (reboot the system)
|
||
+'suspend' (trigger a Suspend-to-RAM transition)
|
||
+'test_resume' (resume-after-hibernation test mode)
|
||
+
|
||
+The currently selected option is printed in square brackets.
|
||
+
|
||
+The 'platform' option is only available if the platform provides a special
|
||
+mechanism to put the system to sleep after creating a hibernation image (ACPI
|
||
+does that, for example). The 'suspend' option is available if Suspend-to-RAM
|
||
+is supported. Refer to Documentation/power/basic_pm_debugging.txt for the
|
||
+description of the 'test_resume' option.
|
||
+
|
||
+To select an option, write the string representing it to /sys/power/disk.
|
||
+
|
||
+/sys/power/image_size controls the size of hibernation images.
|
||
+
|
||
+It can be written a string representing a non-negative integer that will be
|
||
+used as a best-effort upper limit of the image size, in bytes. The hibernation
|
||
+core will do its best to ensure that the image size will not exceed that number.
|
||
+However, if that turns out to be impossible to achieve, a hibernation image will
|
||
+still be created and its size will be as small as possible. In particular,
|
||
+writing '0' to this file will enforce hibernation images to be as small as
|
||
+possible.
|
||
+
|
||
+Reading from this file returns the current image size limit, which is set to
|
||
+around 2/5 of available RAM by default.
|
||
+
|
||
+/sys/power/pm_trace controls the PM trace mechanism saving the last suspend
|
||
+or resume event point in the RTC across reboots.
|
||
+
|
||
+It helps to debug hard lockups or reboots due to device driver failures that
|
||
+occur during system suspend or resume (which is more common) more effectively.
|
||
+
|
||
+If /sys/power/pm_trace contains '1', the fingerprint of each suspend/resume
|
||
+event point in turn will be stored in the RTC memory (overwriting the actual
|
||
+RTC information), so it will survive a system crash if one occurs right after
|
||
+storing it and it can be used later to identify the driver that caused the crash
|
||
+to happen (see Documentation/power/s2ram.txt for more information).
|
||
+
|
||
+Initially it contains '0' which may be changed to '1' by writing a string
|
||
+representing a nonzero integer into it.
|
||
diff --git a/arch/x86/power/hibernate_64.c b/arch/x86/power/hibernate_64.c
|
||
index a3e3ccc..9634557 100644
|
||
--- a/arch/x86/power/hibernate_64.c
|
||
+++ b/arch/x86/power/hibernate_64.c
|
||
@@ -113,7 +113,7 @@ static int set_up_temporary_mappings(void)
|
||
return result;
|
||
}
|
||
|
||
- temp_level4_pgt = (unsigned long)pgd - __PAGE_OFFSET;
|
||
+ temp_level4_pgt = __pa(pgd);
|
||
return 0;
|
||
}
|
||
|
||
diff --git a/drivers/acpi/acpica/acapps.h b/drivers/acpi/acpica/acapps.h
|
||
index ca2c060..0bd6307 100644
|
||
--- a/drivers/acpi/acpica/acapps.h
|
||
+++ b/drivers/acpi/acpica/acapps.h
|
||
@@ -44,7 +44,9 @@
|
||
#ifndef _ACAPPS
|
||
#define _ACAPPS
|
||
|
||
-#include <stdio.h>
|
||
+#ifdef ACPI_USE_STANDARD_HEADERS
|
||
+#include <sys/stat.h>
|
||
+#endif /* ACPI_USE_STANDARD_HEADERS */
|
||
|
||
/* Common info for tool signons */
|
||
|
||
@@ -81,13 +83,13 @@
|
||
/* Macros for usage messages */
|
||
|
||
#define ACPI_USAGE_HEADER(usage) \
|
||
- acpi_os_printf ("Usage: %s\nOptions:\n", usage);
|
||
+ printf ("Usage: %s\nOptions:\n", usage);
|
||
|
||
#define ACPI_USAGE_TEXT(description) \
|
||
- acpi_os_printf (description);
|
||
+ printf (description);
|
||
|
||
#define ACPI_OPTION(name, description) \
|
||
- acpi_os_printf (" %-20s%s\n", name, description);
|
||
+ printf (" %-20s%s\n", name, description);
|
||
|
||
/* Check for unexpected exceptions */
|
||
|
||
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h
|
||
index 77af91c..92fa47c 100644
|
||
--- a/drivers/acpi/acpica/acevents.h
|
||
+++ b/drivers/acpi/acpica/acevents.h
|
||
@@ -86,6 +86,9 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info);
|
||
acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info);
|
||
|
||
acpi_status
|
||
+acpi_ev_mask_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 is_masked);
|
||
+
|
||
+acpi_status
|
||
acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info);
|
||
|
||
acpi_status
|
||
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
|
||
index fded776..750fa82 100644
|
||
--- a/drivers/acpi/acpica/acglobal.h
|
||
+++ b/drivers/acpi/acpica/acglobal.h
|
||
@@ -317,6 +317,7 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_ignore_noop_operator, FALSE);
|
||
ACPI_INIT_GLOBAL(u8, acpi_gbl_cstyle_disassembly, TRUE);
|
||
ACPI_INIT_GLOBAL(u8, acpi_gbl_force_aml_disassembly, FALSE);
|
||
ACPI_INIT_GLOBAL(u8, acpi_gbl_dm_opt_verbose, TRUE);
|
||
+ACPI_INIT_GLOBAL(u8, acpi_gbl_dm_emit_external_opcodes, FALSE);
|
||
|
||
ACPI_GLOBAL(u8, acpi_gbl_dm_opt_disasm);
|
||
ACPI_GLOBAL(u8, acpi_gbl_dm_opt_listing);
|
||
@@ -382,6 +383,7 @@ ACPI_GLOBAL(const char, *acpi_gbl_pld_shape_list[]);
|
||
|
||
ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_debug_file, NULL);
|
||
ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_output_file, NULL);
|
||
+ACPI_INIT_GLOBAL(u8, acpi_gbl_debug_timeout, FALSE);
|
||
|
||
/* Print buffer */
|
||
|
||
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
|
||
index 13331d7..dff1207 100644
|
||
--- a/drivers/acpi/acpica/aclocal.h
|
||
+++ b/drivers/acpi/acpica/aclocal.h
|
||
@@ -484,6 +484,7 @@ struct acpi_gpe_event_info {
|
||
u8 flags; /* Misc info about this GPE */
|
||
u8 gpe_number; /* This GPE */
|
||
u8 runtime_count; /* References to a run GPE */
|
||
+ u8 disable_for_dispatch; /* Masked during dispatching */
|
||
};
|
||
|
||
/* Information about a GPE register pair, one per each status/enable pair in an array */
|
||
@@ -494,6 +495,7 @@ struct acpi_gpe_register_info {
|
||
u16 base_gpe_number; /* Base GPE number for this register */
|
||
u8 enable_for_wake; /* GPEs to keep enabled when sleeping */
|
||
u8 enable_for_run; /* GPEs to keep enabled when running */
|
||
+ u8 mask_for_run; /* GPEs to keep masked when running */
|
||
u8 enable_mask; /* Current mask of enabled GPEs */
|
||
};
|
||
|
||
diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h
|
||
index cd5a135..86d4d62 100644
|
||
--- a/drivers/acpi/acpica/actables.h
|
||
+++ b/drivers/acpi/acpica/actables.h
|
||
@@ -159,7 +159,8 @@ acpi_status
|
||
acpi_tb_install_fixed_table(acpi_physical_address address,
|
||
char *signature, u32 *table_index);
|
||
|
||
-acpi_status acpi_tb_parse_root_table(acpi_physical_address rsdp_address);
|
||
+acpi_status ACPI_INIT_FUNCTION
|
||
+acpi_tb_parse_root_table(acpi_physical_address rsdp_address);
|
||
|
||
/*
|
||
* tbxfload
|
||
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h
|
||
index a7dbb2b..d899296 100644
|
||
--- a/drivers/acpi/acpica/acutils.h
|
||
+++ b/drivers/acpi/acpica/acutils.h
|
||
@@ -114,13 +114,25 @@ extern const char *acpi_gbl_pt_decode[];
|
||
/*
|
||
* Common error message prefixes
|
||
*/
|
||
+#ifndef ACPI_MSG_ERROR
|
||
#define ACPI_MSG_ERROR "ACPI Error: "
|
||
+#endif
|
||
+#ifndef ACPI_MSG_EXCEPTION
|
||
#define ACPI_MSG_EXCEPTION "ACPI Exception: "
|
||
+#endif
|
||
+#ifndef ACPI_MSG_WARNING
|
||
#define ACPI_MSG_WARNING "ACPI Warning: "
|
||
+#endif
|
||
+#ifndef ACPI_MSG_INFO
|
||
#define ACPI_MSG_INFO "ACPI: "
|
||
+#endif
|
||
|
||
+#ifndef ACPI_MSG_BIOS_ERROR
|
||
#define ACPI_MSG_BIOS_ERROR "ACPI BIOS Error (bug): "
|
||
+#endif
|
||
+#ifndef ACPI_MSG_BIOS_WARNING
|
||
#define ACPI_MSG_BIOS_WARNING "ACPI BIOS Warning (bug): "
|
||
+#endif
|
||
|
||
/*
|
||
* Common message suffix
|
||
@@ -318,6 +330,11 @@ acpi_ut_ptr_exit(u32 line_number,
|
||
const char *module_name, u32 component_id, u8 *ptr);
|
||
|
||
void
|
||
+acpi_ut_str_exit(u32 line_number,
|
||
+ const char *function_name,
|
||
+ const char *module_name, u32 component_id, const char *string);
|
||
+
|
||
+void
|
||
acpi_ut_debug_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id);
|
||
|
||
void acpi_ut_dump_buffer(u8 *buffer, u32 count, u32 display, u32 offset);
|
||
@@ -707,25 +724,6 @@ const struct ah_device_id *acpi_ah_match_hardware_id(char *hid);
|
||
const char *acpi_ah_match_uuid(u8 *data);
|
||
|
||
/*
|
||
- * utprint - printf/vprintf output functions
|
||
- */
|
||
-const char *acpi_ut_scan_number(const char *string, u64 *number_ptr);
|
||
-
|
||
-const char *acpi_ut_print_number(char *string, u64 number);
|
||
-
|
||
-int
|
||
-acpi_ut_vsnprintf(char *string,
|
||
- acpi_size size, const char *format, va_list args);
|
||
-
|
||
-int acpi_ut_snprintf(char *string, acpi_size size, const char *format, ...);
|
||
-
|
||
-#ifdef ACPI_APPLICATION
|
||
-int acpi_ut_file_vprintf(ACPI_FILE file, const char *format, va_list args);
|
||
-
|
||
-int acpi_ut_file_printf(ACPI_FILE file, const char *format, ...);
|
||
-#endif
|
||
-
|
||
-/*
|
||
* utuuid -- UUID support functions
|
||
*/
|
||
#if (defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP || defined ACPI_HELP_APP)
|
||
diff --git a/drivers/acpi/acpica/dbfileio.c b/drivers/acpi/acpica/dbfileio.c
|
||
index 4832879..6f05b8c 100644
|
||
--- a/drivers/acpi/acpica/dbfileio.c
|
||
+++ b/drivers/acpi/acpica/dbfileio.c
|
||
@@ -46,14 +46,12 @@
|
||
#include "accommon.h"
|
||
#include "acdebug.h"
|
||
#include "actables.h"
|
||
-#include <stdio.h>
|
||
-#ifdef ACPI_APPLICATION
|
||
-#include "acapps.h"
|
||
-#endif
|
||
|
||
#define _COMPONENT ACPI_CA_DEBUGGER
|
||
ACPI_MODULE_NAME("dbfileio")
|
||
|
||
+#ifdef ACPI_APPLICATION
|
||
+#include "acapps.h"
|
||
#ifdef ACPI_DEBUGGER
|
||
/*******************************************************************************
|
||
*
|
||
@@ -69,8 +67,6 @@ ACPI_MODULE_NAME("dbfileio")
|
||
void acpi_db_close_debug_file(void)
|
||
{
|
||
|
||
-#ifdef ACPI_APPLICATION
|
||
-
|
||
if (acpi_gbl_debug_file) {
|
||
fclose(acpi_gbl_debug_file);
|
||
acpi_gbl_debug_file = NULL;
|
||
@@ -78,7 +74,6 @@ void acpi_db_close_debug_file(void)
|
||
acpi_os_printf("Debug output file %s closed\n",
|
||
acpi_gbl_db_debug_filename);
|
||
}
|
||
-#endif
|
||
}
|
||
|
||
/*******************************************************************************
|
||
@@ -96,8 +91,6 @@ void acpi_db_close_debug_file(void)
|
||
void acpi_db_open_debug_file(char *name)
|
||
{
|
||
|
||
-#ifdef ACPI_APPLICATION
|
||
-
|
||
acpi_db_close_debug_file();
|
||
acpi_gbl_debug_file = fopen(name, "w+");
|
||
if (!acpi_gbl_debug_file) {
|
||
@@ -109,8 +102,6 @@ void acpi_db_open_debug_file(char *name)
|
||
strncpy(acpi_gbl_db_debug_filename, name,
|
||
sizeof(acpi_gbl_db_debug_filename));
|
||
acpi_gbl_db_output_to_file = TRUE;
|
||
-
|
||
-#endif
|
||
}
|
||
#endif
|
||
|
||
@@ -152,12 +143,13 @@ acpi_status acpi_db_load_tables(struct acpi_new_table_desc *list_head)
|
||
return (status);
|
||
}
|
||
|
||
- fprintf(stderr,
|
||
- "Acpi table [%4.4s] successfully installed and loaded\n",
|
||
- table->signature);
|
||
+ acpi_os_printf
|
||
+ ("Acpi table [%4.4s] successfully installed and loaded\n",
|
||
+ table->signature);
|
||
|
||
table_list_head = table_list_head->next;
|
||
}
|
||
|
||
return (AE_OK);
|
||
}
|
||
+#endif
|
||
diff --git a/drivers/acpi/acpica/dbobject.c b/drivers/acpi/acpica/dbobject.c
|
||
index 1d59e8b..08eaaf3 100644
|
||
--- a/drivers/acpi/acpica/dbobject.c
|
||
+++ b/drivers/acpi/acpica/dbobject.c
|
||
@@ -142,11 +142,11 @@ void acpi_db_decode_internal_object(union acpi_operand_object *obj_desc)
|
||
|
||
case ACPI_TYPE_STRING:
|
||
|
||
- acpi_os_printf("(%u) \"%.24s",
|
||
+ acpi_os_printf("(%u) \"%.60s",
|
||
obj_desc->string.length,
|
||
obj_desc->string.pointer);
|
||
|
||
- if (obj_desc->string.length > 24) {
|
||
+ if (obj_desc->string.length > 60) {
|
||
acpi_os_printf("...");
|
||
} else {
|
||
acpi_os_printf("\"");
|
||
diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c
|
||
index f393de9..7d8ef52 100644
|
||
--- a/drivers/acpi/acpica/dsutils.c
|
||
+++ b/drivers/acpi/acpica/dsutils.c
|
||
@@ -565,15 +565,14 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state,
|
||
status = AE_OK;
|
||
} else if (parent_op->common.aml_opcode ==
|
||
AML_EXTERNAL_OP) {
|
||
-
|
||
- /* TBD: May only be temporary */
|
||
-
|
||
- obj_desc =
|
||
- acpi_ut_create_string_object((acpi_size)name_length);
|
||
-
|
||
- strncpy(obj_desc->string.pointer,
|
||
- name_string, name_length);
|
||
- status = AE_OK;
|
||
+ /*
|
||
+ * This opcode should never appear here. It is used only
|
||
+ * by AML disassemblers and is surrounded by an If(0)
|
||
+ * by the ASL compiler.
|
||
+ *
|
||
+ * Therefore, if we see it here, it is a serious error.
|
||
+ */
|
||
+ status = AE_AML_BAD_OPCODE;
|
||
} else {
|
||
/*
|
||
* We just plain didn't find it -- which is a
|
||
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c
|
||
index 4b4949c..bdb10be 100644
|
||
--- a/drivers/acpi/acpica/evgpe.c
|
||
+++ b/drivers/acpi/acpica/evgpe.c
|
||
@@ -130,6 +130,60 @@ acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
|
||
|
||
/*******************************************************************************
|
||
*
|
||
+ * FUNCTION: acpi_ev_mask_gpe
|
||
+ *
|
||
+ * PARAMETERS: gpe_event_info - GPE to be blocked/unblocked
|
||
+ * is_masked - Whether the GPE is masked or not
|
||
+ *
|
||
+ * RETURN: Status
|
||
+ *
|
||
+ * DESCRIPTION: Unconditionally mask/unmask a GPE during runtime.
|
||
+ *
|
||
+ ******************************************************************************/
|
||
+
|
||
+acpi_status
|
||
+acpi_ev_mask_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 is_masked)
|
||
+{
|
||
+ struct acpi_gpe_register_info *gpe_register_info;
|
||
+ u32 register_bit;
|
||
+
|
||
+ ACPI_FUNCTION_TRACE(ev_mask_gpe);
|
||
+
|
||
+ gpe_register_info = gpe_event_info->register_info;
|
||
+ if (!gpe_register_info) {
|
||
+ return_ACPI_STATUS(AE_NOT_EXIST);
|
||
+ }
|
||
+
|
||
+ register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
|
||
+
|
||
+ /* Perform the action */
|
||
+
|
||
+ if (is_masked) {
|
||
+ if (register_bit & gpe_register_info->mask_for_run) {
|
||
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||
+ }
|
||
+
|
||
+ (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
|
||
+ ACPI_SET_BIT(gpe_register_info->mask_for_run, (u8)register_bit);
|
||
+ } else {
|
||
+ if (!(register_bit & gpe_register_info->mask_for_run)) {
|
||
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||
+ }
|
||
+
|
||
+ ACPI_CLEAR_BIT(gpe_register_info->mask_for_run,
|
||
+ (u8)register_bit);
|
||
+ if (gpe_event_info->runtime_count
|
||
+ && !gpe_event_info->disable_for_dispatch) {
|
||
+ (void)acpi_hw_low_set_gpe(gpe_event_info,
|
||
+ ACPI_GPE_ENABLE);
|
||
+ }
|
||
+ }
|
||
+
|
||
+ return_ACPI_STATUS(AE_OK);
|
||
+}
|
||
+
|
||
+/*******************************************************************************
|
||
+ *
|
||
* FUNCTION: acpi_ev_add_gpe_reference
|
||
*
|
||
* PARAMETERS: gpe_event_info - Add a reference to this GPE
|
||
@@ -674,6 +728,7 @@ acpi_status acpi_ev_finish_gpe(struct acpi_gpe_event_info *gpe_event_info)
|
||
* in the event_info.
|
||
*/
|
||
(void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_CONDITIONAL_ENABLE);
|
||
+ gpe_event_info->disable_for_dispatch = FALSE;
|
||
return (AE_OK);
|
||
}
|
||
|
||
@@ -737,6 +792,8 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
|
||
}
|
||
}
|
||
|
||
+ gpe_event_info->disable_for_dispatch = TRUE;
|
||
+
|
||
/*
|
||
* Dispatch the GPE to either an installed handler or the control
|
||
* method associated with this GPE (_Lxx or _Exx). If a handler
|
||
diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c
|
||
index 17cfef7..d7a3b27 100644
|
||
--- a/drivers/acpi/acpica/evxfgpe.c
|
||
+++ b/drivers/acpi/acpica/evxfgpe.c
|
||
@@ -235,11 +235,13 @@ acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action)
|
||
case ACPI_GPE_ENABLE:
|
||
|
||
status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE);
|
||
+ gpe_event_info->disable_for_dispatch = FALSE;
|
||
break;
|
||
|
||
case ACPI_GPE_DISABLE:
|
||
|
||
status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
|
||
+ gpe_event_info->disable_for_dispatch = TRUE;
|
||
break;
|
||
|
||
default:
|
||
@@ -257,6 +259,47 @@ ACPI_EXPORT_SYMBOL(acpi_set_gpe)
|
||
|
||
/*******************************************************************************
|
||
*
|
||
+ * FUNCTION: acpi_mask_gpe
|
||
+ *
|
||
+ * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
|
||
+ * gpe_number - GPE level within the GPE block
|
||
+ * is_masked - Whether the GPE is masked or not
|
||
+ *
|
||
+ * RETURN: Status
|
||
+ *
|
||
+ * DESCRIPTION: Unconditionally mask/unmask the an individual GPE, ex., to
|
||
+ * prevent a GPE flooding.
|
||
+ *
|
||
+ ******************************************************************************/
|
||
+acpi_status acpi_mask_gpe(acpi_handle gpe_device, u32 gpe_number, u8 is_masked)
|
||
+{
|
||
+ struct acpi_gpe_event_info *gpe_event_info;
|
||
+ acpi_status status;
|
||
+ acpi_cpu_flags flags;
|
||
+
|
||
+ ACPI_FUNCTION_TRACE(acpi_mask_gpe);
|
||
+
|
||
+ flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
|
||
+
|
||
+ /* Ensure that we have a valid GPE number */
|
||
+
|
||
+ gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
|
||
+ if (!gpe_event_info) {
|
||
+ status = AE_BAD_PARAMETER;
|
||
+ goto unlock_and_exit;
|
||
+ }
|
||
+
|
||
+ status = acpi_ev_mask_gpe(gpe_event_info, is_masked);
|
||
+
|
||
+unlock_and_exit:
|
||
+ acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
|
||
+ return_ACPI_STATUS(status);
|
||
+}
|
||
+
|
||
+ACPI_EXPORT_SYMBOL(acpi_mask_gpe)
|
||
+
|
||
+/*******************************************************************************
|
||
+ *
|
||
* FUNCTION: acpi_mark_gpe_for_wake
|
||
*
|
||
* PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
|
||
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c
|
||
index bdecd5e..76b0e35 100644
|
||
--- a/drivers/acpi/acpica/hwgpe.c
|
||
+++ b/drivers/acpi/acpica/hwgpe.c
|
||
@@ -98,7 +98,7 @@ acpi_status
|
||
acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action)
|
||
{
|
||
struct acpi_gpe_register_info *gpe_register_info;
|
||
- acpi_status status;
|
||
+ acpi_status status = AE_OK;
|
||
u32 enable_mask;
|
||
u32 register_bit;
|
||
|
||
@@ -148,9 +148,14 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action)
|
||
return (AE_BAD_PARAMETER);
|
||
}
|
||
|
||
- /* Write the updated enable mask */
|
||
+ if (!(register_bit & gpe_register_info->mask_for_run)) {
|
||
|
||
- status = acpi_hw_write(enable_mask, &gpe_register_info->enable_address);
|
||
+ /* Write the updated enable mask */
|
||
+
|
||
+ status =
|
||
+ acpi_hw_write(enable_mask,
|
||
+ &gpe_register_info->enable_address);
|
||
+ }
|
||
return (status);
|
||
}
|
||
|
||
@@ -242,6 +247,12 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info *gpe_event_info,
|
||
local_event_status |= ACPI_EVENT_FLAG_ENABLED;
|
||
}
|
||
|
||
+ /* GPE currently masked? (masked for runtime?) */
|
||
+
|
||
+ if (register_bit & gpe_register_info->mask_for_run) {
|
||
+ local_event_status |= ACPI_EVENT_FLAG_MASKED;
|
||
+ }
|
||
+
|
||
/* GPE enabled for wake? */
|
||
|
||
if (register_bit & gpe_register_info->enable_for_wake) {
|
||
@@ -397,6 +408,7 @@ acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
|
||
u32 i;
|
||
acpi_status status;
|
||
struct acpi_gpe_register_info *gpe_register_info;
|
||
+ u8 enable_mask;
|
||
|
||
/* NOTE: assumes that all GPEs are currently disabled */
|
||
|
||
@@ -410,9 +422,10 @@ acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
|
||
|
||
/* Enable all "runtime" GPEs in this register */
|
||
|
||
+ enable_mask = gpe_register_info->enable_for_run &
|
||
+ ~gpe_register_info->mask_for_run;
|
||
status =
|
||
- acpi_hw_gpe_enable_write(gpe_register_info->enable_for_run,
|
||
- gpe_register_info);
|
||
+ acpi_hw_gpe_enable_write(enable_mask, gpe_register_info);
|
||
if (ACPI_FAILURE(status)) {
|
||
return (status);
|
||
}
|
||
diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c
|
||
index 426a630..73f98d3 100644
|
||
--- a/drivers/acpi/acpica/nsaccess.c
|
||
+++ b/drivers/acpi/acpica/nsaccess.c
|
||
@@ -108,9 +108,9 @@ acpi_status acpi_ns_root_initialize(void)
|
||
}
|
||
|
||
status =
|
||
- acpi_ns_lookup(NULL, (char *)init_val->name, init_val->type,
|
||
- ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH,
|
||
- NULL, &new_node);
|
||
+ acpi_ns_lookup(NULL, ACPI_CAST_PTR(char, init_val->name),
|
||
+ init_val->type, ACPI_IMODE_LOAD_PASS2,
|
||
+ ACPI_NS_NO_UPSEARCH, NULL, &new_node);
|
||
if (ACPI_FAILURE(status)) {
|
||
ACPI_EXCEPTION((AE_INFO, status,
|
||
"Could not create predefined name %s",
|
||
diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c
|
||
index ce1f860..84f35dd 100644
|
||
--- a/drivers/acpi/acpica/nsdump.c
|
||
+++ b/drivers/acpi/acpica/nsdump.c
|
||
@@ -338,7 +338,7 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
|
||
case ACPI_TYPE_STRING:
|
||
|
||
acpi_os_printf("Len %.2X ", obj_desc->string.length);
|
||
- acpi_ut_print_string(obj_desc->string.pointer, 32);
|
||
+ acpi_ut_print_string(obj_desc->string.pointer, 80);
|
||
acpi_os_printf("\n");
|
||
break;
|
||
|
||
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c
|
||
index 6208069..016bcdc 100644
|
||
--- a/drivers/acpi/acpica/tbfadt.c
|
||
+++ b/drivers/acpi/acpica/tbfadt.c
|
||
@@ -476,17 +476,19 @@ static void acpi_tb_convert_fadt(void)
|
||
u32 i;
|
||
|
||
/*
|
||
- * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which
|
||
+ * For ACPI 1.0 FADTs (revision 1), ensure that reserved fields which
|
||
* should be zero are indeed zero. This will workaround BIOSs that
|
||
* inadvertently place values in these fields.
|
||
*
|
||
* The ACPI 1.0 reserved fields that will be zeroed are the bytes located
|
||
* at offset 45, 55, 95, and the word located at offset 109, 110.
|
||
*
|
||
- * Note: The FADT revision value is unreliable. Only the length can be
|
||
- * trusted.
|
||
+ * Note: The FADT revision value is unreliable because of BIOS errors.
|
||
+ * The table length is instead used as the final word on the version.
|
||
+ *
|
||
+ * Note: FADT revision 3 is the ACPI 2.0 version of the FADT.
|
||
*/
|
||
- if (acpi_gbl_FADT.header.length <= ACPI_FADT_V2_SIZE) {
|
||
+ if (acpi_gbl_FADT.header.length <= ACPI_FADT_V3_SIZE) {
|
||
acpi_gbl_FADT.preferred_profile = 0;
|
||
acpi_gbl_FADT.pstate_control = 0;
|
||
acpi_gbl_FADT.cst_control = 0;
|
||
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c
|
||
index e285539..51eb07c 100644
|
||
--- a/drivers/acpi/acpica/tbutils.c
|
||
+++ b/drivers/acpi/acpica/tbutils.c
|
||
@@ -252,7 +252,8 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size)
|
||
*
|
||
******************************************************************************/
|
||
|
||
-acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
|
||
+acpi_status ACPI_INIT_FUNCTION
|
||
+acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
|
||
{
|
||
struct acpi_table_rsdp *rsdp;
|
||
u32 table_entry_size;
|
||
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
|
||
index 3ecec93..4ab6b9c 100644
|
||
--- a/drivers/acpi/acpica/tbxface.c
|
||
+++ b/drivers/acpi/acpica/tbxface.c
|
||
@@ -98,7 +98,7 @@ acpi_status acpi_allocate_root_table(u32 initial_table_count)
|
||
*
|
||
******************************************************************************/
|
||
|
||
-acpi_status __init
|
||
+acpi_status ACPI_INIT_FUNCTION
|
||
acpi_initialize_tables(struct acpi_table_desc *initial_table_array,
|
||
u32 initial_table_count, u8 allow_resize)
|
||
{
|
||
@@ -164,7 +164,7 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_initialize_tables)
|
||
* kernel.
|
||
*
|
||
******************************************************************************/
|
||
-acpi_status __init acpi_reallocate_root_table(void)
|
||
+acpi_status ACPI_INIT_FUNCTION acpi_reallocate_root_table(void)
|
||
{
|
||
acpi_status status;
|
||
|
||
diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c
|
||
index ac71abc..e0cc919 100644
|
||
--- a/drivers/acpi/acpica/tbxfload.c
|
||
+++ b/drivers/acpi/acpica/tbxfload.c
|
||
@@ -63,7 +63,7 @@ ACPI_MODULE_NAME("tbxfload")
|
||
* DESCRIPTION: Load the ACPI tables from the RSDT/XSDT
|
||
*
|
||
******************************************************************************/
|
||
-acpi_status __init acpi_load_tables(void)
|
||
+acpi_status ACPI_INIT_FUNCTION acpi_load_tables(void)
|
||
{
|
||
acpi_status status;
|
||
|
||
@@ -272,7 +272,7 @@ unlock_and_exit:
|
||
*
|
||
******************************************************************************/
|
||
|
||
-acpi_status __init
|
||
+acpi_status ACPI_INIT_FUNCTION
|
||
acpi_install_table(acpi_physical_address address, u8 physical)
|
||
{
|
||
acpi_status status;
|
||
diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c
|
||
index adb6cfc..0adb1c7 100644
|
||
--- a/drivers/acpi/acpica/tbxfroot.c
|
||
+++ b/drivers/acpi/acpica/tbxfroot.c
|
||
@@ -142,7 +142,8 @@ acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp)
|
||
*
|
||
******************************************************************************/
|
||
|
||
-acpi_status __init acpi_find_root_pointer(acpi_physical_address *table_address)
|
||
+acpi_status ACPI_INIT_FUNCTION
|
||
+acpi_find_root_pointer(acpi_physical_address *table_address)
|
||
{
|
||
u8 *table_ptr;
|
||
u8 *mem_rover;
|
||
@@ -244,6 +245,8 @@ acpi_status __init acpi_find_root_pointer(acpi_physical_address *table_address)
|
||
return_ACPI_STATUS(AE_NOT_FOUND);
|
||
}
|
||
|
||
+ACPI_EXPORT_SYMBOL_INIT(acpi_find_root_pointer)
|
||
+
|
||
/*******************************************************************************
|
||
*
|
||
* FUNCTION: acpi_tb_scan_memory_for_rsdp
|
||
diff --git a/drivers/acpi/acpica/utbuffer.c b/drivers/acpi/acpica/utbuffer.c
|
||
index bd31faf..ff29812 100644
|
||
--- a/drivers/acpi/acpica/utbuffer.c
|
||
+++ b/drivers/acpi/acpica/utbuffer.c
|
||
@@ -239,8 +239,7 @@ acpi_ut_dump_buffer_to_file(ACPI_FILE file,
|
||
u8 buf_char;
|
||
|
||
if (!buffer) {
|
||
- acpi_ut_file_printf(file,
|
||
- "Null Buffer Pointer in DumpBuffer!\n");
|
||
+ fprintf(file, "Null Buffer Pointer in DumpBuffer!\n");
|
||
return;
|
||
}
|
||
|
||
@@ -254,7 +253,7 @@ acpi_ut_dump_buffer_to_file(ACPI_FILE file,
|
||
|
||
/* Print current offset */
|
||
|
||
- acpi_ut_file_printf(file, "%6.4X: ", (base_offset + i));
|
||
+ fprintf(file, "%6.4X: ", (base_offset + i));
|
||
|
||
/* Print 16 hex chars */
|
||
|
||
@@ -263,8 +262,7 @@ acpi_ut_dump_buffer_to_file(ACPI_FILE file,
|
||
|
||
/* Dump fill spaces */
|
||
|
||
- acpi_ut_file_printf(file, "%*s",
|
||
- ((display * 2) + 1), " ");
|
||
+ fprintf(file, "%*s", ((display * 2) + 1), " ");
|
||
j += display;
|
||
continue;
|
||
}
|
||
@@ -273,34 +271,34 @@ acpi_ut_dump_buffer_to_file(ACPI_FILE file,
|
||
case DB_BYTE_DISPLAY:
|
||
default: /* Default is BYTE display */
|
||
|
||
- acpi_ut_file_printf(file, "%02X ",
|
||
- buffer[(acpi_size)i + j]);
|
||
+ fprintf(file, "%02X ",
|
||
+ buffer[(acpi_size)i + j]);
|
||
break;
|
||
|
||
case DB_WORD_DISPLAY:
|
||
|
||
ACPI_MOVE_16_TO_32(&temp32,
|
||
&buffer[(acpi_size)i + j]);
|
||
- acpi_ut_file_printf(file, "%04X ", temp32);
|
||
+ fprintf(file, "%04X ", temp32);
|
||
break;
|
||
|
||
case DB_DWORD_DISPLAY:
|
||
|
||
ACPI_MOVE_32_TO_32(&temp32,
|
||
&buffer[(acpi_size)i + j]);
|
||
- acpi_ut_file_printf(file, "%08X ", temp32);
|
||
+ fprintf(file, "%08X ", temp32);
|
||
break;
|
||
|
||
case DB_QWORD_DISPLAY:
|
||
|
||
ACPI_MOVE_32_TO_32(&temp32,
|
||
&buffer[(acpi_size)i + j]);
|
||
- acpi_ut_file_printf(file, "%08X", temp32);
|
||
+ fprintf(file, "%08X", temp32);
|
||
|
||
ACPI_MOVE_32_TO_32(&temp32,
|
||
&buffer[(acpi_size)i + j +
|
||
4]);
|
||
- acpi_ut_file_printf(file, "%08X ", temp32);
|
||
+ fprintf(file, "%08X ", temp32);
|
||
break;
|
||
}
|
||
|
||
@@ -311,24 +309,24 @@ acpi_ut_dump_buffer_to_file(ACPI_FILE file,
|
||
* Print the ASCII equivalent characters but watch out for the bad
|
||
* unprintable ones (printable chars are 0x20 through 0x7E)
|
||
*/
|
||
- acpi_ut_file_printf(file, " ");
|
||
+ fprintf(file, " ");
|
||
for (j = 0; j < 16; j++) {
|
||
if (i + j >= count) {
|
||
- acpi_ut_file_printf(file, "\n");
|
||
+ fprintf(file, "\n");
|
||
return;
|
||
}
|
||
|
||
buf_char = buffer[(acpi_size)i + j];
|
||
if (isprint(buf_char)) {
|
||
- acpi_ut_file_printf(file, "%c", buf_char);
|
||
+ fprintf(file, "%c", buf_char);
|
||
} else {
|
||
- acpi_ut_file_printf(file, ".");
|
||
+ fprintf(file, ".");
|
||
}
|
||
}
|
||
|
||
/* Done with that line. */
|
||
|
||
- acpi_ut_file_printf(file, "\n");
|
||
+ fprintf(file, "\n");
|
||
i += 16;
|
||
}
|
||
|
||
diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c
|
||
index 5744222..044df9b 100644
|
||
--- a/drivers/acpi/acpica/utdebug.c
|
||
+++ b/drivers/acpi/acpica/utdebug.c
|
||
@@ -562,6 +562,43 @@ acpi_ut_ptr_exit(u32 line_number,
|
||
|
||
/*******************************************************************************
|
||
*
|
||
+ * FUNCTION: acpi_ut_str_exit
|
||
+ *
|
||
+ * PARAMETERS: line_number - Caller's line number
|
||
+ * function_name - Caller's procedure name
|
||
+ * module_name - Caller's module name
|
||
+ * component_id - Caller's component ID
|
||
+ * string - String to display
|
||
+ *
|
||
+ * RETURN: None
|
||
+ *
|
||
+ * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is
|
||
+ * set in debug_level. Prints exit value also.
|
||
+ *
|
||
+ ******************************************************************************/
|
||
+
|
||
+void
|
||
+acpi_ut_str_exit(u32 line_number,
|
||
+ const char *function_name,
|
||
+ const char *module_name, u32 component_id, const char *string)
|
||
+{
|
||
+
|
||
+ /* Check if enabled up-front for performance */
|
||
+
|
||
+ if (ACPI_IS_DEBUG_ENABLED(ACPI_LV_FUNCTIONS, component_id)) {
|
||
+ acpi_debug_print(ACPI_LV_FUNCTIONS,
|
||
+ line_number, function_name, module_name,
|
||
+ component_id, "%s %s\n",
|
||
+ acpi_gbl_function_exit_prefix, string);
|
||
+ }
|
||
+
|
||
+ if (acpi_gbl_nesting_level) {
|
||
+ acpi_gbl_nesting_level--;
|
||
+ }
|
||
+}
|
||
+
|
||
+/*******************************************************************************
|
||
+ *
|
||
* FUNCTION: acpi_trace_point
|
||
*
|
||
* PARAMETERS: type - Trace event type
|
||
@@ -591,27 +628,3 @@ acpi_trace_point(acpi_trace_event_type type, u8 begin, u8 *aml, char *pathname)
|
||
|
||
ACPI_EXPORT_SYMBOL(acpi_trace_point)
|
||
#endif
|
||
-#ifdef ACPI_APPLICATION
|
||
-/*******************************************************************************
|
||
- *
|
||
- * FUNCTION: acpi_log_error
|
||
- *
|
||
- * PARAMETERS: format - Printf format field
|
||
- * ... - Optional printf arguments
|
||
- *
|
||
- * RETURN: None
|
||
- *
|
||
- * DESCRIPTION: Print error message to the console, used by applications.
|
||
- *
|
||
- ******************************************************************************/
|
||
-void ACPI_INTERNAL_VAR_XFACE acpi_log_error(const char *format, ...)
|
||
-{
|
||
- va_list args;
|
||
-
|
||
- va_start(args, format);
|
||
- (void)acpi_ut_file_vprintf(ACPI_FILE_ERR, format, args);
|
||
- va_end(args);
|
||
-}
|
||
-
|
||
-ACPI_EXPORT_SYMBOL(acpi_log_error)
|
||
-#endif
|
||
diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c
|
||
index efd7988..15728ad 100644
|
||
--- a/drivers/acpi/acpica/utdecode.c
|
||
+++ b/drivers/acpi/acpica/utdecode.c
|
||
@@ -253,7 +253,7 @@ const char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc)
|
||
return_PTR("Invalid object");
|
||
}
|
||
|
||
- return_PTR(acpi_ut_get_type_name(obj_desc->common.type));
|
||
+ return_STR(acpi_ut_get_type_name(obj_desc->common.type));
|
||
}
|
||
|
||
/*******************************************************************************
|
||
diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c
|
||
index f91f724..1711fdf 100644
|
||
--- a/drivers/acpi/acpica/utinit.c
|
||
+++ b/drivers/acpi/acpica/utinit.c
|
||
@@ -206,7 +206,7 @@ acpi_status acpi_ut_init_globals(void)
|
||
acpi_gbl_next_owner_id_offset = 0;
|
||
acpi_gbl_debugger_configuration = DEBUGGER_THREADING;
|
||
acpi_gbl_osi_mutex = NULL;
|
||
- acpi_gbl_max_loop_iterations = 0xFFFF;
|
||
+ acpi_gbl_max_loop_iterations = ACPI_MAX_LOOP_COUNT;
|
||
|
||
/* Hardware oriented */
|
||
|
||
diff --git a/drivers/acpi/acpica/utpredef.c b/drivers/acpi/acpica/utpredef.c
|
||
index 770a177..ce18346 100644
|
||
--- a/drivers/acpi/acpica/utpredef.c
|
||
+++ b/drivers/acpi/acpica/utpredef.c
|
||
@@ -176,8 +176,6 @@ void acpi_ut_get_expected_return_types(char *buffer, u32 expected_btypes)
|
||
******************************************************************************/
|
||
|
||
#if (defined ACPI_ASL_COMPILER || defined ACPI_HELP_APP)
|
||
-#include <stdio.h>
|
||
-#include <string.h>
|
||
|
||
/* Local prototypes */
|
||
|
||
diff --git a/drivers/acpi/acpica/utprint.c b/drivers/acpi/acpica/utprint.c
|
||
index dd084cf..40eba80 100644
|
||
--- a/drivers/acpi/acpica/utprint.c
|
||
+++ b/drivers/acpi/acpica/utprint.c
|
||
@@ -336,7 +336,7 @@ static char *acpi_ut_format_number(char *string,
|
||
|
||
/*******************************************************************************
|
||
*
|
||
- * FUNCTION: acpi_ut_vsnprintf
|
||
+ * FUNCTION: vsnprintf
|
||
*
|
||
* PARAMETERS: string - String with boundary
|
||
* size - Boundary of the string
|
||
@@ -349,9 +349,7 @@ static char *acpi_ut_format_number(char *string,
|
||
*
|
||
******************************************************************************/
|
||
|
||
-int
|
||
-acpi_ut_vsnprintf(char *string,
|
||
- acpi_size size, const char *format, va_list args)
|
||
+int vsnprintf(char *string, acpi_size size, const char *format, va_list args)
|
||
{
|
||
u8 base;
|
||
u8 type;
|
||
@@ -586,7 +584,7 @@ acpi_ut_vsnprintf(char *string,
|
||
|
||
/*******************************************************************************
|
||
*
|
||
- * FUNCTION: acpi_ut_snprintf
|
||
+ * FUNCTION: snprintf
|
||
*
|
||
* PARAMETERS: string - String with boundary
|
||
* size - Boundary of the string
|
||
@@ -598,13 +596,38 @@ acpi_ut_vsnprintf(char *string,
|
||
*
|
||
******************************************************************************/
|
||
|
||
-int acpi_ut_snprintf(char *string, acpi_size size, const char *format, ...)
|
||
+int snprintf(char *string, acpi_size size, const char *format, ...)
|
||
{
|
||
va_list args;
|
||
int length;
|
||
|
||
va_start(args, format);
|
||
- length = acpi_ut_vsnprintf(string, size, format, args);
|
||
+ length = vsnprintf(string, size, format, args);
|
||
+ va_end(args);
|
||
+
|
||
+ return (length);
|
||
+}
|
||
+
|
||
+/*******************************************************************************
|
||
+ *
|
||
+ * FUNCTION: sprintf
|
||
+ *
|
||
+ * PARAMETERS: string - String with boundary
|
||
+ * Format, ... - Standard printf format
|
||
+ *
|
||
+ * RETURN: Number of bytes actually written.
|
||
+ *
|
||
+ * DESCRIPTION: Formatted output to a string.
|
||
+ *
|
||
+ ******************************************************************************/
|
||
+
|
||
+int sprintf(char *string, const char *format, ...)
|
||
+{
|
||
+ va_list args;
|
||
+ int length;
|
||
+
|
||
+ va_start(args, format);
|
||
+ length = vsnprintf(string, ACPI_UINT32_MAX, format, args);
|
||
va_end(args);
|
||
|
||
return (length);
|
||
@@ -613,7 +636,59 @@ int acpi_ut_snprintf(char *string, acpi_size size, const char *format, ...)
|
||
#ifdef ACPI_APPLICATION
|
||
/*******************************************************************************
|
||
*
|
||
- * FUNCTION: acpi_ut_file_vprintf
|
||
+ * FUNCTION: vprintf
|
||
+ *
|
||
+ * PARAMETERS: format - Standard printf format
|
||
+ * args - Argument list
|
||
+ *
|
||
+ * RETURN: Number of bytes actually written.
|
||
+ *
|
||
+ * DESCRIPTION: Formatted output to stdout using argument list pointer.
|
||
+ *
|
||
+ ******************************************************************************/
|
||
+
|
||
+int vprintf(const char *format, va_list args)
|
||
+{
|
||
+ acpi_cpu_flags flags;
|
||
+ int length;
|
||
+
|
||
+ flags = acpi_os_acquire_lock(acpi_gbl_print_lock);
|
||
+ length = vsnprintf(acpi_gbl_print_buffer,
|
||
+ sizeof(acpi_gbl_print_buffer), format, args);
|
||
+
|
||
+ (void)fwrite(acpi_gbl_print_buffer, length, 1, ACPI_FILE_OUT);
|
||
+ acpi_os_release_lock(acpi_gbl_print_lock, flags);
|
||
+
|
||
+ return (length);
|
||
+}
|
||
+
|
||
+/*******************************************************************************
|
||
+ *
|
||
+ * FUNCTION: printf
|
||
+ *
|
||
+ * PARAMETERS: Format, ... - Standard printf format
|
||
+ *
|
||
+ * RETURN: Number of bytes actually written.
|
||
+ *
|
||
+ * DESCRIPTION: Formatted output to stdout.
|
||
+ *
|
||
+ ******************************************************************************/
|
||
+
|
||
+int printf(const char *format, ...)
|
||
+{
|
||
+ va_list args;
|
||
+ int length;
|
||
+
|
||
+ va_start(args, format);
|
||
+ length = vprintf(format, args);
|
||
+ va_end(args);
|
||
+
|
||
+ return (length);
|
||
+}
|
||
+
|
||
+/*******************************************************************************
|
||
+ *
|
||
+ * FUNCTION: vfprintf
|
||
*
|
||
* PARAMETERS: file - File descriptor
|
||
* format - Standard printf format
|
||
@@ -625,16 +700,16 @@ int acpi_ut_snprintf(char *string, acpi_size size, const char *format, ...)
|
||
*
|
||
******************************************************************************/
|
||
|
||
-int acpi_ut_file_vprintf(ACPI_FILE file, const char *format, va_list args)
|
||
+int vfprintf(FILE * file, const char *format, va_list args)
|
||
{
|
||
acpi_cpu_flags flags;
|
||
int length;
|
||
|
||
flags = acpi_os_acquire_lock(acpi_gbl_print_lock);
|
||
- length = acpi_ut_vsnprintf(acpi_gbl_print_buffer,
|
||
- sizeof(acpi_gbl_print_buffer), format, args);
|
||
+ length = vsnprintf(acpi_gbl_print_buffer,
|
||
+ sizeof(acpi_gbl_print_buffer), format, args);
|
||
|
||
- (void)acpi_os_write_file(file, acpi_gbl_print_buffer, length, 1);
|
||
+ (void)fwrite(acpi_gbl_print_buffer, length, 1, file);
|
||
acpi_os_release_lock(acpi_gbl_print_lock, flags);
|
||
|
||
return (length);
|
||
@@ -642,7 +717,7 @@ int acpi_ut_file_vprintf(ACPI_FILE file, const char *format, va_list args)
|
||
|
||
/*******************************************************************************
|
||
*
|
||
- * FUNCTION: acpi_ut_file_printf
|
||
+ * FUNCTION: fprintf
|
||
*
|
||
* PARAMETERS: file - File descriptor
|
||
* Format, ... - Standard printf format
|
||
@@ -653,13 +728,13 @@ int acpi_ut_file_vprintf(ACPI_FILE file, const char *format, va_list args)
|
||
*
|
||
******************************************************************************/
|
||
|
||
-int acpi_ut_file_printf(ACPI_FILE file, const char *format, ...)
|
||
+int fprintf(FILE * file, const char *format, ...)
|
||
{
|
||
va_list args;
|
||
int length;
|
||
|
||
va_start(args, format);
|
||
- length = acpi_ut_file_vprintf(file, format, args);
|
||
+ length = vfprintf(file, format, args);
|
||
va_end(args);
|
||
|
||
return (length);
|
||
diff --git a/drivers/acpi/acpica/uttrack.c b/drivers/acpi/acpica/uttrack.c
|
||
index 0df07df..df31d71 100644
|
||
--- a/drivers/acpi/acpica/uttrack.c
|
||
+++ b/drivers/acpi/acpica/uttrack.c
|
||
@@ -95,13 +95,11 @@ acpi_ut_create_list(const char *list_name,
|
||
{
|
||
struct acpi_memory_list *cache;
|
||
|
||
- cache = acpi_os_allocate(sizeof(struct acpi_memory_list));
|
||
+ cache = acpi_os_allocate_zeroed(sizeof(struct acpi_memory_list));
|
||
if (!cache) {
|
||
return (AE_NO_MEMORY);
|
||
}
|
||
|
||
- memset(cache, 0, sizeof(struct acpi_memory_list));
|
||
-
|
||
cache->list_name = list_name;
|
||
cache->object_size = object_size;
|
||
|
||
diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c
|
||
index d9e6aac..ec503c8 100644
|
||
--- a/drivers/acpi/acpica/utxface.c
|
||
+++ b/drivers/acpi/acpica/utxface.c
|
||
@@ -61,7 +61,7 @@ ACPI_MODULE_NAME("utxface")
|
||
* DESCRIPTION: Shutdown the ACPICA subsystem and release all resources.
|
||
*
|
||
******************************************************************************/
|
||
-acpi_status __init acpi_terminate(void)
|
||
+acpi_status ACPI_INIT_FUNCTION acpi_terminate(void)
|
||
{
|
||
acpi_status status;
|
||
|
||
diff --git a/drivers/acpi/acpica/utxfinit.c b/drivers/acpi/acpica/utxfinit.c
|
||
index 75b5f27..d6d9462 100644
|
||
--- a/drivers/acpi/acpica/utxfinit.c
|
||
+++ b/drivers/acpi/acpica/utxfinit.c
|
||
@@ -69,7 +69,7 @@ void ae_do_object_overrides(void);
|
||
*
|
||
******************************************************************************/
|
||
|
||
-acpi_status __init acpi_initialize_subsystem(void)
|
||
+acpi_status ACPI_INIT_FUNCTION acpi_initialize_subsystem(void)
|
||
{
|
||
acpi_status status;
|
||
|
||
@@ -141,7 +141,7 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_initialize_subsystem)
|
||
* Puts system into ACPI mode if it isn't already.
|
||
*
|
||
******************************************************************************/
|
||
-acpi_status __init acpi_enable_subsystem(u32 flags)
|
||
+acpi_status ACPI_INIT_FUNCTION acpi_enable_subsystem(u32 flags)
|
||
{
|
||
acpi_status status = AE_OK;
|
||
|
||
@@ -239,7 +239,7 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_enable_subsystem)
|
||
* objects and executing AML code for Regions, buffers, etc.
|
||
*
|
||
******************************************************************************/
|
||
-acpi_status __init acpi_initialize_objects(u32 flags)
|
||
+acpi_status ACPI_INIT_FUNCTION acpi_initialize_objects(u32 flags)
|
||
{
|
||
acpi_status status = AE_OK;
|
||
|
||
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
|
||
index a1f2aff..058c8b6 100644
|
||
--- a/drivers/base/power/domain.c
|
||
+++ b/drivers/base/power/domain.c
|
||
@@ -1636,7 +1636,7 @@ EXPORT_SYMBOL_GPL(genpd_dev_pm_attach);
|
||
|
||
/*** debugfs support ***/
|
||
|
||
-#ifdef CONFIG_PM_ADVANCED_DEBUG
|
||
+#ifdef CONFIG_DEBUG_FS
|
||
#include <linux/pm.h>
|
||
#include <linux/device.h>
|
||
#include <linux/debugfs.h>
|
||
@@ -1784,4 +1784,4 @@ static void __exit pm_genpd_debug_exit(void)
|
||
debugfs_remove_recursive(pm_genpd_debugfs_dir);
|
||
}
|
||
__exitcall(pm_genpd_debug_exit);
|
||
-#endif /* CONFIG_PM_ADVANCED_DEBUG */
|
||
+#endif /* CONFIG_DEBUG_FS */
|
||
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
|
||
index 74919aa..4dc9525 100644
|
||
--- a/drivers/cpufreq/Kconfig
|
||
+++ b/drivers/cpufreq/Kconfig
|
||
@@ -194,7 +194,7 @@ config CPU_FREQ_GOV_CONSERVATIVE
|
||
If in doubt, say N.
|
||
|
||
config CPU_FREQ_GOV_SCHEDUTIL
|
||
- tristate "'schedutil' cpufreq policy governor"
|
||
+ bool "'schedutil' cpufreq policy governor"
|
||
depends on CPU_FREQ && SMP
|
||
select CPU_FREQ_GOV_ATTR_SET
|
||
select IRQ_WORK
|
||
@@ -208,9 +208,6 @@ config CPU_FREQ_GOV_SCHEDUTIL
|
||
frequency tipping point is at utilization/capacity equal to 80% in
|
||
both cases.
|
||
|
||
- To compile this driver as a module, choose M here: the module will
|
||
- be called cpufreq_schedutil.
|
||
-
|
||
If in doubt, say N.
|
||
|
||
comment "CPU frequency scaling drivers"
|
||
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
|
||
index 0bb44d5..470db30 100644
|
||
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
|
||
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
|
||
@@ -40,6 +40,7 @@ static const struct of_device_id machines[] __initconst = {
|
||
{ .compatible = "samsung,exynos5250", },
|
||
#ifndef CONFIG_BL_SWITCHER
|
||
{ .compatible = "samsung,exynos5420", },
|
||
+ { .compatible = "samsung,exynos5433", },
|
||
{ .compatible = "samsung,exynos5800", },
|
||
#endif
|
||
|
||
diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
|
||
index e415349..642dd0f 100644
|
||
--- a/drivers/cpufreq/cpufreq_governor.c
|
||
+++ b/drivers/cpufreq/cpufreq_governor.c
|
||
@@ -260,7 +260,7 @@ static void dbs_irq_work(struct irq_work *irq_work)
|
||
}
|
||
|
||
static void dbs_update_util_handler(struct update_util_data *data, u64 time,
|
||
- unsigned long util, unsigned long max)
|
||
+ unsigned int flags)
|
||
{
|
||
struct cpu_dbs_info *cdbs = container_of(data, struct cpu_dbs_info, update_util);
|
||
struct policy_dbs_info *policy_dbs = cdbs->policy_dbs;
|
||
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
|
||
index be9eade..bdbe936 100644
|
||
--- a/drivers/cpufreq/intel_pstate.c
|
||
+++ b/drivers/cpufreq/intel_pstate.c
|
||
@@ -1329,7 +1329,7 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
|
||
}
|
||
|
||
static void intel_pstate_update_util(struct update_util_data *data, u64 time,
|
||
- unsigned long util, unsigned long max)
|
||
+ unsigned int flags)
|
||
{
|
||
struct cpudata *cpu = container_of(data, struct cpudata, update_util);
|
||
u64 delta_ns = time - cpu->sample.time;
|
||
diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c
|
||
index 4ba3d3f..f440d38 100644
|
||
--- a/drivers/cpuidle/cpuidle-arm.c
|
||
+++ b/drivers/cpuidle/cpuidle-arm.c
|
||
@@ -121,6 +121,7 @@ static int __init arm_idle_init(void)
|
||
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||
if (!dev) {
|
||
pr_err("Failed to allocate cpuidle device\n");
|
||
+ ret = -ENOMEM;
|
||
goto out_fail;
|
||
}
|
||
dev->cpu = cpu;
|
||
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
|
||
index cf88f9b6..d8bf5a1 100644
|
||
--- a/drivers/pnp/isapnp/core.c
|
||
+++ b/drivers/pnp/isapnp/core.c
|
||
@@ -34,7 +34,7 @@
|
||
* 2003-08-11 Resource Management Updates - Adam Belay <ambx1@neo.rr.com>
|
||
*/
|
||
|
||
-#include <linux/module.h>
|
||
+#include <linux/moduleparam.h>
|
||
#include <linux/kernel.h>
|
||
#include <linux/errno.h>
|
||
#include <linux/delay.h>
|
||
@@ -54,8 +54,6 @@ static int isapnp_rdp; /* Read Data Port */
|
||
static int isapnp_reset = 1; /* reset all PnP cards (deactivate) */
|
||
static int isapnp_verbose = 1; /* verbose mode */
|
||
|
||
-MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
|
||
-MODULE_DESCRIPTION("Generic ISA Plug & Play support");
|
||
module_param(isapnp_disable, int, 0);
|
||
MODULE_PARM_DESC(isapnp_disable, "ISA Plug & Play disable");
|
||
module_param(isapnp_rdp, int, 0);
|
||
@@ -64,7 +62,6 @@ module_param(isapnp_reset, int, 0);
|
||
MODULE_PARM_DESC(isapnp_reset, "ISA Plug & Play reset all cards");
|
||
module_param(isapnp_verbose, int, 0);
|
||
MODULE_PARM_DESC(isapnp_verbose, "ISA Plug & Play verbose mode");
|
||
-MODULE_LICENSE("GPL");
|
||
|
||
#define _PIDXR 0x279
|
||
#define _PNPWRP 0xa79
|
||
diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c
|
||
index 71a3392..5f81792 100644
|
||
--- a/drivers/thermal/rcar_thermal.c
|
||
+++ b/drivers/thermal/rcar_thermal.c
|
||
@@ -504,6 +504,7 @@ static int rcar_thermal_probe(struct platform_device *pdev)
|
||
if (IS_ERR(priv->zone)) {
|
||
dev_err(dev, "can't register thermal zone\n");
|
||
ret = PTR_ERR(priv->zone);
|
||
+ priv->zone = NULL;
|
||
goto error_unregister;
|
||
}
|
||
|
||
diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h
|
||
index fe2e3ac..12c2882 100644
|
||
--- a/include/acpi/acconfig.h
|
||
+++ b/include/acpi/acconfig.h
|
||
@@ -144,6 +144,10 @@
|
||
|
||
#define ACPI_ADDRESS_RANGE_MAX 2
|
||
|
||
+/* Maximum number of While() loops before abort */
|
||
+
|
||
+#define ACPI_MAX_LOOP_COUNT 0xFFFF
|
||
+
|
||
/******************************************************************************
|
||
*
|
||
* ACPI Specification constants (Do not change unless the specification changes)
|
||
diff --git a/include/acpi/acoutput.h b/include/acpi/acoutput.h
|
||
index 34f601e..48eb4dd 100644
|
||
--- a/include/acpi/acoutput.h
|
||
+++ b/include/acpi/acoutput.h
|
||
@@ -366,7 +366,7 @@
|
||
ACPI_TRACE_ENTRY (name, acpi_ut_trace_u32, u32, value)
|
||
|
||
#define ACPI_FUNCTION_TRACE_STR(name, string) \
|
||
- ACPI_TRACE_ENTRY (name, acpi_ut_trace_str, char *, string)
|
||
+ ACPI_TRACE_ENTRY (name, acpi_ut_trace_str, const char *, string)
|
||
|
||
#define ACPI_FUNCTION_ENTRY() \
|
||
acpi_ut_track_stack_ptr()
|
||
@@ -425,6 +425,9 @@
|
||
#define return_PTR(pointer) \
|
||
ACPI_TRACE_EXIT (acpi_ut_ptr_exit, void *, pointer)
|
||
|
||
+#define return_STR(string) \
|
||
+ ACPI_TRACE_EXIT (acpi_ut_str_exit, const char *, string)
|
||
+
|
||
#define return_VALUE(value) \
|
||
ACPI_TRACE_EXIT (acpi_ut_value_exit, u64, value)
|
||
|
||
@@ -478,6 +481,7 @@
|
||
#define return_VOID return
|
||
#define return_ACPI_STATUS(s) return(s)
|
||
#define return_PTR(s) return(s)
|
||
+#define return_STR(s) return(s)
|
||
#define return_VALUE(s) return(s)
|
||
#define return_UINT8(s) return(s)
|
||
#define return_UINT32(s) return(s)
|
||
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
|
||
index 562603d..f3414c8 100644
|
||
--- a/include/acpi/acpiosxf.h
|
||
+++ b/include/acpi/acpiosxf.h
|
||
@@ -371,6 +371,12 @@ acpi_status acpi_os_wait_command_ready(void);
|
||
acpi_status acpi_os_notify_command_complete(void);
|
||
#endif
|
||
|
||
+#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_trace_point
|
||
+void
|
||
+acpi_os_trace_point(acpi_trace_event_type type,
|
||
+ u8 begin, u8 *aml, char *pathname);
|
||
+#endif
|
||
+
|
||
/*
|
||
* Obtain ACPI table(s)
|
||
*/
|
||
@@ -416,41 +422,4 @@ char *acpi_os_get_next_filename(void *dir_handle);
|
||
void acpi_os_close_directory(void *dir_handle);
|
||
#endif
|
||
|
||
-/*
|
||
- * File I/O and related support
|
||
- */
|
||
-#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_open_file
|
||
-ACPI_FILE acpi_os_open_file(const char *path, u8 modes);
|
||
-#endif
|
||
-
|
||
-#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_close_file
|
||
-void acpi_os_close_file(ACPI_FILE file);
|
||
-#endif
|
||
-
|
||
-#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_read_file
|
||
-int
|
||
-acpi_os_read_file(ACPI_FILE file,
|
||
- void *buffer, acpi_size size, acpi_size count);
|
||
-#endif
|
||
-
|
||
-#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_write_file
|
||
-int
|
||
-acpi_os_write_file(ACPI_FILE file,
|
||
- void *buffer, acpi_size size, acpi_size count);
|
||
-#endif
|
||
-
|
||
-#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_file_offset
|
||
-long acpi_os_get_file_offset(ACPI_FILE file);
|
||
-#endif
|
||
-
|
||
-#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_set_file_offset
|
||
-acpi_status acpi_os_set_file_offset(ACPI_FILE file, long offset, u8 from);
|
||
-#endif
|
||
-
|
||
-#ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_trace_point
|
||
-void
|
||
-acpi_os_trace_point(acpi_trace_event_type type,
|
||
- u8 begin, u8 *aml, char *pathname);
|
||
-#endif
|
||
-
|
||
#endif /* __ACPIOSXF_H__ */
|
||
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
|
||
index 1ff3a76..8b44717 100644
|
||
--- a/include/acpi/acpixf.h
|
||
+++ b/include/acpi/acpixf.h
|
||
@@ -46,7 +46,7 @@
|
||
|
||
/* Current ACPICA subsystem version in YYYYMMDD format */
|
||
|
||
-#define ACPI_CA_VERSION 0x20160422
|
||
+#define ACPI_CA_VERSION 0x20160729
|
||
|
||
#include <acpi/acconfig.h>
|
||
#include <acpi/actypes.h>
|
||
@@ -416,18 +416,19 @@ ACPI_GLOBAL(u8, acpi_gbl_system_awake_and_running);
|
||
/*
|
||
* Initialization
|
||
*/
|
||
-ACPI_EXTERNAL_RETURN_STATUS(acpi_status __init
|
||
+ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_INIT_FUNCTION
|
||
acpi_initialize_tables(struct acpi_table_desc
|
||
*initial_storage,
|
||
u32 initial_table_count,
|
||
u8 allow_resize))
|
||
-ACPI_EXTERNAL_RETURN_STATUS(acpi_status __init acpi_initialize_subsystem(void))
|
||
-
|
||
-ACPI_EXTERNAL_RETURN_STATUS(acpi_status __init acpi_enable_subsystem(u32 flags))
|
||
-
|
||
-ACPI_EXTERNAL_RETURN_STATUS(acpi_status __init
|
||
- acpi_initialize_objects(u32 flags))
|
||
-ACPI_EXTERNAL_RETURN_STATUS(acpi_status __init acpi_terminate(void))
|
||
+ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_INIT_FUNCTION
|
||
+ acpi_initialize_subsystem(void))
|
||
+ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_INIT_FUNCTION
|
||
+ acpi_enable_subsystem(u32 flags))
|
||
+ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_INIT_FUNCTION
|
||
+ acpi_initialize_objects(u32 flags))
|
||
+ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_INIT_FUNCTION
|
||
+ acpi_terminate(void))
|
||
|
||
/*
|
||
* Miscellaneous global interfaces
|
||
@@ -467,7 +468,7 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status
|
||
/*
|
||
* ACPI table load/unload interfaces
|
||
*/
|
||
-ACPI_EXTERNAL_RETURN_STATUS(acpi_status __init
|
||
+ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_INIT_FUNCTION
|
||
acpi_install_table(acpi_physical_address address,
|
||
u8 physical))
|
||
|
||
@@ -476,14 +477,17 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status
|
||
|
||
ACPI_EXTERNAL_RETURN_STATUS(acpi_status
|
||
acpi_unload_parent_table(acpi_handle object))
|
||
-ACPI_EXTERNAL_RETURN_STATUS(acpi_status __init acpi_load_tables(void))
|
||
+
|
||
+ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_INIT_FUNCTION
|
||
+ acpi_load_tables(void))
|
||
|
||
/*
|
||
* ACPI table manipulation interfaces
|
||
*/
|
||
-ACPI_EXTERNAL_RETURN_STATUS(acpi_status __init acpi_reallocate_root_table(void))
|
||
+ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_INIT_FUNCTION
|
||
+ acpi_reallocate_root_table(void))
|
||
|
||
-ACPI_EXTERNAL_RETURN_STATUS(acpi_status __init
|
||
+ACPI_EXTERNAL_RETURN_STATUS(acpi_status ACPI_INIT_FUNCTION
|
||
acpi_find_root_pointer(acpi_physical_address
|
||
*rsdp_address))
|
||
ACPI_EXTERNAL_RETURN_STATUS(acpi_status
|
||
@@ -732,6 +736,10 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
|
||
u32 gpe_number))
|
||
|
||
ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
|
||
+ acpi_mask_gpe(acpi_handle gpe_device,
|
||
+ u32 gpe_number, u8 is_masked))
|
||
+
|
||
+ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
|
||
acpi_mark_gpe_for_wake(acpi_handle gpe_device,
|
||
u32 gpe_number))
|
||
|
||
@@ -935,9 +943,6 @@ ACPI_DBG_DEPENDENT_RETURN_VOID(void
|
||
acpi_trace_point(acpi_trace_event_type type,
|
||
u8 begin,
|
||
u8 *aml, char *pathname))
|
||
-ACPI_APP_DEPENDENT_RETURN_VOID(ACPI_PRINTF_LIKE(1)
|
||
- void ACPI_INTERNAL_VAR_XFACE
|
||
- acpi_log_error(const char *format, ...))
|
||
|
||
acpi_status acpi_initialize_debugger(void);
|
||
|
||
diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h
|
||
index c19700e..1b949e0 100644
|
||
--- a/include/acpi/actbl.h
|
||
+++ b/include/acpi/actbl.h
|
||
@@ -230,62 +230,72 @@ struct acpi_table_facs {
|
||
/* Fields common to all versions of the FADT */
|
||
|
||
struct acpi_table_fadt {
|
||
- struct acpi_table_header header; /* Common ACPI table header */
|
||
- u32 facs; /* 32-bit physical address of FACS */
|
||
- u32 dsdt; /* 32-bit physical address of DSDT */
|
||
- u8 model; /* System Interrupt Model (ACPI 1.0) - not used in ACPI 2.0+ */
|
||
- u8 preferred_profile; /* Conveys preferred power management profile to OSPM. */
|
||
- u16 sci_interrupt; /* System vector of SCI interrupt */
|
||
- u32 smi_command; /* 32-bit Port address of SMI command port */
|
||
- u8 acpi_enable; /* Value to write to SMI_CMD to enable ACPI */
|
||
- u8 acpi_disable; /* Value to write to SMI_CMD to disable ACPI */
|
||
- u8 s4_bios_request; /* Value to write to SMI_CMD to enter S4BIOS state */
|
||
- u8 pstate_control; /* Processor performance state control */
|
||
- u32 pm1a_event_block; /* 32-bit port address of Power Mgt 1a Event Reg Blk */
|
||
- u32 pm1b_event_block; /* 32-bit port address of Power Mgt 1b Event Reg Blk */
|
||
- u32 pm1a_control_block; /* 32-bit port address of Power Mgt 1a Control Reg Blk */
|
||
- u32 pm1b_control_block; /* 32-bit port address of Power Mgt 1b Control Reg Blk */
|
||
- u32 pm2_control_block; /* 32-bit port address of Power Mgt 2 Control Reg Blk */
|
||
- u32 pm_timer_block; /* 32-bit port address of Power Mgt Timer Ctrl Reg Blk */
|
||
- u32 gpe0_block; /* 32-bit port address of General Purpose Event 0 Reg Blk */
|
||
- u32 gpe1_block; /* 32-bit port address of General Purpose Event 1 Reg Blk */
|
||
- u8 pm1_event_length; /* Byte Length of ports at pm1x_event_block */
|
||
- u8 pm1_control_length; /* Byte Length of ports at pm1x_control_block */
|
||
- u8 pm2_control_length; /* Byte Length of ports at pm2_control_block */
|
||
- u8 pm_timer_length; /* Byte Length of ports at pm_timer_block */
|
||
- u8 gpe0_block_length; /* Byte Length of ports at gpe0_block */
|
||
- u8 gpe1_block_length; /* Byte Length of ports at gpe1_block */
|
||
- u8 gpe1_base; /* Offset in GPE number space where GPE1 events start */
|
||
- u8 cst_control; /* Support for the _CST object and C-States change notification */
|
||
- u16 c2_latency; /* Worst case HW latency to enter/exit C2 state */
|
||
- u16 c3_latency; /* Worst case HW latency to enter/exit C3 state */
|
||
- u16 flush_size; /* Processor memory cache line width, in bytes */
|
||
- u16 flush_stride; /* Number of flush strides that need to be read */
|
||
- u8 duty_offset; /* Processor duty cycle index in processor P_CNT reg */
|
||
- u8 duty_width; /* Processor duty cycle value bit width in P_CNT register */
|
||
- u8 day_alarm; /* Index to day-of-month alarm in RTC CMOS RAM */
|
||
- u8 month_alarm; /* Index to month-of-year alarm in RTC CMOS RAM */
|
||
- u8 century; /* Index to century in RTC CMOS RAM */
|
||
- u16 boot_flags; /* IA-PC Boot Architecture Flags (see below for individual flags) */
|
||
- u8 reserved; /* Reserved, must be zero */
|
||
- u32 flags; /* Miscellaneous flag bits (see below for individual flags) */
|
||
- struct acpi_generic_address reset_register; /* 64-bit address of the Reset register */
|
||
- u8 reset_value; /* Value to write to the reset_register port to reset the system */
|
||
- u16 arm_boot_flags; /* ARM-Specific Boot Flags (see below for individual flags) (ACPI 5.1) */
|
||
- u8 minor_revision; /* FADT Minor Revision (ACPI 5.1) */
|
||
- u64 Xfacs; /* 64-bit physical address of FACS */
|
||
- u64 Xdsdt; /* 64-bit physical address of DSDT */
|
||
- struct acpi_generic_address xpm1a_event_block; /* 64-bit Extended Power Mgt 1a Event Reg Blk address */
|
||
- struct acpi_generic_address xpm1b_event_block; /* 64-bit Extended Power Mgt 1b Event Reg Blk address */
|
||
- struct acpi_generic_address xpm1a_control_block; /* 64-bit Extended Power Mgt 1a Control Reg Blk address */
|
||
- struct acpi_generic_address xpm1b_control_block; /* 64-bit Extended Power Mgt 1b Control Reg Blk address */
|
||
- struct acpi_generic_address xpm2_control_block; /* 64-bit Extended Power Mgt 2 Control Reg Blk address */
|
||
- struct acpi_generic_address xpm_timer_block; /* 64-bit Extended Power Mgt Timer Ctrl Reg Blk address */
|
||
- struct acpi_generic_address xgpe0_block; /* 64-bit Extended General Purpose Event 0 Reg Blk address */
|
||
- struct acpi_generic_address xgpe1_block; /* 64-bit Extended General Purpose Event 1 Reg Blk address */
|
||
- struct acpi_generic_address sleep_control; /* 64-bit Sleep Control register (ACPI 5.0) */
|
||
- struct acpi_generic_address sleep_status; /* 64-bit Sleep Status register (ACPI 5.0) */
|
||
- u64 hypervisor_id; /* Hypervisor Vendor ID (ACPI 6.0) */
|
||
+ struct acpi_table_header header; /* [V1] Common ACPI table header */
|
||
+ u32 facs; /* [V1] 32-bit physical address of FACS */
|
||
+ u32 dsdt; /* [V1] 32-bit physical address of DSDT */
|
||
+ u8 model; /* [V1] System Interrupt Model (ACPI 1.0) - not used in ACPI 2.0+ */
|
||
+ u8 preferred_profile; /* [V1] Conveys preferred power management profile to OSPM. */
|
||
+ u16 sci_interrupt; /* [V1] System vector of SCI interrupt */
|
||
+ u32 smi_command; /* [V1] 32-bit Port address of SMI command port */
|
||
+ u8 acpi_enable; /* [V1] Value to write to SMI_CMD to enable ACPI */
|
||
+ u8 acpi_disable; /* [V1] Value to write to SMI_CMD to disable ACPI */
|
||
+ u8 s4_bios_request; /* [V1] Value to write to SMI_CMD to enter S4BIOS state */
|
||
+ u8 pstate_control; /* [V1] Processor performance state control */
|
||
+ u32 pm1a_event_block; /* [V1] 32-bit port address of Power Mgt 1a Event Reg Blk */
|
||
+ u32 pm1b_event_block; /* [V1] 32-bit port address of Power Mgt 1b Event Reg Blk */
|
||
+ u32 pm1a_control_block; /* [V1] 32-bit port address of Power Mgt 1a Control Reg Blk */
|
||
+ u32 pm1b_control_block; /* [V1] 32-bit port address of Power Mgt 1b Control Reg Blk */
|
||
+ u32 pm2_control_block; /* [V1] 32-bit port address of Power Mgt 2 Control Reg Blk */
|
||
+ u32 pm_timer_block; /* [V1] 32-bit port address of Power Mgt Timer Ctrl Reg Blk */
|
||
+ u32 gpe0_block; /* [V1] 32-bit port address of General Purpose Event 0 Reg Blk */
|
||
+ u32 gpe1_block; /* [V1] 32-bit port address of General Purpose Event 1 Reg Blk */
|
||
+ u8 pm1_event_length; /* [V1] Byte Length of ports at pm1x_event_block */
|
||
+ u8 pm1_control_length; /* [V1] Byte Length of ports at pm1x_control_block */
|
||
+ u8 pm2_control_length; /* [V1] Byte Length of ports at pm2_control_block */
|
||
+ u8 pm_timer_length; /* [V1] Byte Length of ports at pm_timer_block */
|
||
+ u8 gpe0_block_length; /* [V1] Byte Length of ports at gpe0_block */
|
||
+ u8 gpe1_block_length; /* [V1] Byte Length of ports at gpe1_block */
|
||
+ u8 gpe1_base; /* [V1] Offset in GPE number space where GPE1 events start */
|
||
+ u8 cst_control; /* [V1] Support for the _CST object and C-States change notification */
|
||
+ u16 c2_latency; /* [V1] Worst case HW latency to enter/exit C2 state */
|
||
+ u16 c3_latency; /* [V1] Worst case HW latency to enter/exit C3 state */
|
||
+ u16 flush_size; /* [V1] Processor memory cache line width, in bytes */
|
||
+ u16 flush_stride; /* [V1] Number of flush strides that need to be read */
|
||
+ u8 duty_offset; /* [V1] Processor duty cycle index in processor P_CNT reg */
|
||
+ u8 duty_width; /* [V1] Processor duty cycle value bit width in P_CNT register */
|
||
+ u8 day_alarm; /* [V1] Index to day-of-month alarm in RTC CMOS RAM */
|
||
+ u8 month_alarm; /* [V1] Index to month-of-year alarm in RTC CMOS RAM */
|
||
+ u8 century; /* [V1] Index to century in RTC CMOS RAM */
|
||
+ u16 boot_flags; /* [V3] IA-PC Boot Architecture Flags (see below for individual flags) */
|
||
+ u8 reserved; /* [V1] Reserved, must be zero */
|
||
+ u32 flags; /* [V1] Miscellaneous flag bits (see below for individual flags) */
|
||
+ /* End of Version 1 FADT fields (ACPI 1.0) */
|
||
+
|
||
+ struct acpi_generic_address reset_register; /* [V3] 64-bit address of the Reset register */
|
||
+ u8 reset_value; /* [V3] Value to write to the reset_register port to reset the system */
|
||
+ u16 arm_boot_flags; /* [V5] ARM-Specific Boot Flags (see below for individual flags) (ACPI 5.1) */
|
||
+ u8 minor_revision; /* [V5] FADT Minor Revision (ACPI 5.1) */
|
||
+ u64 Xfacs; /* [V3] 64-bit physical address of FACS */
|
||
+ u64 Xdsdt; /* [V3] 64-bit physical address of DSDT */
|
||
+ struct acpi_generic_address xpm1a_event_block; /* [V3] 64-bit Extended Power Mgt 1a Event Reg Blk address */
|
||
+ struct acpi_generic_address xpm1b_event_block; /* [V3] 64-bit Extended Power Mgt 1b Event Reg Blk address */
|
||
+ struct acpi_generic_address xpm1a_control_block; /* [V3] 64-bit Extended Power Mgt 1a Control Reg Blk address */
|
||
+ struct acpi_generic_address xpm1b_control_block; /* [V3] 64-bit Extended Power Mgt 1b Control Reg Blk address */
|
||
+ struct acpi_generic_address xpm2_control_block; /* [V3] 64-bit Extended Power Mgt 2 Control Reg Blk address */
|
||
+ struct acpi_generic_address xpm_timer_block; /* [V3] 64-bit Extended Power Mgt Timer Ctrl Reg Blk address */
|
||
+ struct acpi_generic_address xgpe0_block; /* [V3] 64-bit Extended General Purpose Event 0 Reg Blk address */
|
||
+ struct acpi_generic_address xgpe1_block; /* [V3] 64-bit Extended General Purpose Event 1 Reg Blk address */
|
||
+ /* End of Version 3 FADT fields (ACPI 2.0) */
|
||
+
|
||
+ struct acpi_generic_address sleep_control; /* [V4] 64-bit Sleep Control register (ACPI 5.0) */
|
||
+ /* End of Version 4 FADT fields (ACPI 3.0 and ACPI 4.0) (Field was originally reserved in ACPI 3.0) */
|
||
+
|
||
+ struct acpi_generic_address sleep_status; /* [V5] 64-bit Sleep Status register (ACPI 5.0) */
|
||
+ /* End of Version 5 FADT fields (ACPI 5.0) */
|
||
+
|
||
+ u64 hypervisor_id; /* [V6] Hypervisor Vendor ID (ACPI 6.0) */
|
||
+ /* End of Version 6 FADT fields (ACPI 6.0) */
|
||
+
|
||
};
|
||
|
||
/* Masks for FADT IA-PC Boot Architecture Flags (boot_flags) [Vx]=Introduced in this FADT revision */
|
||
@@ -301,8 +311,8 @@ struct acpi_table_fadt {
|
||
|
||
/* Masks for FADT ARM Boot Architecture Flags (arm_boot_flags) ACPI 5.1 */
|
||
|
||
-#define ACPI_FADT_PSCI_COMPLIANT (1) /* 00: [V5+] PSCI 0.2+ is implemented */
|
||
-#define ACPI_FADT_PSCI_USE_HVC (1<<1) /* 01: [V5+] HVC must be used instead of SMC as the PSCI conduit */
|
||
+#define ACPI_FADT_PSCI_COMPLIANT (1) /* 00: [V5] PSCI 0.2+ is implemented */
|
||
+#define ACPI_FADT_PSCI_USE_HVC (1<<1) /* 01: [V5] HVC must be used instead of SMC as the PSCI conduit */
|
||
|
||
/* Masks for FADT flags */
|
||
|
||
@@ -399,20 +409,34 @@ struct acpi_table_desc {
|
||
* match the expected length. In other words, the length of the
|
||
* FADT is the bottom line as to what the version really is.
|
||
*
|
||
- * For reference, the values below are as follows:
|
||
- * FADT V1 size: 0x074
|
||
- * FADT V2 size: 0x084
|
||
- * FADT V3 size: 0x0F4
|
||
- * FADT V4 size: 0x0F4
|
||
- * FADT V5 size: 0x10C
|
||
- * FADT V6 size: 0x114
|
||
+ * NOTE: There is no officialy released V2 of the FADT. This
|
||
+ * version was used only for prototyping and testing during the
|
||
+ * 32-bit to 64-bit transition. V3 was the first official 64-bit
|
||
+ * version of the FADT.
|
||
+ *
|
||
+ * Update this list of defines when a new version of the FADT is
|
||
+ * added to the ACPI specification. Note that the FADT version is
|
||
+ * only incremented when new fields are appended to the existing
|
||
+ * version. Therefore, the FADT version is competely independent
|
||
+ * from the version of the ACPI specification where it is
|
||
+ * defined.
|
||
+ *
|
||
+ * For reference, the various FADT lengths are as follows:
|
||
+ * FADT V1 size: 0x074 ACPI 1.0
|
||
+ * FADT V3 size: 0x0F4 ACPI 2.0
|
||
+ * FADT V4 size: 0x100 ACPI 3.0 and ACPI 4.0
|
||
+ * FADT V5 size: 0x10C ACPI 5.0
|
||
+ * FADT V6 size: 0x114 ACPI 6.0
|
||
*/
|
||
-#define ACPI_FADT_V1_SIZE (u32) (ACPI_FADT_OFFSET (flags) + 4)
|
||
-#define ACPI_FADT_V2_SIZE (u32) (ACPI_FADT_OFFSET (minor_revision) + 1)
|
||
-#define ACPI_FADT_V3_SIZE (u32) (ACPI_FADT_OFFSET (sleep_control))
|
||
-#define ACPI_FADT_V5_SIZE (u32) (ACPI_FADT_OFFSET (hypervisor_id))
|
||
-#define ACPI_FADT_V6_SIZE (u32) (sizeof (struct acpi_table_fadt))
|
||
+#define ACPI_FADT_V1_SIZE (u32) (ACPI_FADT_OFFSET (flags) + 4) /* ACPI 1.0 */
|
||
+#define ACPI_FADT_V3_SIZE (u32) (ACPI_FADT_OFFSET (sleep_control)) /* ACPI 2.0 */
|
||
+#define ACPI_FADT_V4_SIZE (u32) (ACPI_FADT_OFFSET (sleep_status)) /* ACPI 3.0 and ACPI 4.0 */
|
||
+#define ACPI_FADT_V5_SIZE (u32) (ACPI_FADT_OFFSET (hypervisor_id)) /* ACPI 5.0 */
|
||
+#define ACPI_FADT_V6_SIZE (u32) (sizeof (struct acpi_table_fadt)) /* ACPI 6.0 */
|
||
+
|
||
+/* Update these when new FADT versions are added */
|
||
|
||
+#define ACPI_FADT_MAX_VERSION 6
|
||
#define ACPI_FADT_CONFORMANCE "ACPI 6.1 (FADT version 6)"
|
||
|
||
#endif /* __ACTBL_H__ */
|
||
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
|
||
index cb389ef..e96907b 100644
|
||
--- a/include/acpi/actypes.h
|
||
+++ b/include/acpi/actypes.h
|
||
@@ -732,16 +732,17 @@ typedef u32 acpi_event_type;
|
||
* The encoding of acpi_event_status is illustrated below.
|
||
* Note that a set bit (1) indicates the property is TRUE
|
||
* (e.g. if bit 0 is set then the event is enabled).
|
||
- * +-------------+-+-+-+-+-+
|
||
- * | Bits 31:5 |4|3|2|1|0|
|
||
- * +-------------+-+-+-+-+-+
|
||
- * | | | | | |
|
||
- * | | | | | +- Enabled?
|
||
- * | | | | +--- Enabled for wake?
|
||
- * | | | +----- Status bit set?
|
||
- * | | +------- Enable bit set?
|
||
- * | +--------- Has a handler?
|
||
- * +--------------- <Reserved>
|
||
+ * +-------------+-+-+-+-+-+-+
|
||
+ * | Bits 31:6 |5|4|3|2|1|0|
|
||
+ * +-------------+-+-+-+-+-+-+
|
||
+ * | | | | | | |
|
||
+ * | | | | | | +- Enabled?
|
||
+ * | | | | | +--- Enabled for wake?
|
||
+ * | | | | +----- Status bit set?
|
||
+ * | | | +------- Enable bit set?
|
||
+ * | | +--------- Has a handler?
|
||
+ * | +----------- Masked?
|
||
+ * +----------------- <Reserved>
|
||
*/
|
||
typedef u32 acpi_event_status;
|
||
|
||
@@ -751,6 +752,7 @@ typedef u32 acpi_event_status;
|
||
#define ACPI_EVENT_FLAG_STATUS_SET (acpi_event_status) 0x04
|
||
#define ACPI_EVENT_FLAG_ENABLE_SET (acpi_event_status) 0x08
|
||
#define ACPI_EVENT_FLAG_HAS_HANDLER (acpi_event_status) 0x10
|
||
+#define ACPI_EVENT_FLAG_MASKED (acpi_event_status) 0x20
|
||
#define ACPI_EVENT_FLAG_SET ACPI_EVENT_FLAG_STATUS_SET
|
||
|
||
/* Actions for acpi_set_gpe, acpi_gpe_wakeup, acpi_hw_low_set_gpe */
|
||
@@ -761,14 +763,15 @@ typedef u32 acpi_event_status;
|
||
|
||
/*
|
||
* GPE info flags - Per GPE
|
||
- * +-------+-+-+---+
|
||
- * | 7:5 |4|3|2:0|
|
||
- * +-------+-+-+---+
|
||
- * | | | |
|
||
- * | | | +-- Type of dispatch:to method, handler, notify, or none
|
||
- * | | +----- Interrupt type: edge or level triggered
|
||
- * | +------- Is a Wake GPE
|
||
- * +------------ <Reserved>
|
||
+ * +---+-+-+-+---+
|
||
+ * |7:6|5|4|3|2:0|
|
||
+ * +---+-+-+-+---+
|
||
+ * | | | | |
|
||
+ * | | | | +-- Type of dispatch:to method, handler, notify, or none
|
||
+ * | | | +----- Interrupt type: edge or level triggered
|
||
+ * | | +------- Is a Wake GPE
|
||
+ * | +--------- Is GPE masked by the software GPE masking machanism
|
||
+ * +------------ <Reserved>
|
||
*/
|
||
#define ACPI_GPE_DISPATCH_NONE (u8) 0x00
|
||
#define ACPI_GPE_DISPATCH_METHOD (u8) 0x01
|
||
@@ -1285,15 +1288,6 @@ typedef enum {
|
||
#define ACPI_OSI_WIN_8 0x0C
|
||
#define ACPI_OSI_WIN_10 0x0D
|
||
|
||
-/* Definitions of file IO */
|
||
-
|
||
-#define ACPI_FILE_READING 0x01
|
||
-#define ACPI_FILE_WRITING 0x02
|
||
-#define ACPI_FILE_BINARY 0x04
|
||
-
|
||
-#define ACPI_FILE_BEGIN 0x01
|
||
-#define ACPI_FILE_END 0x02
|
||
-
|
||
/* Definitions of getopt */
|
||
|
||
#define ACPI_OPT_END -1
|
||
diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h
|
||
index 86b5a84..34cce72 100644
|
||
--- a/include/acpi/platform/acenv.h
|
||
+++ b/include/acpi/platform/acenv.h
|
||
@@ -78,6 +78,7 @@
|
||
(defined ACPI_EXAMPLE_APP)
|
||
#define ACPI_APPLICATION
|
||
#define ACPI_SINGLE_THREADED
|
||
+#define USE_NATIVE_ALLOCATE_ZEROED
|
||
#endif
|
||
|
||
/* iASL configuration */
|
||
@@ -124,7 +125,6 @@
|
||
|
||
#ifdef ACPI_DUMP_APP
|
||
#define ACPI_USE_NATIVE_MEMORY_MAPPING
|
||
-#define USE_NATIVE_ALLOCATE_ZEROED
|
||
#endif
|
||
|
||
/* acpi_names/Example configuration. Hardware disabled */
|
||
@@ -149,7 +149,6 @@
|
||
/* Common for all ACPICA applications */
|
||
|
||
#ifdef ACPI_APPLICATION
|
||
-#define ACPI_USE_SYSTEM_CLIBRARY
|
||
#define ACPI_USE_LOCAL_CACHE
|
||
#endif
|
||
|
||
@@ -167,10 +166,21 @@
|
||
/******************************************************************************
|
||
*
|
||
* Host configuration files. The compiler configuration files are included
|
||
- * by the host files.
|
||
+ * first.
|
||
*
|
||
*****************************************************************************/
|
||
|
||
+#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
|
||
+#include <acpi/platform/acgcc.h>
|
||
+
|
||
+#elif defined(_MSC_VER)
|
||
+#include "acmsvc.h"
|
||
+
|
||
+#elif defined(__INTEL_COMPILER)
|
||
+#include "acintel.h"
|
||
+
|
||
+#endif
|
||
+
|
||
#if defined(_LINUX) || defined(__linux__)
|
||
#include <acpi/platform/aclinux.h>
|
||
|
||
@@ -210,18 +220,20 @@
|
||
#elif defined(__OS2__)
|
||
#include "acos2.h"
|
||
|
||
-#elif defined(_AED_EFI)
|
||
-#include "acefi.h"
|
||
-
|
||
-#elif defined(_GNU_EFI)
|
||
-#include "acefi.h"
|
||
-
|
||
#elif defined(__HAIKU__)
|
||
#include "achaiku.h"
|
||
|
||
#elif defined(__QNX__)
|
||
#include "acqnx.h"
|
||
|
||
+/*
|
||
+ * EFI applications can be built with -nostdlib, in this case, it must be
|
||
+ * included after including all other host environmental definitions, in
|
||
+ * order to override the definitions.
|
||
+ */
|
||
+#elif defined(_AED_EFI) || defined(_GNU_EFI) || defined(_EDK2_EFI)
|
||
+#include "acefi.h"
|
||
+
|
||
#else
|
||
|
||
/* Unknown environment */
|
||
@@ -326,7 +338,8 @@
|
||
* ACPI_USE_SYSTEM_CLIBRARY - Define this if linking to an actual C library.
|
||
* Otherwise, local versions of string/memory functions will be used.
|
||
* ACPI_USE_STANDARD_HEADERS - Define this if linking to a C library and
|
||
- * the standard header files may be used.
|
||
+ * the standard header files may be used. Defining this implies that
|
||
+ * ACPI_USE_SYSTEM_CLIBRARY has been defined.
|
||
*
|
||
* The ACPICA subsystem only uses low level C library functions that do not
|
||
* call operating system services and may therefore be inlined in the code.
|
||
@@ -334,7 +347,6 @@
|
||
* It may be necessary to tailor these include files to the target
|
||
* generation environment.
|
||
*/
|
||
-#ifdef ACPI_USE_SYSTEM_CLIBRARY
|
||
|
||
/* Use the standard C library headers. We want to keep these to a minimum. */
|
||
|
||
@@ -342,57 +354,20 @@
|
||
|
||
/* Use the standard headers from the standard locations */
|
||
|
||
-#include <stdarg.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#include <ctype.h>
|
||
+#ifdef ACPI_APPLICATION
|
||
+#include <stdio.h>
|
||
+#include <fcntl.h>
|
||
+#include <errno.h>
|
||
+#include <time.h>
|
||
+#include <signal.h>
|
||
+#endif
|
||
|
||
#endif /* ACPI_USE_STANDARD_HEADERS */
|
||
|
||
-/* We will be linking to the standard Clib functions */
|
||
-
|
||
-#else
|
||
-
|
||
-/******************************************************************************
|
||
- *
|
||
- * Not using native C library, use local implementations
|
||
- *
|
||
- *****************************************************************************/
|
||
-
|
||
-/*
|
||
- * Use local definitions of C library macros and functions. These function
|
||
- * implementations may not be as efficient as an inline or assembly code
|
||
- * implementation provided by a native C library, but they are functionally
|
||
- * equivalent.
|
||
- */
|
||
-#ifndef va_arg
|
||
-
|
||
-#ifndef _VALIST
|
||
-#define _VALIST
|
||
-typedef char *va_list;
|
||
-#endif /* _VALIST */
|
||
-
|
||
-/* Storage alignment properties */
|
||
-
|
||
-#define _AUPBND (sizeof (acpi_native_int) - 1)
|
||
-#define _ADNBND (sizeof (acpi_native_int) - 1)
|
||
-
|
||
-/* Variable argument list macro definitions */
|
||
-
|
||
-#define _bnd(X, bnd) (((sizeof (X)) + (bnd)) & (~(bnd)))
|
||
-#define va_arg(ap, T) (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND))))
|
||
-#define va_end(ap) (ap = (va_list) NULL)
|
||
-#define va_start(ap, A) (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND))))
|
||
-
|
||
-#endif /* va_arg */
|
||
-
|
||
-/* Use the local (ACPICA) definitions of the clib functions */
|
||
-
|
||
-#endif /* ACPI_USE_SYSTEM_CLIBRARY */
|
||
-
|
||
-#ifndef ACPI_FILE
|
||
#ifdef ACPI_APPLICATION
|
||
-#include <stdio.h>
|
||
#define ACPI_FILE FILE *
|
||
#define ACPI_FILE_OUT stdout
|
||
#define ACPI_FILE_ERR stderr
|
||
@@ -401,6 +376,9 @@ typedef char *va_list;
|
||
#define ACPI_FILE_OUT NULL
|
||
#define ACPI_FILE_ERR NULL
|
||
#endif /* ACPI_APPLICATION */
|
||
-#endif /* ACPI_FILE */
|
||
+
|
||
+#ifndef ACPI_INIT_FUNCTION
|
||
+#define ACPI_INIT_FUNCTION
|
||
+#endif
|
||
|
||
#endif /* __ACENV_H__ */
|
||
diff --git a/include/acpi/platform/acenvex.h b/include/acpi/platform/acenvex.h
|
||
index 4f15c1d..b3171b9 100644
|
||
--- a/include/acpi/platform/acenvex.h
|
||
+++ b/include/acpi/platform/acenvex.h
|
||
@@ -56,17 +56,24 @@
|
||
#if defined(_LINUX) || defined(__linux__)
|
||
#include <acpi/platform/aclinuxex.h>
|
||
|
||
-#elif defined(WIN32)
|
||
-#include "acwinex.h"
|
||
+#elif defined(__DragonFly__)
|
||
+#include "acdragonflyex.h"
|
||
|
||
-#elif defined(_AED_EFI)
|
||
+/*
|
||
+ * EFI applications can be built with -nostdlib, in this case, it must be
|
||
+ * included after including all other host environmental definitions, in
|
||
+ * order to override the definitions.
|
||
+ */
|
||
+#elif defined(_AED_EFI) || defined(_GNU_EFI) || defined(_EDK2_EFI)
|
||
#include "acefiex.h"
|
||
|
||
-#elif defined(_GNU_EFI)
|
||
-#include "acefiex.h"
|
||
+#endif
|
||
|
||
-#elif defined(__DragonFly__)
|
||
-#include "acdragonflyex.h"
|
||
+#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
|
||
+#include "acgccex.h"
|
||
+
|
||
+#elif defined(_MSC_VER)
|
||
+#include "acmsvcex.h"
|
||
|
||
#endif
|
||
|
||
diff --git a/include/acpi/platform/acgcc.h b/include/acpi/platform/acgcc.h
|
||
index c5a216c..8f66aaa 100644
|
||
--- a/include/acpi/platform/acgcc.h
|
||
+++ b/include/acpi/platform/acgcc.h
|
||
@@ -44,6 +44,12 @@
|
||
#ifndef __ACGCC_H__
|
||
#define __ACGCC_H__
|
||
|
||
+/*
|
||
+ * Use compiler specific <stdarg.h> is a good practice for even when
|
||
+ * -nostdinc is specified (i.e., ACPI_USE_STANDARD_HEADERS undefined.
|
||
+ */
|
||
+#include <stdarg.h>
|
||
+
|
||
#define ACPI_INLINE __inline__
|
||
|
||
/* Function name is used for debug output. Non-ANSI, compiler-dependent */
|
||
@@ -64,17 +70,6 @@
|
||
*/
|
||
#define ACPI_UNUSED_VAR __attribute__ ((unused))
|
||
|
||
-/*
|
||
- * Some versions of gcc implement strchr() with a buggy macro. So,
|
||
- * undef it here. Prevents error messages of this form (usually from the
|
||
- * file getopt.c):
|
||
- *
|
||
- * error: logical '&&' with non-zero constant will always evaluate as true
|
||
- */
|
||
-#ifdef strchr
|
||
-#undef strchr
|
||
-#endif
|
||
-
|
||
/* GCC supports __VA_ARGS__ in macros */
|
||
|
||
#define COMPILER_VA_MACRO 1
|
||
diff --git a/include/acpi/platform/acgccex.h b/include/acpi/platform/acgccex.h
|
||
new file mode 100644
|
||
index 0000000..46ead2c
|
||
--- /dev/null
|
||
+++ b/include/acpi/platform/acgccex.h
|
||
@@ -0,0 +1,58 @@
|
||
+/******************************************************************************
|
||
+ *
|
||
+ * Name: acgccex.h - Extra GCC specific defines, etc.
|
||
+ *
|
||
+ *****************************************************************************/
|
||
+
|
||
+/*
|
||
+ * Copyright (C) 2000 - 2016, Intel Corp.
|
||
+ * All rights reserved.
|
||
+ *
|
||
+ * Redistribution and use in source and binary forms, with or without
|
||
+ * modification, are permitted provided that the following conditions
|
||
+ * are met:
|
||
+ * 1. Redistributions of source code must retain the above copyright
|
||
+ * notice, this list of conditions, and the following disclaimer,
|
||
+ * without modification.
|
||
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||
+ * substantially similar to the "NO WARRANTY" disclaimer below
|
||
+ * ("Disclaimer") and any redistribution must be conditioned upon
|
||
+ * including a substantially similar Disclaimer requirement for further
|
||
+ * binary redistribution.
|
||
+ * 3. Neither the names of the above-listed copyright holders nor the names
|
||
+ * of any contributors may be used to endorse or promote products derived
|
||
+ * from this software without specific prior written permission.
|
||
+ *
|
||
+ * Alternatively, this software may be distributed under the terms of the
|
||
+ * GNU General Public License ("GPL") version 2 as published by the Free
|
||
+ * Software Foundation.
|
||
+ *
|
||
+ * NO WARRANTY
|
||
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||
+ * POSSIBILITY OF SUCH DAMAGES.
|
||
+ */
|
||
+
|
||
+#ifndef __ACGCCEX_H__
|
||
+#define __ACGCCEX_H__
|
||
+
|
||
+/*
|
||
+ * Some versions of gcc implement strchr() with a buggy macro. So,
|
||
+ * undef it here. Prevents error messages of this form (usually from the
|
||
+ * file getopt.c):
|
||
+ *
|
||
+ * error: logical '&&' with non-zero constant will always evaluate as true
|
||
+ */
|
||
+#ifdef strchr
|
||
+#undef strchr
|
||
+#endif
|
||
+
|
||
+#endif /* __ACGCCEX_H__ */
|
||
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h
|
||
index 93b61b1..a5d98d1 100644
|
||
--- a/include/acpi/platform/aclinux.h
|
||
+++ b/include/acpi/platform/aclinux.h
|
||
@@ -92,6 +92,8 @@
|
||
#include <asm/acenv.h>
|
||
#endif
|
||
|
||
+#define ACPI_INIT_FUNCTION __init
|
||
+
|
||
#ifndef CONFIG_ACPI
|
||
|
||
/* External globals for __KERNEL__, stubs is needed */
|
||
@@ -168,13 +170,21 @@
|
||
#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_get_next_filename
|
||
#define ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_close_directory
|
||
|
||
+#define ACPI_MSG_ERROR KERN_ERR "ACPI Error: "
|
||
+#define ACPI_MSG_EXCEPTION KERN_ERR "ACPI Exception: "
|
||
+#define ACPI_MSG_WARNING KERN_WARNING "ACPI Warning: "
|
||
+#define ACPI_MSG_INFO KERN_INFO "ACPI: "
|
||
+
|
||
+#define ACPI_MSG_BIOS_ERROR KERN_ERR "ACPI BIOS Error (bug): "
|
||
+#define ACPI_MSG_BIOS_WARNING KERN_WARNING "ACPI BIOS Warning (bug): "
|
||
+
|
||
#else /* !__KERNEL__ */
|
||
|
||
-#include <stdarg.h>
|
||
-#include <string.h>
|
||
-#include <stdlib.h>
|
||
-#include <ctype.h>
|
||
+#define ACPI_USE_STANDARD_HEADERS
|
||
+
|
||
+#ifdef ACPI_USE_STANDARD_HEADERS
|
||
#include <unistd.h>
|
||
+#endif
|
||
|
||
/* Define/disable kernel-specific declarators */
|
||
|
||
@@ -205,8 +215,4 @@
|
||
|
||
#endif /* __KERNEL__ */
|
||
|
||
-/* Linux uses GCC */
|
||
-
|
||
-#include <acpi/platform/acgcc.h>
|
||
-
|
||
#endif /* __ACLINUX_H__ */
|
||
diff --git a/include/acpi/platform/aclinuxex.h b/include/acpi/platform/aclinuxex.h
|
||
index f8bb0d8..a5509d8 100644
|
||
--- a/include/acpi/platform/aclinuxex.h
|
||
+++ b/include/acpi/platform/aclinuxex.h
|
||
@@ -71,7 +71,7 @@
|
||
/*
|
||
* Overrides for in-kernel ACPICA
|
||
*/
|
||
-acpi_status __init acpi_os_initialize(void);
|
||
+acpi_status ACPI_INIT_FUNCTION acpi_os_initialize(void);
|
||
|
||
acpi_status acpi_os_terminate(void);
|
||
|
||
diff --git a/include/linux/sched.h b/include/linux/sched.h
|
||
index 62c68e5..b0fa726 100644
|
||
--- a/include/linux/sched.h
|
||
+++ b/include/linux/sched.h
|
||
@@ -3469,15 +3469,19 @@ static inline unsigned long rlimit_max(unsigned int limit)
|
||
return task_rlimit_max(current, limit);
|
||
}
|
||
|
||
+#define SCHED_CPUFREQ_RT (1U << 0)
|
||
+#define SCHED_CPUFREQ_DL (1U << 1)
|
||
+
|
||
+#define SCHED_CPUFREQ_RT_DL (SCHED_CPUFREQ_RT | SCHED_CPUFREQ_DL)
|
||
+
|
||
#ifdef CONFIG_CPU_FREQ
|
||
struct update_util_data {
|
||
- void (*func)(struct update_util_data *data,
|
||
- u64 time, unsigned long util, unsigned long max);
|
||
+ void (*func)(struct update_util_data *data, u64 time, unsigned int flags);
|
||
};
|
||
|
||
void cpufreq_add_update_util_hook(int cpu, struct update_util_data *data,
|
||
- void (*func)(struct update_util_data *data, u64 time,
|
||
- unsigned long util, unsigned long max));
|
||
+ void (*func)(struct update_util_data *data, u64 time,
|
||
+ unsigned int flags));
|
||
void cpufreq_remove_update_util_hook(int cpu);
|
||
#endif /* CONFIG_CPU_FREQ */
|
||
|
||
diff --git a/include/sound/hda_register.h b/include/sound/hda_register.h
|
||
index ff1aecf..0013063 100644
|
||
--- a/include/sound/hda_register.h
|
||
+++ b/include/sound/hda_register.h
|
||
@@ -89,6 +89,19 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
|
||
#define AZX_REG_SD_BDLPL 0x18
|
||
#define AZX_REG_SD_BDLPU 0x1c
|
||
|
||
+/* GTS registers */
|
||
+#define AZX_REG_LLCH 0x14
|
||
+
|
||
+#define AZX_REG_GTS_BASE 0x520
|
||
+
|
||
+#define AZX_REG_GTSCC (AZX_REG_GTS_BASE + 0x00)
|
||
+#define AZX_REG_WALFCC (AZX_REG_GTS_BASE + 0x04)
|
||
+#define AZX_REG_TSCCL (AZX_REG_GTS_BASE + 0x08)
|
||
+#define AZX_REG_TSCCU (AZX_REG_GTS_BASE + 0x0C)
|
||
+#define AZX_REG_LLPFOC (AZX_REG_GTS_BASE + 0x14)
|
||
+#define AZX_REG_LLPCL (AZX_REG_GTS_BASE + 0x18)
|
||
+#define AZX_REG_LLPCU (AZX_REG_GTS_BASE + 0x1C)
|
||
+
|
||
/* Haswell/Broadwell display HD-A controller Extended Mode registers */
|
||
#define AZX_REG_HSW_EM4 0x100c
|
||
#define AZX_REG_HSW_EM5 0x1010
|
||
@@ -242,6 +255,29 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
|
||
/* Interval used to calculate the iterating register offset */
|
||
#define AZX_DRSM_INTERVAL 0x08
|
||
|
||
+/* Global time synchronization registers */
|
||
+#define GTSCC_TSCCD_MASK 0x80000000
|
||
+#define GTSCC_TSCCD_SHIFT BIT(31)
|
||
+#define GTSCC_TSCCI_MASK 0x20
|
||
+#define GTSCC_CDMAS_DMA_DIR_SHIFT 4
|
||
+
|
||
+#define WALFCC_CIF_MASK 0x1FF
|
||
+#define WALFCC_FN_SHIFT 9
|
||
+#define HDA_CLK_CYCLES_PER_FRAME 512
|
||
+
|
||
+/*
|
||
+ * An error occurs near frame "rollover". The clocks in frame value indicates
|
||
+ * whether this error may have occurred. Here we use the value of 10. Please
|
||
+ * see the errata for the right number [<10]
|
||
+ */
|
||
+#define HDA_MAX_CYCLE_VALUE 499
|
||
+#define HDA_MAX_CYCLE_OFFSET 10
|
||
+#define HDA_MAX_CYCLE_READ_RETRY 10
|
||
+
|
||
+#define TSCCU_CCU_SHIFT 32
|
||
+#define LLPC_CCU_SHIFT 32
|
||
+
|
||
+
|
||
/*
|
||
* helpers to read the stream position
|
||
*/
|
||
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
|
||
index 93e63c5..56004ec 100644
|
||
--- a/include/sound/hdaudio.h
|
||
+++ b/include/sound/hdaudio.h
|
||
@@ -245,6 +245,12 @@ struct hdac_rb {
|
||
|
||
/*
|
||
* HD-audio bus base driver
|
||
+ *
|
||
+ * @ppcap: pp capabilities pointer
|
||
+ * @spbcap: SPIB capabilities pointer
|
||
+ * @mlcap: MultiLink capabilities pointer
|
||
+ * @gtscap: gts capabilities pointer
|
||
+ * @drsmcap: dma resume capabilities pointer
|
||
*/
|
||
struct hdac_bus {
|
||
struct device *dev;
|
||
@@ -256,6 +262,12 @@ struct hdac_bus {
|
||
void __iomem *remap_addr;
|
||
int irq;
|
||
|
||
+ void __iomem *ppcap;
|
||
+ void __iomem *spbcap;
|
||
+ void __iomem *mlcap;
|
||
+ void __iomem *gtscap;
|
||
+ void __iomem *drsmcap;
|
||
+
|
||
/* codec linked list */
|
||
struct list_head codec_list;
|
||
unsigned int num_codecs;
|
||
@@ -335,6 +347,7 @@ static inline void snd_hdac_codec_link_down(struct hdac_device *codec)
|
||
int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val);
|
||
int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr,
|
||
unsigned int *res);
|
||
+int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus);
|
||
int snd_hdac_link_power(struct hdac_device *codec, bool enable);
|
||
|
||
bool snd_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset);
|
||
diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h
|
||
index b9593b2..8660a7f 100644
|
||
--- a/include/sound/hdaudio_ext.h
|
||
+++ b/include/sound/hdaudio_ext.h
|
||
@@ -8,11 +8,6 @@
|
||
*
|
||
* @bus: hdac bus
|
||
* @num_streams: streams supported
|
||
- * @ppcap: pp capabilities pointer
|
||
- * @spbcap: SPIB capabilities pointer
|
||
- * @mlcap: MultiLink capabilities pointer
|
||
- * @gtscap: gts capabilities pointer
|
||
- * @drsmcap: dma resume capabilities pointer
|
||
* @hlink_list: link list of HDA links
|
||
* @lock: lock for link mgmt
|
||
* @cmd_dma_state: state of cmd DMAs: CORB and RIRB
|
||
@@ -22,12 +17,6 @@ struct hdac_ext_bus {
|
||
int num_streams;
|
||
int idx;
|
||
|
||
- void __iomem *ppcap;
|
||
- void __iomem *spbcap;
|
||
- void __iomem *mlcap;
|
||
- void __iomem *gtscap;
|
||
- void __iomem *drsmcap;
|
||
-
|
||
struct list_head hlink_list;
|
||
|
||
struct mutex lock;
|
||
@@ -54,7 +43,6 @@ void snd_hdac_ext_bus_device_remove(struct hdac_ext_bus *ebus);
|
||
#define HDA_CODEC_EXT_ENTRY(_vid, _revid, _name, _drv_data) \
|
||
HDA_CODEC_REV_EXT_ENTRY(_vid, _revid, _name, _drv_data)
|
||
|
||
-int snd_hdac_ext_bus_parse_capabilities(struct hdac_ext_bus *sbus);
|
||
void snd_hdac_ext_bus_ppcap_enable(struct hdac_ext_bus *chip, bool enable);
|
||
void snd_hdac_ext_bus_ppcap_int_enable(struct hdac_ext_bus *chip, bool enable);
|
||
|
||
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
|
||
index 9a0178c..b022284 100644
|
||
--- a/kernel/power/snapshot.c
|
||
+++ b/kernel/power/snapshot.c
|
||
@@ -835,9 +835,9 @@ static bool memory_bm_pfn_present(struct memory_bitmap *bm, unsigned long pfn)
|
||
*/
|
||
static bool rtree_next_node(struct memory_bitmap *bm)
|
||
{
|
||
- bm->cur.node = list_entry(bm->cur.node->list.next,
|
||
- struct rtree_node, list);
|
||
- if (&bm->cur.node->list != &bm->cur.zone->leaves) {
|
||
+ if (!list_is_last(&bm->cur.node->list, &bm->cur.zone->leaves)) {
|
||
+ bm->cur.node = list_entry(bm->cur.node->list.next,
|
||
+ struct rtree_node, list);
|
||
bm->cur.node_pfn += BM_BITS_PER_BLOCK;
|
||
bm->cur.node_bit = 0;
|
||
touch_softlockup_watchdog();
|
||
@@ -845,9 +845,9 @@ static bool rtree_next_node(struct memory_bitmap *bm)
|
||
}
|
||
|
||
/* No more nodes, goto next zone */
|
||
- bm->cur.zone = list_entry(bm->cur.zone->list.next,
|
||
+ if (!list_is_last(&bm->cur.zone->list, &bm->zones)) {
|
||
+ bm->cur.zone = list_entry(bm->cur.zone->list.next,
|
||
struct mem_zone_bm_rtree, list);
|
||
- if (&bm->cur.zone->list != &bm->zones) {
|
||
bm->cur.node = list_entry(bm->cur.zone->leaves.next,
|
||
struct rtree_node, list);
|
||
bm->cur.node_pfn = 0;
|
||
diff --git a/kernel/sched/cpufreq.c b/kernel/sched/cpufreq.c
|
||
index 1141954..dbc5144 100644
|
||
--- a/kernel/sched/cpufreq.c
|
||
+++ b/kernel/sched/cpufreq.c
|
||
@@ -33,7 +33,7 @@ DEFINE_PER_CPU(struct update_util_data *, cpufreq_update_util_data);
|
||
*/
|
||
void cpufreq_add_update_util_hook(int cpu, struct update_util_data *data,
|
||
void (*func)(struct update_util_data *data, u64 time,
|
||
- unsigned long util, unsigned long max))
|
||
+ unsigned int flags))
|
||
{
|
||
if (WARN_ON(!data || !func))
|
||
return;
|
||
diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c
|
||
index a84641b..60d985f 100644
|
||
--- a/kernel/sched/cpufreq_schedutil.c
|
||
+++ b/kernel/sched/cpufreq_schedutil.c
|
||
@@ -12,7 +12,6 @@
|
||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||
|
||
#include <linux/cpufreq.h>
|
||
-#include <linux/module.h>
|
||
#include <linux/slab.h>
|
||
#include <trace/events/power.h>
|
||
|
||
@@ -53,6 +52,7 @@ struct sugov_cpu {
|
||
unsigned long util;
|
||
unsigned long max;
|
||
u64 last_update;
|
||
+ unsigned int flags;
|
||
};
|
||
|
||
static DEFINE_PER_CPU(struct sugov_cpu, sugov_cpu);
|
||
@@ -144,24 +144,39 @@ static unsigned int get_next_freq(struct sugov_cpu *sg_cpu, unsigned long util,
|
||
return cpufreq_driver_resolve_freq(policy, freq);
|
||
}
|
||
|
||
+static void sugov_get_util(unsigned long *util, unsigned long *max)
|
||
+{
|
||
+ struct rq *rq = this_rq();
|
||
+ unsigned long cfs_max = rq->cpu_capacity_orig;
|
||
+
|
||
+ *util = min(rq->cfs.avg.util_avg, cfs_max);
|
||
+ *max = cfs_max;
|
||
+}
|
||
+
|
||
static void sugov_update_single(struct update_util_data *hook, u64 time,
|
||
- unsigned long util, unsigned long max)
|
||
+ unsigned int flags)
|
||
{
|
||
struct sugov_cpu *sg_cpu = container_of(hook, struct sugov_cpu, update_util);
|
||
struct sugov_policy *sg_policy = sg_cpu->sg_policy;
|
||
struct cpufreq_policy *policy = sg_policy->policy;
|
||
+ unsigned long util, max;
|
||
unsigned int next_f;
|
||
|
||
if (!sugov_should_update_freq(sg_policy, time))
|
||
return;
|
||
|
||
- next_f = util == ULONG_MAX ? policy->cpuinfo.max_freq :
|
||
- get_next_freq(sg_cpu, util, max);
|
||
+ if (flags & SCHED_CPUFREQ_RT_DL) {
|
||
+ next_f = policy->cpuinfo.max_freq;
|
||
+ } else {
|
||
+ sugov_get_util(&util, &max);
|
||
+ next_f = get_next_freq(sg_cpu, util, max);
|
||
+ }
|
||
sugov_update_commit(sg_policy, time, next_f);
|
||
}
|
||
|
||
static unsigned int sugov_next_freq_shared(struct sugov_cpu *sg_cpu,
|
||
- unsigned long util, unsigned long max)
|
||
+ unsigned long util, unsigned long max,
|
||
+ unsigned int flags)
|
||
{
|
||
struct sugov_policy *sg_policy = sg_cpu->sg_policy;
|
||
struct cpufreq_policy *policy = sg_policy->policy;
|
||
@@ -169,7 +184,7 @@ static unsigned int sugov_next_freq_shared(struct sugov_cpu *sg_cpu,
|
||
u64 last_freq_update_time = sg_policy->last_freq_update_time;
|
||
unsigned int j;
|
||
|
||
- if (util == ULONG_MAX)
|
||
+ if (flags & SCHED_CPUFREQ_RT_DL)
|
||
return max_f;
|
||
|
||
for_each_cpu(j, policy->cpus) {
|
||
@@ -192,10 +207,10 @@ static unsigned int sugov_next_freq_shared(struct sugov_cpu *sg_cpu,
|
||
if (delta_ns > TICK_NSEC)
|
||
continue;
|
||
|
||
- j_util = j_sg_cpu->util;
|
||
- if (j_util == ULONG_MAX)
|
||
+ if (j_sg_cpu->flags & SCHED_CPUFREQ_RT_DL)
|
||
return max_f;
|
||
|
||
+ j_util = j_sg_cpu->util;
|
||
j_max = j_sg_cpu->max;
|
||
if (j_util * max > j_max * util) {
|
||
util = j_util;
|
||
@@ -207,20 +222,24 @@ static unsigned int sugov_next_freq_shared(struct sugov_cpu *sg_cpu,
|
||
}
|
||
|
||
static void sugov_update_shared(struct update_util_data *hook, u64 time,
|
||
- unsigned long util, unsigned long max)
|
||
+ unsigned int flags)
|
||
{
|
||
struct sugov_cpu *sg_cpu = container_of(hook, struct sugov_cpu, update_util);
|
||
struct sugov_policy *sg_policy = sg_cpu->sg_policy;
|
||
+ unsigned long util, max;
|
||
unsigned int next_f;
|
||
|
||
+ sugov_get_util(&util, &max);
|
||
+
|
||
raw_spin_lock(&sg_policy->update_lock);
|
||
|
||
sg_cpu->util = util;
|
||
sg_cpu->max = max;
|
||
+ sg_cpu->flags = flags;
|
||
sg_cpu->last_update = time;
|
||
|
||
if (sugov_should_update_freq(sg_policy, time)) {
|
||
- next_f = sugov_next_freq_shared(sg_cpu, util, max);
|
||
+ next_f = sugov_next_freq_shared(sg_cpu, util, max, flags);
|
||
sugov_update_commit(sg_policy, time, next_f);
|
||
}
|
||
|
||
@@ -444,8 +463,9 @@ static int sugov_start(struct cpufreq_policy *policy)
|
||
|
||
sg_cpu->sg_policy = sg_policy;
|
||
if (policy_is_shared(policy)) {
|
||
- sg_cpu->util = ULONG_MAX;
|
||
+ sg_cpu->util = 0;
|
||
sg_cpu->max = 0;
|
||
+ sg_cpu->flags = SCHED_CPUFREQ_RT;
|
||
sg_cpu->last_update = 0;
|
||
sg_cpu->cached_raw_freq = 0;
|
||
cpufreq_add_update_util_hook(cpu, &sg_cpu->update_util,
|
||
@@ -495,28 +515,15 @@ static struct cpufreq_governor schedutil_gov = {
|
||
.limits = sugov_limits,
|
||
};
|
||
|
||
-static int __init sugov_module_init(void)
|
||
-{
|
||
- return cpufreq_register_governor(&schedutil_gov);
|
||
-}
|
||
-
|
||
-static void __exit sugov_module_exit(void)
|
||
-{
|
||
- cpufreq_unregister_governor(&schedutil_gov);
|
||
-}
|
||
-
|
||
-MODULE_AUTHOR("Rafael J. Wysocki <rafael.j.wysocki@intel.com>");
|
||
-MODULE_DESCRIPTION("Utilization-based CPU frequency selection");
|
||
-MODULE_LICENSE("GPL");
|
||
-
|
||
#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL
|
||
struct cpufreq_governor *cpufreq_default_governor(void)
|
||
{
|
||
return &schedutil_gov;
|
||
}
|
||
-
|
||
-fs_initcall(sugov_module_init);
|
||
-#else
|
||
-module_init(sugov_module_init);
|
||
#endif
|
||
-module_exit(sugov_module_exit);
|
||
+
|
||
+static int __init sugov_register(void)
|
||
+{
|
||
+ return cpufreq_register_governor(&schedutil_gov);
|
||
+}
|
||
+fs_initcall(sugov_register);
|
||
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
|
||
index 1ce8867..9747796 100644
|
||
--- a/kernel/sched/deadline.c
|
||
+++ b/kernel/sched/deadline.c
|
||
@@ -735,9 +735,8 @@ static void update_curr_dl(struct rq *rq)
|
||
return;
|
||
}
|
||
|
||
- /* kick cpufreq (see the comment in linux/cpufreq.h). */
|
||
- if (cpu_of(rq) == smp_processor_id())
|
||
- cpufreq_trigger_update(rq_clock(rq));
|
||
+ /* kick cpufreq (see the comment in kernel/sched/sched.h). */
|
||
+ cpufreq_update_this_cpu(rq, SCHED_CPUFREQ_DL);
|
||
|
||
schedstat_set(curr->se.statistics.exec_max,
|
||
max(curr->se.statistics.exec_max, delta_exec));
|
||
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
|
||
index 039de34..5d558cc 100644
|
||
--- a/kernel/sched/fair.c
|
||
+++ b/kernel/sched/fair.c
|
||
@@ -2875,12 +2875,7 @@ static inline void update_tg_load_avg(struct cfs_rq *cfs_rq, int force) {}
|
||
|
||
static inline void cfs_rq_util_change(struct cfs_rq *cfs_rq)
|
||
{
|
||
- struct rq *rq = rq_of(cfs_rq);
|
||
- int cpu = cpu_of(rq);
|
||
-
|
||
- if (cpu == smp_processor_id() && &rq->cfs == cfs_rq) {
|
||
- unsigned long max = rq->cpu_capacity_orig;
|
||
-
|
||
+ if (&this_rq()->cfs == cfs_rq) {
|
||
/*
|
||
* There are a few boundary cases this might miss but it should
|
||
* get called often enough that that should (hopefully) not be
|
||
@@ -2897,8 +2892,7 @@ static inline void cfs_rq_util_change(struct cfs_rq *cfs_rq)
|
||
*
|
||
* See cpu_util().
|
||
*/
|
||
- cpufreq_update_util(rq_clock(rq),
|
||
- min(cfs_rq->avg.util_avg, max), max);
|
||
+ cpufreq_update_util(rq_of(cfs_rq), 0);
|
||
}
|
||
}
|
||
|
||
@@ -3159,10 +3153,7 @@ update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq, bool update_freq)
|
||
|
||
static inline void update_load_avg(struct sched_entity *se, int not_used)
|
||
{
|
||
- struct cfs_rq *cfs_rq = cfs_rq_of(se);
|
||
- struct rq *rq = rq_of(cfs_rq);
|
||
-
|
||
- cpufreq_trigger_update(rq_clock(rq));
|
||
+ cpufreq_update_util(rq_of(cfs_rq_of(se)), 0);
|
||
}
|
||
|
||
static inline void
|
||
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
|
||
index d5690b7..2516b8d 100644
|
||
--- a/kernel/sched/rt.c
|
||
+++ b/kernel/sched/rt.c
|
||
@@ -957,9 +957,8 @@ static void update_curr_rt(struct rq *rq)
|
||
if (unlikely((s64)delta_exec <= 0))
|
||
return;
|
||
|
||
- /* Kick cpufreq (see the comment in linux/cpufreq.h). */
|
||
- if (cpu_of(rq) == smp_processor_id())
|
||
- cpufreq_trigger_update(rq_clock(rq));
|
||
+ /* Kick cpufreq (see the comment in kernel/sched/sched.h). */
|
||
+ cpufreq_update_this_cpu(rq, SCHED_CPUFREQ_RT);
|
||
|
||
schedstat_set(curr->se.statistics.exec_max,
|
||
max(curr->se.statistics.exec_max, delta_exec));
|
||
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
|
||
index c64fc51..b7fc1ce 100644
|
||
--- a/kernel/sched/sched.h
|
||
+++ b/kernel/sched/sched.h
|
||
@@ -1763,27 +1763,13 @@ DECLARE_PER_CPU(struct update_util_data *, cpufreq_update_util_data);
|
||
|
||
/**
|
||
* cpufreq_update_util - Take a note about CPU utilization changes.
|
||
- * @time: Current time.
|
||
- * @util: Current utilization.
|
||
- * @max: Utilization ceiling.
|
||
+ * @rq: Runqueue to carry out the update for.
|
||
+ * @flags: Update reason flags.
|
||
*
|
||
- * This function is called by the scheduler on every invocation of
|
||
- * update_load_avg() on the CPU whose utilization is being updated.
|
||
+ * This function is called by the scheduler on the CPU whose utilization is
|
||
+ * being updated.
|
||
*
|
||
* It can only be called from RCU-sched read-side critical sections.
|
||
- */
|
||
-static inline void cpufreq_update_util(u64 time, unsigned long util, unsigned long max)
|
||
-{
|
||
- struct update_util_data *data;
|
||
-
|
||
- data = rcu_dereference_sched(*this_cpu_ptr(&cpufreq_update_util_data));
|
||
- if (data)
|
||
- data->func(data, time, util, max);
|
||
-}
|
||
-
|
||
-/**
|
||
- * cpufreq_trigger_update - Trigger CPU performance state evaluation if needed.
|
||
- * @time: Current time.
|
||
*
|
||
* The way cpufreq is currently arranged requires it to evaluate the CPU
|
||
* performance state (frequency/voltage) on a regular basis to prevent it from
|
||
@@ -1797,13 +1783,23 @@ static inline void cpufreq_update_util(u64 time, unsigned long util, unsigned lo
|
||
* but that really is a band-aid. Going forward it should be replaced with
|
||
* solutions targeted more specifically at RT and DL tasks.
|
||
*/
|
||
-static inline void cpufreq_trigger_update(u64 time)
|
||
+static inline void cpufreq_update_util(struct rq *rq, unsigned int flags)
|
||
+{
|
||
+ struct update_util_data *data;
|
||
+
|
||
+ data = rcu_dereference_sched(*this_cpu_ptr(&cpufreq_update_util_data));
|
||
+ if (data)
|
||
+ data->func(data, rq_clock(rq), flags);
|
||
+}
|
||
+
|
||
+static inline void cpufreq_update_this_cpu(struct rq *rq, unsigned int flags)
|
||
{
|
||
- cpufreq_update_util(time, ULONG_MAX, 0);
|
||
+ if (cpu_of(rq) == smp_processor_id())
|
||
+ cpufreq_update_util(rq, flags);
|
||
}
|
||
#else
|
||
-static inline void cpufreq_update_util(u64 time, unsigned long util, unsigned long max) {}
|
||
-static inline void cpufreq_trigger_update(u64 time) {}
|
||
+static inline void cpufreq_update_util(struct rq *rq, unsigned int flags) {}
|
||
+static inline void cpufreq_update_this_cpu(struct rq *rq, unsigned int flags) {}
|
||
#endif /* CONFIG_CPU_FREQ */
|
||
|
||
#ifdef arch_scale_freq_capacity
|
||
diff --git a/sound/hda/ext/hdac_ext_controller.c b/sound/hda/ext/hdac_ext_controller.c
|
||
index 860f8ca..2614691 100644
|
||
--- a/sound/hda/ext/hdac_ext_controller.c
|
||
+++ b/sound/hda/ext/hdac_ext_controller.c
|
||
@@ -29,81 +29,6 @@
|
||
*/
|
||
#define HDAC_MAX_CAPS 10
|
||
|
||
-/**
|
||
- * snd_hdac_ext_bus_parse_capabilities - parse capablity structure
|
||
- * @ebus: the pointer to extended bus object
|
||
- *
|
||
- * Returns 0 if successful, or a negative error code.
|
||
- */
|
||
-int snd_hdac_ext_bus_parse_capabilities(struct hdac_ext_bus *ebus)
|
||
-{
|
||
- unsigned int cur_cap;
|
||
- unsigned int offset;
|
||
- struct hdac_bus *bus = &ebus->bus;
|
||
- unsigned int counter = 0;
|
||
-
|
||
- offset = snd_hdac_chip_readl(bus, LLCH);
|
||
-
|
||
- /* Lets walk the linked capabilities list */
|
||
- do {
|
||
- cur_cap = _snd_hdac_chip_read(l, bus, offset);
|
||
-
|
||
- dev_dbg(bus->dev, "Capability version: 0x%x\n",
|
||
- ((cur_cap & AZX_CAP_HDR_VER_MASK) >> AZX_CAP_HDR_VER_OFF));
|
||
-
|
||
- dev_dbg(bus->dev, "HDA capability ID: 0x%x\n",
|
||
- (cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF);
|
||
-
|
||
- switch ((cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF) {
|
||
- case AZX_ML_CAP_ID:
|
||
- dev_dbg(bus->dev, "Found ML capability\n");
|
||
- ebus->mlcap = bus->remap_addr + offset;
|
||
- break;
|
||
-
|
||
- case AZX_GTS_CAP_ID:
|
||
- dev_dbg(bus->dev, "Found GTS capability offset=%x\n", offset);
|
||
- ebus->gtscap = bus->remap_addr + offset;
|
||
- break;
|
||
-
|
||
- case AZX_PP_CAP_ID:
|
||
- /* PP capability found, the Audio DSP is present */
|
||
- dev_dbg(bus->dev, "Found PP capability offset=%x\n", offset);
|
||
- ebus->ppcap = bus->remap_addr + offset;
|
||
- break;
|
||
-
|
||
- case AZX_SPB_CAP_ID:
|
||
- /* SPIB capability found, handler function */
|
||
- dev_dbg(bus->dev, "Found SPB capability\n");
|
||
- ebus->spbcap = bus->remap_addr + offset;
|
||
- break;
|
||
-
|
||
- case AZX_DRSM_CAP_ID:
|
||
- /* DMA resume capability found, handler function */
|
||
- dev_dbg(bus->dev, "Found DRSM capability\n");
|
||
- ebus->drsmcap = bus->remap_addr + offset;
|
||
- break;
|
||
-
|
||
- default:
|
||
- dev_dbg(bus->dev, "Unknown capability %d\n", cur_cap);
|
||
- break;
|
||
- }
|
||
-
|
||
- counter++;
|
||
-
|
||
- if (counter > HDAC_MAX_CAPS) {
|
||
- dev_err(bus->dev, "We exceeded HDAC Ext capablities!!!\n");
|
||
- break;
|
||
- }
|
||
-
|
||
- /* read the offset of next capabiity */
|
||
- offset = cur_cap & AZX_CAP_HDR_NXT_PTR_MASK;
|
||
-
|
||
- } while (offset);
|
||
-
|
||
- return 0;
|
||
-}
|
||
-EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_parse_capabilities);
|
||
-
|
||
/*
|
||
* processing pipe helpers - these helpers are useful for dealing with HDA
|
||
* new capability of processing pipelines
|
||
@@ -118,15 +43,15 @@ void snd_hdac_ext_bus_ppcap_enable(struct hdac_ext_bus *ebus, bool enable)
|
||
{
|
||
struct hdac_bus *bus = &ebus->bus;
|
||
|
||
- if (!ebus->ppcap) {
|
||
+ if (!bus->ppcap) {
|
||
dev_err(bus->dev, "Address of PP capability is NULL");
|
||
return;
|
||
}
|
||
|
||
if (enable)
|
||
- snd_hdac_updatel(ebus->ppcap, AZX_REG_PP_PPCTL, 0, AZX_PPCTL_GPROCEN);
|
||
+ snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, 0, AZX_PPCTL_GPROCEN);
|
||
else
|
||
- snd_hdac_updatel(ebus->ppcap, AZX_REG_PP_PPCTL, AZX_PPCTL_GPROCEN, 0);
|
||
+ snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, AZX_PPCTL_GPROCEN, 0);
|
||
}
|
||
EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_ppcap_enable);
|
||
|
||
@@ -139,15 +64,15 @@ void snd_hdac_ext_bus_ppcap_int_enable(struct hdac_ext_bus *ebus, bool enable)
|
||
{
|
||
struct hdac_bus *bus = &ebus->bus;
|
||
|
||
- if (!ebus->ppcap) {
|
||
+ if (!bus->ppcap) {
|
||
dev_err(bus->dev, "Address of PP capability is NULL\n");
|
||
return;
|
||
}
|
||
|
||
if (enable)
|
||
- snd_hdac_updatel(ebus->ppcap, AZX_REG_PP_PPCTL, 0, AZX_PPCTL_PIE);
|
||
+ snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, 0, AZX_PPCTL_PIE);
|
||
else
|
||
- snd_hdac_updatel(ebus->ppcap, AZX_REG_PP_PPCTL, AZX_PPCTL_PIE, 0);
|
||
+ snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, AZX_PPCTL_PIE, 0);
|
||
}
|
||
EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_ppcap_int_enable);
|
||
|
||
@@ -171,7 +96,7 @@ int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_ext_bus *ebus)
|
||
struct hdac_ext_link *hlink;
|
||
struct hdac_bus *bus = &ebus->bus;
|
||
|
||
- link_count = readl(ebus->mlcap + AZX_REG_ML_MLCD) + 1;
|
||
+ link_count = readl(bus->mlcap + AZX_REG_ML_MLCD) + 1;
|
||
|
||
dev_dbg(bus->dev, "In %s Link count: %d\n", __func__, link_count);
|
||
|
||
@@ -181,7 +106,7 @@ int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_ext_bus *ebus)
|
||
return -ENOMEM;
|
||
hlink->index = idx;
|
||
hlink->bus = bus;
|
||
- hlink->ml_addr = ebus->mlcap + AZX_ML_BASE +
|
||
+ hlink->ml_addr = bus->mlcap + AZX_ML_BASE +
|
||
(AZX_ML_INTERVAL * idx);
|
||
hlink->lcaps = readl(hlink->ml_addr + AZX_REG_ML_LCAP);
|
||
hlink->lsdiid = readw(hlink->ml_addr + AZX_REG_ML_LSDIID);
|
||
diff --git a/sound/hda/ext/hdac_ext_stream.c b/sound/hda/ext/hdac_ext_stream.c
|
||
index 626f3bb..2441273 100644
|
||
--- a/sound/hda/ext/hdac_ext_stream.c
|
||
+++ b/sound/hda/ext/hdac_ext_stream.c
|
||
@@ -40,27 +40,27 @@ void snd_hdac_ext_stream_init(struct hdac_ext_bus *ebus,
|
||
{
|
||
struct hdac_bus *bus = &ebus->bus;
|
||
|
||
- if (ebus->ppcap) {
|
||
- stream->pphc_addr = ebus->ppcap + AZX_PPHC_BASE +
|
||
+ if (bus->ppcap) {
|
||
+ stream->pphc_addr = bus->ppcap + AZX_PPHC_BASE +
|
||
AZX_PPHC_INTERVAL * idx;
|
||
|
||
- stream->pplc_addr = ebus->ppcap + AZX_PPLC_BASE +
|
||
+ stream->pplc_addr = bus->ppcap + AZX_PPLC_BASE +
|
||
AZX_PPLC_MULTI * ebus->num_streams +
|
||
AZX_PPLC_INTERVAL * idx;
|
||
}
|
||
|
||
- if (ebus->spbcap) {
|
||
- stream->spib_addr = ebus->spbcap + AZX_SPB_BASE +
|
||
+ if (bus->spbcap) {
|
||
+ stream->spib_addr = bus->spbcap + AZX_SPB_BASE +
|
||
AZX_SPB_INTERVAL * idx +
|
||
AZX_SPB_SPIB;
|
||
|
||
- stream->fifo_addr = ebus->spbcap + AZX_SPB_BASE +
|
||
+ stream->fifo_addr = bus->spbcap + AZX_SPB_BASE +
|
||
AZX_SPB_INTERVAL * idx +
|
||
AZX_SPB_MAXFIFO;
|
||
}
|
||
|
||
- if (ebus->drsmcap)
|
||
- stream->dpibr_addr = ebus->drsmcap + AZX_DRSM_BASE +
|
||
+ if (bus->drsmcap)
|
||
+ stream->dpibr_addr = bus->drsmcap + AZX_DRSM_BASE +
|
||
AZX_DRSM_INTERVAL * idx;
|
||
|
||
stream->decoupled = false;
|
||
@@ -131,10 +131,10 @@ void snd_hdac_ext_stream_decouple(struct hdac_ext_bus *ebus,
|
||
|
||
spin_lock_irq(&bus->reg_lock);
|
||
if (decouple)
|
||
- snd_hdac_updatel(ebus->ppcap, AZX_REG_PP_PPCTL, 0,
|
||
+ snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, 0,
|
||
AZX_PPCTL_PROCEN(hstream->index));
|
||
else
|
||
- snd_hdac_updatel(ebus->ppcap, AZX_REG_PP_PPCTL,
|
||
+ snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL,
|
||
AZX_PPCTL_PROCEN(hstream->index), 0);
|
||
stream->decoupled = decouple;
|
||
spin_unlock_irq(&bus->reg_lock);
|
||
@@ -255,7 +255,7 @@ hdac_ext_link_stream_assign(struct hdac_ext_bus *ebus,
|
||
struct hdac_stream *stream = NULL;
|
||
struct hdac_bus *hbus = &ebus->bus;
|
||
|
||
- if (!ebus->ppcap) {
|
||
+ if (!hbus->ppcap) {
|
||
dev_err(hbus->dev, "stream type not supported\n");
|
||
return NULL;
|
||
}
|
||
@@ -296,7 +296,7 @@ hdac_ext_host_stream_assign(struct hdac_ext_bus *ebus,
|
||
struct hdac_stream *stream = NULL;
|
||
struct hdac_bus *hbus = &ebus->bus;
|
||
|
||
- if (!ebus->ppcap) {
|
||
+ if (!hbus->ppcap) {
|
||
dev_err(hbus->dev, "stream type not supported\n");
|
||
return NULL;
|
||
}
|
||
@@ -423,21 +423,21 @@ void snd_hdac_ext_stream_spbcap_enable(struct hdac_ext_bus *ebus,
|
||
u32 register_mask = 0;
|
||
struct hdac_bus *bus = &ebus->bus;
|
||
|
||
- if (!ebus->spbcap) {
|
||
+ if (!bus->spbcap) {
|
||
dev_err(bus->dev, "Address of SPB capability is NULL");
|
||
return;
|
||
}
|
||
|
||
mask |= (1 << index);
|
||
|
||
- register_mask = readl(ebus->spbcap + AZX_REG_SPB_SPBFCCTL);
|
||
+ register_mask = readl(bus->spbcap + AZX_REG_SPB_SPBFCCTL);
|
||
|
||
mask |= register_mask;
|
||
|
||
if (enable)
|
||
- snd_hdac_updatel(ebus->spbcap, AZX_REG_SPB_SPBFCCTL, 0, mask);
|
||
+ snd_hdac_updatel(bus->spbcap, AZX_REG_SPB_SPBFCCTL, 0, mask);
|
||
else
|
||
- snd_hdac_updatel(ebus->spbcap, AZX_REG_SPB_SPBFCCTL, mask, 0);
|
||
+ snd_hdac_updatel(bus->spbcap, AZX_REG_SPB_SPBFCCTL, mask, 0);
|
||
}
|
||
EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_spbcap_enable);
|
||
|
||
@@ -452,7 +452,7 @@ int snd_hdac_ext_stream_set_spib(struct hdac_ext_bus *ebus,
|
||
{
|
||
struct hdac_bus *bus = &ebus->bus;
|
||
|
||
- if (!ebus->spbcap) {
|
||
+ if (!bus->spbcap) {
|
||
dev_err(bus->dev, "Address of SPB capability is NULL");
|
||
return -EINVAL;
|
||
}
|
||
@@ -475,7 +475,7 @@ int snd_hdac_ext_stream_get_spbmaxfifo(struct hdac_ext_bus *ebus,
|
||
{
|
||
struct hdac_bus *bus = &ebus->bus;
|
||
|
||
- if (!ebus->spbcap) {
|
||
+ if (!bus->spbcap) {
|
||
dev_err(bus->dev, "Address of SPB capability is NULL");
|
||
return -EINVAL;
|
||
}
|
||
@@ -515,21 +515,21 @@ void snd_hdac_ext_stream_drsm_enable(struct hdac_ext_bus *ebus,
|
||
u32 register_mask = 0;
|
||
struct hdac_bus *bus = &ebus->bus;
|
||
|
||
- if (!ebus->drsmcap) {
|
||
+ if (!bus->drsmcap) {
|
||
dev_err(bus->dev, "Address of DRSM capability is NULL");
|
||
return;
|
||
}
|
||
|
||
mask |= (1 << index);
|
||
|
||
- register_mask = readl(ebus->drsmcap + AZX_REG_SPB_SPBFCCTL);
|
||
+ register_mask = readl(bus->drsmcap + AZX_REG_SPB_SPBFCCTL);
|
||
|
||
mask |= register_mask;
|
||
|
||
if (enable)
|
||
- snd_hdac_updatel(ebus->drsmcap, AZX_REG_DRSM_CTL, 0, mask);
|
||
+ snd_hdac_updatel(bus->drsmcap, AZX_REG_DRSM_CTL, 0, mask);
|
||
else
|
||
- snd_hdac_updatel(ebus->drsmcap, AZX_REG_DRSM_CTL, mask, 0);
|
||
+ snd_hdac_updatel(bus->drsmcap, AZX_REG_DRSM_CTL, mask, 0);
|
||
}
|
||
EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_drsm_enable);
|
||
|
||
@@ -544,7 +544,7 @@ int snd_hdac_ext_stream_set_dpibr(struct hdac_ext_bus *ebus,
|
||
{
|
||
struct hdac_bus *bus = &ebus->bus;
|
||
|
||
- if (!ebus->drsmcap) {
|
||
+ if (!bus->drsmcap) {
|
||
dev_err(bus->dev, "Address of DRSM capability is NULL");
|
||
return -EINVAL;
|
||
}
|
||
diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c
|
||
index 9fee464..0430658 100644
|
||
--- a/sound/hda/hdac_controller.c
|
||
+++ b/sound/hda/hdac_controller.c
|
||
@@ -255,6 +255,81 @@ int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr,
|
||
}
|
||
EXPORT_SYMBOL_GPL(snd_hdac_bus_get_response);
|
||
|
||
+#define HDAC_MAX_CAPS 10
|
||
+/**
|
||
+ * snd_hdac_bus_parse_capabilities - parse capability structure
|
||
+ * @bus: the pointer to bus object
|
||
+ *
|
||
+ * Returns 0 if successful, or a negative error code.
|
||
+ */
|
||
+int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus)
|
||
+{
|
||
+ unsigned int cur_cap;
|
||
+ unsigned int offset;
|
||
+ unsigned int counter = 0;
|
||
+
|
||
+ offset = snd_hdac_chip_readl(bus, LLCH);
|
||
+
|
||
+ /* Lets walk the linked capabilities list */
|
||
+ do {
|
||
+ cur_cap = _snd_hdac_chip_read(l, bus, offset);
|
||
+
|
||
+ dev_dbg(bus->dev, "Capability version: 0x%x\n",
|
||
+ (cur_cap & AZX_CAP_HDR_VER_MASK) >> AZX_CAP_HDR_VER_OFF);
|
||
+
|
||
+ dev_dbg(bus->dev, "HDA capability ID: 0x%x\n",
|
||
+ (cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF);
|
||
+
|
||
+ switch ((cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF) {
|
||
+ case AZX_ML_CAP_ID:
|
||
+ dev_dbg(bus->dev, "Found ML capability\n");
|
||
+ bus->mlcap = bus->remap_addr + offset;
|
||
+ break;
|
||
+
|
||
+ case AZX_GTS_CAP_ID:
|
||
+ dev_dbg(bus->dev, "Found GTS capability offset=%x\n", offset);
|
||
+ bus->gtscap = bus->remap_addr + offset;
|
||
+ break;
|
||
+
|
||
+ case AZX_PP_CAP_ID:
|
||
+ /* PP capability found, the Audio DSP is present */
|
||
+ dev_dbg(bus->dev, "Found PP capability offset=%x\n", offset);
|
||
+ bus->ppcap = bus->remap_addr + offset;
|
||
+ break;
|
||
+
|
||
+ case AZX_SPB_CAP_ID:
|
||
+ /* SPIB capability found, handler function */
|
||
+ dev_dbg(bus->dev, "Found SPB capability\n");
|
||
+ bus->spbcap = bus->remap_addr + offset;
|
||
+ break;
|
||
+
|
||
+ case AZX_DRSM_CAP_ID:
|
||
+ /* DMA resume capability found, handler function */
|
||
+ dev_dbg(bus->dev, "Found DRSM capability\n");
|
||
+ bus->drsmcap = bus->remap_addr + offset;
|
||
+ break;
|
||
+
|
||
+ default:
|
||
+ dev_dbg(bus->dev, "Unknown capability %d\n", cur_cap);
|
||
+ break;
|
||
+ }
|
||
+
|
||
+ counter++;
|
||
+
|
||
+ if (counter > HDAC_MAX_CAPS) {
|
||
+ dev_err(bus->dev, "We exceeded HDAC capabilities!!!\n");
|
||
+ break;
|
||
+ }
|
||
+
|
||
+ /* read the offset of next capability */
|
||
+ offset = cur_cap & AZX_CAP_HDR_NXT_PTR_MASK;
|
||
+
|
||
+ } while (offset);
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+EXPORT_SYMBOL_GPL(snd_hdac_bus_parse_capabilities);
|
||
+
|
||
/*
|
||
* Lowlevel interface
|
||
*/
|
||
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
|
||
index 27de801..2ad3b44 100644
|
||
--- a/sound/pci/hda/hda_controller.c
|
||
+++ b/sound/pci/hda/hda_controller.c
|
||
@@ -27,6 +27,12 @@
|
||
#include <linux/module.h>
|
||
#include <linux/pm_runtime.h>
|
||
#include <linux/slab.h>
|
||
+
|
||
+#ifdef CONFIG_X86
|
||
+/* for art-tsc conversion */
|
||
+#include <asm/tsc.h>
|
||
+#endif
|
||
+
|
||
#include <sound/core.h>
|
||
#include <sound/initval.h>
|
||
#include "hda_controller.h"
|
||
@@ -337,12 +343,173 @@ static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream)
|
||
azx_get_position(chip, azx_dev));
|
||
}
|
||
|
||
+/*
|
||
+ * azx_scale64: Scale base by mult/div while not overflowing sanely
|
||
+ *
|
||
+ * Derived from scale64_check_overflow in kernel/time/timekeeping.c
|
||
+ *
|
||
+ * The tmestamps for a 48Khz stream can overflow after (2^64/10^9)/48K which
|
||
+ * is about 384307 ie ~4.5 days.
|
||
+ *
|
||
+ * This scales the calculation so that overflow will happen but after 2^64 /
|
||
+ * 48000 secs, which is pretty large!
|
||
+ *
|
||
+ * In caln below:
|
||
+ * base may overflow, but since there isn’t any additional division
|
||
+ * performed on base it’s OK
|
||
+ * rem can’t overflow because both are 32-bit values
|
||
+ */
|
||
+
|
||
+#ifdef CONFIG_X86
|
||
+static u64 azx_scale64(u64 base, u32 num, u32 den)
|
||
+{
|
||
+ u64 rem;
|
||
+
|
||
+ rem = do_div(base, den);
|
||
+
|
||
+ base *= num;
|
||
+ rem *= num;
|
||
+
|
||
+ do_div(rem, den);
|
||
+
|
||
+ return base + rem;
|
||
+}
|
||
+
|
||
+static int azx_get_sync_time(ktime_t *device,
|
||
+ struct system_counterval_t *system, void *ctx)
|
||
+{
|
||
+ struct snd_pcm_substream *substream = ctx;
|
||
+ struct azx_dev *azx_dev = get_azx_dev(substream);
|
||
+ struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
|
||
+ struct azx *chip = apcm->chip;
|
||
+ struct snd_pcm_runtime *runtime;
|
||
+ u64 ll_counter, ll_counter_l, ll_counter_h;
|
||
+ u64 tsc_counter, tsc_counter_l, tsc_counter_h;
|
||
+ u32 wallclk_ctr, wallclk_cycles;
|
||
+ bool direction;
|
||
+ u32 dma_select;
|
||
+ u32 timeout = 200;
|
||
+ u32 retry_count = 0;
|
||
+
|
||
+ runtime = substream->runtime;
|
||
+
|
||
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||
+ direction = 1;
|
||
+ else
|
||
+ direction = 0;
|
||
+
|
||
+ /* 0th stream tag is not used, so DMA ch 0 is for 1st stream tag */
|
||
+ do {
|
||
+ timeout = 100;
|
||
+ dma_select = (direction << GTSCC_CDMAS_DMA_DIR_SHIFT) |
|
||
+ (azx_dev->core.stream_tag - 1);
|
||
+ snd_hdac_chip_writel(azx_bus(chip), GTSCC, dma_select);
|
||
+
|
||
+ /* Enable the capture */
|
||
+ snd_hdac_chip_updatel(azx_bus(chip), GTSCC, 0, GTSCC_TSCCI_MASK);
|
||
+
|
||
+ while (timeout) {
|
||
+ if (snd_hdac_chip_readl(azx_bus(chip), GTSCC) &
|
||
+ GTSCC_TSCCD_MASK)
|
||
+ break;
|
||
+
|
||
+ timeout--;
|
||
+ }
|
||
+
|
||
+ if (!timeout) {
|
||
+ dev_err(chip->card->dev, "GTSCC capture Timedout!\n");
|
||
+ return -EIO;
|
||
+ }
|
||
+
|
||
+ /* Read wall clock counter */
|
||
+ wallclk_ctr = snd_hdac_chip_readl(azx_bus(chip), WALFCC);
|
||
+
|
||
+ /* Read TSC counter */
|
||
+ tsc_counter_l = snd_hdac_chip_readl(azx_bus(chip), TSCCL);
|
||
+ tsc_counter_h = snd_hdac_chip_readl(azx_bus(chip), TSCCU);
|
||
+
|
||
+ /* Read Link counter */
|
||
+ ll_counter_l = snd_hdac_chip_readl(azx_bus(chip), LLPCL);
|
||
+ ll_counter_h = snd_hdac_chip_readl(azx_bus(chip), LLPCU);
|
||
+
|
||
+ /* Ack: registers read done */
|
||
+ snd_hdac_chip_writel(azx_bus(chip), GTSCC, GTSCC_TSCCD_SHIFT);
|
||
+
|
||
+ tsc_counter = (tsc_counter_h << TSCCU_CCU_SHIFT) |
|
||
+ tsc_counter_l;
|
||
+
|
||
+ ll_counter = (ll_counter_h << LLPC_CCU_SHIFT) | ll_counter_l;
|
||
+ wallclk_cycles = wallclk_ctr & WALFCC_CIF_MASK;
|
||
+
|
||
+ /*
|
||
+ * An error occurs near frame "rollover". The clocks in
|
||
+ * frame value indicates whether this error may have
|
||
+ * occurred. Here we use the value of 10 i.e.,
|
||
+ * HDA_MAX_CYCLE_OFFSET
|
||
+ */
|
||
+ if (wallclk_cycles < HDA_MAX_CYCLE_VALUE - HDA_MAX_CYCLE_OFFSET
|
||
+ && wallclk_cycles > HDA_MAX_CYCLE_OFFSET)
|
||
+ break;
|
||
+
|
||
+ /*
|
||
+ * Sleep before we read again, else we may again get
|
||
+ * value near to MAX_CYCLE. Try to sleep for different
|
||
+ * amount of time so we dont hit the same number again
|
||
+ */
|
||
+ udelay(retry_count++);
|
||
+
|
||
+ } while (retry_count != HDA_MAX_CYCLE_READ_RETRY);
|
||
+
|
||
+ if (retry_count == HDA_MAX_CYCLE_READ_RETRY) {
|
||
+ dev_err_ratelimited(chip->card->dev,
|
||
+ "Error in WALFCC cycle count\n");
|
||
+ return -EIO;
|
||
+ }
|
||
+
|
||
+ *device = ns_to_ktime(azx_scale64(ll_counter,
|
||
+ NSEC_PER_SEC, runtime->rate));
|
||
+ *device = ktime_add_ns(*device, (wallclk_cycles * NSEC_PER_SEC) /
|
||
+ ((HDA_MAX_CYCLE_VALUE + 1) * runtime->rate));
|
||
+
|
||
+ *system = convert_art_to_tsc(tsc_counter);
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+#else
|
||
+static int azx_get_sync_time(ktime_t *device,
|
||
+ struct system_counterval_t *system, void *ctx)
|
||
+{
|
||
+ return -ENXIO;
|
||
+}
|
||
+#endif
|
||
+
|
||
+static int azx_get_crosststamp(struct snd_pcm_substream *substream,
|
||
+ struct system_device_crosststamp *xtstamp)
|
||
+{
|
||
+ return get_device_system_crosststamp(azx_get_sync_time,
|
||
+ substream, NULL, xtstamp);
|
||
+}
|
||
+
|
||
+static inline bool is_link_time_supported(struct snd_pcm_runtime *runtime,
|
||
+ struct snd_pcm_audio_tstamp_config *ts)
|
||
+{
|
||
+ if (runtime->hw.info & SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME)
|
||
+ if (ts->type_requested == SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED)
|
||
+ return true;
|
||
+
|
||
+ return false;
|
||
+}
|
||
+
|
||
static int azx_get_time_info(struct snd_pcm_substream *substream,
|
||
struct timespec *system_ts, struct timespec *audio_ts,
|
||
struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
|
||
struct snd_pcm_audio_tstamp_report *audio_tstamp_report)
|
||
{
|
||
struct azx_dev *azx_dev = get_azx_dev(substream);
|
||
+ struct snd_pcm_runtime *runtime = substream->runtime;
|
||
+ struct system_device_crosststamp xtstamp;
|
||
+ int ret;
|
||
u64 nsec;
|
||
|
||
if ((substream->runtime->hw.info & SNDRV_PCM_INFO_HAS_LINK_ATIME) &&
|
||
@@ -361,8 +528,37 @@ static int azx_get_time_info(struct snd_pcm_substream *substream,
|
||
audio_tstamp_report->accuracy_report = 1; /* rest of structure is valid */
|
||
audio_tstamp_report->accuracy = 42; /* 24 MHz WallClock == 42ns resolution */
|
||
|
||
- } else
|
||
+ } else if (is_link_time_supported(runtime, audio_tstamp_config)) {
|
||
+
|
||
+ ret = azx_get_crosststamp(substream, &xtstamp);
|
||
+ if (ret)
|
||
+ return ret;
|
||
+
|
||
+ switch (runtime->tstamp_type) {
|
||
+ case SNDRV_PCM_TSTAMP_TYPE_MONOTONIC:
|
||
+ return -EINVAL;
|
||
+
|
||
+ case SNDRV_PCM_TSTAMP_TYPE_MONOTONIC_RAW:
|
||
+ *system_ts = ktime_to_timespec(xtstamp.sys_monoraw);
|
||
+ break;
|
||
+
|
||
+ default:
|
||
+ *system_ts = ktime_to_timespec(xtstamp.sys_realtime);
|
||
+ break;
|
||
+
|
||
+ }
|
||
+
|
||
+ *audio_ts = ktime_to_timespec(xtstamp.device);
|
||
+
|
||
+ audio_tstamp_report->actual_type =
|
||
+ SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED;
|
||
+ audio_tstamp_report->accuracy_report = 1;
|
||
+ /* 24 MHz WallClock == 42ns resolution */
|
||
+ audio_tstamp_report->accuracy = 42;
|
||
+
|
||
+ } else {
|
||
audio_tstamp_report->actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT;
|
||
+ }
|
||
|
||
return 0;
|
||
}
|
||
@@ -412,6 +608,11 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
|
||
goto unlock;
|
||
}
|
||
runtime->private_data = azx_dev;
|
||
+
|
||
+ if (chip->gts_present)
|
||
+ azx_pcm_hw.info = azx_pcm_hw.info |
|
||
+ SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME;
|
||
+
|
||
runtime->hw = azx_pcm_hw;
|
||
runtime->hw.channels_min = hinfo->channels_min;
|
||
runtime->hw.channels_max = hinfo->channels_max;
|
||
diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h
|
||
index ec63bbf..a50e053 100644
|
||
--- a/sound/pci/hda/hda_controller.h
|
||
+++ b/sound/pci/hda/hda_controller.h
|
||
@@ -159,6 +159,9 @@ struct azx {
|
||
unsigned int region_requested:1;
|
||
unsigned int disabled:1; /* disabled by vga_switcheroo */
|
||
|
||
+ /* GTS present */
|
||
+ unsigned int gts_present:1;
|
||
+
|
||
#ifdef CONFIG_SND_HDA_DSP_LOADER
|
||
struct azx_dev saved_azx_dev;
|
||
#endif
|
||
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
|
||
index 160c7f7..c3469f7 100644
|
||
--- a/sound/pci/hda/hda_intel.c
|
||
+++ b/sound/pci/hda/hda_intel.c
|
||
@@ -54,6 +54,7 @@
|
||
/* for snoop control */
|
||
#include <asm/pgtable.h>
|
||
#include <asm/cacheflush.h>
|
||
+#include <asm/cpufeature.h>
|
||
#endif
|
||
#include <sound/core.h>
|
||
#include <sound/initval.h>
|
||
@@ -1663,6 +1664,22 @@ static int azx_first_init(struct azx *chip)
|
||
return -ENXIO;
|
||
}
|
||
|
||
+ if (IS_SKL_PLUS(pci))
|
||
+ snd_hdac_bus_parse_capabilities(bus);
|
||
+
|
||
+ /*
|
||
+ * Some Intel CPUs has always running timer (ART) feature and
|
||
+ * controller may have Global time sync reporting capability, so
|
||
+ * check both of these before declaring synchronized time reporting
|
||
+ * capability SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME
|
||
+ */
|
||
+ chip->gts_present = false;
|
||
+
|
||
+#ifdef CONFIG_X86
|
||
+ if (bus->ppcap && boot_cpu_has(X86_FEATURE_ART))
|
||
+ chip->gts_present = true;
|
||
+#endif
|
||
+
|
||
if (chip->msi) {
|
||
if (chip->driver_caps & AZX_DCAPS_NO_MSI64) {
|
||
dev_dbg(card->dev, "Disabling 64bit MSI\n");
|
||
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
|
||
index 09e8988..b0f6f07 100644
|
||
--- a/sound/soc/codecs/rt5640.c
|
||
+++ b/sound/soc/codecs/rt5640.c
|
||
@@ -1870,6 +1870,9 @@ static int rt5640_set_dai_sysclk(struct snd_soc_dai *dai,
|
||
case RT5640_SCLK_S_PLL1:
|
||
reg_val |= RT5640_SCLK_SRC_PLL1;
|
||
break;
|
||
+ case RT5640_SCLK_S_RCCLK:
|
||
+ reg_val |= RT5640_SCLK_SRC_RCCLK;
|
||
+ break;
|
||
default:
|
||
dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id);
|
||
return -EINVAL;
|
||
diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h
|
||
index 58b664b..90c8871 100644
|
||
--- a/sound/soc/codecs/rt5640.h
|
||
+++ b/sound/soc/codecs/rt5640.h
|
||
@@ -984,6 +984,7 @@
|
||
#define RT5640_SCLK_SRC_SFT 14
|
||
#define RT5640_SCLK_SRC_MCLK (0x0 << 14)
|
||
#define RT5640_SCLK_SRC_PLL1 (0x1 << 14)
|
||
+#define RT5640_SCLK_SRC_RCCLK (0x2 << 14)
|
||
#define RT5640_PLL1_SRC_MASK (0x3 << 12)
|
||
#define RT5640_PLL1_SRC_SFT 12
|
||
#define RT5640_PLL1_SRC_MCLK (0x0 << 12)
|
||
diff --git a/sound/soc/intel/atom/sst-atom-controls.c b/sound/soc/intel/atom/sst-atom-controls.c
|
||
index 98720a9..0838478 100644
|
||
--- a/sound/soc/intel/atom/sst-atom-controls.c
|
||
+++ b/sound/soc/intel/atom/sst-atom-controls.c
|
||
@@ -1,4 +1,4 @@
|
||
-/*
|
||
+ /*
|
||
* sst-atom-controls.c - Intel MID Platform driver DPCM ALSA controls for Mrfld
|
||
*
|
||
* Copyright (C) 2013-14 Intel Corp
|
||
@@ -534,6 +534,7 @@ static const DECLARE_TLV_DB_SCALE(sst_gain_tlv_common, SST_GAIN_MIN_VALUE * 10,
|
||
|
||
/* Look up table to convert MIXER SW bit regs to SWM inputs */
|
||
static const uint swm_mixer_input_ids[SST_SWM_INPUT_COUNT] = {
|
||
+ [SST_IP_MODEM] = SST_SWM_IN_MODEM,
|
||
[SST_IP_CODEC0] = SST_SWM_IN_CODEC0,
|
||
[SST_IP_CODEC1] = SST_SWM_IN_CODEC1,
|
||
[SST_IP_LOOP0] = SST_SWM_IN_SPROT_LOOP,
|
||
@@ -674,6 +675,7 @@ static int sst_swm_mixer_event(struct snd_soc_dapm_widget *w,
|
||
/* SBA mixers - 16 inputs */
|
||
#define SST_SBA_DECLARE_MIX_CONTROLS(kctl_name) \
|
||
static const struct snd_kcontrol_new kctl_name[] = { \
|
||
+ SOC_DAPM_SINGLE("modem_in Switch", SND_SOC_NOPM, SST_IP_MODEM, 1, 0), \
|
||
SOC_DAPM_SINGLE("codec_in0 Switch", SND_SOC_NOPM, SST_IP_CODEC0, 1, 0), \
|
||
SOC_DAPM_SINGLE("codec_in1 Switch", SND_SOC_NOPM, SST_IP_CODEC1, 1, 0), \
|
||
SOC_DAPM_SINGLE("sprot_loop_in Switch", SND_SOC_NOPM, SST_IP_LOOP0, 1, 0), \
|
||
@@ -684,6 +686,7 @@ static int sst_swm_mixer_event(struct snd_soc_dapm_widget *w,
|
||
}
|
||
|
||
#define SST_SBA_MIXER_GRAPH_MAP(mix_name) \
|
||
+ { mix_name, "modem_in Switch", "modem_in" }, \
|
||
{ mix_name, "codec_in0 Switch", "codec_in0" }, \
|
||
{ mix_name, "codec_in1 Switch", "codec_in1" }, \
|
||
{ mix_name, "sprot_loop_in Switch", "sprot_loop_in" }, \
|
||
@@ -713,6 +716,7 @@ SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_media_l2_controls);
|
||
SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_voip_controls);
|
||
SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_codec0_controls);
|
||
SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_codec1_controls);
|
||
+SST_SBA_DECLARE_MIX_CONTROLS(sst_mix_modem_controls);
|
||
|
||
/*
|
||
* sst_handle_vb_timer - Start/Stop the DSP scheduler
|
||
@@ -931,17 +935,26 @@ void sst_fill_ssp_defaults(struct snd_soc_dai *dai)
|
||
int send_ssp_cmd(struct snd_soc_dai *dai, const char *id, bool enable)
|
||
{
|
||
struct sst_data *drv = snd_soc_dai_get_drvdata(dai);
|
||
- const struct sst_ssp_config *config;
|
||
+ int ssp_id;
|
||
|
||
dev_info(dai->dev, "Enter: enable=%d port_name=%s\n", enable, id);
|
||
|
||
+ if (strcmp(id, "ssp0-port") == 0)
|
||
+ ssp_id = SSP_MODEM;
|
||
+ else if (strcmp(id, "ssp2-port") == 0)
|
||
+ ssp_id = SSP_CODEC;
|
||
+ else {
|
||
+ dev_dbg(dai->dev, "port %s is not supported\n", id);
|
||
+ return -1;
|
||
+ }
|
||
+
|
||
SST_FILL_DEFAULT_DESTINATION(drv->ssp_cmd.header.dst);
|
||
drv->ssp_cmd.header.command_id = SBA_HW_SET_SSP;
|
||
drv->ssp_cmd.header.length = sizeof(struct sst_cmd_sba_hw_set_ssp)
|
||
- sizeof(struct sst_dsp_header);
|
||
|
||
- config = &sst_ssp_configs;
|
||
- dev_dbg(dai->dev, "ssp_id: %u\n", config->ssp_id);
|
||
+ drv->ssp_cmd.selection = ssp_id;
|
||
+ dev_dbg(dai->dev, "ssp_id: %u\n", ssp_id);
|
||
|
||
if (enable)
|
||
drv->ssp_cmd.switch_state = SST_SWITCH_ON;
|
||
@@ -1047,8 +1060,10 @@ static int sst_set_media_loop(struct snd_soc_dapm_widget *w,
|
||
}
|
||
|
||
static const struct snd_soc_dapm_widget sst_dapm_widgets[] = {
|
||
+ SST_AIF_IN("modem_in", sst_set_be_modules),
|
||
SST_AIF_IN("codec_in0", sst_set_be_modules),
|
||
SST_AIF_IN("codec_in1", sst_set_be_modules),
|
||
+ SST_AIF_OUT("modem_out", sst_set_be_modules),
|
||
SST_AIF_OUT("codec_out0", sst_set_be_modules),
|
||
SST_AIF_OUT("codec_out1", sst_set_be_modules),
|
||
|
||
@@ -1103,6 +1118,9 @@ static const struct snd_soc_dapm_widget sst_dapm_widgets[] = {
|
||
sst_mix_codec0_controls, sst_swm_mixer_event),
|
||
SST_SWM_MIXER("codec_out1 mix 0", SND_SOC_NOPM, SST_TASK_SBA, SST_SWM_OUT_CODEC1,
|
||
sst_mix_codec1_controls, sst_swm_mixer_event),
|
||
+ SST_SWM_MIXER("modem_out mix 0", SND_SOC_NOPM, SST_TASK_SBA, SST_SWM_OUT_MODEM,
|
||
+ sst_mix_modem_controls, sst_swm_mixer_event),
|
||
+
|
||
};
|
||
|
||
static const struct snd_soc_dapm_route intercon[] = {
|
||
@@ -1148,6 +1166,9 @@ static const struct snd_soc_dapm_route intercon[] = {
|
||
SST_SBA_MIXER_GRAPH_MAP("codec_out0 mix 0"),
|
||
{"codec_out1", NULL, "codec_out1 mix 0"},
|
||
SST_SBA_MIXER_GRAPH_MAP("codec_out1 mix 0"),
|
||
+ {"modem_out", NULL, "modem_out mix 0"},
|
||
+ SST_SBA_MIXER_GRAPH_MAP("modem_out mix 0"),
|
||
+
|
||
|
||
};
|
||
static const char * const slot_names[] = {
|
||
@@ -1217,6 +1238,9 @@ static const struct snd_kcontrol_new sst_gain_controls[] = {
|
||
SST_GAIN("media_loop2_out", SST_PATH_INDEX_MEDIA_LOOP2_OUT, SST_TASK_SBA, 0, &sst_gains[13]),
|
||
SST_GAIN("sprot_loop_out", SST_PATH_INDEX_SPROT_LOOP_OUT, SST_TASK_SBA, 0, &sst_gains[14]),
|
||
SST_VOLUME("media0_in", SST_PATH_INDEX_MEDIA0_IN, SST_TASK_MMX, 0, &sst_gains[15]),
|
||
+ SST_GAIN("modem_in", SST_PATH_INDEX_MODEM_IN, SST_TASK_SBA, 0, &sst_gains[16]),
|
||
+ SST_GAIN("modem_out", SST_PATH_INDEX_MODEM_OUT, SST_TASK_SBA, 0, &sst_gains[17]),
|
||
+
|
||
};
|
||
|
||
#define SST_GAIN_NUM_CONTROLS 3
|
||
diff --git a/sound/soc/intel/atom/sst-atom-controls.h b/sound/soc/intel/atom/sst-atom-controls.h
|
||
index e011311..351d814 100644
|
||
--- a/sound/soc/intel/atom/sst-atom-controls.h
|
||
+++ b/sound/soc/intel/atom/sst-atom-controls.h
|
||
@@ -35,6 +35,8 @@ enum {
|
||
/* define a bit for each mixer input */
|
||
#define SST_MIX_IP(x) (x)
|
||
|
||
+#define SST_IP_MODEM SST_MIX_IP(0)
|
||
+#define SST_IP_BT SST_MIX_IP(1)
|
||
#define SST_IP_CODEC0 SST_MIX_IP(2)
|
||
#define SST_IP_CODEC1 SST_MIX_IP(3)
|
||
#define SST_IP_LOOP0 SST_MIX_IP(4)
|
||
@@ -63,6 +65,7 @@ enum {
|
||
* Audio DSP Path Ids. Specified by the audio DSP FW
|
||
*/
|
||
enum sst_path_index {
|
||
+ SST_PATH_INDEX_MODEM_OUT = (0x00 << SST_PATH_ID_SHIFT),
|
||
SST_PATH_INDEX_CODEC_OUT0 = (0x02 << SST_PATH_ID_SHIFT),
|
||
SST_PATH_INDEX_CODEC_OUT1 = (0x03 << SST_PATH_ID_SHIFT),
|
||
|
||
@@ -80,6 +83,7 @@ enum sst_path_index {
|
||
|
||
|
||
/* Start of input paths */
|
||
+ SST_PATH_INDEX_MODEM_IN = (0x80 << SST_PATH_ID_SHIFT),
|
||
SST_PATH_INDEX_CODEC_IN0 = (0x82 << SST_PATH_ID_SHIFT),
|
||
SST_PATH_INDEX_CODEC_IN1 = (0x83 << SST_PATH_ID_SHIFT),
|
||
|
||
@@ -105,6 +109,7 @@ enum sst_path_index {
|
||
* path IDs
|
||
*/
|
||
enum sst_swm_inputs {
|
||
+ SST_SWM_IN_MODEM = (SST_PATH_INDEX_MODEM_IN | SST_DEFAULT_CELL_NBR),
|
||
SST_SWM_IN_CODEC0 = (SST_PATH_INDEX_CODEC_IN0 | SST_DEFAULT_CELL_NBR),
|
||
SST_SWM_IN_CODEC1 = (SST_PATH_INDEX_CODEC_IN1 | SST_DEFAULT_CELL_NBR),
|
||
SST_SWM_IN_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_IN | SST_DEFAULT_CELL_NBR),
|
||
@@ -124,6 +129,7 @@ enum sst_swm_inputs {
|
||
* path IDs
|
||
*/
|
||
enum sst_swm_outputs {
|
||
+ SST_SWM_OUT_MODEM = (SST_PATH_INDEX_MODEM_OUT | SST_DEFAULT_CELL_NBR),
|
||
SST_SWM_OUT_CODEC0 = (SST_PATH_INDEX_CODEC_OUT0 | SST_DEFAULT_CELL_NBR),
|
||
SST_SWM_OUT_CODEC1 = (SST_PATH_INDEX_CODEC_OUT1 | SST_DEFAULT_CELL_NBR),
|
||
SST_SWM_OUT_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_OUT | SST_DEFAULT_CELL_NBR),
|
||
diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c
|
||
index 4d31849..773acfb 100644
|
||
--- a/sound/soc/intel/atom/sst/sst_acpi.c
|
||
+++ b/sound/soc/intel/atom/sst/sst_acpi.c
|
||
@@ -39,6 +39,8 @@
|
||
#include <acpi/platform/aclinux.h>
|
||
#include <acpi/actypes.h>
|
||
#include <acpi/acpi_bus.h>
|
||
+#include <asm/cpu_device_id.h>
|
||
+#include <asm/iosf_mbi.h>
|
||
#include "../sst-mfld-platform.h"
|
||
#include "../../common/sst-dsp.h"
|
||
#include "../../common/sst-acpi.h"
|
||
@@ -113,6 +115,28 @@ static const struct sst_res_info byt_rvp_res_info = {
|
||
.acpi_ipc_irq_index = 5,
|
||
};
|
||
|
||
+/* BYTCR has different BIOS from BYT */
|
||
+static const struct sst_res_info bytcr_res_info = {
|
||
+ .shim_offset = 0x140000,
|
||
+ .shim_size = 0x000100,
|
||
+ .shim_phy_addr = SST_BYT_SHIM_PHY_ADDR,
|
||
+ .ssp0_offset = 0xa0000,
|
||
+ .ssp0_size = 0x1000,
|
||
+ .dma0_offset = 0x98000,
|
||
+ .dma0_size = 0x4000,
|
||
+ .dma1_offset = 0x9c000,
|
||
+ .dma1_size = 0x4000,
|
||
+ .iram_offset = 0x0c0000,
|
||
+ .iram_size = 0x14000,
|
||
+ .dram_offset = 0x100000,
|
||
+ .dram_size = 0x28000,
|
||
+ .mbox_offset = 0x144000,
|
||
+ .mbox_size = 0x1000,
|
||
+ .acpi_lpe_res_index = 0,
|
||
+ .acpi_ddr_index = 2,
|
||
+ .acpi_ipc_irq_index = 0
|
||
+};
|
||
+
|
||
static struct sst_platform_info byt_rvp_platform_data = {
|
||
.probe_data = &byt_fwparse_info,
|
||
.ipc_info = &byt_ipc_info,
|
||
@@ -215,6 +239,47 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
|
||
return 0;
|
||
}
|
||
|
||
+
|
||
+static int is_byt_cr(struct device *dev, bool *bytcr)
|
||
+{
|
||
+ int status = 0;
|
||
+
|
||
+ if (IS_ENABLED(CONFIG_IOSF_MBI)) {
|
||
+ static const struct x86_cpu_id cpu_ids[] = {
|
||
+ { X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */
|
||
+ {}
|
||
+ };
|
||
+ int status;
|
||
+ u32 bios_status;
|
||
+
|
||
+ if (!x86_match_cpu(cpu_ids) || !iosf_mbi_available()) {
|
||
+ /* bail silently */
|
||
+ return status;
|
||
+ }
|
||
+
|
||
+ status = iosf_mbi_read(BT_MBI_UNIT_PMC, /* 0x04 PUNIT */
|
||
+ MBI_REG_READ, /* 0x10 */
|
||
+ 0x006, /* BIOS_CONFIG */
|
||
+ &bios_status);
|
||
+
|
||
+ if (status) {
|
||
+ dev_err(dev, "could not read PUNIT BIOS_CONFIG\n");
|
||
+ } else {
|
||
+ /* bits 26:27 mirror PMIC options */
|
||
+ bios_status = (bios_status >> 26) & 3;
|
||
+
|
||
+ if ((bios_status == 1) || (bios_status == 3))
|
||
+ *bytcr = true;
|
||
+ else
|
||
+ dev_info(dev, "BYT-CR not detected\n");
|
||
+ }
|
||
+ } else {
|
||
+ dev_info(dev, "IOSF_MBI not enabled, no BYT-CR detection\n");
|
||
+ }
|
||
+ return status;
|
||
+}
|
||
+
|
||
+
|
||
static int sst_acpi_probe(struct platform_device *pdev)
|
||
{
|
||
struct device *dev = &pdev->dev;
|
||
@@ -226,6 +291,7 @@ static int sst_acpi_probe(struct platform_device *pdev)
|
||
struct platform_device *plat_dev;
|
||
struct sst_platform_info *pdata;
|
||
unsigned int dev_id;
|
||
+ bool bytcr = false;
|
||
|
||
id = acpi_match_device(dev->driver->acpi_match_table, dev);
|
||
if (!id)
|
||
@@ -251,6 +317,18 @@ static int sst_acpi_probe(struct platform_device *pdev)
|
||
|
||
dev_dbg(dev, "ACPI device id: %x\n", dev_id);
|
||
|
||
+ ret = sst_alloc_drv_context(&ctx, dev, dev_id);
|
||
+ if (ret < 0)
|
||
+ return ret;
|
||
+
|
||
+ ret = is_byt_cr(dev, &bytcr);
|
||
+ if (!((ret < 0) || (bytcr == false))) {
|
||
+ dev_info(dev, "Detected Baytrail-CR platform\n");
|
||
+
|
||
+ /* override resource info */
|
||
+ byt_rvp_platform_data.res_info = &bytcr_res_info;
|
||
+ }
|
||
+
|
||
plat_dev = platform_device_register_data(dev, pdata->platform, -1,
|
||
NULL, 0);
|
||
if (IS_ERR(plat_dev)) {
|
||
@@ -271,10 +349,6 @@ static int sst_acpi_probe(struct platform_device *pdev)
|
||
return PTR_ERR(mdev);
|
||
}
|
||
|
||
- ret = sst_alloc_drv_context(&ctx, dev, dev_id);
|
||
- if (ret < 0)
|
||
- return ret;
|
||
-
|
||
/* Fill sst platform data */
|
||
ctx->pdata = pdata;
|
||
strcpy(ctx->firmware_name, mach->fw_filename);
|
||
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
|
||
index 88efb62..bff77a1 100644
|
||
--- a/sound/soc/intel/boards/bytcr_rt5640.c
|
||
+++ b/sound/soc/intel/boards/bytcr_rt5640.c
|
||
@@ -24,6 +24,9 @@
|
||
#include <linux/device.h>
|
||
#include <linux/dmi.h>
|
||
#include <linux/slab.h>
|
||
+#include <asm/cpu_device_id.h>
|
||
+#include <asm/platform_sst_audio.h>
|
||
+#include <linux/clk.h>
|
||
#include <sound/pcm.h>
|
||
#include <sound/pcm_params.h>
|
||
#include <sound/soc.h>
|
||
@@ -31,42 +34,153 @@
|
||
#include "../../codecs/rt5640.h"
|
||
#include "../atom/sst-atom-controls.h"
|
||
#include "../common/sst-acpi.h"
|
||
+#include "../common/sst-dsp.h"
|
||
|
||
enum {
|
||
BYT_RT5640_DMIC1_MAP,
|
||
BYT_RT5640_DMIC2_MAP,
|
||
BYT_RT5640_IN1_MAP,
|
||
+ BYT_RT5640_IN3_MAP,
|
||
};
|
||
|
||
#define BYT_RT5640_MAP(quirk) ((quirk) & 0xff)
|
||
#define BYT_RT5640_DMIC_EN BIT(16)
|
||
+#define BYT_RT5640_MONO_SPEAKER BIT(17)
|
||
+#define BYT_RT5640_DIFF_MIC BIT(18) /* defaut is single-ended */
|
||
+#define BYT_RT5640_SSP2_AIF2 BIT(19) /* default is using AIF1 */
|
||
+#define BYT_RT5640_SSP0_AIF1 BIT(20)
|
||
+#define BYT_RT5640_SSP0_AIF2 BIT(21)
|
||
+#define BYT_RT5640_MCLK_EN BIT(22)
|
||
+#define BYT_RT5640_MCLK_25MHZ BIT(23)
|
||
+
|
||
+struct byt_rt5640_private {
|
||
+ struct clk *mclk;
|
||
+};
|
||
|
||
static unsigned long byt_rt5640_quirk = BYT_RT5640_DMIC1_MAP |
|
||
- BYT_RT5640_DMIC_EN;
|
||
+ BYT_RT5640_DMIC_EN |
|
||
+ BYT_RT5640_MCLK_EN;
|
||
+
|
||
+static void log_quirks(struct device *dev)
|
||
+{
|
||
+ if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_DMIC1_MAP)
|
||
+ dev_info(dev, "quirk DMIC1_MAP enabled");
|
||
+ if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_DMIC2_MAP)
|
||
+ dev_info(dev, "quirk DMIC2_MAP enabled");
|
||
+ if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_IN1_MAP)
|
||
+ dev_info(dev, "quirk IN1_MAP enabled");
|
||
+ if (BYT_RT5640_MAP(byt_rt5640_quirk) == BYT_RT5640_IN3_MAP)
|
||
+ dev_info(dev, "quirk IN3_MAP enabled");
|
||
+ if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN)
|
||
+ dev_info(dev, "quirk DMIC enabled");
|
||
+ if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER)
|
||
+ dev_info(dev, "quirk MONO_SPEAKER enabled");
|
||
+ if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
|
||
+ dev_info(dev, "quirk DIFF_MIC enabled");
|
||
+ if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2)
|
||
+ dev_info(dev, "quirk SSP2_AIF2 enabled");
|
||
+ if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1)
|
||
+ dev_info(dev, "quirk SSP0_AIF1 enabled");
|
||
+ if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)
|
||
+ dev_info(dev, "quirk SSP0_AIF2 enabled");
|
||
+ if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN)
|
||
+ dev_info(dev, "quirk MCLK_EN enabled");
|
||
+ if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ)
|
||
+ dev_info(dev, "quirk MCLK_25MHZ enabled");
|
||
+}
|
||
+
|
||
+
|
||
+#define BYT_CODEC_DAI1 "rt5640-aif1"
|
||
+#define BYT_CODEC_DAI2 "rt5640-aif2"
|
||
+
|
||
+static inline struct snd_soc_dai *byt_get_codec_dai(struct snd_soc_card *card)
|
||
+{
|
||
+ struct snd_soc_pcm_runtime *rtd;
|
||
+
|
||
+ list_for_each_entry(rtd, &card->rtd_list, list) {
|
||
+ if (!strncmp(rtd->codec_dai->name, BYT_CODEC_DAI1,
|
||
+ strlen(BYT_CODEC_DAI1)))
|
||
+ return rtd->codec_dai;
|
||
+ if (!strncmp(rtd->codec_dai->name, BYT_CODEC_DAI2,
|
||
+ strlen(BYT_CODEC_DAI2)))
|
||
+ return rtd->codec_dai;
|
||
+
|
||
+ }
|
||
+ return NULL;
|
||
+}
|
||
+
|
||
+static int platform_clock_control(struct snd_soc_dapm_widget *w,
|
||
+ struct snd_kcontrol *k, int event)
|
||
+{
|
||
+ struct snd_soc_dapm_context *dapm = w->dapm;
|
||
+ struct snd_soc_card *card = dapm->card;
|
||
+ struct snd_soc_dai *codec_dai;
|
||
+ struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
|
||
+ int ret;
|
||
+
|
||
+ codec_dai = byt_get_codec_dai(card);
|
||
+ if (!codec_dai) {
|
||
+ dev_err(card->dev,
|
||
+ "Codec dai not found; Unable to set platform clock\n");
|
||
+ return -EIO;
|
||
+ }
|
||
+
|
||
+ if (SND_SOC_DAPM_EVENT_ON(event)) {
|
||
+ if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk) {
|
||
+ ret = clk_prepare_enable(priv->mclk);
|
||
+ if (ret < 0) {
|
||
+ dev_err(card->dev,
|
||
+ "could not configure MCLK state");
|
||
+ return ret;
|
||
+ }
|
||
+ }
|
||
+ ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
|
||
+ 48000 * 512,
|
||
+ SND_SOC_CLOCK_IN);
|
||
+ } else {
|
||
+ /*
|
||
+ * Set codec clock source to internal clock before
|
||
+ * turning off the platform clock. Codec needs clock
|
||
+ * for Jack detection and button press
|
||
+ */
|
||
+ ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_RCCLK,
|
||
+ 0,
|
||
+ SND_SOC_CLOCK_IN);
|
||
+ if (!ret) {
|
||
+ if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk)
|
||
+ clk_disable_unprepare(priv->mclk);
|
||
+ }
|
||
+ }
|
||
+
|
||
+ if (ret < 0) {
|
||
+ dev_err(card->dev, "can't set codec sysclk: %d\n", ret);
|
||
+ return ret;
|
||
+ }
|
||
+
|
||
+ return 0;
|
||
+}
|
||
|
||
static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = {
|
||
SND_SOC_DAPM_HP("Headphone", NULL),
|
||
SND_SOC_DAPM_MIC("Headset Mic", NULL),
|
||
SND_SOC_DAPM_MIC("Internal Mic", NULL),
|
||
SND_SOC_DAPM_SPK("Speaker", NULL),
|
||
+ SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
|
||
+ platform_clock_control, SND_SOC_DAPM_PRE_PMU |
|
||
+ SND_SOC_DAPM_POST_PMD),
|
||
+
|
||
};
|
||
|
||
static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = {
|
||
- {"AIF1 Playback", NULL, "ssp2 Tx"},
|
||
- {"ssp2 Tx", NULL, "codec_out0"},
|
||
- {"ssp2 Tx", NULL, "codec_out1"},
|
||
- {"codec_in0", NULL, "ssp2 Rx"},
|
||
- {"codec_in1", NULL, "ssp2 Rx"},
|
||
- {"ssp2 Rx", NULL, "AIF1 Capture"},
|
||
+ {"Headphone", NULL, "Platform Clock"},
|
||
+ {"Headset Mic", NULL, "Platform Clock"},
|
||
+ {"Internal Mic", NULL, "Platform Clock"},
|
||
+ {"Speaker", NULL, "Platform Clock"},
|
||
|
||
{"Headset Mic", NULL, "MICBIAS1"},
|
||
{"IN2P", NULL, "Headset Mic"},
|
||
{"Headphone", NULL, "HPOL"},
|
||
{"Headphone", NULL, "HPOR"},
|
||
- {"Speaker", NULL, "SPOLP"},
|
||
- {"Speaker", NULL, "SPOLN"},
|
||
- {"Speaker", NULL, "SPORP"},
|
||
- {"Speaker", NULL, "SPORN"},
|
||
};
|
||
|
||
static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic1_map[] = {
|
||
@@ -82,6 +196,59 @@ static const struct snd_soc_dapm_route byt_rt5640_intmic_in1_map[] = {
|
||
{"IN1P", NULL, "Internal Mic"},
|
||
};
|
||
|
||
+static const struct snd_soc_dapm_route byt_rt5640_intmic_in3_map[] = {
|
||
+ {"Internal Mic", NULL, "MICBIAS1"},
|
||
+ {"IN3P", NULL, "Internal Mic"},
|
||
+};
|
||
+
|
||
+static const struct snd_soc_dapm_route byt_rt5640_ssp2_aif1_map[] = {
|
||
+ {"ssp2 Tx", NULL, "codec_out0"},
|
||
+ {"ssp2 Tx", NULL, "codec_out1"},
|
||
+ {"codec_in0", NULL, "ssp2 Rx"},
|
||
+ {"codec_in1", NULL, "ssp2 Rx"},
|
||
+
|
||
+ {"AIF1 Playback", NULL, "ssp2 Tx"},
|
||
+ {"ssp2 Rx", NULL, "AIF1 Capture"},
|
||
+};
|
||
+
|
||
+static const struct snd_soc_dapm_route byt_rt5640_ssp2_aif2_map[] = {
|
||
+ {"ssp2 Tx", NULL, "codec_out0"},
|
||
+ {"ssp2 Tx", NULL, "codec_out1"},
|
||
+ {"codec_in0", NULL, "ssp2 Rx"},
|
||
+ {"codec_in1", NULL, "ssp2 Rx"},
|
||
+
|
||
+ {"AIF2 Playback", NULL, "ssp2 Tx"},
|
||
+ {"ssp2 Rx", NULL, "AIF2 Capture"},
|
||
+};
|
||
+
|
||
+static const struct snd_soc_dapm_route byt_rt5640_ssp0_aif1_map[] = {
|
||
+ {"ssp0 Tx", NULL, "modem_out"},
|
||
+ {"modem_in", NULL, "ssp0 Rx"},
|
||
+
|
||
+ {"AIF1 Playback", NULL, "ssp0 Tx"},
|
||
+ {"ssp0 Rx", NULL, "AIF1 Capture"},
|
||
+};
|
||
+
|
||
+static const struct snd_soc_dapm_route byt_rt5640_ssp0_aif2_map[] = {
|
||
+ {"ssp0 Tx", NULL, "modem_out"},
|
||
+ {"modem_in", NULL, "ssp0 Rx"},
|
||
+
|
||
+ {"AIF2 Playback", NULL, "ssp0 Tx"},
|
||
+ {"ssp0 Rx", NULL, "AIF2 Capture"},
|
||
+};
|
||
+
|
||
+static const struct snd_soc_dapm_route byt_rt5640_stereo_spk_map[] = {
|
||
+ {"Speaker", NULL, "SPOLP"},
|
||
+ {"Speaker", NULL, "SPOLN"},
|
||
+ {"Speaker", NULL, "SPORP"},
|
||
+ {"Speaker", NULL, "SPORN"},
|
||
+};
|
||
+
|
||
+static const struct snd_soc_dapm_route byt_rt5640_mono_spk_map[] = {
|
||
+ {"Speaker", NULL, "SPOLP"},
|
||
+ {"Speaker", NULL, "SPOLN"},
|
||
+};
|
||
+
|
||
static const struct snd_kcontrol_new byt_rt5640_controls[] = {
|
||
SOC_DAPM_PIN_SWITCH("Headphone"),
|
||
SOC_DAPM_PIN_SWITCH("Headset Mic"),
|
||
@@ -96,19 +263,46 @@ static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
|
||
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
||
int ret;
|
||
|
||
- snd_soc_dai_set_bclk_ratio(codec_dai, 50);
|
||
-
|
||
ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
|
||
params_rate(params) * 512,
|
||
SND_SOC_CLOCK_IN);
|
||
+
|
||
if (ret < 0) {
|
||
dev_err(rtd->dev, "can't set codec clock %d\n", ret);
|
||
return ret;
|
||
}
|
||
|
||
- ret = snd_soc_dai_set_pll(codec_dai, 0, RT5640_PLL1_S_BCLK1,
|
||
- params_rate(params) * 50,
|
||
- params_rate(params) * 512);
|
||
+ if (!(byt_rt5640_quirk & BYT_RT5640_MCLK_EN)) {
|
||
+ /* use bitclock as PLL input */
|
||
+ if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
|
||
+ (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
|
||
+
|
||
+ /* 2x16 bit slots on SSP0 */
|
||
+ ret = snd_soc_dai_set_pll(codec_dai, 0,
|
||
+ RT5640_PLL1_S_BCLK1,
|
||
+ params_rate(params) * 32,
|
||
+ params_rate(params) * 512);
|
||
+ } else {
|
||
+ /* 2x15 bit slots on SSP2 */
|
||
+ ret = snd_soc_dai_set_pll(codec_dai, 0,
|
||
+ RT5640_PLL1_S_BCLK1,
|
||
+ params_rate(params) * 50,
|
||
+ params_rate(params) * 512);
|
||
+ }
|
||
+ } else {
|
||
+ if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) {
|
||
+ ret = snd_soc_dai_set_pll(codec_dai, 0,
|
||
+ RT5640_PLL1_S_MCLK,
|
||
+ 25000000,
|
||
+ params_rate(params) * 512);
|
||
+ } else {
|
||
+ ret = snd_soc_dai_set_pll(codec_dai, 0,
|
||
+ RT5640_PLL1_S_MCLK,
|
||
+ 19200000,
|
||
+ params_rate(params) * 512);
|
||
+ }
|
||
+ }
|
||
+
|
||
if (ret < 0) {
|
||
dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
|
||
return ret;
|
||
@@ -127,27 +321,73 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
|
||
{
|
||
.callback = byt_rt5640_quirk_cb,
|
||
.matches = {
|
||
- DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||
- DMI_MATCH(DMI_PRODUCT_NAME, "T100TA"),
|
||
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"),
|
||
+ },
|
||
+ .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP |
|
||
+ BYT_RT5640_MCLK_EN),
|
||
+ },
|
||
+ {
|
||
+ .callback = byt_rt5640_quirk_cb,
|
||
+ .matches = {
|
||
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"),
|
||
},
|
||
- .driver_data = (unsigned long *)BYT_RT5640_IN1_MAP,
|
||
+ .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP |
|
||
+ BYT_RT5640_MONO_SPEAKER |
|
||
+ BYT_RT5640_DIFF_MIC |
|
||
+ BYT_RT5640_SSP0_AIF2 |
|
||
+ BYT_RT5640_MCLK_EN
|
||
+ ),
|
||
},
|
||
{
|
||
.callback = byt_rt5640_quirk_cb,
|
||
.matches = {
|
||
- DMI_MATCH(DMI_SYS_VENDOR, "DellInc."),
|
||
- DMI_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"),
|
||
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "DellInc."),
|
||
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"),
|
||
},
|
||
.driver_data = (unsigned long *)(BYT_RT5640_DMIC2_MAP |
|
||
+ BYT_RT5640_DMIC_EN |
|
||
+ BYT_RT5640_MCLK_EN),
|
||
+ },
|
||
+ {
|
||
+ .callback = byt_rt5640_quirk_cb,
|
||
+ .matches = {
|
||
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
|
||
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"),
|
||
+ },
|
||
+ .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP |
|
||
+ BYT_RT5640_MCLK_EN),
|
||
+ },
|
||
+ {
|
||
+ .callback = byt_rt5640_quirk_cb,
|
||
+ .matches = {
|
||
+ DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
|
||
+ DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
|
||
+ },
|
||
+ .driver_data = (unsigned long *)(BYT_RT5640_DMIC1_MAP |
|
||
BYT_RT5640_DMIC_EN),
|
||
},
|
||
{
|
||
.callback = byt_rt5640_quirk_cb,
|
||
.matches = {
|
||
- DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
|
||
- DMI_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"),
|
||
+ DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"),
|
||
+ DMI_MATCH(DMI_BOARD_NAME, "tPAD"),
|
||
},
|
||
- .driver_data = (unsigned long *)BYT_RT5640_IN1_MAP,
|
||
+ .driver_data = (unsigned long *)(BYT_RT5640_IN3_MAP |
|
||
+ BYT_RT5640_MCLK_EN |
|
||
+ BYT_RT5640_SSP0_AIF1),
|
||
+ },
|
||
+ {
|
||
+ .callback = byt_rt5640_quirk_cb,
|
||
+ .matches = {
|
||
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
|
||
+ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
|
||
+ },
|
||
+ .driver_data = (unsigned long *)(BYT_RT5640_IN1_MAP |
|
||
+ BYT_RT5640_MCLK_EN |
|
||
+ BYT_RT5640_SSP0_AIF1),
|
||
+
|
||
},
|
||
{}
|
||
};
|
||
@@ -158,13 +398,18 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
|
||
struct snd_soc_codec *codec = runtime->codec;
|
||
struct snd_soc_card *card = runtime->card;
|
||
const struct snd_soc_dapm_route *custom_map;
|
||
+ struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
|
||
int num_routes;
|
||
|
||
card->dapm.idle_bias_off = true;
|
||
|
||
rt5640_sel_asrc_clk_src(codec,
|
||
RT5640_DA_STEREO_FILTER |
|
||
- RT5640_AD_STEREO_FILTER,
|
||
+ RT5640_DA_MONO_L_FILTER |
|
||
+ RT5640_DA_MONO_R_FILTER |
|
||
+ RT5640_AD_STEREO_FILTER |
|
||
+ RT5640_AD_MONO_L_FILTER |
|
||
+ RT5640_AD_MONO_R_FILTER,
|
||
RT5640_CLK_SEL_ASRC);
|
||
|
||
ret = snd_soc_add_card_controls(card, byt_rt5640_controls,
|
||
@@ -179,6 +424,10 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
|
||
custom_map = byt_rt5640_intmic_in1_map;
|
||
num_routes = ARRAY_SIZE(byt_rt5640_intmic_in1_map);
|
||
break;
|
||
+ case BYT_RT5640_IN3_MAP:
|
||
+ custom_map = byt_rt5640_intmic_in3_map;
|
||
+ num_routes = ARRAY_SIZE(byt_rt5640_intmic_in3_map);
|
||
+ break;
|
||
case BYT_RT5640_DMIC2_MAP:
|
||
custom_map = byt_rt5640_intmic_dmic2_map;
|
||
num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic2_map);
|
||
@@ -192,6 +441,43 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
|
||
if (ret)
|
||
return ret;
|
||
|
||
+ if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) {
|
||
+ ret = snd_soc_dapm_add_routes(&card->dapm,
|
||
+ byt_rt5640_ssp2_aif2_map,
|
||
+ ARRAY_SIZE(byt_rt5640_ssp2_aif2_map));
|
||
+ } else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) {
|
||
+ ret = snd_soc_dapm_add_routes(&card->dapm,
|
||
+ byt_rt5640_ssp0_aif1_map,
|
||
+ ARRAY_SIZE(byt_rt5640_ssp0_aif1_map));
|
||
+ } else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2) {
|
||
+ ret = snd_soc_dapm_add_routes(&card->dapm,
|
||
+ byt_rt5640_ssp0_aif2_map,
|
||
+ ARRAY_SIZE(byt_rt5640_ssp0_aif2_map));
|
||
+ } else {
|
||
+ ret = snd_soc_dapm_add_routes(&card->dapm,
|
||
+ byt_rt5640_ssp2_aif1_map,
|
||
+ ARRAY_SIZE(byt_rt5640_ssp2_aif1_map));
|
||
+ }
|
||
+ if (ret)
|
||
+ return ret;
|
||
+
|
||
+ if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) {
|
||
+ ret = snd_soc_dapm_add_routes(&card->dapm,
|
||
+ byt_rt5640_mono_spk_map,
|
||
+ ARRAY_SIZE(byt_rt5640_mono_spk_map));
|
||
+ } else {
|
||
+ ret = snd_soc_dapm_add_routes(&card->dapm,
|
||
+ byt_rt5640_stereo_spk_map,
|
||
+ ARRAY_SIZE(byt_rt5640_stereo_spk_map));
|
||
+ }
|
||
+ if (ret)
|
||
+ return ret;
|
||
+
|
||
+ if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) {
|
||
+ snd_soc_update_bits(codec, RT5640_IN1_IN2, RT5640_IN_DF1,
|
||
+ RT5640_IN_DF1);
|
||
+ }
|
||
+
|
||
if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) {
|
||
ret = rt5640_dmic_enable(codec, 0, 0);
|
||
if (ret)
|
||
@@ -201,6 +487,30 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
|
||
snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone");
|
||
snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker");
|
||
|
||
+ if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && priv->mclk) {
|
||
+ /*
|
||
+ * The firmware might enable the clock at
|
||
+ * boot (this information may or may not
|
||
+ * be reflected in the enable clock register).
|
||
+ * To change the rate we must disable the clock
|
||
+ * first to cover these cases. Due to common
|
||
+ * clock framework restrictions that do not allow
|
||
+ * to disable a clock that has not been enabled,
|
||
+ * we need to enable the clock first.
|
||
+ */
|
||
+ ret = clk_prepare_enable(priv->mclk);
|
||
+ if (!ret)
|
||
+ clk_disable_unprepare(priv->mclk);
|
||
+
|
||
+ if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ)
|
||
+ ret = clk_set_rate(priv->mclk, 25000000);
|
||
+ else
|
||
+ ret = clk_set_rate(priv->mclk, 19200000);
|
||
+
|
||
+ if (ret)
|
||
+ dev_err(card->dev, "unable to set MCLK rate\n");
|
||
+ }
|
||
+
|
||
return ret;
|
||
}
|
||
|
||
@@ -221,34 +531,63 @@ static int byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime *rtd,
|
||
SNDRV_PCM_HW_PARAM_CHANNELS);
|
||
int ret;
|
||
|
||
- /* The DSP will covert the FE rate to 48k, stereo, 24bits */
|
||
+ /* The DSP will covert the FE rate to 48k, stereo */
|
||
rate->min = rate->max = 48000;
|
||
channels->min = channels->max = 2;
|
||
|
||
- /* set SSP2 to 24-bit */
|
||
- params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
|
||
+ if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
|
||
+ (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
|
||
+
|
||
+ /* set SSP0 to 16-bit */
|
||
+ params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
|
||
+
|
||
+ /*
|
||
+ * Default mode for SSP configuration is TDM 4 slot, override config
|
||
+ * with explicit setting to I2S 2ch 16-bit. The word length is set with
|
||
+ * dai_set_tdm_slot() since there is no other API exposed
|
||
+ */
|
||
+ ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
|
||
+ SND_SOC_DAIFMT_I2S |
|
||
+ SND_SOC_DAIFMT_NB_IF |
|
||
+ SND_SOC_DAIFMT_CBS_CFS
|
||
+ );
|
||
+ if (ret < 0) {
|
||
+ dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
|
||
+ return ret;
|
||
+ }
|
||
|
||
- /*
|
||
- * Default mode for SSP configuration is TDM 4 slot, override config
|
||
- * with explicit setting to I2S 2ch 24-bit. The word length is set with
|
||
- * dai_set_tdm_slot() since there is no other API exposed
|
||
- */
|
||
- ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
|
||
- SND_SOC_DAIFMT_I2S |
|
||
- SND_SOC_DAIFMT_NB_IF |
|
||
- SND_SOC_DAIFMT_CBS_CFS
|
||
- );
|
||
- if (ret < 0) {
|
||
- dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
|
||
- return ret;
|
||
- }
|
||
+ ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 16);
|
||
+ if (ret < 0) {
|
||
+ dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
|
||
+ return ret;
|
||
+ }
|
||
|
||
- ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
|
||
- if (ret < 0) {
|
||
- dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
|
||
- return ret;
|
||
- }
|
||
+ } else {
|
||
+
|
||
+ /* set SSP2 to 24-bit */
|
||
+ params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
|
||
+
|
||
+ /*
|
||
+ * Default mode for SSP configuration is TDM 4 slot, override config
|
||
+ * with explicit setting to I2S 2ch 24-bit. The word length is set with
|
||
+ * dai_set_tdm_slot() since there is no other API exposed
|
||
+ */
|
||
+ ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
|
||
+ SND_SOC_DAIFMT_I2S |
|
||
+ SND_SOC_DAIFMT_NB_IF |
|
||
+ SND_SOC_DAIFMT_CBS_CFS
|
||
+ );
|
||
+ if (ret < 0) {
|
||
+ dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
|
||
+ return ret;
|
||
+ }
|
||
|
||
+ ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
|
||
+ if (ret < 0) {
|
||
+ dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
|
||
+ return ret;
|
||
+ }
|
||
+ }
|
||
return 0;
|
||
}
|
||
|
||
@@ -305,10 +644,10 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
|
||
{
|
||
.name = "SSP2-Codec",
|
||
.id = 1,
|
||
- .cpu_dai_name = "ssp2-port",
|
||
+ .cpu_dai_name = "ssp2-port", /* overwritten for ssp0 routing */
|
||
.platform_name = "sst-mfld-platform",
|
||
.no_pcm = 1,
|
||
- .codec_dai_name = "rt5640-aif1",
|
||
+ .codec_dai_name = "rt5640-aif1", /* changed w/ quirk */
|
||
.codec_name = "i2c-10EC5640:00", /* overwritten with HID */
|
||
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
|
||
| SND_SOC_DAIFMT_CBS_CFS,
|
||
@@ -335,6 +674,21 @@ static struct snd_soc_card byt_rt5640_card = {
|
||
};
|
||
|
||
static char byt_rt5640_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */
|
||
+static char byt_rt5640_codec_aif_name[12]; /* = "rt5640-aif[1|2]" */
|
||
+static char byt_rt5640_cpu_dai_name[10]; /* = "ssp[0|2]-port" */
|
||
+
|
||
+static bool is_valleyview(void)
|
||
+{
|
||
+ static const struct x86_cpu_id cpu_ids[] = {
|
||
+ { X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */
|
||
+ {}
|
||
+ };
|
||
+
|
||
+ if (!x86_match_cpu(cpu_ids))
|
||
+ return false;
|
||
+ return true;
|
||
+}
|
||
+
|
||
|
||
static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
|
||
{
|
||
@@ -343,10 +697,16 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
|
||
const char *i2c_name = NULL;
|
||
int i;
|
||
int dai_index;
|
||
+ struct byt_rt5640_private *priv;
|
||
+
|
||
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC);
|
||
+ if (!priv)
|
||
+ return -ENOMEM;
|
||
|
||
/* register the soc card */
|
||
byt_rt5640_card.dev = &pdev->dev;
|
||
mach = byt_rt5640_card.dev->platform_data;
|
||
+ snd_soc_card_set_drvdata(&byt_rt5640_card, priv);
|
||
|
||
/* fix index of codec dai */
|
||
dai_index = MERR_DPCM_COMPR + 1;
|
||
@@ -366,8 +726,57 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
|
||
byt_rt5640_dais[dai_index].codec_name = byt_rt5640_codec_name;
|
||
}
|
||
|
||
+ /*
|
||
+ * swap SSP0 if bytcr is detected
|
||
+ * (will be overridden if DMI quirk is detected)
|
||
+ */
|
||
+ if (is_valleyview()) {
|
||
+ struct sst_platform_info *p_info = mach->pdata;
|
||
+ const struct sst_res_info *res_info = p_info->res_info;
|
||
+
|
||
+ /* TODO: use CHAN package info from BIOS to detect AIF1/AIF2 */
|
||
+ if (res_info->acpi_ipc_irq_index == 0) {
|
||
+ byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF2;
|
||
+ }
|
||
+ }
|
||
+
|
||
/* check quirks before creating card */
|
||
dmi_check_system(byt_rt5640_quirk_table);
|
||
+ log_quirks(&pdev->dev);
|
||
+
|
||
+ if ((byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) ||
|
||
+ (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
|
||
+
|
||
+ /* fixup codec aif name */
|
||
+ snprintf(byt_rt5640_codec_aif_name,
|
||
+ sizeof(byt_rt5640_codec_aif_name),
|
||
+ "%s", "rt5640-aif2");
|
||
+
|
||
+ byt_rt5640_dais[dai_index].codec_dai_name =
|
||
+ byt_rt5640_codec_aif_name;
|
||
+ }
|
||
+
|
||
+ if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
|
||
+ (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
|
||
+
|
||
+ /* fixup cpu dai name name */
|
||
+ snprintf(byt_rt5640_cpu_dai_name,
|
||
+ sizeof(byt_rt5640_cpu_dai_name),
|
||
+ "%s", "ssp0-port");
|
||
+
|
||
+ byt_rt5640_dais[dai_index].cpu_dai_name =
|
||
+ byt_rt5640_cpu_dai_name;
|
||
+ }
|
||
+
|
||
+ if ((byt_rt5640_quirk & BYT_RT5640_MCLK_EN) && (is_valleyview())) {
|
||
+ priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
|
||
+ if (IS_ERR(priv->mclk)) {
|
||
+ dev_err(&pdev->dev,
|
||
+ "Failed to get MCLK from pmc_plt_clk_3: %ld\n",
|
||
+ PTR_ERR(priv->mclk));
|
||
+ return PTR_ERR(priv->mclk);
|
||
+ }
|
||
+ }
|
||
|
||
ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card);
|
||
|
||
diff --git a/sound/soc/intel/skylake/bxt-sst.c b/sound/soc/intel/skylake/bxt-sst.c
|
||
index 2663781..48a4ae5 100644
|
||
--- a/sound/soc/intel/skylake/bxt-sst.c
|
||
+++ b/sound/soc/intel/skylake/bxt-sst.c
|
||
@@ -23,6 +23,7 @@
|
||
#include "../common/sst-dsp.h"
|
||
#include "../common/sst-dsp-priv.h"
|
||
#include "skl-sst-ipc.h"
|
||
+#include "skl-tplg-interface.h"
|
||
|
||
#define BXT_BASEFW_TIMEOUT 3000
|
||
#define BXT_INIT_TIMEOUT 500
|
||
@@ -40,11 +41,73 @@
|
||
#define BXT_INSTANCE_ID 0
|
||
#define BXT_BASE_FW_MODULE_ID 0
|
||
|
||
+#define BXT_ADSP_FW_BIN_HDR_OFFSET 0x2000
|
||
+
|
||
static unsigned int bxt_get_errorcode(struct sst_dsp *ctx)
|
||
{
|
||
return sst_dsp_shim_read(ctx, BXT_ADSP_ERROR_CODE);
|
||
}
|
||
|
||
+static int
|
||
+bxt_load_library(struct sst_dsp *ctx, struct skl_dfw_manifest *minfo)
|
||
+{
|
||
+ struct snd_dma_buffer dmab;
|
||
+ struct skl_sst *skl = ctx->thread_context;
|
||
+ const struct firmware *fw = NULL;
|
||
+ struct firmware stripped_fw;
|
||
+ int ret = 0, i, dma_id, stream_tag;
|
||
+
|
||
+ /* library indices start from 1 to N. 0 represents base FW */
|
||
+ for (i = 1; i < minfo->lib_count; i++) {
|
||
+ ret = request_firmware(&fw, minfo->lib[i].name, ctx->dev);
|
||
+ if (ret < 0) {
|
||
+ dev_err(ctx->dev, "Request lib %s failed:%d\n",
|
||
+ minfo->lib[i].name, ret);
|
||
+ return ret;
|
||
+ }
|
||
+
|
||
+ if (skl->is_first_boot) {
|
||
+ ret = snd_skl_parse_uuids(ctx, fw,
|
||
+ BXT_ADSP_FW_BIN_HDR_OFFSET, i);
|
||
+ if (ret < 0)
|
||
+ goto load_library_failed;
|
||
+ }
|
||
+
|
||
+ stripped_fw.data = fw->data;
|
||
+ stripped_fw.size = fw->size;
|
||
+ skl_dsp_strip_extended_manifest(&stripped_fw);
|
||
+
|
||
+ stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40,
|
||
+ stripped_fw.size, &dmab);
|
||
+ if (stream_tag <= 0) {
|
||
+ dev_err(ctx->dev, "Lib prepare DMA err: %x\n",
|
||
+ stream_tag);
|
||
+ ret = stream_tag;
|
||
+ goto load_library_failed;
|
||
+ }
|
||
+
|
||
+ dma_id = stream_tag - 1;
|
||
+ memcpy(dmab.area, stripped_fw.data, stripped_fw.size);
|
||
+
|
||
+ ctx->dsp_ops.trigger(ctx->dev, true, stream_tag);
|
||
+ ret = skl_sst_ipc_load_library(&skl->ipc, dma_id, i);
|
||
+ if (ret < 0)
|
||
+ dev_err(ctx->dev, "IPC Load Lib for %s fail: %d\n",
|
||
+ minfo->lib[i].name, ret);
|
||
+
|
||
+ ctx->dsp_ops.trigger(ctx->dev, false, stream_tag);
|
||
+ ctx->dsp_ops.cleanup(ctx->dev, &dmab, stream_tag);
|
||
+ release_firmware(fw);
|
||
+ fw = NULL;
|
||
+ }
|
||
+
|
||
+ return ret;
|
||
+
|
||
+load_library_failed:
|
||
+ release_firmware(fw);
|
||
+ return ret;
|
||
+}
|
||
+
|
||
/*
|
||
* First boot sequence has some extra steps. Core 0 waits for power
|
||
* status on core 1, so power up core 1 also momentarily, keep it in
|
||
@@ -157,8 +220,6 @@ static int sst_transfer_fw_host_dma(struct sst_dsp *ctx)
|
||
return ret;
|
||
}
|
||
|
||
-#define BXT_ADSP_FW_BIN_HDR_OFFSET 0x2000
|
||
-
|
||
static int bxt_load_base_firmware(struct sst_dsp *ctx)
|
||
{
|
||
struct firmware stripped_fw;
|
||
@@ -175,9 +236,12 @@ static int bxt_load_base_firmware(struct sst_dsp *ctx)
|
||
if (ctx->fw == NULL)
|
||
goto sst_load_base_firmware_failed;
|
||
|
||
- ret = snd_skl_parse_uuids(ctx, BXT_ADSP_FW_BIN_HDR_OFFSET);
|
||
- if (ret < 0)
|
||
- goto sst_load_base_firmware_failed;
|
||
+ /* prase uuids on first boot */
|
||
+ if (skl->is_first_boot) {
|
||
+ ret = snd_skl_parse_uuids(ctx, ctx->fw, BXT_ADSP_FW_BIN_HDR_OFFSET, 0);
|
||
+ if (ret < 0)
|
||
+ goto sst_load_base_firmware_failed;
|
||
+ }
|
||
|
||
stripped_fw.data = ctx->fw->data;
|
||
stripped_fw.size = ctx->fw->size;
|
||
@@ -230,12 +294,23 @@ static int bxt_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id)
|
||
int ret;
|
||
struct skl_ipc_dxstate_info dx;
|
||
unsigned int core_mask = SKL_DSP_CORE_MASK(core_id);
|
||
+ struct skl_dfw_manifest *minfo = &skl->manifest;
|
||
|
||
if (skl->fw_loaded == false) {
|
||
skl->boot_complete = false;
|
||
ret = bxt_load_base_firmware(ctx);
|
||
- if (ret < 0)
|
||
+ if (ret < 0) {
|
||
dev_err(ctx->dev, "reload fw failed: %d\n", ret);
|
||
+ return ret;
|
||
+ }
|
||
+
|
||
+ if (minfo->lib_count > 1) {
|
||
+ ret = bxt_load_library(ctx, minfo);
|
||
+ if (ret < 0) {
|
||
+ dev_err(ctx->dev, "reload libs failed: %d\n", ret);
|
||
+ return ret;
|
||
+ }
|
||
+ }
|
||
return ret;
|
||
}
|
||
|
||
@@ -341,6 +416,7 @@ static struct skl_dsp_fw_ops bxt_fw_ops = {
|
||
.set_state_D3 = bxt_set_dsp_D3,
|
||
.load_fw = bxt_load_base_firmware,
|
||
.get_fw_errcode = bxt_get_errorcode,
|
||
+ .load_library = bxt_load_library,
|
||
};
|
||
|
||
static struct sst_ops skl_ops = {
|
||
@@ -397,6 +473,19 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
|
||
skl->cores.count = 2;
|
||
skl->boot_complete = false;
|
||
init_waitqueue_head(&skl->boot_wait);
|
||
+ skl->is_first_boot = true;
|
||
+
|
||
+ if (dsp)
|
||
+ *dsp = skl;
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+EXPORT_SYMBOL_GPL(bxt_sst_dsp_init);
|
||
+
|
||
+int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx)
|
||
+{
|
||
+ int ret;
|
||
+ struct sst_dsp *sst = ctx->dsp;
|
||
|
||
ret = sst->fw_ops.load_fw(sst);
|
||
if (ret < 0) {
|
||
@@ -406,13 +495,18 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
|
||
|
||
skl_dsp_init_core_state(sst);
|
||
|
||
- if (dsp)
|
||
- *dsp = skl;
|
||
+ if (ctx->manifest.lib_count > 1) {
|
||
+ ret = sst->fw_ops.load_library(sst, &ctx->manifest);
|
||
+ if (ret < 0) {
|
||
+ dev_err(dev, "Load Library failed : %x", ret);
|
||
+ return ret;
|
||
+ }
|
||
+ }
|
||
+ ctx->is_first_boot = false;
|
||
|
||
return 0;
|
||
}
|
||
-EXPORT_SYMBOL_GPL(bxt_sst_dsp_init);
|
||
-
|
||
+EXPORT_SYMBOL_GPL(bxt_sst_init_fw);
|
||
|
||
void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
|
||
{
|
||
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c
|
||
index 44ab595..8eb5ba2 100644
|
||
--- a/sound/soc/intel/skylake/skl-messages.c
|
||
+++ b/sound/soc/intel/skylake/skl-messages.c
|
||
@@ -203,32 +203,35 @@ static const struct skl_dsp_ops dsp_ops[] = {
|
||
.id = 0x9d70,
|
||
.loader_ops = skl_get_loader_ops,
|
||
.init = skl_sst_dsp_init,
|
||
+ .init_fw = skl_sst_init_fw,
|
||
.cleanup = skl_sst_dsp_cleanup
|
||
},
|
||
{
|
||
.id = 0x9d71,
|
||
.loader_ops = skl_get_loader_ops,
|
||
.init = skl_sst_dsp_init,
|
||
+ .init_fw = skl_sst_init_fw,
|
||
.cleanup = skl_sst_dsp_cleanup
|
||
},
|
||
{
|
||
.id = 0x5a98,
|
||
.loader_ops = bxt_get_loader_ops,
|
||
.init = bxt_sst_dsp_init,
|
||
+ .init_fw = bxt_sst_init_fw,
|
||
.cleanup = bxt_sst_dsp_cleanup
|
||
},
|
||
};
|
||
|
||
-static int skl_get_dsp_ops(int pci_id)
|
||
+const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id)
|
||
{
|
||
int i;
|
||
|
||
for (i = 0; i < ARRAY_SIZE(dsp_ops); i++) {
|
||
if (dsp_ops[i].id == pci_id)
|
||
- return i;
|
||
+ return &dsp_ops[i];
|
||
}
|
||
|
||
- return -EINVAL;
|
||
+ return NULL;
|
||
}
|
||
|
||
int skl_init_dsp(struct skl *skl)
|
||
@@ -238,7 +241,8 @@ int skl_init_dsp(struct skl *skl)
|
||
struct hdac_bus *bus = ebus_to_hbus(ebus);
|
||
struct skl_dsp_loader_ops loader_ops;
|
||
int irq = bus->irq;
|
||
- int ret, index;
|
||
+ const struct skl_dsp_ops *ops;
|
||
+ int ret;
|
||
|
||
/* enable ppcap interrupt */
|
||
snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true);
|
||
@@ -251,18 +255,18 @@ int skl_init_dsp(struct skl *skl)
|
||
return -ENXIO;
|
||
}
|
||
|
||
- index = skl_get_dsp_ops(skl->pci->device);
|
||
- if (index < 0)
|
||
- return -EINVAL;
|
||
+ ops = skl_get_dsp_ops(skl->pci->device);
|
||
+ if (!ops)
|
||
+ return -EIO;
|
||
|
||
- loader_ops = dsp_ops[index].loader_ops();
|
||
- ret = dsp_ops[index].init(bus->dev, mmio_base, irq,
|
||
- skl->fw_name, loader_ops, &skl->skl_sst);
|
||
+ loader_ops = ops->loader_ops();
|
||
+ ret = ops->init(bus->dev, mmio_base, irq,
|
||
+ skl->fw_name, loader_ops,
|
||
+ &skl->skl_sst);
|
||
|
||
if (ret < 0)
|
||
return ret;
|
||
|
||
- skl_dsp_enable_notification(skl->skl_sst, false);
|
||
dev_dbg(bus->dev, "dsp registration status=%d\n", ret);
|
||
|
||
return ret;
|
||
@@ -273,16 +277,16 @@ int skl_free_dsp(struct skl *skl)
|
||
struct hdac_ext_bus *ebus = &skl->ebus;
|
||
struct hdac_bus *bus = ebus_to_hbus(ebus);
|
||
struct skl_sst *ctx = skl->skl_sst;
|
||
- int index;
|
||
+ const struct skl_dsp_ops *ops;
|
||
|
||
/* disable ppcap interrupt */
|
||
snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false);
|
||
|
||
- index = skl_get_dsp_ops(skl->pci->device);
|
||
- if (index < 0)
|
||
+ ops = skl_get_dsp_ops(skl->pci->device);
|
||
+ if (!ops)
|
||
return -EIO;
|
||
|
||
- dsp_ops[index].cleanup(bus->dev, ctx);
|
||
+ ops->cleanup(bus->dev, ctx);
|
||
|
||
if (ctx->dsp->addr.lpe)
|
||
iounmap(ctx->dsp->addr.lpe);
|
||
@@ -296,7 +300,7 @@ int skl_suspend_dsp(struct skl *skl)
|
||
int ret;
|
||
|
||
/* if ppcap is not supported return 0 */
|
||
- if (!skl->ebus.ppcap)
|
||
+ if (!skl->ebus.bus.ppcap)
|
||
return 0;
|
||
|
||
ret = skl_dsp_sleep(ctx->dsp);
|
||
@@ -316,13 +320,17 @@ int skl_resume_dsp(struct skl *skl)
|
||
int ret;
|
||
|
||
/* if ppcap is not supported return 0 */
|
||
- if (!skl->ebus.ppcap)
|
||
+ if (!skl->ebus.bus.ppcap)
|
||
return 0;
|
||
|
||
/* enable ppcap interrupt */
|
||
snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true);
|
||
snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, true);
|
||
|
||
+ /* check if DSP 1st boot is done */
|
||
+ if (skl->skl_sst->is_first_boot == true)
|
||
+ return 0;
|
||
+
|
||
ret = skl_dsp_wake(ctx->dsp);
|
||
if (ret < 0)
|
||
return ret;
|
||
@@ -862,6 +870,7 @@ int skl_init_module(struct skl_sst *ctx,
|
||
msg.ppl_instance_id = mconfig->pipe->ppl_id;
|
||
msg.param_data_size = module_config_size;
|
||
msg.core_id = mconfig->core_id;
|
||
+ msg.domain = mconfig->domain;
|
||
|
||
ret = skl_ipc_init_instance(&ctx->ipc, &msg, param_data);
|
||
if (ret < 0) {
|
||
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c
|
||
index 6e05bf8..eb1f00b 100644
|
||
--- a/sound/soc/intel/skylake/skl-pcm.c
|
||
+++ b/sound/soc/intel/skylake/skl-pcm.c
|
||
@@ -106,7 +106,7 @@ static void skl_set_pcm_constrains(struct hdac_ext_bus *ebus,
|
||
|
||
static enum hdac_ext_stream_type skl_get_host_stream_type(struct hdac_ext_bus *ebus)
|
||
{
|
||
- if (ebus->ppcap)
|
||
+ if ((ebus_to_hbus(ebus))->ppcap)
|
||
return HDAC_EXT_STREAM_TYPE_HOST;
|
||
else
|
||
return HDAC_EXT_STREAM_TYPE_COUPLED;
|
||
@@ -188,7 +188,7 @@ static int skl_get_format(struct snd_pcm_substream *substream,
|
||
struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev);
|
||
int format_val = 0;
|
||
|
||
- if (ebus->ppcap) {
|
||
+ if ((ebus_to_hbus(ebus))->ppcap) {
|
||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||
|
||
format_val = snd_hdac_calc_stream_format(runtime->rate,
|
||
@@ -1020,7 +1020,7 @@ static int skl_platform_pcm_trigger(struct snd_pcm_substream *substream,
|
||
{
|
||
struct hdac_ext_bus *ebus = get_bus_ctx(substream);
|
||
|
||
- if (!ebus->ppcap)
|
||
+ if ((ebus_to_hbus(ebus))->ppcap)
|
||
return skl_coupled_trigger(substream, cmd);
|
||
|
||
return 0;
|
||
@@ -1138,20 +1138,67 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd)
|
||
return retval;
|
||
}
|
||
|
||
+static int skl_populate_modules(struct skl *skl)
|
||
+{
|
||
+ struct skl_pipeline *p;
|
||
+ struct skl_pipe_module *m;
|
||
+ struct snd_soc_dapm_widget *w;
|
||
+ struct skl_module_cfg *mconfig;
|
||
+ int ret;
|
||
+
|
||
+ list_for_each_entry(p, &skl->ppl_list, node) {
|
||
+ list_for_each_entry(m, &p->pipe->w_list, node) {
|
||
+
|
||
+ w = m->w;
|
||
+ mconfig = w->priv;
|
||
+
|
||
+ ret = snd_skl_get_module_info(skl->skl_sst, mconfig);
|
||
+ if (ret < 0) {
|
||
+ dev_err(skl->skl_sst->dev,
|
||
+ "query module info failed:%d\n", ret);
|
||
+ goto err;
|
||
+ }
|
||
+ }
|
||
+ }
|
||
+err:
|
||
+ return ret;
|
||
+}
|
||
+
|
||
static int skl_platform_soc_probe(struct snd_soc_platform *platform)
|
||
{
|
||
struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev);
|
||
struct skl *skl = ebus_to_skl(ebus);
|
||
+ const struct skl_dsp_ops *ops;
|
||
int ret;
|
||
|
||
- if (ebus->ppcap) {
|
||
+ pm_runtime_get_sync(platform->dev);
|
||
+ if ((ebus_to_hbus(ebus))->ppcap) {
|
||
ret = skl_tplg_init(platform, ebus);
|
||
if (ret < 0) {
|
||
dev_err(platform->dev, "Failed to init topology!\n");
|
||
return ret;
|
||
}
|
||
skl->platform = platform;
|
||
+
|
||
+ /* load the firmwares, since all is set */
|
||
+ ops = skl_get_dsp_ops(skl->pci->device);
|
||
+ if (!ops)
|
||
+ return -EIO;
|
||
+
|
||
+ if (skl->skl_sst->is_first_boot == false) {
|
||
+ dev_err(platform->dev, "DSP reports first boot done!!!\n");
|
||
+ return -EIO;
|
||
+ }
|
||
+
|
||
+ ret = ops->init_fw(platform->dev, skl->skl_sst);
|
||
+ if (ret < 0) {
|
||
+ dev_err(platform->dev, "Failed to boot first fw: %d\n", ret);
|
||
+ return ret;
|
||
+ }
|
||
+ skl_populate_modules(skl);
|
||
}
|
||
+ pm_runtime_mark_last_busy(platform->dev);
|
||
+ pm_runtime_put_autosuspend(platform->dev);
|
||
|
||
return 0;
|
||
}
|
||
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h
|
||
index 0f8629e..6ad5cab 100644
|
||
--- a/sound/soc/intel/skylake/skl-sst-dsp.h
|
||
+++ b/sound/soc/intel/skylake/skl-sst-dsp.h
|
||
@@ -20,6 +20,7 @@
|
||
#include <sound/memalloc.h>
|
||
#include "skl-sst-cldma.h"
|
||
#include "skl-tplg-interface.h"
|
||
+#include "skl-topology.h"
|
||
|
||
struct sst_dsp;
|
||
struct skl_sst;
|
||
@@ -133,6 +134,8 @@ enum skl_dsp_states {
|
||
struct skl_dsp_fw_ops {
|
||
int (*load_fw)(struct sst_dsp *ctx);
|
||
/* FW module parser/loader */
|
||
+ int (*load_library)(struct sst_dsp *ctx,
|
||
+ struct skl_dfw_manifest *minfo);
|
||
int (*parse_fw)(struct sst_dsp *ctx);
|
||
int (*set_state_D0)(struct sst_dsp *ctx, unsigned int core_id);
|
||
int (*set_state_D3)(struct sst_dsp *ctx, unsigned int core_id);
|
||
@@ -203,12 +206,15 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
|
||
int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
|
||
const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
|
||
struct skl_sst **dsp);
|
||
+int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx);
|
||
+int bxt_sst_init_fw(struct device *dev, struct skl_sst *ctx);
|
||
void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx);
|
||
void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx);
|
||
|
||
-int snd_skl_get_module_info(struct skl_sst *ctx, u8 *uuid,
|
||
- struct skl_dfw_module *dfw_config);
|
||
-int snd_skl_parse_uuids(struct sst_dsp *ctx, unsigned int offset);
|
||
+int snd_skl_get_module_info(struct skl_sst *ctx,
|
||
+ struct skl_module_cfg *mconfig);
|
||
+int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw,
|
||
+ unsigned int offset, int index);
|
||
void skl_freeup_uuid_list(struct skl_sst *ctx);
|
||
|
||
int skl_dsp_strip_extended_manifest(struct firmware *fw);
|
||
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c
|
||
index 96f2f68..74dbecc 100644
|
||
--- a/sound/soc/intel/skylake/skl-sst-ipc.c
|
||
+++ b/sound/soc/intel/skylake/skl-sst-ipc.c
|
||
@@ -114,6 +114,11 @@
|
||
#define IPC_CORE_ID(x) (((x) & IPC_CORE_ID_MASK) \
|
||
<< IPC_CORE_ID_SHIFT)
|
||
|
||
+#define IPC_DOMAIN_SHIFT 28
|
||
+#define IPC_DOMAIN_MASK 0x1
|
||
+#define IPC_DOMAIN(x) (((x) & IPC_DOMAIN_MASK) \
|
||
+ << IPC_DOMAIN_SHIFT)
|
||
+
|
||
/* Bind/Unbind message extension register */
|
||
#define IPC_DST_MOD_ID_SHIFT 0
|
||
#define IPC_DST_MOD_ID(x) (((x) & IPC_MOD_ID_MASK) \
|
||
@@ -190,6 +195,7 @@ enum skl_ipc_glb_type {
|
||
IPC_GLB_GET_PPL_CONTEXT_SIZE = 21,
|
||
IPC_GLB_SAVE_PPL = 22,
|
||
IPC_GLB_RESTORE_PPL = 23,
|
||
+ IPC_GLB_LOAD_LIBRARY = 24,
|
||
IPC_GLB_NOTIFY = 26,
|
||
IPC_GLB_MAX_IPC_MSG_NUMBER = 31 /* Maximum message number */
|
||
};
|
||
@@ -704,6 +710,7 @@ int skl_ipc_init_instance(struct sst_generic_ipc *ipc,
|
||
header.extension = IPC_CORE_ID(msg->core_id);
|
||
header.extension |= IPC_PPL_INSTANCE_ID(msg->ppl_instance_id);
|
||
header.extension |= IPC_PARAM_BLOCK_SIZE(param_block_size);
|
||
+ header.extension |= IPC_DOMAIN(msg->domain);
|
||
|
||
dev_dbg(ipc->dev, "In %s primary =%x ext=%x\n", __func__,
|
||
header.primary, header.extension);
|
||
@@ -902,3 +909,25 @@ int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
|
||
return ret;
|
||
}
|
||
EXPORT_SYMBOL_GPL(skl_ipc_get_large_config);
|
||
+
|
||
+int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
|
||
+ u8 dma_id, u8 table_id)
|
||
+{
|
||
+ struct skl_ipc_header header = {0};
|
||
+ u64 *ipc_header = (u64 *)(&header);
|
||
+ int ret = 0;
|
||
+
|
||
+ header.primary = IPC_MSG_TARGET(IPC_FW_GEN_MSG);
|
||
+ header.primary |= IPC_MSG_DIR(IPC_MSG_REQUEST);
|
||
+ header.primary |= IPC_GLB_TYPE(IPC_GLB_LOAD_LIBRARY);
|
||
+ header.primary |= IPC_MOD_INSTANCE_ID(table_id);
|
||
+ header.primary |= IPC_MOD_ID(dma_id);
|
||
+
|
||
+ ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
|
||
+
|
||
+ if (ret < 0)
|
||
+ dev_err(ipc->dev, "ipc: load lib failed\n");
|
||
+
|
||
+ return ret;
|
||
+}
|
||
+EXPORT_SYMBOL_GPL(skl_sst_ipc_load_library);
|
||
diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h
|
||
index 2e3d4e8..0334ed4 100644
|
||
--- a/sound/soc/intel/skylake/skl-sst-ipc.h
|
||
+++ b/sound/soc/intel/skylake/skl-sst-ipc.h
|
||
@@ -66,7 +66,7 @@ struct skl_sst {
|
||
|
||
/* callback for miscbdge */
|
||
void (*enable_miscbdcge)(struct device *dev, bool enable);
|
||
- /*Is CGCTL.MISCBDCGE disabled*/
|
||
+ /* Is CGCTL.MISCBDCGE disabled */
|
||
bool miscbdcg_disabled;
|
||
|
||
/* Populate module information */
|
||
@@ -75,8 +75,14 @@ struct skl_sst {
|
||
/* Is firmware loaded */
|
||
bool fw_loaded;
|
||
|
||
+ /* first boot ? */
|
||
+ bool is_first_boot;
|
||
+
|
||
/* multi-core */
|
||
struct skl_dsp_cores cores;
|
||
+
|
||
+ /* tplg manifest */
|
||
+ struct skl_dfw_manifest manifest;
|
||
};
|
||
|
||
struct skl_ipc_init_instance_msg {
|
||
@@ -85,6 +91,7 @@ struct skl_ipc_init_instance_msg {
|
||
u16 param_data_size;
|
||
u8 ppl_instance_id;
|
||
u8 core_id;
|
||
+ u8 domain;
|
||
};
|
||
|
||
struct skl_ipc_bind_unbind_msg {
|
||
@@ -145,6 +152,9 @@ int skl_ipc_set_large_config(struct sst_generic_ipc *ipc,
|
||
int skl_ipc_get_large_config(struct sst_generic_ipc *ipc,
|
||
struct skl_ipc_large_config_msg *msg, u32 *param);
|
||
|
||
+int skl_sst_ipc_load_library(struct sst_generic_ipc *ipc,
|
||
+ u8 dma_id, u8 table_id);
|
||
+
|
||
void skl_ipc_int_enable(struct sst_dsp *dsp);
|
||
void skl_ipc_op_int_enable(struct sst_dsp *ctx);
|
||
void skl_ipc_op_int_disable(struct sst_dsp *ctx);
|
||
diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c
|
||
index 588f899..064fc7e 100644
|
||
--- a/sound/soc/intel/skylake/skl-sst.c
|
||
+++ b/sound/soc/intel/skylake/skl-sst.c
|
||
@@ -88,13 +88,15 @@ static int skl_load_base_firmware(struct sst_dsp *ctx)
|
||
}
|
||
}
|
||
|
||
- ret = snd_skl_parse_uuids(ctx, SKL_ADSP_FW_BIN_HDR_OFFSET);
|
||
- if (ret < 0) {
|
||
- dev_err(ctx->dev,
|
||
- "UUID parsing err: %d\n", ret);
|
||
- release_firmware(ctx->fw);
|
||
- skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK);
|
||
- return ret;
|
||
+ /* prase uuids on first boot */
|
||
+ if (skl->is_first_boot) {
|
||
+ ret = snd_skl_parse_uuids(ctx, ctx->fw, SKL_ADSP_FW_BIN_HDR_OFFSET, 0);
|
||
+ if (ret < 0) {
|
||
+ dev_err(ctx->dev, "UUID parsing err: %d\n", ret);
|
||
+ release_firmware(ctx->fw);
|
||
+ skl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK);
|
||
+ return ret;
|
||
+ }
|
||
}
|
||
|
||
/* check for extended manifest */
|
||
@@ -484,25 +486,32 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
|
||
return ret;
|
||
|
||
skl->cores.count = 2;
|
||
+ skl->is_first_boot = true;
|
||
+
|
||
+ if (dsp)
|
||
+ *dsp = skl;
|
||
+
|
||
+ return ret;
|
||
+}
|
||
+EXPORT_SYMBOL_GPL(skl_sst_dsp_init);
|
||
+
|
||
+int skl_sst_init_fw(struct device *dev, struct skl_sst *ctx)
|
||
+{
|
||
+ int ret;
|
||
+ struct sst_dsp *sst = ctx->dsp;
|
||
|
||
ret = sst->fw_ops.load_fw(sst);
|
||
if (ret < 0) {
|
||
dev_err(dev, "Load base fw failed : %d", ret);
|
||
- goto cleanup;
|
||
+ return ret;
|
||
}
|
||
|
||
skl_dsp_init_core_state(sst);
|
||
+ ctx->is_first_boot = false;
|
||
|
||
- if (dsp)
|
||
- *dsp = skl;
|
||
-
|
||
- return ret;
|
||
-
|
||
-cleanup:
|
||
- skl_sst_dsp_cleanup(dev, skl);
|
||
- return ret;
|
||
+ return 0;
|
||
}
|
||
-EXPORT_SYMBOL_GPL(skl_sst_dsp_init);
|
||
+EXPORT_SYMBOL_GPL(skl_sst_init_fw);
|
||
|
||
void skl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx)
|
||
{
|
||
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
|
||
index cc0150f..4bc8f9c 100644
|
||
--- a/sound/soc/intel/skylake/skl-topology.c
|
||
+++ b/sound/soc/intel/skylake/skl-topology.c
|
||
@@ -473,6 +473,14 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe)
|
||
w = w_module->w;
|
||
mconfig = w->priv;
|
||
|
||
+ /* check if module ids are populated */
|
||
+ if (mconfig->id.module_id < 0) {
|
||
+ dev_err(skl->skl_sst->dev,
|
||
+ "module %pUL id not populated\n",
|
||
+ (uuid_le *)mconfig->guid);
|
||
+ return -EIO;
|
||
+ }
|
||
+
|
||
/* check resource available */
|
||
if (!skl_is_pipe_mcps_avail(skl, mconfig))
|
||
return -ENOMEM;
|
||
@@ -1621,11 +1629,11 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt,
|
||
w->priv = mconfig;
|
||
memcpy(&mconfig->guid, &dfw_config->uuid, 16);
|
||
|
||
- ret = snd_skl_get_module_info(skl->skl_sst, mconfig->guid, dfw_config);
|
||
- if (ret < 0)
|
||
- return ret;
|
||
-
|
||
- mconfig->id.module_id = dfw_config->module_id;
|
||
+ /*
|
||
+ * module binary can be loaded later, so set it to query when
|
||
+ * module is load for a use case
|
||
+ */
|
||
+ mconfig->id.module_id = -1;
|
||
mconfig->id.instance_id = dfw_config->instance_id;
|
||
mconfig->mcps = dfw_config->max_mcps;
|
||
mconfig->ibs = dfw_config->ibs;
|
||
@@ -1634,6 +1642,7 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt,
|
||
mconfig->max_in_queue = dfw_config->max_in_queue;
|
||
mconfig->max_out_queue = dfw_config->max_out_queue;
|
||
mconfig->is_loadable = dfw_config->is_loadable;
|
||
+ mconfig->domain = dfw_config->proc_domain;
|
||
skl_tplg_fill_fmt(mconfig->in_fmt, dfw_config->in_fmt,
|
||
MODULE_MAX_IN_PINS);
|
||
skl_tplg_fill_fmt(mconfig->out_fmt, dfw_config->out_fmt,
|
||
@@ -1767,11 +1776,33 @@ static int skl_tplg_control_load(struct snd_soc_component *cmpnt,
|
||
return 0;
|
||
}
|
||
|
||
+static int skl_manifest_load(struct snd_soc_component *cmpnt,
|
||
+ struct snd_soc_tplg_manifest *manifest)
|
||
+{
|
||
+ struct skl_dfw_manifest *minfo;
|
||
+ struct hdac_ext_bus *ebus = snd_soc_component_get_drvdata(cmpnt);
|
||
+ struct hdac_bus *bus = ebus_to_hbus(ebus);
|
||
+ struct skl *skl = ebus_to_skl(ebus);
|
||
+ int ret = 0;
|
||
+
|
||
+ minfo = &skl->skl_sst->manifest;
|
||
+ memcpy(minfo, manifest->priv.data, sizeof(struct skl_dfw_manifest));
|
||
+
|
||
+ if (minfo->lib_count > HDA_MAX_LIB) {
|
||
+ dev_err(bus->dev, "Exceeding max Library count. Got:%d\n",
|
||
+ minfo->lib_count);
|
||
+ ret = -EINVAL;
|
||
+ }
|
||
+
|
||
+ return ret;
|
||
+}
|
||
+
|
||
static struct snd_soc_tplg_ops skl_tplg_ops = {
|
||
.widget_load = skl_tplg_widget_load,
|
||
.control_load = skl_tplg_control_load,
|
||
.bytes_ext_ops = skl_tlv_ops,
|
||
.bytes_ext_ops_count = ARRAY_SIZE(skl_tlv_ops),
|
||
+ .manifest = skl_manifest_load,
|
||
};
|
||
|
||
/*
|
||
diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h
|
||
index 22d3ef8..96fa86d 100644
|
||
--- a/sound/soc/intel/skylake/skl-topology.h
|
||
+++ b/sound/soc/intel/skylake/skl-topology.h
|
||
@@ -216,7 +216,7 @@ struct skl_module_fmt {
|
||
struct skl_module_cfg;
|
||
|
||
struct skl_module_inst_id {
|
||
- u32 module_id;
|
||
+ int module_id;
|
||
u32 instance_id;
|
||
};
|
||
|
||
diff --git a/sound/soc/intel/skylake/skl-tplg-interface.h b/sound/soc/intel/skylake/skl-tplg-interface.h
|
||
index a32e5e9..bd8b4ae 100644
|
||
--- a/sound/soc/intel/skylake/skl-tplg-interface.h
|
||
+++ b/sound/soc/intel/skylake/skl-tplg-interface.h
|
||
@@ -210,7 +210,8 @@ struct skl_dfw_module {
|
||
u32 is_dynamic_in_pin:1;
|
||
u32 is_dynamic_out_pin:1;
|
||
u32 is_loadable:1;
|
||
- u32 rsvd3:11;
|
||
+ u32 proc_domain:1;
|
||
+ u32 rsvd3:10;
|
||
|
||
struct skl_dfw_pipe pipe;
|
||
struct skl_dfw_module_fmt in_fmt[MAX_IN_QUEUE];
|
||
@@ -228,4 +229,16 @@ struct skl_dfw_algo_data {
|
||
char params[0];
|
||
} __packed;
|
||
|
||
+#define LIB_NAME_LENGTH 128
|
||
+#define HDA_MAX_LIB 16
|
||
+
|
||
+struct lib_info {
|
||
+ char name[LIB_NAME_LENGTH];
|
||
+} __packed;
|
||
+
|
||
+struct skl_dfw_manifest {
|
||
+ u32 lib_count;
|
||
+ struct lib_info lib[HDA_MAX_LIB];
|
||
+} __packed;
|
||
+
|
||
#endif
|
||
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
|
||
index cd59536..a893ca1 100644
|
||
--- a/sound/soc/intel/skylake/skl.c
|
||
+++ b/sound/soc/intel/skylake/skl.c
|
||
@@ -587,7 +587,7 @@ static int skl_first_init(struct hdac_ext_bus *ebus)
|
||
return -ENXIO;
|
||
}
|
||
|
||
- snd_hdac_ext_bus_parse_capabilities(ebus);
|
||
+ snd_hdac_bus_parse_capabilities(bus);
|
||
|
||
if (skl_acquire_irq(ebus, 0) < 0)
|
||
return -EBUSY;
|
||
@@ -682,7 +682,7 @@ static int skl_probe(struct pci_dev *pci,
|
||
skl_dmic_data.dmic_num = skl_get_dmic_geo(skl);
|
||
|
||
/* check if dsp is there */
|
||
- if (ebus->ppcap) {
|
||
+ if (bus->ppcap) {
|
||
err = skl_machine_device_register(skl,
|
||
(void *)pci_id->driver_data);
|
||
if (err < 0)
|
||
@@ -696,7 +696,7 @@ static int skl_probe(struct pci_dev *pci,
|
||
skl->skl_sst->enable_miscbdcge = skl_enable_miscbdcge;
|
||
|
||
}
|
||
- if (ebus->mlcap)
|
||
+ if (bus->mlcap)
|
||
snd_hdac_ext_bus_get_ml_capabilities(ebus);
|
||
|
||
/* create device for soc dmic */
|
||
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h
|
||
index 9064e5b..5d4fbb0 100644
|
||
--- a/sound/soc/intel/skylake/skl.h
|
||
+++ b/sound/soc/intel/skylake/skl.h
|
||
@@ -105,6 +105,7 @@ struct skl_dsp_ops {
|
||
int irq, const char *fw_name,
|
||
struct skl_dsp_loader_ops loader_ops,
|
||
struct skl_sst **skl_sst);
|
||
+ int (*init_fw)(struct device *dev, struct skl_sst *ctx);
|
||
void (*cleanup)(struct device *dev, struct skl_sst *ctx);
|
||
};
|
||
|
||
@@ -123,4 +124,5 @@ int skl_free_dsp(struct skl *skl);
|
||
int skl_suspend_dsp(struct skl *skl);
|
||
int skl_resume_dsp(struct skl *skl);
|
||
void skl_cleanup_resources(struct skl *skl);
|
||
+const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id);
|
||
#endif /* __SOUND_SOC_SKL_H */
|
||
diff --git a/tools/power/acpi/common/cmfsize.c b/tools/power/acpi/common/cmfsize.c
|
||
index e73a79f..bc82596 100644
|
||
--- a/tools/power/acpi/common/cmfsize.c
|
||
+++ b/tools/power/acpi/common/cmfsize.c
|
||
@@ -44,7 +44,6 @@
|
||
#include <acpi/acpi.h>
|
||
#include "accommon.h"
|
||
#include "acapps.h"
|
||
-#include <stdio.h>
|
||
|
||
#define _COMPONENT ACPI_TOOLS
|
||
ACPI_MODULE_NAME("cmfsize")
|
||
@@ -69,24 +68,24 @@ u32 cm_get_file_size(ACPI_FILE file)
|
||
|
||
/* Save the current file pointer, seek to EOF to obtain file size */
|
||
|
||
- current_offset = acpi_os_get_file_offset(file);
|
||
+ current_offset = ftell(file);
|
||
if (current_offset < 0) {
|
||
goto offset_error;
|
||
}
|
||
|
||
- status = acpi_os_set_file_offset(file, 0, ACPI_FILE_END);
|
||
+ status = fseek(file, 0, SEEK_END);
|
||
if (ACPI_FAILURE(status)) {
|
||
goto seek_error;
|
||
}
|
||
|
||
- file_size = acpi_os_get_file_offset(file);
|
||
+ file_size = ftell(file);
|
||
if (file_size < 0) {
|
||
goto offset_error;
|
||
}
|
||
|
||
/* Restore original file pointer */
|
||
|
||
- status = acpi_os_set_file_offset(file, current_offset, ACPI_FILE_BEGIN);
|
||
+ status = fseek(file, current_offset, SEEK_SET);
|
||
if (ACPI_FAILURE(status)) {
|
||
goto seek_error;
|
||
}
|
||
@@ -94,10 +93,10 @@ u32 cm_get_file_size(ACPI_FILE file)
|
||
return ((u32)file_size);
|
||
|
||
offset_error:
|
||
- acpi_log_error("Could not get file offset");
|
||
+ fprintf(stderr, "Could not get file offset\n");
|
||
return (ACPI_UINT32_MAX);
|
||
|
||
seek_error:
|
||
- acpi_log_error("Could not set file offset");
|
||
+ fprintf(stderr, "Could not set file offset\n");
|
||
return (ACPI_UINT32_MAX);
|
||
}
|
||
diff --git a/tools/power/acpi/common/getopt.c b/tools/power/acpi/common/getopt.c
|
||
index 0bd343f..3919970 100644
|
||
--- a/tools/power/acpi/common/getopt.c
|
||
+++ b/tools/power/acpi/common/getopt.c
|
||
@@ -57,7 +57,7 @@
|
||
#include "acapps.h"
|
||
|
||
#define ACPI_OPTION_ERROR(msg, badchar) \
|
||
- if (acpi_gbl_opterr) {acpi_log_error ("%s%c\n", msg, badchar);}
|
||
+ if (acpi_gbl_opterr) {fprintf (stderr, "%s%c\n", msg, badchar);}
|
||
|
||
int acpi_gbl_opterr = 1;
|
||
int acpi_gbl_optind = 1;
|
||
@@ -94,7 +94,7 @@ int acpi_getopt_argument(int argc, char **argv)
|
||
acpi_gbl_optarg =
|
||
&argv[acpi_gbl_optind++][(int)(current_char_ptr + 1)];
|
||
} else if (++acpi_gbl_optind >= argc) {
|
||
- ACPI_OPTION_ERROR("Option requires an argument: -", 'v');
|
||
+ ACPI_OPTION_ERROR("\nOption requires an argument", 0);
|
||
|
||
current_char_ptr = 1;
|
||
return (-1);
|
||
diff --git a/tools/power/acpi/os_specific/service_layers/oslibcfs.c b/tools/power/acpi/os_specific/service_layers/oslibcfs.c
|
||
deleted file mode 100644
|
||
index 11f4aba..0000000
|
||
--- a/tools/power/acpi/os_specific/service_layers/oslibcfs.c
|
||
+++ /dev/null
|
||
@@ -1,217 +0,0 @@
|
||
-/******************************************************************************
|
||
- *
|
||
- * Module Name: oslibcfs - C library OSL for file I/O
|
||
- *
|
||
- *****************************************************************************/
|
||
-
|
||
-/*
|
||
- * Copyright (C) 2000 - 2016, Intel Corp.
|
||
- * All rights reserved.
|
||
- *
|
||
- * Redistribution and use in source and binary forms, with or without
|
||
- * modification, are permitted provided that the following conditions
|
||
- * are met:
|
||
- * 1. Redistributions of source code must retain the above copyright
|
||
- * notice, this list of conditions, and the following disclaimer,
|
||
- * without modification.
|
||
- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||
- * substantially similar to the "NO WARRANTY" disclaimer below
|
||
- * ("Disclaimer") and any redistribution must be conditioned upon
|
||
- * including a substantially similar Disclaimer requirement for further
|
||
- * binary redistribution.
|
||
- * 3. Neither the names of the above-listed copyright holders nor the names
|
||
- * of any contributors may be used to endorse or promote products derived
|
||
- * from this software without specific prior written permission.
|
||
- *
|
||
- * Alternatively, this software may be distributed under the terms of the
|
||
- * GNU General Public License ("GPL") version 2 as published by the Free
|
||
- * Software Foundation.
|
||
- *
|
||
- * NO WARRANTY
|
||
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||
- * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||
- * POSSIBILITY OF SUCH DAMAGES.
|
||
- */
|
||
-
|
||
-#include <acpi/acpi.h>
|
||
-#include <stdio.h>
|
||
-#include <stdarg.h>
|
||
-
|
||
-#define _COMPONENT ACPI_OS_SERVICES
|
||
-ACPI_MODULE_NAME("oslibcfs")
|
||
-
|
||
-/*******************************************************************************
|
||
- *
|
||
- * FUNCTION: acpi_os_open_file
|
||
- *
|
||
- * PARAMETERS: path - File path
|
||
- * modes - File operation type
|
||
- *
|
||
- * RETURN: File descriptor.
|
||
- *
|
||
- * DESCRIPTION: Open a file for reading (ACPI_FILE_READING) or/and writing
|
||
- * (ACPI_FILE_WRITING).
|
||
- *
|
||
- ******************************************************************************/
|
||
-ACPI_FILE acpi_os_open_file(const char *path, u8 modes)
|
||
-{
|
||
- ACPI_FILE file;
|
||
- u32 i = 0;
|
||
- char modes_str[4];
|
||
-
|
||
- if (modes & ACPI_FILE_READING) {
|
||
- modes_str[i++] = 'r';
|
||
- }
|
||
- if (modes & ACPI_FILE_WRITING) {
|
||
- modes_str[i++] = 'w';
|
||
- }
|
||
-
|
||
- if (modes & ACPI_FILE_BINARY) {
|
||
- modes_str[i++] = 'b';
|
||
- }
|
||
-
|
||
- modes_str[i++] = '\0';
|
||
-
|
||
- file = fopen(path, modes_str);
|
||
- if (!file) {
|
||
- perror("Could not open file");
|
||
- }
|
||
-
|
||
- return (file);
|
||
-}
|
||
-
|
||
-/*******************************************************************************
|
||
- *
|
||
- * FUNCTION: acpi_os_close_file
|
||
- *
|
||
- * PARAMETERS: file - An open file descriptor
|
||
- *
|
||
- * RETURN: None.
|
||
- *
|
||
- * DESCRIPTION: Close a file opened via acpi_os_open_file.
|
||
- *
|
||
- ******************************************************************************/
|
||
-
|
||
-void acpi_os_close_file(ACPI_FILE file)
|
||
-{
|
||
-
|
||
- fclose(file);
|
||
-}
|
||
-
|
||
-/*******************************************************************************
|
||
- *
|
||
- * FUNCTION: acpi_os_read_file
|
||
- *
|
||
- * PARAMETERS: file - An open file descriptor
|
||
- * buffer - Data buffer
|
||
- * size - Data block size
|
||
- * count - Number of data blocks
|
||
- *
|
||
- * RETURN: Number of bytes actually read.
|
||
- *
|
||
- * DESCRIPTION: Read from a file.
|
||
- *
|
||
- ******************************************************************************/
|
||
-
|
||
-int
|
||
-acpi_os_read_file(ACPI_FILE file, void *buffer, acpi_size size, acpi_size count)
|
||
-{
|
||
- int length;
|
||
-
|
||
- length = fread(buffer, size, count, file);
|
||
- if (length < 0) {
|
||
- perror("Error reading file");
|
||
- }
|
||
-
|
||
- return (length);
|
||
-}
|
||
-
|
||
-/*******************************************************************************
|
||
- *
|
||
- * FUNCTION: acpi_os_write_file
|
||
- *
|
||
- * PARAMETERS: file - An open file descriptor
|
||
- * buffer - Data buffer
|
||
- * size - Data block size
|
||
- * count - Number of data blocks
|
||
- *
|
||
- * RETURN: Number of bytes actually written.
|
||
- *
|
||
- * DESCRIPTION: Write to a file.
|
||
- *
|
||
- ******************************************************************************/
|
||
-
|
||
-int
|
||
-acpi_os_write_file(ACPI_FILE file,
|
||
- void *buffer, acpi_size size, acpi_size count)
|
||
-{
|
||
- int length;
|
||
-
|
||
- length = fwrite(buffer, size, count, file);
|
||
- if (length < 0) {
|
||
- perror("Error writing file");
|
||
- }
|
||
-
|
||
- return (length);
|
||
-}
|
||
-
|
||
-/*******************************************************************************
|
||
- *
|
||
- * FUNCTION: acpi_os_get_file_offset
|
||
- *
|
||
- * PARAMETERS: file - An open file descriptor
|
||
- *
|
||
- * RETURN: Current file pointer position.
|
||
- *
|
||
- * DESCRIPTION: Get current file offset.
|
||
- *
|
||
- ******************************************************************************/
|
||
-
|
||
-long acpi_os_get_file_offset(ACPI_FILE file)
|
||
-{
|
||
- long offset;
|
||
-
|
||
- offset = ftell(file);
|
||
- return (offset);
|
||
-}
|
||
-
|
||
-/*******************************************************************************
|
||
- *
|
||
- * FUNCTION: acpi_os_set_file_offset
|
||
- *
|
||
- * PARAMETERS: file - An open file descriptor
|
||
- * offset - New file offset
|
||
- * from - From begin/end of file
|
||
- *
|
||
- * RETURN: Status
|
||
- *
|
||
- * DESCRIPTION: Set current file offset.
|
||
- *
|
||
- ******************************************************************************/
|
||
-
|
||
-acpi_status acpi_os_set_file_offset(ACPI_FILE file, long offset, u8 from)
|
||
-{
|
||
- int ret = 0;
|
||
-
|
||
- if (from == ACPI_FILE_BEGIN) {
|
||
- ret = fseek(file, offset, SEEK_SET);
|
||
- }
|
||
-
|
||
- if (from == ACPI_FILE_END) {
|
||
- ret = fseek(file, offset, SEEK_END);
|
||
- }
|
||
-
|
||
- if (ret < 0) {
|
||
- return (AE_ERROR);
|
||
- } else {
|
||
- return (AE_OK);
|
||
- }
|
||
-}
|
||
diff --git a/tools/power/acpi/os_specific/service_layers/osunixxf.c b/tools/power/acpi/os_specific/service_layers/osunixxf.c
|
||
index 88aa66e..8d8003c 100644
|
||
--- a/tools/power/acpi/os_specific/service_layers/osunixxf.c
|
||
+++ b/tools/power/acpi/os_specific/service_layers/osunixxf.c
|
||
@@ -63,10 +63,7 @@
|
||
#define _COMPONENT ACPI_OS_SERVICES
|
||
ACPI_MODULE_NAME("osunixxf")
|
||
|
||
-u8 acpi_gbl_debug_timeout = FALSE;
|
||
-
|
||
/* Upcalls to acpi_exec */
|
||
-
|
||
void
|
||
ae_table_override(struct acpi_table_header *existing_table,
|
||
struct acpi_table_header **new_table);
|
||
diff --git a/tools/power/acpi/tools/acpidump/Makefile b/tools/power/acpi/tools/acpidump/Makefile
|
||
index 2942cdc..a710f60 100644
|
||
--- a/tools/power/acpi/tools/acpidump/Makefile
|
||
+++ b/tools/power/acpi/tools/acpidump/Makefile
|
||
@@ -41,7 +41,6 @@ TOOL_OBJS = \
|
||
utprint.o\
|
||
utstring.o\
|
||
utxferror.o\
|
||
- oslibcfs.o\
|
||
oslinuxtbl.o\
|
||
cmfsize.o\
|
||
getopt.o
|
||
diff --git a/tools/power/acpi/tools/acpidump/acpidump.h b/tools/power/acpi/tools/acpidump/acpidump.h
|
||
index 025c232..00423fc 100644
|
||
--- a/tools/power/acpi/tools/acpidump/acpidump.h
|
||
+++ b/tools/power/acpi/tools/acpidump/acpidump.h
|
||
@@ -55,11 +55,7 @@
|
||
#include <acpi/acpi.h>
|
||
#include "accommon.h"
|
||
#include "actables.h"
|
||
-
|
||
-#include <stdio.h>
|
||
-#include <fcntl.h>
|
||
-#include <errno.h>
|
||
-#include <sys/stat.h>
|
||
+#include "acapps.h"
|
||
|
||
/* Globals */
|
||
|
||
@@ -72,12 +68,6 @@ EXTERN ACPI_FILE INIT_GLOBAL(gbl_output_file, NULL);
|
||
EXTERN char INIT_GLOBAL(*gbl_output_filename, NULL);
|
||
EXTERN u64 INIT_GLOBAL(gbl_rsdp_base, 0);
|
||
|
||
-/* Globals required for use with ACPICA modules */
|
||
-
|
||
-#ifdef _DECLARE_GLOBALS
|
||
-u8 acpi_gbl_integer_byte_width = 8;
|
||
-#endif
|
||
-
|
||
/* Action table used to defer requested options */
|
||
|
||
struct ap_dump_action {
|
||
diff --git a/tools/power/acpi/tools/acpidump/apdump.c b/tools/power/acpi/tools/acpidump/apdump.c
|
||
index fb8f1d9..1c4e00b 100644
|
||
--- a/tools/power/acpi/tools/acpidump/apdump.c
|
||
+++ b/tools/power/acpi/tools/acpidump/apdump.c
|
||
@@ -69,16 +69,17 @@ u8 ap_is_valid_header(struct acpi_table_header *table)
|
||
/* Make sure signature is all ASCII and a valid ACPI name */
|
||
|
||
if (!acpi_ut_valid_nameseg(table->signature)) {
|
||
- acpi_log_error("Table signature (0x%8.8X) is invalid\n",
|
||
- *(u32 *)table->signature);
|
||
+ fprintf(stderr,
|
||
+ "Table signature (0x%8.8X) is invalid\n",
|
||
+ *(u32 *)table->signature);
|
||
return (FALSE);
|
||
}
|
||
|
||
/* Check for minimum table length */
|
||
|
||
if (table->length < sizeof(struct acpi_table_header)) {
|
||
- acpi_log_error("Table length (0x%8.8X) is invalid\n",
|
||
- table->length);
|
||
+ fprintf(stderr, "Table length (0x%8.8X) is invalid\n",
|
||
+ table->length);
|
||
return (FALSE);
|
||
}
|
||
}
|
||
@@ -115,8 +116,8 @@ u8 ap_is_valid_checksum(struct acpi_table_header *table)
|
||
}
|
||
|
||
if (ACPI_FAILURE(status)) {
|
||
- acpi_log_error("%4.4s: Warning: wrong checksum in table\n",
|
||
- table->signature);
|
||
+ fprintf(stderr, "%4.4s: Warning: wrong checksum in table\n",
|
||
+ table->signature);
|
||
}
|
||
|
||
return (AE_OK);
|
||
@@ -195,13 +196,13 @@ ap_dump_table_buffer(struct acpi_table_header *table,
|
||
* Note: simplest to just always emit a 64-bit address. acpi_xtract
|
||
* utility can handle this.
|
||
*/
|
||
- acpi_ut_file_printf(gbl_output_file, "%4.4s @ 0x%8.8X%8.8X\n",
|
||
- table->signature, ACPI_FORMAT_UINT64(address));
|
||
+ fprintf(gbl_output_file, "%4.4s @ 0x%8.8X%8.8X\n",
|
||
+ table->signature, ACPI_FORMAT_UINT64(address));
|
||
|
||
acpi_ut_dump_buffer_to_file(gbl_output_file,
|
||
ACPI_CAST_PTR(u8, table), table_length,
|
||
DB_BYTE_DISPLAY, 0);
|
||
- acpi_ut_file_printf(gbl_output_file, "\n");
|
||
+ fprintf(gbl_output_file, "\n");
|
||
return (0);
|
||
}
|
||
|
||
@@ -239,14 +240,14 @@ int ap_dump_all_tables(void)
|
||
if (status == AE_LIMIT) {
|
||
return (0);
|
||
} else if (i == 0) {
|
||
- acpi_log_error
|
||
- ("Could not get ACPI tables, %s\n",
|
||
- acpi_format_exception(status));
|
||
+ fprintf(stderr,
|
||
+ "Could not get ACPI tables, %s\n",
|
||
+ acpi_format_exception(status));
|
||
return (-1);
|
||
} else {
|
||
- acpi_log_error
|
||
- ("Could not get ACPI table at index %u, %s\n",
|
||
- i, acpi_format_exception(status));
|
||
+ fprintf(stderr,
|
||
+ "Could not get ACPI table at index %u, %s\n",
|
||
+ i, acpi_format_exception(status));
|
||
continue;
|
||
}
|
||
}
|
||
@@ -289,17 +290,17 @@ int ap_dump_table_by_address(char *ascii_address)
|
||
status = acpi_ut_strtoul64(ascii_address, ACPI_ANY_BASE,
|
||
ACPI_MAX64_BYTE_WIDTH, &long_address);
|
||
if (ACPI_FAILURE(status)) {
|
||
- acpi_log_error("%s: Could not convert to a physical address\n",
|
||
- ascii_address);
|
||
+ fprintf(stderr, "%s: Could not convert to a physical address\n",
|
||
+ ascii_address);
|
||
return (-1);
|
||
}
|
||
|
||
address = (acpi_physical_address)long_address;
|
||
status = acpi_os_get_table_by_address(address, &table);
|
||
if (ACPI_FAILURE(status)) {
|
||
- acpi_log_error("Could not get table at 0x%8.8X%8.8X, %s\n",
|
||
- ACPI_FORMAT_UINT64(address),
|
||
- acpi_format_exception(status));
|
||
+ fprintf(stderr, "Could not get table at 0x%8.8X%8.8X, %s\n",
|
||
+ ACPI_FORMAT_UINT64(address),
|
||
+ acpi_format_exception(status));
|
||
return (-1);
|
||
}
|
||
|
||
@@ -331,9 +332,9 @@ int ap_dump_table_by_name(char *signature)
|
||
int table_status;
|
||
|
||
if (strlen(signature) != ACPI_NAME_SIZE) {
|
||
- acpi_log_error
|
||
- ("Invalid table signature [%s]: must be exactly 4 characters\n",
|
||
- signature);
|
||
+ fprintf(stderr,
|
||
+ "Invalid table signature [%s]: must be exactly 4 characters\n",
|
||
+ signature);
|
||
return (-1);
|
||
}
|
||
|
||
@@ -363,9 +364,9 @@ int ap_dump_table_by_name(char *signature)
|
||
return (0);
|
||
}
|
||
|
||
- acpi_log_error
|
||
- ("Could not get ACPI table with signature [%s], %s\n",
|
||
- local_signature, acpi_format_exception(status));
|
||
+ fprintf(stderr,
|
||
+ "Could not get ACPI table with signature [%s], %s\n",
|
||
+ local_signature, acpi_format_exception(status));
|
||
return (-1);
|
||
}
|
||
|
||
@@ -408,24 +409,24 @@ int ap_dump_table_from_file(char *pathname)
|
||
}
|
||
|
||
if (!acpi_ut_valid_nameseg(table->signature)) {
|
||
- acpi_log_error
|
||
- ("No valid ACPI signature was found in input file %s\n",
|
||
- pathname);
|
||
+ fprintf(stderr,
|
||
+ "No valid ACPI signature was found in input file %s\n",
|
||
+ pathname);
|
||
}
|
||
|
||
/* File must be at least as long as the table length */
|
||
|
||
if (table->length > file_size) {
|
||
- acpi_log_error
|
||
- ("Table length (0x%X) is too large for input file (0x%X) %s\n",
|
||
- table->length, file_size, pathname);
|
||
+ fprintf(stderr,
|
||
+ "Table length (0x%X) is too large for input file (0x%X) %s\n",
|
||
+ table->length, file_size, pathname);
|
||
goto exit;
|
||
}
|
||
|
||
if (gbl_verbose_mode) {
|
||
- acpi_log_error
|
||
- ("Input file: %s contains table [%4.4s], 0x%X (%u) bytes\n",
|
||
- pathname, table->signature, file_size, file_size);
|
||
+ fprintf(stderr,
|
||
+ "Input file: %s contains table [%4.4s], 0x%X (%u) bytes\n",
|
||
+ pathname, table->signature, file_size, file_size);
|
||
}
|
||
|
||
table_status = ap_dump_table_buffer(table, 0, 0);
|
||
diff --git a/tools/power/acpi/tools/acpidump/apfiles.c b/tools/power/acpi/tools/acpidump/apfiles.c
|
||
index 5fcd970..dd5b861 100644
|
||
--- a/tools/power/acpi/tools/acpidump/apfiles.c
|
||
+++ b/tools/power/acpi/tools/acpidump/apfiles.c
|
||
@@ -42,7 +42,6 @@
|
||
*/
|
||
|
||
#include "acpidump.h"
|
||
-#include "acapps.h"
|
||
|
||
/* Local prototypes */
|
||
|
||
@@ -66,7 +65,8 @@ static int ap_is_existing_file(char *pathname)
|
||
struct stat stat_info;
|
||
|
||
if (!stat(pathname, &stat_info)) {
|
||
- acpi_log_error("Target path already exists, overwrite? [y|n] ");
|
||
+ fprintf(stderr,
|
||
+ "Target path already exists, overwrite? [y|n] ");
|
||
|
||
if (getchar() != 'y') {
|
||
return (-1);
|
||
@@ -102,9 +102,9 @@ int ap_open_output_file(char *pathname)
|
||
|
||
/* Point stdout to the file */
|
||
|
||
- file = acpi_os_open_file(pathname, ACPI_FILE_WRITING);
|
||
+ file = fopen(pathname, "w");
|
||
if (!file) {
|
||
- acpi_log_error("Could not open output file: %s\n", pathname);
|
||
+ fprintf(stderr, "Could not open output file: %s\n", pathname);
|
||
return (-1);
|
||
}
|
||
|
||
@@ -134,7 +134,7 @@ int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance)
|
||
char filename[ACPI_NAME_SIZE + 16];
|
||
char instance_str[16];
|
||
ACPI_FILE file;
|
||
- size_t actual;
|
||
+ acpi_size actual;
|
||
u32 table_length;
|
||
|
||
/* Obtain table length */
|
||
@@ -158,37 +158,36 @@ int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance)
|
||
/* Handle multiple SSDts - create different filenames for each */
|
||
|
||
if (instance > 0) {
|
||
- acpi_ut_snprintf(instance_str, sizeof(instance_str), "%u",
|
||
- instance);
|
||
+ snprintf(instance_str, sizeof(instance_str), "%u", instance);
|
||
strcat(filename, instance_str);
|
||
}
|
||
|
||
strcat(filename, FILE_SUFFIX_BINARY_TABLE);
|
||
|
||
if (gbl_verbose_mode) {
|
||
- acpi_log_error
|
||
- ("Writing [%4.4s] to binary file: %s 0x%X (%u) bytes\n",
|
||
- table->signature, filename, table->length, table->length);
|
||
+ fprintf(stderr,
|
||
+ "Writing [%4.4s] to binary file: %s 0x%X (%u) bytes\n",
|
||
+ table->signature, filename, table->length,
|
||
+ table->length);
|
||
}
|
||
|
||
/* Open the file and dump the entire table in binary mode */
|
||
|
||
- file = acpi_os_open_file(filename,
|
||
- ACPI_FILE_WRITING | ACPI_FILE_BINARY);
|
||
+ file = fopen(filename, "wb");
|
||
if (!file) {
|
||
- acpi_log_error("Could not open output file: %s\n", filename);
|
||
+ fprintf(stderr, "Could not open output file: %s\n", filename);
|
||
return (-1);
|
||
}
|
||
|
||
- actual = acpi_os_write_file(file, table, 1, table_length);
|
||
+ actual = fwrite(table, 1, table_length, file);
|
||
if (actual != table_length) {
|
||
- acpi_log_error("Error writing binary output file: %s\n",
|
||
- filename);
|
||
- acpi_os_close_file(file);
|
||
+ fprintf(stderr, "Error writing binary output file: %s\n",
|
||
+ filename);
|
||
+ fclose(file);
|
||
return (-1);
|
||
}
|
||
|
||
- acpi_os_close_file(file);
|
||
+ fclose(file);
|
||
return (0);
|
||
}
|
||
|
||
@@ -211,14 +210,13 @@ struct acpi_table_header *ap_get_table_from_file(char *pathname,
|
||
struct acpi_table_header *buffer = NULL;
|
||
ACPI_FILE file;
|
||
u32 file_size;
|
||
- size_t actual;
|
||
+ acpi_size actual;
|
||
|
||
/* Must use binary mode */
|
||
|
||
- file =
|
||
- acpi_os_open_file(pathname, ACPI_FILE_READING | ACPI_FILE_BINARY);
|
||
+ file = fopen(pathname, "rb");
|
||
if (!file) {
|
||
- acpi_log_error("Could not open input file: %s\n", pathname);
|
||
+ fprintf(stderr, "Could not open input file: %s\n", pathname);
|
||
return (NULL);
|
||
}
|
||
|
||
@@ -226,7 +224,8 @@ struct acpi_table_header *ap_get_table_from_file(char *pathname,
|
||
|
||
file_size = cm_get_file_size(file);
|
||
if (file_size == ACPI_UINT32_MAX) {
|
||
- acpi_log_error("Could not get input file size: %s\n", pathname);
|
||
+ fprintf(stderr,
|
||
+ "Could not get input file size: %s\n", pathname);
|
||
goto cleanup;
|
||
}
|
||
|
||
@@ -234,16 +233,17 @@ struct acpi_table_header *ap_get_table_from_file(char *pathname,
|
||
|
||
buffer = ACPI_ALLOCATE_ZEROED(file_size);
|
||
if (!buffer) {
|
||
- acpi_log_error("Could not allocate file buffer of size: %u\n",
|
||
- file_size);
|
||
+ fprintf(stderr,
|
||
+ "Could not allocate file buffer of size: %u\n",
|
||
+ file_size);
|
||
goto cleanup;
|
||
}
|
||
|
||
/* Read the entire file */
|
||
|
||
- actual = acpi_os_read_file(file, buffer, 1, file_size);
|
||
+ actual = fread(buffer, 1, file_size, file);
|
||
if (actual != file_size) {
|
||
- acpi_log_error("Could not read input file: %s\n", pathname);
|
||
+ fprintf(stderr, "Could not read input file: %s\n", pathname);
|
||
ACPI_FREE(buffer);
|
||
buffer = NULL;
|
||
goto cleanup;
|
||
@@ -252,6 +252,6 @@ struct acpi_table_header *ap_get_table_from_file(char *pathname,
|
||
*out_file_size = file_size;
|
||
|
||
cleanup:
|
||
- acpi_os_close_file(file);
|
||
+ fclose(file);
|
||
return (buffer);
|
||
}
|
||
diff --git a/tools/power/acpi/tools/acpidump/apmain.c b/tools/power/acpi/tools/acpidump/apmain.c
|
||
index 7692e6b..f32968e 100644
|
||
--- a/tools/power/acpi/tools/acpidump/apmain.c
|
||
+++ b/tools/power/acpi/tools/acpidump/apmain.c
|
||
@@ -43,7 +43,6 @@
|
||
|
||
#define _DECLARE_GLOBALS
|
||
#include "acpidump.h"
|
||
-#include "acapps.h"
|
||
|
||
/*
|
||
* acpidump - A portable utility for obtaining system ACPI tables and dumping
|
||
@@ -140,8 +139,8 @@ static int ap_insert_action(char *argument, u32 to_be_done)
|
||
|
||
current_action++;
|
||
if (current_action > AP_MAX_ACTIONS) {
|
||
- acpi_log_error("Too many table options (max %u)\n",
|
||
- AP_MAX_ACTIONS);
|
||
+ fprintf(stderr, "Too many table options (max %u)\n",
|
||
+ AP_MAX_ACTIONS);
|
||
return (-1);
|
||
}
|
||
|
||
@@ -186,9 +185,9 @@ static int ap_do_options(int argc, char **argv)
|
||
} else if (!strcmp(acpi_gbl_optarg, "off")) {
|
||
gbl_dump_customized_tables = FALSE;
|
||
} else {
|
||
- acpi_log_error
|
||
- ("%s: Cannot handle this switch, please use on|off\n",
|
||
- acpi_gbl_optarg);
|
||
+ fprintf(stderr,
|
||
+ "%s: Cannot handle this switch, please use on|off\n",
|
||
+ acpi_gbl_optarg);
|
||
return (-1);
|
||
}
|
||
continue;
|
||
@@ -213,9 +212,9 @@ static int ap_do_options(int argc, char **argv)
|
||
ACPI_MAX64_BYTE_WIDTH,
|
||
&gbl_rsdp_base);
|
||
if (ACPI_FAILURE(status)) {
|
||
- acpi_log_error
|
||
- ("%s: Could not convert to a physical address\n",
|
||
- acpi_gbl_optarg);
|
||
+ fprintf(stderr,
|
||
+ "%s: Could not convert to a physical address\n",
|
||
+ acpi_gbl_optarg);
|
||
return (-1);
|
||
}
|
||
continue;
|
||
@@ -242,7 +241,7 @@ static int ap_do_options(int argc, char **argv)
|
||
case 'z': /* Verbose mode */
|
||
|
||
gbl_verbose_mode = TRUE;
|
||
- acpi_log_error(ACPI_COMMON_SIGNON(AP_UTILITY_NAME));
|
||
+ fprintf(stderr, ACPI_COMMON_SIGNON(AP_UTILITY_NAME));
|
||
continue;
|
||
|
||
/*
|
||
@@ -315,6 +314,7 @@ int ACPI_SYSTEM_XFACE acpi_main(int argc, char *argv[])
|
||
ACPI_DEBUG_INITIALIZE(); /* For debug version only */
|
||
acpi_os_initialize();
|
||
gbl_output_file = ACPI_FILE_OUT;
|
||
+ acpi_gbl_integer_byte_width = 8;
|
||
|
||
/* Process command line options */
|
||
|
||
@@ -353,8 +353,9 @@ int ACPI_SYSTEM_XFACE acpi_main(int argc, char *argv[])
|
||
|
||
default:
|
||
|
||
- acpi_log_error("Internal error, invalid action: 0x%X\n",
|
||
- action->to_be_done);
|
||
+ fprintf(stderr,
|
||
+ "Internal error, invalid action: 0x%X\n",
|
||
+ action->to_be_done);
|
||
return (-1);
|
||
}
|
||
|
||
@@ -369,12 +370,12 @@ int ACPI_SYSTEM_XFACE acpi_main(int argc, char *argv[])
|
||
/* Summary for the output file */
|
||
|
||
file_size = cm_get_file_size(gbl_output_file);
|
||
- acpi_log_error
|
||
- ("Output file %s contains 0x%X (%u) bytes\n\n",
|
||
- gbl_output_filename, file_size, file_size);
|
||
+ fprintf(stderr,
|
||
+ "Output file %s contains 0x%X (%u) bytes\n\n",
|
||
+ gbl_output_filename, file_size, file_size);
|
||
}
|
||
|
||
- acpi_os_close_file(gbl_output_file);
|
||
+ fclose(gbl_output_file);
|
||
}
|
||
|
||
return (status);
|
||
--- kernel-baytrail-4.8.17mamba-x86_64/sound/soc/intel/skylake/skl-sst-utils.c.orig 2017-01-09 08:22:35.000000000 +0100
|
||
+++ kernel-baytrail-4.8.17mamba-x86_64/sound/soc/intel/skylake/skl-sst-utils.c 2017-01-24 19:24:57.688115971 +0100
|
||
@@ -115,13 +115,13 @@
|
||
u32 entries;
|
||
};
|
||
|
||
-int snd_skl_get_module_info(struct skl_sst *ctx, u8 *uuid,
|
||
- struct skl_dfw_module *dfw_config)
|
||
+int snd_skl_get_module_info(struct skl_sst *ctx,
|
||
+ struct skl_module_cfg *mconfig)
|
||
{
|
||
struct uuid_module *module;
|
||
uuid_le *uuid_mod;
|
||
|
||
- uuid_mod = (uuid_le *)uuid;
|
||
+ uuid_mod = (uuid_le *)mconfig->guid;
|
||
|
||
if (list_empty(&ctx->uuid_list)) {
|
||
dev_err(ctx->dev, "Module list is empty\n");
|
||
@@ -130,8 +130,8 @@
|
||
|
||
list_for_each_entry(module, &ctx->uuid_list, list) {
|
||
if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) {
|
||
- dfw_config->module_id = module->id;
|
||
- dfw_config->is_loadable = module->is_loadable;
|
||
+ mconfig->id.module_id = module->id;
|
||
+ mconfig->is_loadable = module->is_loadable;
|
||
|
||
return 0;
|
||
}
|
||
@@ -145,7 +145,8 @@
|
||
* Parse the firmware binary to get the UUID, module id
|
||
* and loadable flags
|
||
*/
|
||
-int snd_skl_parse_uuids(struct sst_dsp *ctx, unsigned int offset)
|
||
+int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw,
|
||
+ unsigned int offset, int index)
|
||
{
|
||
struct adsp_fw_hdr *adsp_hdr;
|
||
struct adsp_module_entry *mod_entry;
|
||
@@ -158,8 +159,8 @@
|
||
unsigned int safe_file;
|
||
|
||
/* Get the FW pointer to derive ADSP header */
|
||
- stripped_fw.data = ctx->fw->data;
|
||
- stripped_fw.size = ctx->fw->size;
|
||
+ stripped_fw.data = fw->data;
|
||
+ stripped_fw.size = fw->size;
|
||
|
||
skl_dsp_strip_extended_manifest(&stripped_fw);
|
||
|
||
@@ -210,7 +211,7 @@
|
||
uuid_bin = (uuid_le *)mod_entry->uuid.id;
|
||
memcpy(&module->uuid, uuid_bin, sizeof(module->uuid));
|
||
|
||
- module->id = i;
|
||
+ module->id = (i | (index << 12));
|
||
module->is_loadable = mod_entry->type.load_type;
|
||
|
||
list_add_tail(&module->list, &skl->uuid_list);
|