Merge tag 'v7.1-rc1' into android-mainline
Linux 7.1-rc1 Change-Id: I240ee1560c5b2b848ff0ef91041381ab33c82a88 Signed-off-by: Carlos Llamas <cmllamas@google.com>
This commit is contained in:
commit
2b988bfacb
40 files changed
+706
-357
No files matched your search
@@ -1,28 +0,0 @@
|
||||
ISL12026 I2C RTC/EEPROM
|
||||
|
||||
ISL12026 is an I2C RTC/EEPROM combination device. The RTC and control
|
||||
registers respond at bus address 0x6f, and the EEPROM array responds
|
||||
at bus address 0x57. The canonical "reg" value will be for the RTC portion.
|
||||
|
||||
Required properties supported by the device:
|
||||
|
||||
- "compatible": must be "isil,isl12026"
|
||||
- "reg": I2C bus address of the device (always 0x6f)
|
||||
|
||||
Optional properties:
|
||||
|
||||
- "isil,pwr-bsw": If present PWR.BSW bit must be set to the specified
|
||||
value for proper operation.
|
||||
|
||||
- "isil,pwr-sbib": If present PWR.SBIB bit must be set to the specified
|
||||
value for proper operation.
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
rtc@6f {
|
||||
compatible = "isil,isl12026";
|
||||
reg = <0x6f>;
|
||||
isil,pwr-bsw = <0>;
|
||||
isil,pwr-sbib = <1>;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/rtc/isil,isl12026.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Intersil ISL12026 I2C RTC/EEPROM
|
||||
|
||||
maintainers:
|
||||
- Piyush Patle <piyushpatle228@gmail.com>
|
||||
|
||||
description:
|
||||
The ISL12026 is a combination RTC and EEPROM device connected via I2C.
|
||||
The RTC and control registers respond at address 0x6f, while the EEPROM
|
||||
array responds at address 0x57. The "reg" property refers to the RTC
|
||||
portion of the device.
|
||||
|
||||
allOf:
|
||||
- $ref: rtc.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: isil,isl12026
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
description: I2C address of the RTC portion (must be 0x6f)
|
||||
|
||||
isil,pwr-bsw:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [ 0, 1 ]
|
||||
description:
|
||||
Value written to the PWR.BSW bit for proper device operation.
|
||||
|
||||
isil,pwr-sbib:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [ 0, 1 ]
|
||||
description:
|
||||
Value written to the PWR.SBIB bit for proper device operation.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
rtc@6f {
|
||||
compatible = "isil,isl12026";
|
||||
reg = <0x6f>;
|
||||
isil,pwr-bsw = <0>;
|
||||
isil,pwr-sbib = <1>;
|
||||
};
|
||||
};
|
||||
@@ -47,6 +47,9 @@ properties:
|
||||
- const: rtc
|
||||
- const: rtcref
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
@@ -32,6 +32,8 @@ properties:
|
||||
- 9000
|
||||
- 15000
|
||||
|
||||
vdd-supply: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
OLPC XO-1 RTC
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Required properties:
|
||||
- compatible : "olpc,xo1-rtc"
|
||||
@@ -13,7 +13,12 @@ maintainers:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: sprd,sc2731-rtc
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- sprd,sc2730-rtc
|
||||
- const: sprd,sc2731-rtc
|
||||
- const: sprd,sc2731-rtc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
@@ -65,6 +65,8 @@ properties:
|
||||
- microcrystal,rv3029
|
||||
# Real Time Clock
|
||||
- microcrystal,rv8523
|
||||
# OLPC XO-1 RTC
|
||||
- olpc,xo1-rtc
|
||||
# I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC
|
||||
- ricoh,r2025sd
|
||||
# I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 7
|
||||
PATCHLEVEL = 0
|
||||
PATCHLEVEL = 1
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION =
|
||||
EXTRAVERSION = -rc1
|
||||
NAME = Baby Opossum Posse
|
||||
|
||||
# *DOCUMENTATION*
|
||||
@@ -675,6 +675,8 @@ export RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o \
|
||||
|
||||
# Basic helpers built in scripts/basic/
|
||||
PHONY += scripts_basic
|
||||
scripts_basic: KBUILD_HOSTCFLAGS := $(KBUILD_HOSTCFLAGS)
|
||||
scripts_basic: KBUILD_HOSTLDFLAGS := $(KBUILD_HOSTLDFLAGS)
|
||||
scripts_basic:
|
||||
$(Q)$(MAKE) $(build)=scripts/basic
|
||||
|
||||
|
||||
@@ -247,7 +247,7 @@ static void tpm_dev_release(struct device *dev)
|
||||
kfree(chip->work_space.context_buf);
|
||||
kfree(chip->work_space.session_buf);
|
||||
#ifdef CONFIG_TCG_TPM2_HMAC
|
||||
kfree(chip->auth);
|
||||
kfree_sensitive(chip->auth);
|
||||
#endif
|
||||
kfree(chip);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ static bool disable_pcr_integrity;
|
||||
module_param(disable_pcr_integrity, bool, 0444);
|
||||
MODULE_PARM_DESC(disable_pcr_integrity, "Disable integrity protection of TPM2_PCR_Extend");
|
||||
|
||||
struct tpm2_hash tpm2_hash_map[] = {
|
||||
static const struct tpm2_hash tpm2_hash_map[] = {
|
||||
{HASH_ALGO_SHA1, TPM_ALG_SHA1},
|
||||
{HASH_ALGO_SHA256, TPM_ALG_SHA256},
|
||||
{HASH_ALGO_SHA384, TPM_ALG_SHA384},
|
||||
@@ -295,10 +295,8 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
|
||||
}
|
||||
tpm_buf_append_u16(&buf, num_bytes);
|
||||
err = tpm_buf_fill_hmac_session(chip, &buf);
|
||||
if (err) {
|
||||
tpm_buf_destroy(&buf);
|
||||
return err;
|
||||
}
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = tpm_transmit_cmd(chip, &buf,
|
||||
offsetof(struct tpm2_get_random_out,
|
||||
|
||||
@@ -203,8 +203,10 @@ static int tpm2_read_public(struct tpm_chip *chip, u32 handle, void *name)
|
||||
rc = tpm_buf_read_u16(&buf, &offset);
|
||||
name_size_alg = name_size(&buf.data[offset]);
|
||||
|
||||
if (name_size_alg < 0)
|
||||
if (name_size_alg < 0) {
|
||||
tpm_buf_destroy(&buf);
|
||||
return name_size_alg;
|
||||
}
|
||||
|
||||
if (rc != name_size_alg) {
|
||||
tpm_buf_destroy(&buf);
|
||||
@@ -217,6 +219,7 @@ static int tpm2_read_public(struct tpm_chip *chip, u32 handle, void *name)
|
||||
}
|
||||
|
||||
memcpy(name, &buf.data[offset], rc);
|
||||
tpm_buf_destroy(&buf);
|
||||
return name_size_alg;
|
||||
}
|
||||
#endif /* CONFIG_TCG_TPM2_HMAC */
|
||||
|
||||
+16
-19
@@ -15,6 +15,7 @@
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/rculist.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#ifdef CONFIG_ARM64
|
||||
#include <linux/arm-smccc.h>
|
||||
@@ -602,13 +603,13 @@ static u64 crb_fixup_cmd_size(struct device *dev, struct resource *io_res,
|
||||
return io_res->end - start + 1;
|
||||
}
|
||||
|
||||
static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
|
||||
static int crb_map_io(struct device *dev, struct crb_priv *priv,
|
||||
struct acpi_table_tpm2 *buf)
|
||||
{
|
||||
struct acpi_device *device = ACPI_COMPANION(dev);
|
||||
struct list_head acpi_resource_list;
|
||||
struct resource iores_array[TPM_CRB_MAX_RESOURCES + 1] = { {0} };
|
||||
void __iomem *iobase_array[TPM_CRB_MAX_RESOURCES] = {NULL};
|
||||
struct device *dev = &device->dev;
|
||||
struct resource *iores;
|
||||
void __iomem **iobase_ptr;
|
||||
int i;
|
||||
@@ -782,12 +783,13 @@ static int crb_map_pluton(struct device *dev, struct crb_priv *priv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crb_acpi_add(struct acpi_device *device)
|
||||
static int crb_acpi_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct acpi_device *device = ACPI_COMPANION(dev);
|
||||
struct acpi_table_tpm2 *buf;
|
||||
struct crb_priv *priv;
|
||||
struct tpm_chip *chip;
|
||||
struct device *dev = &device->dev;
|
||||
struct tpm2_crb_smc *crb_smc;
|
||||
struct tpm2_crb_ffa *crb_ffa;
|
||||
struct tpm2_crb_pluton *crb_pluton;
|
||||
@@ -867,7 +869,7 @@ static int crb_acpi_add(struct acpi_device *device)
|
||||
priv->sm = sm;
|
||||
priv->hid = acpi_device_hid(device);
|
||||
|
||||
rc = crb_map_io(device, priv, buf);
|
||||
rc = crb_map_io(dev, priv, buf);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
@@ -901,12 +903,9 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void crb_acpi_remove(struct acpi_device *device)
|
||||
static void crb_acpi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &device->dev;
|
||||
struct tpm_chip *chip = dev_get_drvdata(dev);
|
||||
|
||||
tpm_chip_unregister(chip);
|
||||
tpm_chip_unregister(platform_get_drvdata(pdev));
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops crb_pm = {
|
||||
@@ -919,19 +918,17 @@ static const struct acpi_device_id crb_device_ids[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, crb_device_ids);
|
||||
|
||||
static struct acpi_driver crb_acpi_driver = {
|
||||
.name = "tpm_crb",
|
||||
.ids = crb_device_ids,
|
||||
.ops = {
|
||||
.add = crb_acpi_add,
|
||||
.remove = crb_acpi_remove,
|
||||
},
|
||||
.drv = {
|
||||
static struct platform_driver crb_acpi_driver = {
|
||||
.probe = crb_acpi_probe,
|
||||
.remove = crb_acpi_remove,
|
||||
.driver = {
|
||||
.name = "tpm_crb_acpi",
|
||||
.acpi_match_table = crb_device_ids,
|
||||
.pm = &crb_pm,
|
||||
},
|
||||
};
|
||||
|
||||
module_acpi_driver(crb_acpi_driver);
|
||||
module_platform_driver(crb_acpi_driver);
|
||||
MODULE_AUTHOR("Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>");
|
||||
MODULE_DESCRIPTION("TPM2 Driver");
|
||||
MODULE_VERSION("0.1");
|
||||
|
||||
@@ -31,9 +31,11 @@
|
||||
|
||||
struct priv_data {
|
||||
size_t len;
|
||||
/* This is the amount we read on the first try. 25 was chosen to fit a
|
||||
/*
|
||||
* This is the amount we read on the first try. 25 was chosen to fit a
|
||||
* fair number of read responses in the buffer so a 2nd retry can be
|
||||
* avoided in small message cases. */
|
||||
* avoided in small message cases.
|
||||
*/
|
||||
u8 buffer[sizeof(struct tpm_header) + 25];
|
||||
};
|
||||
|
||||
@@ -58,7 +60,9 @@ static int i2c_atmel_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz,
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
/* The upper layer does not support incomplete sends. */
|
||||
/*
|
||||
* The upper layer does not support incomplete sends.
|
||||
*/
|
||||
if (status != len)
|
||||
return -E2BIG;
|
||||
|
||||
@@ -76,9 +80,11 @@ static int i2c_atmel_recv(struct tpm_chip *chip, u8 *buf, size_t count)
|
||||
if (priv->len == 0)
|
||||
return -EIO;
|
||||
|
||||
/* Get the message size from the message header, if we didn't get the
|
||||
/*
|
||||
* Get the message size from the message header, if we didn't get the
|
||||
* whole message in read_status then we need to re-read the
|
||||
* message. */
|
||||
* message.
|
||||
*/
|
||||
expected_len = be32_to_cpu(hdr->length);
|
||||
if (expected_len > count)
|
||||
return -ENOMEM;
|
||||
@@ -111,15 +117,19 @@ static u8 i2c_atmel_read_status(struct tpm_chip *chip)
|
||||
struct i2c_client *client = to_i2c_client(chip->dev.parent);
|
||||
int rc;
|
||||
|
||||
/* The TPM fails the I2C read until it is ready, so we do the entire
|
||||
/*
|
||||
* The TPM fails the I2C read until it is ready, so we do the entire
|
||||
* transfer here and buffer it locally. This way the common code can
|
||||
* properly handle the timeouts. */
|
||||
* properly handle the timeouts.
|
||||
*/
|
||||
priv->len = 0;
|
||||
memset(priv->buffer, 0, sizeof(priv->buffer));
|
||||
|
||||
|
||||
/* Once the TPM has completed the command the command remains readable
|
||||
* until another command is issued. */
|
||||
/*
|
||||
* Once the TPM has completed the command the command remains readable
|
||||
* until another command is issued.
|
||||
*/
|
||||
rc = i2c_master_recv(client, priv->buffer, sizeof(priv->buffer));
|
||||
dev_dbg(&chip->dev,
|
||||
"%s: sts=%d", __func__, rc);
|
||||
@@ -172,9 +182,11 @@ static int i2c_atmel_probe(struct i2c_client *client)
|
||||
|
||||
dev_set_drvdata(&chip->dev, priv);
|
||||
|
||||
/* There is no known way to probe for this device, and all version
|
||||
/*
|
||||
* There is no known way to probe for this device, and all version
|
||||
* information seems to be read via TPM commands. Thus we rely on the
|
||||
* TPM startup process in the common code to detect the device. */
|
||||
* TPM startup process in the common code to detect the device.
|
||||
*/
|
||||
|
||||
return tpm_chip_register(chip);
|
||||
}
|
||||
|
||||
@@ -471,6 +471,8 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
|
||||
status = tpm_tis_status(chip);
|
||||
if (!itpm && (status & TPM_STS_DATA_EXPECT) == 0) {
|
||||
rc = -EIO;
|
||||
dev_err(&chip->dev, "TPM_STS_DATA_EXPECT should be set. sts = 0x%08x\n",
|
||||
status);
|
||||
goto out_err;
|
||||
}
|
||||
}
|
||||
@@ -491,6 +493,8 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
|
||||
status = tpm_tis_status(chip);
|
||||
if (!itpm && (status & TPM_STS_DATA_EXPECT) != 0) {
|
||||
rc = -EIO;
|
||||
dev_err(&chip->dev, "TPM_STS_DATA_EXPECT should be unset. sts = 0x%08x\n",
|
||||
status);
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
@@ -552,11 +556,16 @@ static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len)
|
||||
break;
|
||||
else if (rc != -EAGAIN && rc != -EIO)
|
||||
/* Data transfer failed, not recoverable */
|
||||
return rc;
|
||||
goto out_err;
|
||||
|
||||
usleep_range(priv->timeout_min, priv->timeout_max);
|
||||
}
|
||||
|
||||
if (rc == -EAGAIN || rc == -EIO) {
|
||||
dev_err(&chip->dev, "Exhausted %d tpm_tis_send_data retries\n", TPM_RETRY);
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
/* go and do it */
|
||||
rc = tpm_tis_write8(priv, TPM_STS(priv->locality), TPM_STS_GO);
|
||||
if (rc < 0)
|
||||
|
||||
@@ -160,6 +160,13 @@ raspberrypi_clk_variants[RPI_FIRMWARE_NUM_CLK_ID] = {
|
||||
[RPI_FIRMWARE_VEC_CLK_ID] = {
|
||||
.export = true,
|
||||
.minimize = true,
|
||||
|
||||
/*
|
||||
* If this clock is disabled during boot, it causes a bus
|
||||
* lockup in RPi 3B. Therefore, make sure it's left enabled
|
||||
* during boot.
|
||||
*/
|
||||
.flags = CLK_IGNORE_UNUSED,
|
||||
},
|
||||
[RPI_FIRMWARE_DISP_CLK_ID] = {
|
||||
.export = true,
|
||||
|
||||
+1
-1
@@ -1986,7 +1986,7 @@ config RTC_DRV_XGENE
|
||||
|
||||
config RTC_DRV_PIC32
|
||||
tristate "Microchip PIC32 RTC"
|
||||
depends on MACH_PIC32
|
||||
depends on MACH_PIC32 || COMPILE_TEST
|
||||
default y
|
||||
help
|
||||
If you say yes here you get support for the PIC32 RTC module.
|
||||
|
||||
+10
-1
@@ -195,7 +195,16 @@ static __poll_t rtc_dev_poll(struct file *file, poll_table *wait)
|
||||
|
||||
poll_wait(file, &rtc->irq_queue, wait);
|
||||
|
||||
data = rtc->irq_data;
|
||||
/*
|
||||
* This read can race with the write in rtc_handle_legacy_irq().
|
||||
*
|
||||
* - If this check misses a zero to non-zero transition the next check
|
||||
* will pick it up (rtc_handle_legacy_irq() wakes up rtc->irq_queue).
|
||||
* - Non-zero to non-zero transition misses do not change return value.
|
||||
* - And a non-zero to zero transition is unlikely to be missed, since
|
||||
* it occurs on rtc_dev_read(), during which polling is not expected.
|
||||
*/
|
||||
data = data_race(rtc->irq_data);
|
||||
|
||||
return (data != 0) ? (EPOLLIN | EPOLLRDNORM) : 0;
|
||||
}
|
||||
|
||||
@@ -772,8 +772,7 @@ static int abx80x_probe(struct i2c_client *client)
|
||||
struct abx80x_priv *priv;
|
||||
int i, data, err, trickle_cfg = -EINVAL;
|
||||
char buf[7];
|
||||
const struct i2c_device_id *id = i2c_match_id(abx80x_id, client);
|
||||
unsigned int part = id->driver_data;
|
||||
unsigned int part = (uintptr_t)i2c_get_match_data(client);
|
||||
unsigned int partnumber;
|
||||
unsigned int majrev, minrev;
|
||||
unsigned int lot;
|
||||
@@ -933,6 +932,8 @@ static int abx80x_probe(struct i2c_client *client)
|
||||
client->irq = 0;
|
||||
}
|
||||
}
|
||||
if (client->irq <= 0)
|
||||
clear_bit(RTC_FEATURE_ALARM, priv->rtc->features);
|
||||
|
||||
err = rtc_add_group(priv->rtc, &rtc_calib_attr_group);
|
||||
if (err) {
|
||||
|
||||
@@ -72,8 +72,8 @@ struct armada38x_rtc {
|
||||
spinlock_t lock;
|
||||
int irq;
|
||||
bool initialized;
|
||||
struct value_to_freq *val_to_freq;
|
||||
const struct armada38x_rtc_data *data;
|
||||
struct value_to_freq val_to_freq[];
|
||||
};
|
||||
|
||||
#define ALARM1 0
|
||||
@@ -490,18 +490,13 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct armada38x_rtc *rtc;
|
||||
|
||||
rtc = devm_kzalloc(&pdev->dev, sizeof(struct armada38x_rtc),
|
||||
rtc = devm_kzalloc(&pdev->dev, struct_size(rtc, val_to_freq, SAMPLE_NR),
|
||||
GFP_KERNEL);
|
||||
if (!rtc)
|
||||
return -ENOMEM;
|
||||
|
||||
rtc->data = of_device_get_match_data(&pdev->dev);
|
||||
|
||||
rtc->val_to_freq = devm_kcalloc(&pdev->dev, SAMPLE_NR,
|
||||
sizeof(struct value_to_freq), GFP_KERNEL);
|
||||
if (!rtc->val_to_freq)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&rtc->lock);
|
||||
|
||||
rtc->regs = devm_platform_ioremap_resource_byname(pdev, "rtc");
|
||||
|
||||
+11
-2
@@ -1429,9 +1429,18 @@ static int __init cmos_platform_probe(struct platform_device *pdev)
|
||||
resource = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
||||
else
|
||||
resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
irq = platform_get_irq_optional(pdev, 0);
|
||||
if (irq < 0) {
|
||||
irq = -1;
|
||||
#ifdef CONFIG_X86
|
||||
/*
|
||||
* On some x86 systems, the IRQ is not defined, but it should
|
||||
* always be safe to hardcode it on systems with a legacy PIC.
|
||||
*/
|
||||
if (nr_legacy_irqs())
|
||||
irq = RTC_IRQ;
|
||||
#endif
|
||||
}
|
||||
|
||||
return cmos_do_probe(&pdev->dev, resource, irq);
|
||||
}
|
||||
|
||||
@@ -924,13 +924,7 @@ static int m41t80_probe(struct i2c_client *client)
|
||||
return -ENOMEM;
|
||||
|
||||
m41t80_data->client = client;
|
||||
if (client->dev.of_node) {
|
||||
m41t80_data->features = (unsigned long)
|
||||
of_device_get_match_data(&client->dev);
|
||||
} else {
|
||||
const struct i2c_device_id *id = i2c_match_id(m41t80_id, client);
|
||||
m41t80_data->features = id->driver_data;
|
||||
}
|
||||
m41t80_data->features = (unsigned long)i2c_get_match_data(client);
|
||||
i2c_set_clientdata(client, m41t80_data);
|
||||
|
||||
m41t80_data->rtc = devm_rtc_allocate_device(&client->dev);
|
||||
|
||||
@@ -686,6 +686,11 @@ static int max77686_rtc_init_reg(struct max77686_rtc_info *info)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void max77686_rtc_release_dev(void *client)
|
||||
{
|
||||
i2c_unregister_device(client);
|
||||
}
|
||||
|
||||
static int max77686_init_rtc_regmap(struct max77686_rtc_info *info)
|
||||
{
|
||||
struct device *parent = info->dev->parent;
|
||||
@@ -713,12 +718,17 @@ static int max77686_init_rtc_regmap(struct max77686_rtc_info *info)
|
||||
goto add_rtc_irq;
|
||||
}
|
||||
|
||||
client = devm_i2c_new_dummy_device(info->dev, parent_i2c->adapter,
|
||||
info->drv_data->rtc_i2c_addr);
|
||||
client = i2c_new_ancillary_device(parent_i2c, "rtc",
|
||||
info->drv_data->rtc_i2c_addr);
|
||||
if (IS_ERR(client))
|
||||
return dev_err_probe(info->dev, PTR_ERR(client),
|
||||
"Failed to allocate I2C device for RTC\n");
|
||||
|
||||
ret = devm_add_action_or_reset(info->dev, max77686_rtc_release_dev,
|
||||
client);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
info->rtc_regmap = devm_regmap_init_i2c(client,
|
||||
info->drv_data->regmap_config);
|
||||
if (IS_ERR(info->rtc_regmap))
|
||||
|
||||
@@ -110,7 +110,7 @@ static int ntxec_rtc_probe(struct platform_device *pdev)
|
||||
struct rtc_device *dev;
|
||||
struct ntxec_rtc *rtc;
|
||||
|
||||
pdev->dev.of_node = pdev->dev.parent->of_node;
|
||||
device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent);
|
||||
|
||||
rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
|
||||
if (!rtc)
|
||||
|
||||
@@ -1449,10 +1449,10 @@ static const struct regmap_bus pcf2127_i2c_regmap = {
|
||||
static struct i2c_driver pcf2127_i2c_driver;
|
||||
|
||||
static const struct i2c_device_id pcf2127_i2c_id[] = {
|
||||
{ "pcf2127", PCF2127 },
|
||||
{ "pcf2129", PCF2129 },
|
||||
{ "pca2129", PCF2129 },
|
||||
{ "pcf2131", PCF2131 },
|
||||
{ "pcf2127", (kernel_ulong_t)&pcf21xx_cfg[PCF2127] },
|
||||
{ "pcf2129", (kernel_ulong_t)&pcf21xx_cfg[PCF2129] },
|
||||
{ "pca2129", (kernel_ulong_t)&pcf21xx_cfg[PCF2129] },
|
||||
{ "pcf2131", (kernel_ulong_t)&pcf21xx_cfg[PCF2131] },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, pcf2127_i2c_id);
|
||||
@@ -1469,18 +1469,9 @@ static int pcf2127_i2c_probe(struct i2c_client *client)
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
|
||||
return -ENODEV;
|
||||
|
||||
if (client->dev.of_node) {
|
||||
variant = of_device_get_match_data(&client->dev);
|
||||
if (!variant)
|
||||
return -ENODEV;
|
||||
} else {
|
||||
enum pcf21xx_type type =
|
||||
i2c_match_id(pcf2127_i2c_id, client)->driver_data;
|
||||
|
||||
if (type >= PCF21XX_LAST_ID)
|
||||
return -ENODEV;
|
||||
variant = &pcf21xx_cfg[type];
|
||||
}
|
||||
variant = i2c_get_match_data(client);
|
||||
if (!variant)
|
||||
return -ENODEV;
|
||||
|
||||
config.max_register = variant->max_register,
|
||||
|
||||
|
||||
@@ -825,12 +825,7 @@ static int rs5c372_probe(struct i2c_client *client)
|
||||
|
||||
rs5c372->client = client;
|
||||
i2c_set_clientdata(client, rs5c372);
|
||||
if (client->dev.of_node) {
|
||||
rs5c372->type = (uintptr_t)of_device_get_match_data(&client->dev);
|
||||
} else {
|
||||
const struct i2c_device_id *id = i2c_match_id(rs5c372_id, client);
|
||||
rs5c372->type = id->driver_data;
|
||||
}
|
||||
rs5c372->type = (uintptr_t)i2c_get_match_data(client);
|
||||
|
||||
/* we read registers 0x0f then 0x00-0x0f; skip the first one */
|
||||
rs5c372->regs = &rs5c372->buf[1];
|
||||
|
||||
@@ -667,13 +667,7 @@ static int rv8803_probe(struct i2c_client *client)
|
||||
|
||||
mutex_init(&rv8803->flags_lock);
|
||||
rv8803->client = client;
|
||||
if (client->dev.of_node) {
|
||||
rv8803->type = (uintptr_t)of_device_get_match_data(&client->dev);
|
||||
} else {
|
||||
const struct i2c_device_id *id = i2c_match_id(rv8803_id, client);
|
||||
|
||||
rv8803->type = id->driver_data;
|
||||
}
|
||||
rv8803->type = (uintptr_t)i2c_get_match_data(client);
|
||||
i2c_set_clientdata(client, rv8803);
|
||||
|
||||
flags = rv8803_read_reg(client, RV8803_FLAG);
|
||||
|
||||
@@ -522,7 +522,6 @@ static const struct attribute_group rx8025_attr_group = {
|
||||
|
||||
static int rx8025_probe(struct i2c_client *client)
|
||||
{
|
||||
const struct i2c_device_id *id = i2c_match_id(rx8025_id, client);
|
||||
struct i2c_adapter *adapter = client->adapter;
|
||||
struct rx8025_data *rx8025;
|
||||
int err = 0;
|
||||
@@ -540,8 +539,7 @@ static int rx8025_probe(struct i2c_client *client)
|
||||
|
||||
i2c_set_clientdata(client, rx8025);
|
||||
|
||||
if (id)
|
||||
rx8025->model = id->driver_data;
|
||||
rx8025->model = (uintptr_t)i2c_get_match_data(client);
|
||||
|
||||
err = rx8025_init_client(client);
|
||||
if (err)
|
||||
|
||||
@@ -640,10 +640,18 @@ static int __maybe_unused ti_k3_rtc_suspend(struct device *dev)
|
||||
static int __maybe_unused ti_k3_rtc_resume(struct device *dev)
|
||||
{
|
||||
struct ti_k3_rtc *priv = dev_get_drvdata(dev);
|
||||
int ret = 0;
|
||||
|
||||
if (k3rtc_check_unlocked(priv)) {
|
||||
/* RTC locked implies low power mode exit where RTC loses context */
|
||||
ret = k3rtc_configure(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (device_may_wakeup(dev))
|
||||
disable_irq_wake(priv->irq);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(ti_k3_rtc_pm_ops, ti_k3_rtc_suspend, ti_k3_rtc_resume);
|
||||
|
||||
@@ -654,7 +654,7 @@ static void radeon_fixup_panel_info(struct radeonfb_info *rinfo)
|
||||
{
|
||||
#ifdef CONFIG_PPC
|
||||
/*
|
||||
* LCD Flat panels should use fixed dividers, we enfore that on
|
||||
* LCD Flat panels should use fixed dividers, we enforce that on
|
||||
* PPC only for now...
|
||||
*/
|
||||
if (!rinfo->panel_info.use_bios_dividers && rinfo->mon1_type == MT_LCD
|
||||
|
||||
@@ -216,12 +216,9 @@ static int clps711x_fb_probe(struct platform_device *pdev)
|
||||
cfb = info->par;
|
||||
platform_set_drvdata(pdev, info);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
goto out_fb_release;
|
||||
cfb->base = devm_ioremap(dev, res->start, resource_size(res));
|
||||
if (!cfb->base) {
|
||||
ret = -ENOMEM;
|
||||
cfb->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||
if (IS_ERR(cfb->base)) {
|
||||
ret = PTR_ERR(cfb->base);
|
||||
goto out_fb_release;
|
||||
}
|
||||
|
||||
|
||||
@@ -295,19 +295,13 @@ static int cobalt_lcdfb_probe(struct platform_device *dev)
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(dev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
info->screen_base = devm_platform_get_and_ioremap_resource(dev, 0, &res);
|
||||
if (IS_ERR(info->screen_base)) {
|
||||
framebuffer_release(info);
|
||||
return -EBUSY;
|
||||
return PTR_ERR(info->screen_base);
|
||||
}
|
||||
|
||||
info->screen_size = resource_size(res);
|
||||
info->screen_base = devm_ioremap(&dev->dev, res->start,
|
||||
info->screen_size);
|
||||
if (!info->screen_base) {
|
||||
framebuffer_release(info);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
info->fbops = &cobalt_lcd_fbops;
|
||||
info->fix = cobalt_lcdfb_fix;
|
||||
|
||||
@@ -276,7 +276,7 @@ static void hga_blank(int blank_mode)
|
||||
spin_unlock_irqrestore(&hga_reg_lock, flags);
|
||||
}
|
||||
|
||||
static int hga_card_detect(void)
|
||||
static int hga_card_detect(struct platform_device *pdev)
|
||||
{
|
||||
int count = 0;
|
||||
void __iomem *p, *q;
|
||||
@@ -284,6 +284,11 @@ static int hga_card_detect(void)
|
||||
|
||||
hga_vram_len = 0x08000;
|
||||
|
||||
if (!devm_request_mem_region(&pdev->dev, 0xb0000, hga_vram_len, "hgafb")) {
|
||||
dev_err(&pdev->dev, "cannot reserve video memory at 0xb0000\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
hga_vram = ioremap(0xb0000, hga_vram_len);
|
||||
if (!hga_vram)
|
||||
return -ENOMEM;
|
||||
@@ -568,7 +573,7 @@ static int hgafb_probe(struct platform_device *pdev)
|
||||
struct fb_info *info;
|
||||
int ret;
|
||||
|
||||
ret = hga_card_detect();
|
||||
ret = hga_card_detect(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
||||
@@ -640,8 +640,13 @@ static void offb_init_nodriver(struct platform_device *parent, struct device_nod
|
||||
vid = be32_to_cpup(vidp);
|
||||
did = be32_to_cpup(didp);
|
||||
pdev = pci_get_device(vid, did, NULL);
|
||||
if (!pdev || pci_enable_device(pdev))
|
||||
if (!pdev)
|
||||
return;
|
||||
|
||||
if (pci_enable_device(pdev)) {
|
||||
pci_dev_put(pdev);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* kludge for valkyrie */
|
||||
|
||||
@@ -2322,6 +2322,8 @@ static int savagefb_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
||||
failed:
|
||||
#ifdef CONFIG_FB_SAVAGE_I2C
|
||||
savagefb_delete_i2c_busses(info);
|
||||
fb_destroy_modelist(&info->modelist);
|
||||
fb_destroy_modedb(info->monspecs.modedb);
|
||||
#endif
|
||||
fb_alloc_cmap(&info->cmap, 0, 0);
|
||||
savage_unmap_video(info);
|
||||
|
||||
@@ -9,7 +9,11 @@
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/pci-tsm.h>
|
||||
|
||||
static struct class *tsm_class;
|
||||
static void tsm_release(struct device *);
|
||||
static const struct class tsm_class = {
|
||||
.name = "tsm",
|
||||
.dev_release = tsm_release
|
||||
};
|
||||
static DEFINE_IDA(tsm_ida);
|
||||
|
||||
static int match_id(struct device *dev, const void *data)
|
||||
@@ -22,7 +26,7 @@ static int match_id(struct device *dev, const void *data)
|
||||
|
||||
struct tsm_dev *find_tsm_dev(int id)
|
||||
{
|
||||
struct device *dev = class_find_device(tsm_class, NULL, &id, match_id);
|
||||
struct device *dev = class_find_device(&tsm_class, NULL, &id, match_id);
|
||||
|
||||
if (!dev)
|
||||
return NULL;
|
||||
@@ -46,7 +50,7 @@ static struct tsm_dev *alloc_tsm_dev(struct device *parent)
|
||||
tsm_dev->id = id;
|
||||
dev = &tsm_dev->dev;
|
||||
dev->parent = parent;
|
||||
dev->class = tsm_class;
|
||||
dev->class = &tsm_class;
|
||||
device_initialize(dev);
|
||||
|
||||
return no_free_ptr(tsm_dev);
|
||||
@@ -114,18 +118,13 @@ static void tsm_release(struct device *dev)
|
||||
|
||||
static int __init tsm_init(void)
|
||||
{
|
||||
tsm_class = class_create("tsm");
|
||||
if (IS_ERR(tsm_class))
|
||||
return PTR_ERR(tsm_class);
|
||||
|
||||
tsm_class->dev_release = tsm_release;
|
||||
return 0;
|
||||
return class_register(&tsm_class);
|
||||
}
|
||||
module_init(tsm_init)
|
||||
|
||||
static void __exit tsm_exit(void)
|
||||
{
|
||||
class_destroy(tsm_class);
|
||||
class_unregister(&tsm_class);
|
||||
}
|
||||
module_exit(tsm_exit)
|
||||
|
||||
|
||||
@@ -131,11 +131,16 @@ struct tcg_algorithm_info {
|
||||
};
|
||||
|
||||
#ifndef TPM_MEMREMAP
|
||||
#define TPM_MEMREMAP(start, size) NULL
|
||||
static inline void *TPM_MEMREMAP(unsigned long start, size_t size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef TPM_MEMUNMAP
|
||||
#define TPM_MEMUNMAP(start, size) do{} while(0)
|
||||
static inline void TPM_MEMUNMAP(void *mapping, size_t size)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -139,7 +139,13 @@ install_kernel_headers () {
|
||||
pdir=debian/$1
|
||||
version=${1#linux-headers-}
|
||||
|
||||
CC="${DEB_HOST_GNU_TYPE}-gcc" "${srctree}/scripts/package/install-extmod-build" "${pdir}/usr/src/linux-headers-${version}"
|
||||
# Override $CC only for cross-compiles, to not unnecessarily rebuild
|
||||
# scripts/ including plugins, which may lead to a full kernel rebuild.
|
||||
if [ -n "${CROSS_COMPILE}" ]; then
|
||||
CC="${DEB_HOST_GNU_TYPE}-gcc" "${srctree}/scripts/package/install-extmod-build" "${pdir}/usr/src/linux-headers-${version}"
|
||||
else
|
||||
"${srctree}/scripts/package/install-extmod-build" "${pdir}/usr/src/linux-headers-${version}"
|
||||
fi
|
||||
|
||||
mkdir -p $pdir/lib/modules/$version/
|
||||
ln -s /usr/src/linux-headers-$version $pdir/lib/modules/$version/build
|
||||
|
||||
@@ -191,6 +191,7 @@ struct msr_counter bic[] = {
|
||||
{ 0x0, "Any%C0", NULL, 0, 0, 0, NULL, 0 },
|
||||
{ 0x0, "GFX%C0", NULL, 0, 0, 0, NULL, 0 },
|
||||
{ 0x0, "CPUGFX%", NULL, 0, 0, 0, NULL, 0 },
|
||||
{ 0x0, "Module", NULL, 0, 0, 0, NULL, 0 },
|
||||
{ 0x0, "Core", NULL, 0, 0, 0, NULL, 0 },
|
||||
{ 0x0, "CPU", NULL, 0, 0, 0, NULL, 0 },
|
||||
{ 0x0, "APIC", NULL, 0, 0, 0, NULL, 0 },
|
||||
@@ -264,6 +265,7 @@ enum bic_names {
|
||||
BIC_Any_c0,
|
||||
BIC_GFX_c0,
|
||||
BIC_CPUGFX,
|
||||
BIC_Module,
|
||||
BIC_Core,
|
||||
BIC_CPU,
|
||||
BIC_APIC,
|
||||
@@ -364,6 +366,7 @@ static void bic_groups_init(void)
|
||||
SET_BIC(BIC_Node, &bic_group_topology);
|
||||
SET_BIC(BIC_CoreCnt, &bic_group_topology);
|
||||
SET_BIC(BIC_PkgCnt, &bic_group_topology);
|
||||
SET_BIC(BIC_Module, &bic_group_topology);
|
||||
SET_BIC(BIC_Core, &bic_group_topology);
|
||||
SET_BIC(BIC_CPU, &bic_group_topology);
|
||||
SET_BIC(BIC_Die, &bic_group_topology);
|
||||
@@ -2383,6 +2386,7 @@ struct platform_counters {
|
||||
struct cpu_topology {
|
||||
int cpu_id;
|
||||
int core_id; /* unique within a package */
|
||||
int module_id;
|
||||
int package_id;
|
||||
int die_id;
|
||||
int l3_id;
|
||||
@@ -2404,6 +2408,8 @@ struct topo_params {
|
||||
int allowed_cores;
|
||||
int max_cpu_num;
|
||||
int max_core_id; /* within a package */
|
||||
int min_module_id; /* system wide */
|
||||
int max_module_id; /* system wide */
|
||||
int max_package_id;
|
||||
int max_die_id;
|
||||
int max_l3_id;
|
||||
@@ -2427,11 +2433,17 @@ char *sys_lpi_file_debugfs = "/sys/kernel/debug/pmc_core/slp_s0_residency_usec";
|
||||
|
||||
int cpu_is_not_present(int cpu)
|
||||
{
|
||||
if (cpu < 0)
|
||||
return 1;
|
||||
|
||||
return !CPU_ISSET_S(cpu, cpu_present_setsize, cpu_present_set);
|
||||
}
|
||||
|
||||
int cpu_is_not_allowed(int cpu)
|
||||
{
|
||||
if (cpu < 0)
|
||||
return 1;
|
||||
|
||||
return !CPU_ISSET_S(cpu, cpu_allowed_setsize, cpu_allowed_set);
|
||||
}
|
||||
|
||||
@@ -2443,6 +2455,22 @@ int cpu_is_not_allowed(int cpu)
|
||||
|
||||
#define PER_THREAD_PARAMS struct thread_data *t, struct core_data *c, struct pkg_data *p
|
||||
|
||||
int has_allowed_lower_ht_sibling(int cpu)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i <= cpus[cpu].ht_id; ++i) {
|
||||
int sibling_cpu_id = cpus[cpu].ht_sibling_cpu_id[i];
|
||||
|
||||
if (sibling_cpu_id == cpu)
|
||||
return 0;
|
||||
|
||||
if (!cpu_is_not_allowed(sibling_cpu_id))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int for_all_cpus(int (func) (struct thread_data *, struct core_data *, struct pkg_data *),
|
||||
struct thread_data *thread_base, struct core_data *core_base, struct pkg_data *pkg_base)
|
||||
{
|
||||
@@ -2460,7 +2488,7 @@ int for_all_cpus(int (func) (struct thread_data *, struct core_data *, struct pk
|
||||
if (cpu_is_not_allowed(cpu))
|
||||
continue;
|
||||
|
||||
if (cpus[cpu].ht_id > 0) /* skip HT sibling */
|
||||
if (has_allowed_lower_ht_sibling(cpu)) /* skip HT sibling */
|
||||
continue;
|
||||
|
||||
t = &thread_base[cpu];
|
||||
@@ -2469,13 +2497,22 @@ int for_all_cpus(int (func) (struct thread_data *, struct core_data *, struct pk
|
||||
|
||||
retval |= func(t, c, p);
|
||||
|
||||
/* Handle HT sibling now */
|
||||
/* Handle other HT siblings now */
|
||||
int i;
|
||||
|
||||
for (i = MAX_HT_ID; i > 0; --i) { /* ht_id 0 is self */
|
||||
if (cpus[cpu].ht_sibling_cpu_id[i] <= 0)
|
||||
for (i = 0; i <= MAX_HT_ID; ++i) {
|
||||
int sibling_cpu_id = cpus[cpu].ht_sibling_cpu_id[i];
|
||||
|
||||
if (sibling_cpu_id < 0)
|
||||
break;
|
||||
|
||||
if (sibling_cpu_id == cpu)
|
||||
continue;
|
||||
t = &thread_base[cpus[cpu].ht_sibling_cpu_id[i]];
|
||||
|
||||
if (cpu_is_not_allowed(sibling_cpu_id))
|
||||
continue;
|
||||
|
||||
t = &thread_base[sibling_cpu_id];
|
||||
|
||||
retval |= func(t, c, p);
|
||||
}
|
||||
@@ -2835,31 +2872,38 @@ void bic_lookup(cpu_set_t *ret_set, char *name_list, enum show_hide_mode mode)
|
||||
static inline int print_name(int width, int *printed, char *delim, char *name, enum counter_type type, enum counter_format format)
|
||||
{
|
||||
UNUSED(type);
|
||||
char *sep = (*printed)++ ? delim : "";
|
||||
|
||||
if (format == FORMAT_RAW && width >= 64)
|
||||
return (sprintf(outp, "%s%-8s", ((*printed)++ ? delim : ""), name));
|
||||
return sprintf(outp, "%s%-8s", sep, name);
|
||||
else
|
||||
return (sprintf(outp, "%s%s", ((*printed)++ ? delim : ""), name));
|
||||
return sprintf(outp, "%s%s", sep, name);
|
||||
}
|
||||
|
||||
static inline int print_hex_value(int width, int *printed, char *delim, unsigned long long value)
|
||||
{
|
||||
char *sep = (*printed)++ ? delim : "";
|
||||
|
||||
if (width <= 32)
|
||||
return (sprintf(outp, "%s%08x", ((*printed)++ ? delim : ""), (unsigned int)value));
|
||||
return sprintf(outp, "%s%08llx", sep, value);
|
||||
else
|
||||
return (sprintf(outp, "%s%016llx", ((*printed)++ ? delim : ""), value));
|
||||
return sprintf(outp, "%s%016llx", sep, value);
|
||||
}
|
||||
|
||||
static inline int print_decimal_value(int width, int *printed, char *delim, unsigned long long value)
|
||||
{
|
||||
char *sep = (*printed)++ ? delim : "";
|
||||
|
||||
UNUSED(width);
|
||||
|
||||
return (sprintf(outp, "%s%lld", ((*printed)++ ? delim : ""), value));
|
||||
return sprintf(outp, "%s%lld", sep, value);
|
||||
}
|
||||
|
||||
static inline int print_float_value(int *printed, char *delim, double value)
|
||||
{
|
||||
return (sprintf(outp, "%s%0.2f", ((*printed)++ ? delim : ""), value));
|
||||
char *sep = (*printed)++ ? delim : "";
|
||||
|
||||
return sprintf(outp, "%s%0.2f", sep, value);
|
||||
}
|
||||
|
||||
void print_header(char *delim)
|
||||
@@ -2881,6 +2925,8 @@ void print_header(char *delim)
|
||||
outp += sprintf(outp, "%sL3", (printed++ ? delim : ""));
|
||||
if (DO_BIC(BIC_Node))
|
||||
outp += sprintf(outp, "%sNode", (printed++ ? delim : ""));
|
||||
if (DO_BIC(BIC_Module))
|
||||
outp += sprintf(outp, "%sModule", (printed++ ? delim : ""));
|
||||
if (DO_BIC(BIC_Core))
|
||||
outp += sprintf(outp, "%sCore", (printed++ ? delim : ""));
|
||||
if (DO_BIC(BIC_CPU))
|
||||
@@ -3176,7 +3222,7 @@ int dump_counters(PER_THREAD_PARAMS)
|
||||
}
|
||||
|
||||
if (c && is_cpu_first_thread_in_core(t, c)) {
|
||||
outp += sprintf(outp, "core: %d\n", cpus[t->cpu_id].core_id);
|
||||
outp += sprintf(outp, "core: 0x%x\n", cpus[t->cpu_id].core_id);
|
||||
outp += sprintf(outp, "c3: %016llX\n", c->c3);
|
||||
outp += sprintf(outp, "c6: %016llX\n", c->c6);
|
||||
outp += sprintf(outp, "c7: %016llX\n", c->c7);
|
||||
@@ -3350,6 +3396,8 @@ int format_counters(PER_THREAD_PARAMS)
|
||||
outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
|
||||
if (DO_BIC(BIC_Node))
|
||||
outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
|
||||
if (DO_BIC(BIC_Module))
|
||||
outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
|
||||
if (DO_BIC(BIC_Core))
|
||||
outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
|
||||
if (DO_BIC(BIC_CPU))
|
||||
@@ -3383,18 +3431,24 @@ int format_counters(PER_THREAD_PARAMS)
|
||||
else
|
||||
outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
|
||||
}
|
||||
if (DO_BIC(BIC_Module)) {
|
||||
if (c)
|
||||
outp += sprintf(outp, "%s0x%x", (printed++ ? delim : ""), cpus[t->cpu_id].module_id);
|
||||
else
|
||||
outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
|
||||
}
|
||||
if (DO_BIC(BIC_Core)) {
|
||||
if (c)
|
||||
outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), cpus[t->cpu_id].core_id);
|
||||
outp += sprintf(outp, "%s0x%x", (printed++ ? delim : ""), cpus[t->cpu_id].core_id);
|
||||
else
|
||||
outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
|
||||
}
|
||||
if (DO_BIC(BIC_CPU))
|
||||
outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->cpu_id);
|
||||
if (DO_BIC(BIC_APIC))
|
||||
outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->apic_id);
|
||||
outp += sprintf(outp, "%s0x%x", (printed++ ? delim : ""), t->apic_id);
|
||||
if (DO_BIC(BIC_X2APIC))
|
||||
outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->x2apic_id);
|
||||
outp += sprintf(outp, "%s0x%x", (printed++ ? delim : ""), t->x2apic_id);
|
||||
}
|
||||
|
||||
if (DO_BIC(BIC_Avg_MHz))
|
||||
@@ -5155,7 +5209,7 @@ static inline int get_rapl_num_domains(void)
|
||||
if (!platform->has_per_core_rapl)
|
||||
return topo.num_packages;
|
||||
|
||||
return topo.num_cores;
|
||||
return GLOBAL_CORE_ID(topo.max_core_id, topo.num_packages) + 1;
|
||||
}
|
||||
|
||||
static inline int get_rapl_domain_id(int cpu)
|
||||
@@ -6041,6 +6095,11 @@ int get_l3_id(int cpu)
|
||||
return parse_int_file("/sys/devices/system/cpu/cpu%d/cache/index3/id", cpu);
|
||||
}
|
||||
|
||||
int get_module_id(int cpu)
|
||||
{
|
||||
return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/cluster_id", cpu);
|
||||
}
|
||||
|
||||
int get_core_id(int cpu)
|
||||
{
|
||||
return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_id", cpu);
|
||||
@@ -6160,59 +6219,6 @@ static int parse_cpu_str(char *cpu_str, cpu_set_t *cpu_set, int cpu_set_size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_thread_siblings(struct cpu_topology *thiscpu)
|
||||
{
|
||||
char path[80], character;
|
||||
FILE *filep;
|
||||
unsigned long map;
|
||||
int so, shift, sib_core;
|
||||
int cpu = thiscpu->cpu_id;
|
||||
int offset = topo.max_cpu_num + 1;
|
||||
size_t size;
|
||||
int thread_id = 0;
|
||||
|
||||
thiscpu->put_ids = CPU_ALLOC((topo.max_cpu_num + 1));
|
||||
if (thiscpu->ht_id < 0)
|
||||
thiscpu->ht_id = thread_id++;
|
||||
if (!thiscpu->put_ids)
|
||||
return -1;
|
||||
|
||||
size = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
|
||||
CPU_ZERO_S(size, thiscpu->put_ids);
|
||||
|
||||
sprintf(path, "/sys/devices/system/cpu/cpu%d/topology/thread_siblings", cpu);
|
||||
filep = fopen(path, "r");
|
||||
|
||||
if (!filep) {
|
||||
warnx("%s: open failed", path);
|
||||
return -1;
|
||||
}
|
||||
do {
|
||||
offset -= BITMASK_SIZE;
|
||||
if (fscanf(filep, "%lx%c", &map, &character) != 2)
|
||||
err(1, "%s: failed to parse file", path);
|
||||
for (shift = 0; shift < BITMASK_SIZE; shift++) {
|
||||
if ((map >> shift) & 0x1) {
|
||||
so = shift + offset;
|
||||
sib_core = get_core_id(so);
|
||||
if (sib_core == thiscpu->core_id) {
|
||||
CPU_SET_S(so, size, thiscpu->put_ids);
|
||||
if ((so != cpu) && (cpus[so].ht_id < 0)) {
|
||||
cpus[so].ht_id = thread_id;
|
||||
cpus[cpu].ht_sibling_cpu_id[thread_id] = so;
|
||||
if (debug)
|
||||
fprintf(stderr, "%s: cpu%d.ht_sibling_cpu_id[%d] = %d\n", __func__, cpu, thread_id, so);
|
||||
thread_id += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (character == ',');
|
||||
fclose(filep);
|
||||
|
||||
return CPU_COUNT_S(size, thiscpu->put_ids);
|
||||
}
|
||||
|
||||
/*
|
||||
* run func(thread, core, package) in topology order
|
||||
* skip non-present cpus
|
||||
@@ -6236,7 +6242,7 @@ int for_all_cpus_2(int (func) (struct thread_data *, struct core_data *,
|
||||
if (cpu_is_not_allowed(cpu))
|
||||
continue;
|
||||
|
||||
if (cpus[cpu].ht_id > 0) /* skip HT sibling */
|
||||
if (has_allowed_lower_ht_sibling(cpu)) /* skip HT sibling */
|
||||
continue;
|
||||
|
||||
t = &thread_base[cpu];
|
||||
@@ -6251,11 +6257,20 @@ int for_all_cpus_2(int (func) (struct thread_data *, struct core_data *,
|
||||
/* Handle HT sibling now */
|
||||
int i;
|
||||
|
||||
for (i = MAX_HT_ID; i > 0; --i) { /* ht_id 0 is self */
|
||||
if (cpus[cpu].ht_sibling_cpu_id[i] <= 0)
|
||||
for (i = 0; i <= MAX_HT_ID; ++i) {
|
||||
int sibling_cpu_id = cpus[cpu].ht_sibling_cpu_id[i];
|
||||
|
||||
if (sibling_cpu_id < 0)
|
||||
break;
|
||||
|
||||
if (sibling_cpu_id == cpu)
|
||||
continue;
|
||||
t = &thread_base[cpus[cpu].ht_sibling_cpu_id[i]];
|
||||
t2 = &thread_base2[cpus[cpu].ht_sibling_cpu_id[i]];
|
||||
|
||||
if (cpu_is_not_allowed(sibling_cpu_id))
|
||||
continue;
|
||||
|
||||
t = &thread_base[sibling_cpu_id];
|
||||
t2 = &thread_base2[sibling_cpu_id];
|
||||
|
||||
retval |= func(t, c, p, t2, c2, p2);
|
||||
}
|
||||
@@ -9475,6 +9490,37 @@ int dir_filter(const struct dirent *dirp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_thread_siblings(struct cpu_topology *thiscpu)
|
||||
{
|
||||
char path[80];
|
||||
int cpu = thiscpu->cpu_id;
|
||||
size_t size;
|
||||
int ht_id = 0;
|
||||
int i;
|
||||
|
||||
thiscpu->put_ids = CPU_ALLOC((topo.max_cpu_num + 1));
|
||||
if (thiscpu->ht_id < 0)
|
||||
thiscpu->ht_id = 0; /* first CPU in core */
|
||||
if (!thiscpu->put_ids)
|
||||
return -1;
|
||||
|
||||
size = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
|
||||
CPU_ZERO_S(size, thiscpu->put_ids);
|
||||
|
||||
sprintf(path, "/sys/devices/system/cpu/cpu%d/topology", cpu);
|
||||
|
||||
initialize_cpu_set_from_sysfs(thiscpu->put_ids, path, "thread_siblings_list");
|
||||
|
||||
for (i = 0; i <= topo.max_cpu_num; ++i)
|
||||
if (CPU_ISSET_S(i, size, thiscpu->put_ids)) {
|
||||
cpus[i].ht_id = ht_id;
|
||||
cpus[cpu].ht_sibling_cpu_id[ht_id] = i;
|
||||
ht_id += 1;
|
||||
}
|
||||
|
||||
return (ht_id - 1);
|
||||
}
|
||||
|
||||
void topology_probe(bool startup)
|
||||
{
|
||||
int i;
|
||||
@@ -9505,6 +9551,8 @@ void topology_probe(bool startup)
|
||||
cpu_present_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
|
||||
CPU_ZERO_S(cpu_present_setsize, cpu_present_set);
|
||||
for_all_proc_cpus(mark_cpu_present);
|
||||
if (debug)
|
||||
print_cpu_set("present set", cpu_present_set);
|
||||
|
||||
/*
|
||||
* Allocate and initialize cpu_possible_set
|
||||
@@ -9515,6 +9563,8 @@ void topology_probe(bool startup)
|
||||
cpu_possible_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
|
||||
CPU_ZERO_S(cpu_possible_setsize, cpu_possible_set);
|
||||
initialize_cpu_set_from_sysfs(cpu_possible_set, "/sys/devices/system/cpu", "possible");
|
||||
if (debug)
|
||||
print_cpu_set("possible set", cpu_possible_set);
|
||||
|
||||
/*
|
||||
* Allocate and initialize cpu_effective_set
|
||||
@@ -9525,6 +9575,8 @@ void topology_probe(bool startup)
|
||||
cpu_effective_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1));
|
||||
CPU_ZERO_S(cpu_effective_setsize, cpu_effective_set);
|
||||
update_effective_set(startup);
|
||||
if (debug)
|
||||
print_cpu_set("effective set", cpu_effective_set);
|
||||
|
||||
/*
|
||||
* Allocate and initialize cpu_allowed_set
|
||||
@@ -9568,6 +9620,8 @@ void topology_probe(bool startup)
|
||||
|
||||
CPU_SET_S(i, cpu_allowed_setsize, cpu_allowed_set);
|
||||
}
|
||||
if (debug)
|
||||
print_cpu_set("allowed set", cpu_allowed_set);
|
||||
|
||||
if (!CPU_COUNT_S(cpu_allowed_setsize, cpu_allowed_set))
|
||||
err(-ENODEV, "No valid cpus found");
|
||||
@@ -9590,6 +9644,7 @@ void topology_probe(bool startup)
|
||||
* For online cpus
|
||||
* find max_core_id, max_package_id, num_cores (per system)
|
||||
*/
|
||||
topo.min_module_id = 0x7FFFFFFF;
|
||||
for (i = 0; i <= topo.max_cpu_num; ++i) {
|
||||
int siblings;
|
||||
|
||||
@@ -9621,6 +9676,13 @@ void topology_probe(bool startup)
|
||||
if (cpus[i].physical_node_id > topo.max_node_num)
|
||||
topo.max_node_num = cpus[i].physical_node_id;
|
||||
|
||||
/* get module information */
|
||||
cpus[i].module_id = get_module_id(i);
|
||||
if (cpus[i].module_id > topo.max_module_id)
|
||||
topo.max_module_id = cpus[i].module_id;
|
||||
if (cpus[i].module_id < topo.min_module_id)
|
||||
topo.min_module_id = cpus[i].module_id;
|
||||
|
||||
/* get core information */
|
||||
cpus[i].core_id = get_core_id(i);
|
||||
if (cpus[i].core_id > max_core_id)
|
||||
@@ -9642,6 +9704,11 @@ void topology_probe(bool startup)
|
||||
if (!summary_only)
|
||||
BIC_PRESENT(BIC_Core);
|
||||
|
||||
if (debug > 1)
|
||||
fprintf(outf, "min_module_id %d max_module_id %d\n", topo.min_module_id, topo.max_module_id);
|
||||
if (!summary_only && (topo.min_module_id != topo.max_module_id))
|
||||
BIC_PRESENT(BIC_Module);
|
||||
|
||||
topo.num_die = topo.max_die_id + 1;
|
||||
if (debug > 1)
|
||||
fprintf(outf, "max_die_id %d, sizing for %d die\n", topo.max_die_id, topo.num_die);
|
||||
@@ -9671,12 +9738,18 @@ void topology_probe(bool startup)
|
||||
return;
|
||||
|
||||
for (i = 0; i <= topo.max_cpu_num; ++i) {
|
||||
int ht_id;
|
||||
|
||||
if (cpu_is_not_present(i))
|
||||
continue;
|
||||
fprintf(outf,
|
||||
"cpu %d pkg %d die %d l3 %d node %d lnode %d core %d thread %d\n",
|
||||
"cpu %d pkg %d die %d l3 %d node %d lnode %d module 0x%x core %d ht_id %d",
|
||||
i, cpus[i].package_id, cpus[i].die_id, cpus[i].l3_id,
|
||||
cpus[i].physical_node_id, cpus[i].logical_node_id, cpus[i].core_id, cpus[i].ht_id);
|
||||
cpus[i].physical_node_id, cpus[i].logical_node_id, cpus[i].module_id, cpus[i].core_id, cpus[i].ht_id);
|
||||
fprintf(outf, " siblings");
|
||||
for (ht_id = 0; ht_id <= MAX_HT_ID; ++ht_id)
|
||||
fprintf(outf, " %d", cpus[i].ht_sibling_cpu_id[ht_id]);
|
||||
fprintf(outf, "\n");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9817,6 +9890,8 @@ void topology_update(void)
|
||||
topo.allowed_cores = 0;
|
||||
topo.allowed_packages = 0;
|
||||
for_all_cpus(update_topo, ODD_COUNTERS);
|
||||
if (debug)
|
||||
fprintf(stderr, "allowed_cpus %d allowed_cores %d allowed_packages %d\n", topo.allowed_cpus, topo.allowed_cores, topo.allowed_packages);
|
||||
}
|
||||
|
||||
void setup_all_buffers(bool startup)
|
||||
@@ -10533,7 +10608,7 @@ int get_and_dump_counters(void)
|
||||
|
||||
void print_version()
|
||||
{
|
||||
fprintf(outf, "turbostat version 2026.02.14 - Len Brown <lenb@kernel.org>\n");
|
||||
fprintf(outf, "turbostat version 2026.04.21 - Len Brown <lenb@kernel.org>\n");
|
||||
}
|
||||
|
||||
#define COMMAND_LINE_SIZE 2048
|
||||
@@ -11449,7 +11524,7 @@ void cmdline(int argc, char **argv)
|
||||
}
|
||||
optind = 0;
|
||||
|
||||
while ((opt = getopt_long_only(argc, argv, "+C:c:Dde:hi:Jn:N:o:qMST:v", long_options, &option_index)) != -1) {
|
||||
while ((opt = getopt_long_only(argc, argv, "+C:c:Dde:hi:Jn:N:o:qMPST:v", long_options, &option_index)) != -1) {
|
||||
switch (opt) {
|
||||
case 'a':
|
||||
parse_add_command(optarg);
|
||||
|
||||
@@ -15,6 +15,8 @@ x86_energy_perf_policy \- Manage Energy vs. Performance Policy
|
||||
.br
|
||||
.RB "other: (\-\-force | \-\-hwp-enable | \-\-turbo-enable) value)"
|
||||
.br
|
||||
.RB "soc-slider: --soc-slider-balance # | --soc-slider-offset # | --platform-profile <name>"
|
||||
.br
|
||||
.RB "value: # | default | performance | balance-performance | balance-power | power"
|
||||
.SH DESCRIPTION
|
||||
\fBx86_energy_perf_policy\fP
|
||||
@@ -154,6 +156,26 @@ level on this processor, specified in multiples of 100 MHz.
|
||||
in the sliding window that HWP uses to maintain average frequency.
|
||||
This parameter is meaningful only when the "desired" field above is non-zero.
|
||||
Default is 0, allowing the HW to choose.
|
||||
.SH SOC SLIDER OPTIONS
|
||||
.PP
|
||||
Note that the Platform Profile Name must be "SoC Slider", and the
|
||||
Platform Profile must be "balanced" for the --soc-slider-balance
|
||||
and --soc-slider-offset options to take effect.
|
||||
.PP
|
||||
\fB--soc-slider-balance #\fP write numeric value to the SoC Slider.
|
||||
Values range from 0 to 6.
|
||||
Lower values result in higher performance,
|
||||
and higher values improve energy efficiency.
|
||||
Actual values are model specific.
|
||||
.PP
|
||||
\fB--soc-slider-offset #\fP write the numeric value to the Soc Slider Offset.
|
||||
The slider offset is the maximum value that software allows the SoC to
|
||||
autonomously add to the SoC Slider to improve energy efficiency.
|
||||
The value 0 prohibits the SoC from autonomously changing the slider.
|
||||
.PP
|
||||
\fB--platform-profile <name>"\fP set the platform profile to <name>.
|
||||
Available choices are in platform-profile-0/choices. The Soc Slider
|
||||
driver currently supports "low-power", "balanced", and "performance".
|
||||
.SH OTHER OPTIONS
|
||||
.PP
|
||||
\fB-f, --force\fP writes the specified values without bounds checking.
|
||||
@@ -208,6 +230,10 @@ runs only as root.
|
||||
EPB: /sys/devices/system/cpu/cpu*/power/energy_perf_bias
|
||||
EPP: /sys/devices/system/cpu/cpu*/cpufreq/energy_performance_preference
|
||||
MSR: /dev/cpu/*/msr
|
||||
Platform Profile Name: /sys/class/platform-profile/platform-profile-0/name
|
||||
Platform Profile: /sys/class/platform-profile/platform-profile-0/profile
|
||||
SOC Slider Balanced: /sys/module/processor_thermal_soc_slider/parameters/slider_balance
|
||||
SOC Slider Balanced Offset: /sys/module/processor_thermal_soc_slider/parameters/slider_offset
|
||||
.fi
|
||||
.SH "SEE ALSO"
|
||||
.nf
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* policy preference bias on recent X86 processors.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2010 - 2025 Intel Corporation.
|
||||
* Copyright (c) 2010 - 2026 Intel Corporation.
|
||||
* Len Brown <len.brown@intel.com>
|
||||
*/
|
||||
|
||||
@@ -82,21 +82,36 @@ size_t cpu_setsize;
|
||||
|
||||
char *proc_stat = "/proc/stat";
|
||||
|
||||
unsigned int has_epb; /* MSR_IA32_ENERGY_PERF_BIAS */
|
||||
unsigned int has_hwp; /* IA32_PM_ENABLE, IA32_HWP_CAPABILITIES */
|
||||
unsigned int has_epb; /* MSR_IA32_ENERGY_PERF_BIAS */
|
||||
unsigned int has_hwp; /* IA32_PM_ENABLE, IA32_HWP_CAPABILITIES */
|
||||
/* IA32_HWP_REQUEST, IA32_HWP_STATUS */
|
||||
unsigned int has_hwp_notify; /* IA32_HWP_INTERRUPT */
|
||||
unsigned int has_hwp_notify; /* IA32_HWP_INTERRUPT */
|
||||
unsigned int has_hwp_activity_window; /* IA32_HWP_REQUEST[bits 41:32] */
|
||||
unsigned int has_hwp_epp; /* IA32_HWP_REQUEST[bits 31:24] */
|
||||
unsigned int has_hwp_request_pkg; /* IA32_HWP_REQUEST_PKG */
|
||||
|
||||
unsigned int bdx_highest_ratio;
|
||||
|
||||
unsigned char update_soc_slider_balance;
|
||||
unsigned char update_soc_slider_offset;
|
||||
unsigned char update_platform_profile;
|
||||
int soc_slider_balance;
|
||||
int soc_slider_offset;
|
||||
char platform_profile[64];
|
||||
|
||||
#define PATH_TO_CPU "/sys/devices/system/cpu/"
|
||||
#define SYSFS_PATH_MAX 255
|
||||
#define PATH_SOC_SLIDER_BALANCE "/sys/module/processor_thermal_soc_slider/parameters/slider_balance"
|
||||
#define PATH_SOC_SLIDER_OFFSET "/sys/module/processor_thermal_soc_slider/parameters/slider_offset"
|
||||
#define PATH_PLATFORM_PROFILE "/sys/class/platform-profile/platform-profile-0/profile"
|
||||
#define PATH_PLATFORM_PROFILE_NAME "/sys/class/platform-profile/platform-profile-0/name"
|
||||
#define POWER_SLIDER_NAME "SoC Power Slider"
|
||||
|
||||
static int use_android_msr_path;
|
||||
|
||||
static unsigned int read_sysfs(const char *, char *, size_t);
|
||||
static int sysfs_read_string(const char *, char *, size_t);
|
||||
|
||||
/*
|
||||
* maintain compatibility with original implementation, but don't document it:
|
||||
*/
|
||||
@@ -106,8 +121,8 @@ void usage(void)
|
||||
fprintf(stderr, "scope: --cpu cpu-list [--hwp-use-pkg #] | --pkg pkg-list\n");
|
||||
fprintf(stderr, "field: --all | --epb | --hwp-epp | --hwp-min | --hwp-max | --hwp-desired\n");
|
||||
fprintf(stderr, "other: --hwp-enable | --turbo-enable (0 | 1) | --help | --force\n");
|
||||
fprintf(stderr,
|
||||
"value: ( # | \"normal\" | \"performance\" | \"balance-performance\" | \"balance-power\"| \"power\")\n");
|
||||
fprintf(stderr, "soc-slider: --soc-slider-balance # | --soc-slider-offset # | --platform-profile <name>\n");
|
||||
fprintf(stderr, "value: ( # | \"normal\" | \"performance\" | \"balance-performance\" | \"balance-power\"| \"power\")\n");
|
||||
fprintf(stderr, "--hwp-window usec\n");
|
||||
|
||||
fprintf(stderr, "Specify only Energy Performance BIAS (legacy usage):\n");
|
||||
@@ -135,6 +150,7 @@ int ratio_2_msr_perf(int ratio)
|
||||
|
||||
return msr_perf;
|
||||
}
|
||||
|
||||
int msr_perf_2_ratio(int msr_perf)
|
||||
{
|
||||
int ratio;
|
||||
@@ -143,8 +159,8 @@ int msr_perf_2_ratio(int msr_perf)
|
||||
if (!bdx_highest_ratio)
|
||||
return msr_perf;
|
||||
|
||||
d = (double)msr_perf * (double) bdx_highest_ratio / 255.0;
|
||||
d = d + 0.5; /* round */
|
||||
d = (double)msr_perf * (double)bdx_highest_ratio / 255.0;
|
||||
d = d + 0.5; /* round */
|
||||
ratio = (int)d;
|
||||
|
||||
if (debug)
|
||||
@@ -152,6 +168,7 @@ int msr_perf_2_ratio(int msr_perf)
|
||||
|
||||
return ratio;
|
||||
}
|
||||
|
||||
int parse_cmdline_epb(int i)
|
||||
{
|
||||
if (!has_epb)
|
||||
@@ -198,6 +215,7 @@ int parse_cmdline_hwp_min(int i)
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* "power" changes hwp_max to cap.lowest
|
||||
* All others leave it at cap.highest
|
||||
@@ -217,6 +235,7 @@ int parse_cmdline_hwp_max(int i)
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* for --hwp-des, all strings leave it in autonomous mode
|
||||
* If you want to change it, you need to explicitly pick a value
|
||||
@@ -254,7 +273,7 @@ int parse_cmdline_hwp_window(int i)
|
||||
fprintf(stderr, "--hwp-window: 0 for auto; 1 - 1270000000 usec for window duration\n");
|
||||
usage();
|
||||
}
|
||||
for (exponent = 0; ; ++exponent) {
|
||||
for (exponent = 0;; ++exponent) {
|
||||
if (debug)
|
||||
printf("%d 10^%d\n", i, exponent);
|
||||
|
||||
@@ -268,6 +287,7 @@ int parse_cmdline_hwp_window(int i)
|
||||
|
||||
return (exponent << 7) | i;
|
||||
}
|
||||
|
||||
int parse_cmdline_hwp_epp(int i)
|
||||
{
|
||||
update_hwp_epp = 1;
|
||||
@@ -289,6 +309,7 @@ int parse_cmdline_hwp_epp(int i)
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
int parse_cmdline_turbo(int i)
|
||||
{
|
||||
update_turbo = 1;
|
||||
@@ -508,7 +529,7 @@ void parse_cmdline_pkg(char *s)
|
||||
}
|
||||
}
|
||||
|
||||
void for_packages(unsigned long long pkg_set, int (func)(int))
|
||||
void for_packages(unsigned long long pkg_set, int (func) (int))
|
||||
{
|
||||
int pkg_num;
|
||||
|
||||
@@ -518,9 +539,79 @@ void for_packages(unsigned long long pkg_set, int (func)(int))
|
||||
}
|
||||
}
|
||||
|
||||
static int parse_cmdline_int(const char *s, int *out)
|
||||
{
|
||||
char *endp;
|
||||
long val;
|
||||
|
||||
val = strtol(s, &endp, 0);
|
||||
if (endp == s || errno == ERANGE)
|
||||
return -1;
|
||||
if (*endp != '\0')
|
||||
return -1;
|
||||
if (val < INT_MIN || val > INT_MAX)
|
||||
return -1;
|
||||
|
||||
*out = (int)val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void print_version(void)
|
||||
{
|
||||
printf("x86_energy_perf_policy 2025.11.22 Len Brown <lenb@kernel.org>\n");
|
||||
printf("x86_energy_perf_policy 2026.04.25 Len Brown <lenb@kernel.org>\n");
|
||||
}
|
||||
|
||||
static int platform_profile_access(int mode)
|
||||
{
|
||||
if (access(PATH_PLATFORM_PROFILE, mode)) {
|
||||
if (debug)
|
||||
fprintf(stderr, "Can not access %s\n", PATH_PLATFORM_PROFILE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int platform_profile_name_is(char *name)
|
||||
{
|
||||
char buf[64];
|
||||
|
||||
if (sysfs_read_string(PATH_PLATFORM_PROFILE_NAME, buf, sizeof(buf)) != 0) {
|
||||
if (debug)
|
||||
fprintf(stderr, "Can not read %s\n", PATH_PLATFORM_PROFILE_NAME);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strncmp(buf, name, 16)) {
|
||||
if (debug)
|
||||
fprintf(stderr, "%s does not match '%s'\n", PATH_PLATFORM_PROFILE_NAME, name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int soc_slider_access(int mode)
|
||||
{
|
||||
if (!platform_profile_access(R_OK))
|
||||
return 0;
|
||||
|
||||
if (!platform_profile_name_is(POWER_SLIDER_NAME))
|
||||
return 0;
|
||||
|
||||
if (access(PATH_SOC_SLIDER_BALANCE, mode)) {
|
||||
if (debug)
|
||||
fprintf(stderr, "Can not access %s\n", PATH_SOC_SLIDER_BALANCE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (access(PATH_SOC_SLIDER_OFFSET, mode)) {
|
||||
if (debug)
|
||||
fprintf(stderr, "Can not access %s\n", PATH_SOC_SLIDER_OFFSET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void cmdline(int argc, char **argv)
|
||||
@@ -529,30 +620,32 @@ void cmdline(int argc, char **argv)
|
||||
int option_index = 0;
|
||||
|
||||
static struct option long_options[] = {
|
||||
{"all", required_argument, 0, 'a'},
|
||||
{"cpu", required_argument, 0, 'c'},
|
||||
{"pkg", required_argument, 0, 'p'},
|
||||
{"debug", no_argument, 0, 'd'},
|
||||
{"hwp-desired", required_argument, 0, 'D'},
|
||||
{"epb", required_argument, 0, 'B'},
|
||||
{"force", no_argument, 0, 'f'},
|
||||
{"hwp-enable", no_argument, 0, 'e'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"hwp-epp", required_argument, 0, 'P'},
|
||||
{"hwp-min", required_argument, 0, 'm'},
|
||||
{"hwp-max", required_argument, 0, 'M'},
|
||||
{"read", no_argument, 0, 'r'},
|
||||
{"turbo-enable", required_argument, 0, 't'},
|
||||
{"hwp-use-pkg", required_argument, 0, 'u'},
|
||||
{"version", no_argument, 0, 'v'},
|
||||
{"hwp-window", required_argument, 0, 'w'},
|
||||
{0, 0, 0, 0 }
|
||||
{ "all", required_argument, 0, 'a' },
|
||||
{ "cpu", required_argument, 0, 'c' },
|
||||
{ "pkg", required_argument, 0, 'p' },
|
||||
{ "debug", no_argument, 0, 'd' },
|
||||
{ "hwp-desired", required_argument, 0, 'D' },
|
||||
{ "epb", required_argument, 0, 'B' },
|
||||
{ "force", no_argument, 0, 'f' },
|
||||
{ "hwp-enable", no_argument, 0, 'e' },
|
||||
{ "help", no_argument, 0, 'h' },
|
||||
{ "hwp-epp", required_argument, 0, 'P' },
|
||||
{ "hwp-min", required_argument, 0, 'm' },
|
||||
{ "hwp-max", required_argument, 0, 'M' },
|
||||
{ "read", no_argument, 0, 'r' },
|
||||
{ "turbo-enable", required_argument, 0, 't' },
|
||||
{ "hwp-use-pkg", required_argument, 0, 'u' },
|
||||
{ "version", no_argument, 0, 'v' },
|
||||
{ "hwp-window", required_argument, 0, 'w' },
|
||||
{ "soc-slider-balance", required_argument, 0, 'S' },
|
||||
{ "soc-slider-offset", required_argument, 0, 'O' },
|
||||
{ "platform-profile", required_argument, 0, 'F' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
progname = argv[0];
|
||||
|
||||
while ((opt = getopt_long_only(argc, argv, "+a:c:dD:E:e:f:m:M:rt:u:vw:",
|
||||
long_options, &option_index)) != -1) {
|
||||
while ((opt = getopt_long_only(argc, argv, "+a:c:dD:E:e:f:m:M:rt:u:vw::S:O:F:", long_options, &option_index)) != -1) {
|
||||
switch (opt) {
|
||||
case 'a':
|
||||
parse_cmdline_all(optarg);
|
||||
@@ -579,12 +672,27 @@ void cmdline(int argc, char **argv)
|
||||
case 'D':
|
||||
req_update.hwp_desired = parse_cmdline_hwp_desired(parse_optarg_string(optarg));
|
||||
break;
|
||||
case 'F':
|
||||
if (strlen(optarg) >= sizeof(platform_profile))
|
||||
errx(1, "--platform-profile: value too long");
|
||||
if (!platform_profile_access(W_OK))
|
||||
errx(1, "Can not update platform-profile in '%s'", PATH_PLATFORM_PROFILE);
|
||||
strcpy(platform_profile, optarg);
|
||||
update_platform_profile = 1;
|
||||
break;
|
||||
case 'm':
|
||||
req_update.hwp_min = parse_cmdline_hwp_min(parse_optarg_string(optarg));
|
||||
break;
|
||||
case 'M':
|
||||
req_update.hwp_max = parse_cmdline_hwp_max(parse_optarg_string(optarg));
|
||||
break;
|
||||
case 'O':
|
||||
if (parse_cmdline_int(optarg, &soc_slider_offset))
|
||||
errx(1, "--soc-slider-offset: invalid value");
|
||||
if (!soc_slider_access(W_OK))
|
||||
errx(1, "Unable to write SOC Slider Offset");
|
||||
update_soc_slider_offset = 1;
|
||||
break;
|
||||
case 'p':
|
||||
parse_cmdline_pkg(optarg);
|
||||
break;
|
||||
@@ -594,6 +702,13 @@ void cmdline(int argc, char **argv)
|
||||
case 'r':
|
||||
/* v1 used -r to specify read-only mode, now the default */
|
||||
break;
|
||||
case 'S':
|
||||
if (parse_cmdline_int(optarg, &soc_slider_balance))
|
||||
errx(1, "--soc-slider-balance: invalid value");
|
||||
if (!soc_slider_access(W_OK))
|
||||
errx(1, "Unable to write SOC Slider-Balance in '%s'", PATH_SOC_SLIDER_BALANCE);
|
||||
update_soc_slider_balance = 1;
|
||||
break;
|
||||
case 't':
|
||||
turbo_update_value = parse_cmdline_turbo(parse_optarg_string(optarg));
|
||||
break;
|
||||
@@ -681,8 +796,7 @@ void err_on_hypervisor(void)
|
||||
free(buffer);
|
||||
|
||||
if (hypervisor)
|
||||
err(-1,
|
||||
"not supported on this virtual machine");
|
||||
err(-1, "not supported on this virtual machine");
|
||||
}
|
||||
|
||||
int get_msr(int cpu, int offset, unsigned long long *msr)
|
||||
@@ -694,9 +808,7 @@ int get_msr(int cpu, int offset, unsigned long long *msr)
|
||||
sprintf(pathname, use_android_msr_path ? "/dev/msr%d" : "/dev/cpu/%d/msr", cpu);
|
||||
fd = open(pathname, O_RDONLY);
|
||||
if (fd < 0)
|
||||
err(-1, "%s open failed, try chown or chmod +r %s, or run as root",
|
||||
pathname, use_android_msr_path ? "/dev/msr*" : "/dev/cpu/*/msr");
|
||||
|
||||
err(-1, "%s open failed, try chown or chmod +r %s, or run as root", pathname, use_android_msr_path ? "/dev/msr*" : "/dev/cpu/*/msr");
|
||||
|
||||
retval = pread(fd, msr, sizeof(*msr), offset);
|
||||
if (retval != sizeof(*msr)) {
|
||||
@@ -720,8 +832,7 @@ int put_msr(int cpu, int offset, unsigned long long new_msr)
|
||||
sprintf(pathname, use_android_msr_path ? "/dev/msr%d" : "/dev/cpu/%d/msr", cpu);
|
||||
fd = open(pathname, O_RDWR);
|
||||
if (fd < 0)
|
||||
err(-1, "%s open failed, try chown or chmod +r %s, or run as root",
|
||||
pathname, use_android_msr_path ? "/dev/msr*" : "/dev/cpu/*/msr");
|
||||
err(-1, "%s open failed, try chown or chmod +r %s, or run as root", pathname, use_android_msr_path ? "/dev/msr*" : "/dev/cpu/*/msr");
|
||||
|
||||
retval = pwrite(fd, &new_msr, sizeof(new_msr), offset);
|
||||
if (retval != sizeof(new_msr))
|
||||
@@ -753,7 +864,7 @@ static unsigned int read_sysfs(const char *path, char *buf, size_t buflen)
|
||||
buf[numread] = '\0';
|
||||
close(fd);
|
||||
|
||||
return (unsigned int) numread;
|
||||
return (unsigned int)numread;
|
||||
}
|
||||
|
||||
static unsigned int write_sysfs(const char *path, char *buf, size_t buflen)
|
||||
@@ -767,14 +878,40 @@ static unsigned int write_sysfs(const char *path, char *buf, size_t buflen)
|
||||
|
||||
numwritten = write(fd, buf, buflen - 1);
|
||||
if (numwritten < 1) {
|
||||
perror("write failed\n");
|
||||
buf[strcspn(buf, "\n")] = '\0';
|
||||
warn("Write '%s' to '%s' failed", buf, path);
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
return (unsigned int) numwritten;
|
||||
return (unsigned int)numwritten;
|
||||
}
|
||||
|
||||
static int sysfs_read_string(const char *path, char *buf, size_t buflen)
|
||||
{
|
||||
unsigned int len;
|
||||
size_t n;
|
||||
|
||||
len = read_sysfs(path, buf, buflen);
|
||||
if (!len)
|
||||
return -1;
|
||||
|
||||
n = strcspn(buf, "\n");
|
||||
buf[n] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sysfs_write_string(const char *path, const char *buf)
|
||||
{
|
||||
char tmp[128];
|
||||
int len;
|
||||
|
||||
len = snprintf(tmp, sizeof(tmp), "%s\n", buf);
|
||||
if (len < 0 || len >= (int)sizeof(tmp))
|
||||
return -1;
|
||||
return write_sysfs(path, tmp, (size_t)len + 1) ? 0 : -1;
|
||||
}
|
||||
|
||||
void print_hwp_cap(int cpu, struct msr_hwp_cap *cap, char *str)
|
||||
@@ -782,9 +919,9 @@ void print_hwp_cap(int cpu, struct msr_hwp_cap *cap, char *str)
|
||||
if (cpu != -1)
|
||||
printf("cpu%d: ", cpu);
|
||||
|
||||
printf("HWP_CAP: low %d eff %d guar %d high %d\n",
|
||||
cap->lowest, cap->efficient, cap->guaranteed, cap->highest);
|
||||
printf("HWP_CAP: low %d eff %d guar %d high %d\n", cap->lowest, cap->efficient, cap->guaranteed, cap->highest);
|
||||
}
|
||||
|
||||
void read_hwp_cap(int cpu, struct msr_hwp_cap *cap, unsigned int msr_offset)
|
||||
{
|
||||
unsigned long long msr;
|
||||
@@ -806,9 +943,9 @@ void print_hwp_request(int cpu, struct msr_hwp_request *h, char *str)
|
||||
printf("%s", str);
|
||||
|
||||
printf("HWP_REQ: min %d max %d des %d epp %d window 0x%x (%d*10^%dus) use_pkg %d\n",
|
||||
h->hwp_min, h->hwp_max, h->hwp_desired, h->hwp_epp,
|
||||
h->hwp_window, h->hwp_window & 0x7F, (h->hwp_window >> 7) & 0x7, h->hwp_use_pkg);
|
||||
h->hwp_min, h->hwp_max, h->hwp_desired, h->hwp_epp, h->hwp_window, h->hwp_window & 0x7F, (h->hwp_window >> 7) & 0x7, h->hwp_use_pkg);
|
||||
}
|
||||
|
||||
void print_hwp_request_pkg(int pkg, struct msr_hwp_request *h, char *str)
|
||||
{
|
||||
printf("pkg%d: ", pkg);
|
||||
@@ -817,9 +954,9 @@ void print_hwp_request_pkg(int pkg, struct msr_hwp_request *h, char *str)
|
||||
printf("%s", str);
|
||||
|
||||
printf("HWP_REQ_PKG: min %d max %d des %d epp %d window 0x%x (%d*10^%dus)\n",
|
||||
h->hwp_min, h->hwp_max, h->hwp_desired, h->hwp_epp,
|
||||
h->hwp_window, h->hwp_window & 0x7F, (h->hwp_window >> 7) & 0x7);
|
||||
h->hwp_min, h->hwp_max, h->hwp_desired, h->hwp_epp, h->hwp_window, h->hwp_window & 0x7F, (h->hwp_window >> 7) & 0x7);
|
||||
}
|
||||
|
||||
void read_hwp_request_msr(int cpu, struct msr_hwp_request *hwp_req, unsigned int msr_offset)
|
||||
{
|
||||
unsigned long long msr;
|
||||
@@ -840,9 +977,7 @@ void write_hwp_request_msr(int cpu, struct msr_hwp_request *hwp_req, unsigned in
|
||||
|
||||
if (debug > 1)
|
||||
printf("cpu%d: requesting min %d max %d des %d epp %d window 0x%0x use_pkg %d\n",
|
||||
cpu, hwp_req->hwp_min, hwp_req->hwp_max,
|
||||
hwp_req->hwp_desired, hwp_req->hwp_epp,
|
||||
hwp_req->hwp_window, hwp_req->hwp_use_pkg);
|
||||
cpu, hwp_req->hwp_min, hwp_req->hwp_max, hwp_req->hwp_desired, hwp_req->hwp_epp, hwp_req->hwp_window, hwp_req->hwp_use_pkg);
|
||||
|
||||
msr |= HWP_MIN_PERF(ratio_2_msr_perf(hwp_req->hwp_min));
|
||||
msr |= HWP_MAX_PERF(ratio_2_msr_perf(hwp_req->hwp_max));
|
||||
@@ -900,6 +1035,58 @@ static int set_epb_sysfs(int cpu, int val)
|
||||
return (int)val;
|
||||
}
|
||||
|
||||
static void print_soc_slider(void)
|
||||
{
|
||||
char buf[64];
|
||||
|
||||
if (!soc_slider_access(R_OK))
|
||||
return;
|
||||
|
||||
if (sysfs_read_string(PATH_SOC_SLIDER_BALANCE, buf, sizeof(buf)) == 0)
|
||||
printf("soc-slider-balance: %s\n", buf);
|
||||
|
||||
if (sysfs_read_string(PATH_SOC_SLIDER_OFFSET, buf, sizeof(buf)) == 0)
|
||||
printf("soc-slider-offset: %s\n", buf);
|
||||
}
|
||||
|
||||
static void print_platform_profile(void)
|
||||
{
|
||||
char buf[64];
|
||||
|
||||
if (!platform_profile_access(R_OK))
|
||||
return;
|
||||
|
||||
if (sysfs_read_string(PATH_PLATFORM_PROFILE_NAME, buf, sizeof(buf)) == 0)
|
||||
printf("platform-profile-name: %s\n", buf);
|
||||
|
||||
if (sysfs_read_string(PATH_PLATFORM_PROFILE, buf, sizeof(buf)) == 0)
|
||||
printf("platform-profile: %s\n", buf);
|
||||
}
|
||||
|
||||
static int update_soc_slider(void)
|
||||
{
|
||||
char tmp[32];
|
||||
|
||||
if (update_soc_slider_balance) {
|
||||
snprintf(tmp, sizeof(tmp), "%d", soc_slider_balance);
|
||||
if (sysfs_write_string(PATH_SOC_SLIDER_BALANCE, tmp))
|
||||
err(1, "soc-slider-balance write failed");
|
||||
}
|
||||
|
||||
if (update_soc_slider_offset) {
|
||||
snprintf(tmp, sizeof(tmp), "%d", soc_slider_offset);
|
||||
if (sysfs_write_string(PATH_SOC_SLIDER_OFFSET, tmp))
|
||||
err(1, "soc-slider-offset write failed");
|
||||
}
|
||||
|
||||
if (update_platform_profile) {
|
||||
if (sysfs_write_string(PATH_PLATFORM_PROFILE, platform_profile))
|
||||
err(1, "platform-profile write failed");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int print_cpu_msrs(int cpu)
|
||||
{
|
||||
struct msr_hwp_request req;
|
||||
@@ -908,7 +1095,7 @@ int print_cpu_msrs(int cpu)
|
||||
|
||||
epb = get_epb_sysfs(cpu);
|
||||
if (epb >= 0)
|
||||
printf("cpu%d: EPB %u\n", cpu, (unsigned int) epb);
|
||||
printf("cpu%d: EPB %u\n", cpu, (unsigned int)epb);
|
||||
|
||||
if (!has_hwp)
|
||||
return 0;
|
||||
@@ -936,17 +1123,13 @@ int print_pkg_msrs(int pkg)
|
||||
if (has_hwp_notify) {
|
||||
get_msr(first_cpu_in_pkg[pkg], MSR_HWP_INTERRUPT, &msr);
|
||||
fprintf(stderr,
|
||||
"pkg%d: MSR_HWP_INTERRUPT: 0x%08llx (Excursion_Min-%sabled, Guaranteed_Perf_Change-%sabled)\n",
|
||||
pkg, msr,
|
||||
((msr) & 0x2) ? "EN" : "Dis",
|
||||
((msr) & 0x1) ? "EN" : "Dis");
|
||||
"pkg%d: MSR_HWP_INTERRUPT: 0x%08llx (Excursion_Min-%sabled, Guaranteed_Perf_Change-%sabled)\n",
|
||||
pkg, msr, ((msr) & 0x2) ? "EN" : "Dis", ((msr) & 0x1) ? "EN" : "Dis");
|
||||
}
|
||||
get_msr(first_cpu_in_pkg[pkg], MSR_HWP_STATUS, &msr);
|
||||
fprintf(stderr,
|
||||
"pkg%d: MSR_HWP_STATUS: 0x%08llx (%sExcursion_Min, %sGuaranteed_Perf_Change)\n",
|
||||
pkg, msr,
|
||||
((msr) & 0x4) ? "" : "No-",
|
||||
((msr) & 0x1) ? "" : "No-");
|
||||
pkg, msr, ((msr) & 0x4) ? "" : "No-", ((msr) & 0x1) ? "" : "No-");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -960,6 +1143,7 @@ int ratio_2_sysfs_khz(int ratio)
|
||||
|
||||
return ratio * bclk_khz;
|
||||
}
|
||||
|
||||
/*
|
||||
* If HWP is enabled and cpufreq sysfs attribtes are present,
|
||||
* then update via sysfs. The intel_pstate driver may modify (clip)
|
||||
@@ -976,8 +1160,7 @@ void update_cpufreq_scaling_freq(int is_max, int cpu, unsigned int ratio)
|
||||
int retval;
|
||||
int khz;
|
||||
|
||||
sprintf(pathname, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_%s_freq",
|
||||
cpu, is_max ? "max" : "min");
|
||||
sprintf(pathname, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_%s_freq", cpu, is_max ? "max" : "min");
|
||||
|
||||
fp = fopen(pathname, "w");
|
||||
if (!fp) {
|
||||
@@ -1029,19 +1212,16 @@ int verify_hwp_req_self_consistency(int cpu, struct msr_hwp_request *req)
|
||||
{
|
||||
/* fail if min > max requested */
|
||||
if (req->hwp_min > req->hwp_max) {
|
||||
errx(1, "cpu%d: requested hwp-min %d > hwp_max %d",
|
||||
cpu, req->hwp_min, req->hwp_max);
|
||||
errx(1, "cpu%d: requested hwp-min %d > hwp_max %d", cpu, req->hwp_min, req->hwp_max);
|
||||
}
|
||||
|
||||
/* fail if desired > max requestd */
|
||||
if (req->hwp_desired && (req->hwp_desired > req->hwp_max)) {
|
||||
errx(1, "cpu%d: requested hwp-desired %d > hwp_max %d",
|
||||
cpu, req->hwp_desired, req->hwp_max);
|
||||
errx(1, "cpu%d: requested hwp-desired %d > hwp_max %d", cpu, req->hwp_desired, req->hwp_max);
|
||||
}
|
||||
/* fail if desired < min requestd */
|
||||
if (req->hwp_desired && (req->hwp_desired < req->hwp_min)) {
|
||||
errx(1, "cpu%d: requested hwp-desired %d < requested hwp_min %d",
|
||||
cpu, req->hwp_desired, req->hwp_min);
|
||||
errx(1, "cpu%d: requested hwp-desired %d < requested hwp_min %d", cpu, req->hwp_desired, req->hwp_min);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1051,39 +1231,30 @@ int check_hwp_request_v_hwp_capabilities(int cpu, struct msr_hwp_request *req, s
|
||||
{
|
||||
if (update_hwp_max) {
|
||||
if (req->hwp_max > cap->highest)
|
||||
errx(1, "cpu%d: requested max %d > capabilities highest %d, use --force?",
|
||||
cpu, req->hwp_max, cap->highest);
|
||||
errx(1, "cpu%d: requested max %d > capabilities highest %d, use --force?", cpu, req->hwp_max, cap->highest);
|
||||
if (req->hwp_max < cap->lowest)
|
||||
errx(1, "cpu%d: requested max %d < capabilities lowest %d, use --force?",
|
||||
cpu, req->hwp_max, cap->lowest);
|
||||
errx(1, "cpu%d: requested max %d < capabilities lowest %d, use --force?", cpu, req->hwp_max, cap->lowest);
|
||||
}
|
||||
|
||||
if (update_hwp_min) {
|
||||
if (req->hwp_min > cap->highest)
|
||||
errx(1, "cpu%d: requested min %d > capabilities highest %d, use --force?",
|
||||
cpu, req->hwp_min, cap->highest);
|
||||
errx(1, "cpu%d: requested min %d > capabilities highest %d, use --force?", cpu, req->hwp_min, cap->highest);
|
||||
if (req->hwp_min < cap->lowest)
|
||||
errx(1, "cpu%d: requested min %d < capabilities lowest %d, use --force?",
|
||||
cpu, req->hwp_min, cap->lowest);
|
||||
errx(1, "cpu%d: requested min %d < capabilities lowest %d, use --force?", cpu, req->hwp_min, cap->lowest);
|
||||
}
|
||||
|
||||
if (update_hwp_min && update_hwp_max && (req->hwp_min > req->hwp_max))
|
||||
errx(1, "cpu%d: requested min %d > requested max %d",
|
||||
cpu, req->hwp_min, req->hwp_max);
|
||||
errx(1, "cpu%d: requested min %d > requested max %d", cpu, req->hwp_min, req->hwp_max);
|
||||
|
||||
if (update_hwp_desired && req->hwp_desired) {
|
||||
if (req->hwp_desired > req->hwp_max)
|
||||
errx(1, "cpu%d: requested desired %d > requested max %d, use --force?",
|
||||
cpu, req->hwp_desired, req->hwp_max);
|
||||
errx(1, "cpu%d: requested desired %d > requested max %d, use --force?", cpu, req->hwp_desired, req->hwp_max);
|
||||
if (req->hwp_desired < req->hwp_min)
|
||||
errx(1, "cpu%d: requested desired %d < requested min %d, use --force?",
|
||||
cpu, req->hwp_desired, req->hwp_min);
|
||||
errx(1, "cpu%d: requested desired %d < requested min %d, use --force?", cpu, req->hwp_desired, req->hwp_min);
|
||||
if (req->hwp_desired < cap->lowest)
|
||||
errx(1, "cpu%d: requested desired %d < capabilities lowest %d, use --force?",
|
||||
cpu, req->hwp_desired, cap->lowest);
|
||||
errx(1, "cpu%d: requested desired %d < capabilities lowest %d, use --force?", cpu, req->hwp_desired, cap->lowest);
|
||||
if (req->hwp_desired > cap->highest)
|
||||
errx(1, "cpu%d: requested desired %d > capabilities highest %d, use --force?",
|
||||
cpu, req->hwp_desired, cap->highest);
|
||||
errx(1, "cpu%d: requested desired %d > capabilities highest %d, use --force?", cpu, req->hwp_desired, cap->highest);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1134,6 +1305,7 @@ int update_hwp_request_msr(int cpu)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int update_hwp_request_pkg_msr(int pkg)
|
||||
{
|
||||
struct msr_hwp_request req;
|
||||
@@ -1205,8 +1377,7 @@ int update_cpu_epb_sysfs(int cpu)
|
||||
set_epb_sysfs(cpu, new_epb);
|
||||
|
||||
if (verbose)
|
||||
printf("cpu%d: ENERGY_PERF_BIAS old: %d new: %d\n",
|
||||
cpu, epb, (unsigned int) new_epb);
|
||||
printf("cpu%d: ENERGY_PERF_BIAS old: %d new: %d\n", cpu, epb, (unsigned int)new_epb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1222,7 +1393,7 @@ int update_cpu_msrs(int cpu)
|
||||
|
||||
turbo_is_present_and_disabled = ((msr & MSR_IA32_MISC_ENABLE_TURBO_DISABLE) != 0);
|
||||
|
||||
if (turbo_update_value == 1) {
|
||||
if (turbo_update_value == 1) {
|
||||
if (turbo_is_present_and_disabled) {
|
||||
msr &= ~MSR_IA32_MISC_ENABLE_TURBO_DISABLE;
|
||||
put_msr(cpu, MSR_IA32_MISC_ENABLE, msr);
|
||||
@@ -1291,6 +1462,7 @@ int set_max_cpu_pkg_num(int cpu)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mark_cpu_present(int cpu)
|
||||
{
|
||||
CPU_SET_S(cpu, cpu_setsize, cpu_present_set);
|
||||
@@ -1301,7 +1473,7 @@ int mark_cpu_present(int cpu)
|
||||
* run func(cpu) on every cpu in /proc/stat
|
||||
* return max_cpu number
|
||||
*/
|
||||
int for_all_proc_cpus(int (func)(int))
|
||||
int for_all_proc_cpus(int (func) (int))
|
||||
{
|
||||
FILE *fp;
|
||||
int cpu_num;
|
||||
@@ -1328,7 +1500,7 @@ int for_all_proc_cpus(int (func)(int))
|
||||
return 0;
|
||||
}
|
||||
|
||||
void for_all_cpus_in_set(size_t set_size, cpu_set_t *cpu_set, int (func)(int))
|
||||
void for_all_cpus_in_set(size_t set_size, cpu_set_t *cpu_set, int (func) (int))
|
||||
{
|
||||
int cpu_num;
|
||||
|
||||
@@ -1336,7 +1508,8 @@ void for_all_cpus_in_set(size_t set_size, cpu_set_t *cpu_set, int (func)(int))
|
||||
if (CPU_ISSET_S(cpu_num, set_size, cpu_set))
|
||||
func(cpu_num);
|
||||
}
|
||||
int for_all_cpus_in_set_and(size_t set_size, cpu_set_t *cpu_set, int (func)(int))
|
||||
|
||||
int for_all_cpus_in_set_and(size_t set_size, cpu_set_t *cpu_set, int (func) (int))
|
||||
{
|
||||
int cpu_num;
|
||||
int retval = 1;
|
||||
@@ -1385,7 +1558,7 @@ void verify_hwp_is_enabled(void)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (!has_hwp) /* set in early_cpuid() */
|
||||
if (!has_hwp) /* set in early_cpuid() */
|
||||
return;
|
||||
|
||||
retval = for_all_cpus_in_set_and(cpu_setsize, cpu_selected_set, is_hwp_enabled_on_cpu);
|
||||
@@ -1402,21 +1575,18 @@ int req_update_bounds_check(void)
|
||||
return 0;
|
||||
|
||||
/* fail if min > max requested */
|
||||
if ((update_hwp_max && update_hwp_min) &&
|
||||
(req_update.hwp_min > req_update.hwp_max)) {
|
||||
if ((update_hwp_max && update_hwp_min) && (req_update.hwp_min > req_update.hwp_max)) {
|
||||
printf("hwp-min %d > hwp_max %d\n", req_update.hwp_min, req_update.hwp_max);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* fail if desired > max requestd */
|
||||
if (req_update.hwp_desired && update_hwp_max &&
|
||||
(req_update.hwp_desired > req_update.hwp_max)) {
|
||||
if (req_update.hwp_desired && update_hwp_max && (req_update.hwp_desired > req_update.hwp_max)) {
|
||||
printf("hwp-desired cannot be greater than hwp_max\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
/* fail if desired < min requestd */
|
||||
if (req_update.hwp_desired && update_hwp_min &&
|
||||
(req_update.hwp_desired < req_update.hwp_min)) {
|
||||
if (req_update.hwp_desired && update_hwp_min && (req_update.hwp_desired < req_update.hwp_min)) {
|
||||
printf("hwp-desired cannot be less than hwp_min\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1459,9 +1629,7 @@ void probe_dev_msr(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void get_cpuid_or_exit(unsigned int leaf,
|
||||
unsigned int *eax, unsigned int *ebx,
|
||||
unsigned int *ecx, unsigned int *edx)
|
||||
static void get_cpuid_or_exit(unsigned int leaf, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx)
|
||||
{
|
||||
if (!__get_cpuid(leaf, eax, ebx, ecx, edx))
|
||||
errx(1, "Processor not supported\n");
|
||||
@@ -1515,8 +1683,7 @@ void parse_cpuid(void)
|
||||
genuine_intel = 1;
|
||||
|
||||
if (debug)
|
||||
fprintf(stderr, "CPUID(0): %.4s%.4s%.4s ",
|
||||
(char *)&ebx, (char *)&edx, (char *)&ecx);
|
||||
fprintf(stderr, "CPUID(0): %.4s%.4s%.4s ", (char *)&ebx, (char *)&edx, (char *)&ecx);
|
||||
|
||||
get_cpuid_or_exit(1, &fms, &ebx, &ecx, &edx);
|
||||
family = (fms >> 8) & 0xf;
|
||||
@@ -1526,23 +1693,18 @@ void parse_cpuid(void)
|
||||
model += ((fms >> 16) & 0xf) << 4;
|
||||
|
||||
if (debug) {
|
||||
fprintf(stderr, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n",
|
||||
max_level, family, model, stepping, family, model, stepping);
|
||||
fprintf(stderr, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n", max_level, family, model, stepping, family, model, stepping);
|
||||
fprintf(stderr, "CPUID(1): %s %s %s %s %s %s %s %s\n",
|
||||
ecx & (1 << 0) ? "SSE3" : "-",
|
||||
ecx & (1 << 3) ? "MONITOR" : "-",
|
||||
ecx & (1 << 7) ? "EIST" : "-",
|
||||
ecx & (1 << 8) ? "TM2" : "-",
|
||||
edx & (1 << 4) ? "TSC" : "-",
|
||||
edx & (1 << 5) ? "MSR" : "-",
|
||||
edx & (1 << 22) ? "ACPI-TM" : "-",
|
||||
edx & (1 << 29) ? "TM" : "-");
|
||||
edx & (1 << 4) ? "TSC" : "-", edx & (1 << 5) ? "MSR" : "-", edx & (1 << 22) ? "ACPI-TM" : "-", edx & (1 << 29) ? "TM" : "-");
|
||||
}
|
||||
|
||||
if (!(edx & (1 << 5)))
|
||||
errx(1, "CPUID: no MSR");
|
||||
|
||||
|
||||
get_cpuid_or_exit(0x6, &eax, &ebx, &ecx, &edx);
|
||||
/* turbo_is_enabled already set */
|
||||
/* has_hwp already set */
|
||||
@@ -1562,12 +1724,9 @@ void parse_cpuid(void)
|
||||
turbo_is_enabled ? "" : "No-",
|
||||
has_hwp ? "" : "No-",
|
||||
has_hwp_notify ? "" : "No-",
|
||||
has_hwp_activity_window ? "" : "No-",
|
||||
has_hwp_epp ? "" : "No-",
|
||||
has_hwp_request_pkg ? "" : "No-",
|
||||
has_epb ? "" : "No-");
|
||||
has_hwp_activity_window ? "" : "No-", has_hwp_epp ? "" : "No-", has_hwp_request_pkg ? "" : "No-", has_epb ? "" : "No-");
|
||||
|
||||
return; /* success */
|
||||
return; /* success */
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
@@ -1577,7 +1736,7 @@ int main(int argc, char **argv)
|
||||
probe_dev_msr();
|
||||
init_data_structures();
|
||||
|
||||
early_cpuid(); /* initial cpuid parse before cmdline */
|
||||
early_cpuid(); /* initial cpuid parse before cmdline */
|
||||
|
||||
cmdline(argc, argv);
|
||||
|
||||
@@ -1586,7 +1745,7 @@ int main(int argc, char **argv)
|
||||
|
||||
parse_cpuid();
|
||||
|
||||
/* If CPU-set and PKG-set are not initialized, default to all CPUs */
|
||||
/* If CPU-set and PKG-set are not initialized, default to all CPUs */
|
||||
if ((cpu_selected_set == 0) && (pkg_selected_set == 0))
|
||||
cpu_selected_set = cpu_present_set;
|
||||
|
||||
@@ -1604,10 +1763,13 @@ int main(int argc, char **argv)
|
||||
return -EINVAL;
|
||||
|
||||
/* display information only, no updates to settings */
|
||||
if (!update_epb && !update_turbo && !hwp_update_enabled()) {
|
||||
if (!update_epb && !update_turbo && !hwp_update_enabled() && !update_soc_slider_balance && !update_soc_slider_offset && !update_platform_profile) {
|
||||
if (cpu_selected_set)
|
||||
for_all_cpus_in_set(cpu_setsize, cpu_selected_set, print_cpu_msrs);
|
||||
|
||||
print_soc_slider();
|
||||
print_platform_profile();
|
||||
|
||||
if (has_hwp_request_pkg) {
|
||||
if (pkg_selected_set == 0)
|
||||
pkg_selected_set = pkg_present_set;
|
||||
@@ -1628,5 +1790,8 @@ int main(int argc, char **argv)
|
||||
} else if (pkg_selected_set)
|
||||
for_packages(pkg_selected_set, update_hwp_request_pkg_msr);
|
||||
|
||||
if (update_soc_slider_balance || update_soc_slider_offset || update_platform_profile)
|
||||
update_soc_slider();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user