Skip to content

Commit

Permalink
Merge tag 'acpi-4.18-rc1' of git://git.kernel.org/pub/scm/linux/kerne…
Browse files Browse the repository at this point in the history
…l/git/rafael/linux-pm

Pull ACPI updates from Rafael Wysocki:
 "These update the ACPICA code in the kernel to the 20180508 upstream
  revision and make it support the RT patch, add CPPC v3 support to the
  ACPI CPPC library, add a WDAT-based watchdog quirk to prevent clashes
  with the RTC, add quirks to the ACPI AC and battery drivers, and
  update the ACPI SoC drivers.

  Specifics:

   - Update the ACPICA code in the kernel to the 20180508 upstream
     revision including:
       * iASL -tc option enhancement (Bob Moore).
       * Debugger improvements (Bob Moore).
       * Support for tables larger than 1 MB in acpidump/acpixtract (Bob
         Moore).
       * Minor fixes and cleanups (Colin Ian King, Toomas Soome).

   - Make the ACPICA code in the kernel support the RT patch (Sebastian
     Andrzej Siewior, Steven Rostedt).

   - Add a kmemleak annotation to the ACPICA code (Larry Finger).

   - Add CPPC v3 support to the ACPI CPPC library and fix two issues
     related to CPPC (Prashanth Prakash, Al Stone).

   - Add an ACPI WDAT-based watchdog quirk to prefer iTCO_wdt on systems
     where WDAT clashes with the RTC SRAM (Mika Westerberg).

   - Add some quirks to the ACPI AC and battery drivers (Carlo Caione,
     Hans de Goede).

   - Update the ACPI SoC drivers for Intel (LPSS) and AMD (APD)
     platforms (Akshu Agrawal, Hans de Goede).

   - Fix up some assorted minor issues (Al Stone, Laszlo Toth, Mathieu
     Malaterre)"

* tag 'acpi-4.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (32 commits)
  ACPICA: Mark acpi_ut_create_internal_object_dbg() memory allocations as non-leaks
  ACPI / watchdog: Prefer iTCO_wdt always when WDAT table uses RTC SRAM
  mailbox: PCC: erroneous error message when parsing ACPI PCCT
  ACPICA: Update version to 20180508
  ACPICA: acpidump/acpixtract: Support for tables larger than 1MB
  ACPI: APD: Add AMD misc clock handler support
  clk: x86: Add ST oscout platform clock
  ACPICA: Update version to 20180427
  ACPICA: Debugger: Removed direct support for EC address space in "Test Objects"
  ACPICA: Debugger: Add Package support for "test objects" command
  ACPICA: Improve error messages for the namespace root node
  ACPICA: Fix potential infinite loop in acpi_rs_dump_byte_list
  ACPICA: vsnprintf: this statement may fall through
  ACPICA: Tables: Fix spelling mistake in comment
  ACPICA: iASL: Enhance the -tc option (create AML hex file in C)
  ACPI: Add missing prototype_for arch_post_acpi_subsys_init()
  ACPI / tables: improve comments regarding acpi_parse_entries_array()
  ACPICA: Convert acpi_gbl_hardware lock back to an acpi_raw_spinlock
  ACPICA: provide abstraction for raw_spinlock_t
  ACPI / CPPC: Fix invalid PCC channel status errors
  ...
  • Loading branch information
torvalds committed Jun 5, 2018
2 parents 3c89adb + 2448d13 commit f4fe74c
Show file tree
Hide file tree
Showing 36 changed files with 751 additions and 194 deletions.
69 changes: 69 additions & 0 deletions Documentation/acpi/cppc_sysfs.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@

Collaborative Processor Performance Control (CPPC)

CPPC defined in the ACPI spec describes a mechanism for the OS to manage the
performance of a logical processor on a contigious and abstract performance
scale. CPPC exposes a set of registers to describe abstract performance scale,
to request performance levels and to measure per-cpu delivered performance.

For more details on CPPC please refer to the ACPI specification at:

http://uefi.org/specifications

Some of the CPPC registers are exposed via sysfs under:

/sys/devices/system/cpu/cpuX/acpi_cppc/

for each cpu X

--------------------------------------------------------------------------------

$ ls -lR /sys/devices/system/cpu/cpu0/acpi_cppc/
/sys/devices/system/cpu/cpu0/acpi_cppc/:
total 0
-r--r--r-- 1 root root 65536 Mar 5 19:38 feedback_ctrs
-r--r--r-- 1 root root 65536 Mar 5 19:38 highest_perf
-r--r--r-- 1 root root 65536 Mar 5 19:38 lowest_freq
-r--r--r-- 1 root root 65536 Mar 5 19:38 lowest_nonlinear_perf
-r--r--r-- 1 root root 65536 Mar 5 19:38 lowest_perf
-r--r--r-- 1 root root 65536 Mar 5 19:38 nominal_freq
-r--r--r-- 1 root root 65536 Mar 5 19:38 nominal_perf
-r--r--r-- 1 root root 65536 Mar 5 19:38 reference_perf
-r--r--r-- 1 root root 65536 Mar 5 19:38 wraparound_time

--------------------------------------------------------------------------------

* highest_perf : Highest performance of this processor (abstract scale).
* nominal_perf : Highest sustained performance of this processor (abstract scale).
* lowest_nonlinear_perf : Lowest performance of this processor with nonlinear
power savings (abstract scale).
* lowest_perf : Lowest performance of this processor (abstract scale).

* lowest_freq : CPU frequency corresponding to lowest_perf (in MHz).
* nominal_freq : CPU frequency corresponding to nominal_perf (in MHz).
The above frequencies should only be used to report processor performance in
freqency instead of abstract scale. These values should not be used for any
functional decisions.

* feedback_ctrs : Includes both Reference and delivered performance counter.
Reference counter ticks up proportional to processor's reference performance.
Delivered counter ticks up proportional to processor's delivered performance.
* wraparound_time: Minimum time for the feedback counters to wraparound (seconds).
* reference_perf : Performance level at which reference performance counter
accumulates (abstract scale).

--------------------------------------------------------------------------------

Computing Average Delivered Performance

Below describes the steps to compute the average performance delivered by taking
two different snapshots of feedback counters at time T1 and T2.

T1: Read feedback_ctrs as fbc_t1
Wait or run some workload
T2: Read feedback_ctrs as fbc_t2

delivered_counter_delta = fbc_t2[del] - fbc_t1[del]
reference_counter_delta = fbc_t2[ref] - fbc_t1[ref]

delivered_perf = (refernce_perf x delivered_counter_delta) / reference_counter_delta
48 changes: 37 additions & 11 deletions drivers/acpi/ac.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ extern void *acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir);


static int ac_sleep_before_get_state_ms;
static int ac_check_pmic = 1;

static struct acpi_driver acpi_ac_driver = {
.name = "ac",
Expand Down Expand Up @@ -293,21 +294,43 @@ static int acpi_ac_battery_notify(struct notifier_block *nb,
return NOTIFY_OK;
}

static int thinkpad_e530_quirk(const struct dmi_system_id *d)
static int __init thinkpad_e530_quirk(const struct dmi_system_id *d)
{
ac_sleep_before_get_state_ms = 1000;
return 0;
}

static const struct dmi_system_id ac_dmi_table[] = {
static int __init ac_do_not_check_pmic_quirk(const struct dmi_system_id *d)
{
ac_check_pmic = 0;
return 0;
}

static const struct dmi_system_id ac_dmi_table[] __initconst = {
{
/* Thinkpad e530 */
.callback = thinkpad_e530_quirk,
.ident = "thinkpad e530",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "32597CG"),
},
},
{
/* ECS EF20EA */
.callback = ac_do_not_check_pmic_quirk,
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"),
},
},
{
/* Lenovo Ideapad Miix 320 */
.callback = ac_do_not_check_pmic_quirk,
.matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "80XF"),
DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"),
},
},
{},
};

Expand Down Expand Up @@ -367,7 +390,6 @@ static int acpi_ac_add(struct acpi_device *device)
kfree(ac);
}

dmi_check_system(ac_dmi_table);
return result;
}

Expand Down Expand Up @@ -425,13 +447,17 @@ static int __init acpi_ac_init(void)
if (acpi_disabled)
return -ENODEV;

for (i = 0; i < ARRAY_SIZE(acpi_ac_blacklist); i++)
if (acpi_dev_present(acpi_ac_blacklist[i].hid, "1",
acpi_ac_blacklist[i].hrv)) {
pr_info(PREFIX "AC: found native %s PMIC, not loading\n",
acpi_ac_blacklist[i].hid);
return -ENODEV;
}
dmi_check_system(ac_dmi_table);

if (ac_check_pmic) {
for (i = 0; i < ARRAY_SIZE(acpi_ac_blacklist); i++)
if (acpi_dev_present(acpi_ac_blacklist[i].hid, "1",
acpi_ac_blacklist[i].hrv)) {
pr_info(PREFIX "AC: found native %s PMIC, not loading\n",
acpi_ac_blacklist[i].hid);
return -ENODEV;
}
}

#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_ac_dir = acpi_lock_ac_dir();
Expand Down
47 changes: 47 additions & 0 deletions drivers/acpi/acpi_apd.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
*/

#include <linux/clk-provider.h>
#include <linux/platform_data/clk-st.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/clkdev.h>
Expand Down Expand Up @@ -72,6 +73,47 @@ static int acpi_apd_setup(struct apd_private_data *pdata)
}

#ifdef CONFIG_X86_AMD_PLATFORM_DEVICE

static int misc_check_res(struct acpi_resource *ares, void *data)
{
struct resource res;

return !acpi_dev_resource_memory(ares, &res);
}

static int st_misc_setup(struct apd_private_data *pdata)
{
struct acpi_device *adev = pdata->adev;
struct platform_device *clkdev;
struct st_clk_data *clk_data;
struct resource_entry *rentry;
struct list_head resource_list;
int ret;

clk_data = devm_kzalloc(&adev->dev, sizeof(*clk_data), GFP_KERNEL);
if (!clk_data)
return -ENOMEM;

INIT_LIST_HEAD(&resource_list);
ret = acpi_dev_get_resources(adev, &resource_list, misc_check_res,
NULL);
if (ret < 0)
return -ENOENT;

list_for_each_entry(rentry, &resource_list, node) {
clk_data->base = devm_ioremap(&adev->dev, rentry->res->start,
resource_size(rentry->res));
break;
}

acpi_dev_free_resource_list(&resource_list);

clkdev = platform_device_register_data(&adev->dev, "clk-st",
PLATFORM_DEVID_NONE, clk_data,
sizeof(*clk_data));
return PTR_ERR_OR_ZERO(clkdev);
}

static const struct apd_device_desc cz_i2c_desc = {
.setup = acpi_apd_setup,
.fixed_clk_rate = 133000000,
Expand All @@ -94,6 +136,10 @@ static const struct apd_device_desc cz_uart_desc = {
.fixed_clk_rate = 48000000,
.properties = uart_properties,
};

static const struct apd_device_desc st_misc_desc = {
.setup = st_misc_setup,
};
#endif

#ifdef CONFIG_ARM64
Expand Down Expand Up @@ -179,6 +225,7 @@ static const struct acpi_device_id acpi_apd_device_ids[] = {
{ "AMD0020", APD_ADDR(cz_uart_desc) },
{ "AMDI0020", APD_ADDR(cz_uart_desc) },
{ "AMD0030", },
{ "AMD0040", APD_ADDR(st_misc_desc)},
#endif
#ifdef CONFIG_ARM64
{ "APMC0D0F", APD_ADDR(xgene_i2c_desc) },
Expand Down
6 changes: 5 additions & 1 deletion drivers/acpi/acpi_lpss.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ ACPI_MODULE_NAME("acpi_lpss");
#define LPSS_SAVE_CTX BIT(4)
#define LPSS_NO_D3_DELAY BIT(5)

/* Crystal Cove PMIC shares same ACPI ID between different platforms */
#define BYT_CRC_HRV 2
#define CHT_CRC_HRV 3

struct lpss_private_data;

struct lpss_device_desc {
Expand Down Expand Up @@ -162,7 +166,7 @@ static void byt_pwm_setup(struct lpss_private_data *pdata)
if (!adev->pnp.unique_id || strcmp(adev->pnp.unique_id, "1"))
return;

if (!acpi_dev_present("INT33FD", NULL, -1))
if (!acpi_dev_present("INT33FD", NULL, BYT_CRC_HRV))
pwm_add_table(byt_pwm_lookup, ARRAY_SIZE(byt_pwm_lookup));
}

Expand Down
72 changes: 45 additions & 27 deletions drivers/acpi/acpi_watchdog.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,51 @@
#define pr_fmt(fmt) "ACPI: watchdog: " fmt

#include <linux/acpi.h>
#include <linux/dmi.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>

#include "internal.h"

static const struct dmi_system_id acpi_watchdog_skip[] = {
{
/*
* On Lenovo Z50-70 there are two issues with the WDAT
* table. First some of the instructions use RTC SRAM
* to store persistent information. This does not work well
* with Linux RTC driver. Second, more important thing is
* that the instructions do not actually reset the system.
*
* On this particular system iTCO_wdt seems to work just
* fine so we prefer that over WDAT for now.
*
* See also https://bugzilla.kernel.org/show_bug.cgi?id=199033.
*/
.ident = "Lenovo Z50-70",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "20354"),
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Z50-70"),
},
},
{}
};
#ifdef CONFIG_RTC_MC146818_LIB
#include <linux/mc146818rtc.h>

/*
* There are several systems where the WDAT table is accessing RTC SRAM to
* store persistent information. This does not work well with the Linux RTC
* driver so on those systems we skip WDAT driver and prefer iTCO_wdt
* instead.
*
* See also https://bugzilla.kernel.org/show_bug.cgi?id=199033.
*/
static bool acpi_watchdog_uses_rtc(const struct acpi_table_wdat *wdat)
{
const struct acpi_wdat_entry *entries;
int i;

entries = (struct acpi_wdat_entry *)(wdat + 1);
for (i = 0; i < wdat->entries; i++) {
const struct acpi_generic_address *gas;

gas = &entries[i].register_region;
if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
switch (gas->address) {
case RTC_PORT(0):
case RTC_PORT(1):
case RTC_PORT(2):
case RTC_PORT(3):
return true;
}
}
}

return false;
}
#else
static bool acpi_watchdog_uses_rtc(const struct acpi_table_wdat *wdat)
{
return false;
}
#endif

static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void)
{
Expand All @@ -50,16 +66,18 @@ static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void)
if (acpi_disabled)
return NULL;

if (dmi_check_system(acpi_watchdog_skip))
return NULL;

status = acpi_get_table(ACPI_SIG_WDAT, 0,
(struct acpi_table_header **)&wdat);
if (ACPI_FAILURE(status)) {
/* It is fine if there is no WDAT */
return NULL;
}

if (acpi_watchdog_uses_rtc(wdat)) {
pr_info("Skipping WDAT on this system because it uses RTC SRAM\n");
return NULL;
}

return wdat;
}

Expand Down
2 changes: 2 additions & 0 deletions drivers/acpi/acpica/acapps.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ acpi_status
fl_split_input_pathname(char *input_path,
char **out_directory_path, char **out_filename);

char *fl_get_file_basename(char *file_pathname);

char *ad_generate_filename(char *prefix, char *table_id);

void
Expand Down
2 changes: 1 addition & 1 deletion drivers/acpi/acpica/acglobal.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ ACPI_GLOBAL(u8, acpi_gbl_global_lock_pending);
* interrupt level
*/
ACPI_GLOBAL(acpi_spinlock, acpi_gbl_gpe_lock); /* For GPE data structs and registers */
ACPI_GLOBAL(acpi_spinlock, acpi_gbl_hardware_lock); /* For ACPI H/W except GPE registers */
ACPI_GLOBAL(acpi_raw_spinlock, acpi_gbl_hardware_lock); /* For ACPI H/W except GPE registers */
ACPI_GLOBAL(acpi_spinlock, acpi_gbl_reference_count_lock);

/* Mutex for _OSI support */
Expand Down
12 changes: 9 additions & 3 deletions drivers/acpi/acpica/dbnames.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,15 @@ void acpi_db_dump_namespace(char *start_arg, char *depth_arg)
}

acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
acpi_os_printf("ACPI Namespace (from %4.4s (%p) subtree):\n",
((struct acpi_namespace_node *)subtree_entry)->name.
ascii, subtree_entry);

if (((struct acpi_namespace_node *)subtree_entry)->parent) {
acpi_os_printf("ACPI Namespace (from %4.4s (%p) subtree):\n",
((struct acpi_namespace_node *)subtree_entry)->
name.ascii, subtree_entry);
} else {
acpi_os_printf("ACPI Namespace (from %s):\n",
ACPI_NAMESPACE_ROOT);
}

/* Display the subtree */

Expand Down
Loading

0 comments on commit f4fe74c

Please sign in to comment.