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:
Carlos Llamas committed 2026-05-26 22:39:38 +00:00
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
+4 -2
View File
@@ -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
+1 -1
View File
@@ -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);
}
+3 -5
View File
@@ -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,
+4 -1
View File
@@ -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
View File
@@ -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");
+23 -11
View File
@@ -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);
}
+10 -1
View File
@@ -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)
+7
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
+3 -2
View File
@@ -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) {
+2 -7
View File
@@ -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
View File
@@ -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);
}
+1 -7
View File
@@ -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);
+12 -2
View File
@@ -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))
+1 -1
View File
@@ -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)
+7 -16
View File
@@ -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,
+1 -6
View File
@@ -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];
+1 -7
View File
@@ -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);
+1 -3
View File
@@ -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)
+9 -1
View File
@@ -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);
+1 -1
View File
@@ -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
+3 -6
View File
@@ -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;
}
+3 -9
View File
@@ -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;
+7 -2
View File
@@ -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;
+6 -1
View File
@@ -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 -10
View File
@@ -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)
+7 -2
View File
@@ -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
/**
+7 -1
View File
@@ -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
+153 -78
View File
@@ -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;
}