summaryrefslogtreecommitdiff
path: root/drivers/acpi/osl.c
diff options
context:
space:
mode:
authorSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>2017-10-05 16:24:03 -0700
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2017-10-11 15:38:10 +0200
commiteeb2d80d502af28e5660ff4bbe00f90ceb82c2db (patch)
tree8d485561b5673a70d876008390dce3cc53e4b63a /drivers/acpi/osl.c
parentc2ebf788f927dcca72beead19fab5f5aba79a098 (diff)
ACPI / LPIT: Add Low Power Idle Table (LPIT) support
Add functionality to read LPIT table, which provides: - Sysfs interface to read residency counters via /sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us /sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us Here the count "low_power_idle_cpu_residency_us" shows the time spent by CPU package in low power state. This is read via MSR interface, which points to MSR for PKG C10. Here the count "low_power_idle_system_residency_us" show the count the system was in low power state. This is read via MMIO interface. This is mapped to SLP_S0 residency on modern Intel systems. This residency is achieved only when CPU is in PKG C10 and all functional blocks are in low power state. It is possible that none of the above counters present or anyone of the counter present or all counters present. For example: On my Kabylake system both of the above counters present. After suspend to idle these counts updated and prints: 6916179 6998564 This counter can be read by tools like turbostat to display. Or it can be used to debug, if modern systems are reaching desired low power state. - Provides an interface to read residency counter memory address This address can be used to get the base address of PMC memory mapped IO. This is utilized by intel_pmc_core driver to print more debug information. In addition, to avoid code duplication to read iomem, removed the read of iomem from acpi_os_read_memory() in osl.c and made a common function acpi_os_read_iomem(). This new function is used for reading iomem in in both osl.c and acpi_lpit.c. Link: http://www.uefi.org/sites/default/files/resources/Intel_ACPI_Low_Power_S0_Idle.pdf Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi/osl.c')
-rw-r--r--drivers/acpi/osl.c42
1 files changed, 26 insertions, 16 deletions
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index db78d353bab1..3bb46cb24a99 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -663,6 +663,29 @@ acpi_status acpi_os_write_port(acpi_io_address port, u32 value, u32 width)
EXPORT_SYMBOL(acpi_os_write_port);
+int acpi_os_read_iomem(void __iomem *virt_addr, u64 *value, u32 width)
+{
+
+ switch (width) {
+ case 8:
+ *(u8 *) value = readb(virt_addr);
+ break;
+ case 16:
+ *(u16 *) value = readw(virt_addr);
+ break;
+ case 32:
+ *(u32 *) value = readl(virt_addr);
+ break;
+ case 64:
+ *(u64 *) value = readq(virt_addr);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
acpi_status
acpi_os_read_memory(acpi_physical_address phys_addr, u64 *value, u32 width)
{
@@ -670,6 +693,7 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u64 *value, u32 width)
unsigned int size = width / 8;
bool unmap = false;
u64 dummy;
+ int error;
rcu_read_lock();
virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
@@ -684,22 +708,8 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u64 *value, u32 width)
if (!value)
value = &dummy;
- switch (width) {
- case 8:
- *(u8 *) value = readb(virt_addr);
- break;
- case 16:
- *(u16 *) value = readw(virt_addr);
- break;
- case 32:
- *(u32 *) value = readl(virt_addr);
- break;
- case 64:
- *(u64 *) value = readq(virt_addr);
- break;
- default:
- BUG();
- }
+ error = acpi_os_read_iomem(virt_addr, value, width);
+ BUG_ON(error);
if (unmap)
iounmap(virt_addr);