aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
authorMark Brown <broonie@kernel.org>2026-05-29 23:00:12 +0100
committerMark Brown <broonie@kernel.org>2026-05-29 23:00:14 +0100
commit166f6eabaab65d0625b28dfafe72b76d44027977 (patch)
tree214d0cacd490fa1c3f1f2c474533ab1e886cae31 /drivers
parente8b79e654b43e511a9ff0af1963f86718564c7d6 (diff)
parent5fdac9983681f743cfaa89414ea154a2c5fd39c4 (diff)
downloadlinux-next-history-166f6eabaab65d0625b28dfafe72b76d44027977.tar.gz
Merge branch 'for-next' of https://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/bus.c15
-rw-r--r--drivers/char/sonypi.c5
-rw-r--r--drivers/hid/hid-asus.c6
-rw-r--r--drivers/platform/arm64/Kconfig13
-rw-r--r--drivers/platform/arm64/Makefile1
-rw-r--r--drivers/platform/arm64/qcom-hamoa-ec.c451
-rw-r--r--drivers/platform/x86/Kconfig1
-rw-r--r--drivers/platform/x86/amd/hfi/hfi.c6
-rw-r--r--drivers/platform/x86/barco-p50-gpio.c10
-rw-r--r--drivers/platform/x86/classmate-laptop.c343
-rw-r--r--drivers/platform/x86/dell/alienware-wmi-base.c31
-rw-r--r--drivers/platform/x86/dell/dell-wmi-sysman/biosattr-interface.c8
-rw-r--r--drivers/platform/x86/dell/dell-wmi-sysman/dell-wmi-sysman.h4
-rw-r--r--drivers/platform/x86/dell/dell-wmi-sysman/passwordattr-interface.c4
-rw-r--r--drivers/platform/x86/dell/dell-wmi-sysman/sysman.c6
-rw-r--r--drivers/platform/x86/dell/dell_rbu.c4
-rw-r--r--drivers/platform/x86/intel/pmc/Makefile3
-rw-r--r--drivers/platform/x86/intel/pmc/arl.c13
-rw-r--r--drivers/platform/x86/intel/pmc/core.c137
-rw-r--r--drivers/platform/x86/intel/pmc/core.h68
-rw-r--r--drivers/platform/x86/intel/pmc/lnl.c6
-rw-r--r--drivers/platform/x86/intel/pmc/mtl.c7
-rw-r--r--drivers/platform/x86/intel/pmc/nvl.c1539
-rw-r--r--drivers/platform/x86/intel/pmc/ptl.c8
-rw-r--r--drivers/platform/x86/intel/pmc/wcl.c6
-rw-r--r--drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c16
-rw-r--r--drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.h8
-rw-r--r--drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c15
-rw-r--r--drivers/platform/x86/intel/vsec.c14
-rw-r--r--drivers/platform/x86/intel/vsec_tpmi.c13
-rw-r--r--drivers/platform/x86/lenovo/thinkpad_acpi.c42
-rw-r--r--drivers/platform/x86/meraki-mx100.c41
-rw-r--r--drivers/platform/x86/panasonic-laptop.c19
-rw-r--r--drivers/platform/x86/pcengines-apuv2.c2
-rw-r--r--drivers/platform/x86/pmc_atom.c4
-rw-r--r--drivers/platform/x86/sel3350-platform.c136
-rw-r--r--drivers/platform/x86/x86-android-tablets/core.c64
-rw-r--r--drivers/platform/x86/xo15-ebook.c91
38 files changed, 2799 insertions, 361 deletions
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index e9eee0d1f0daf..6584f0b88660c 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -1247,6 +1247,21 @@ int acpi_bus_for_each_dev(int (*fn)(struct device *, void *), void *data)
}
EXPORT_SYMBOL_GPL(acpi_bus_for_each_dev);
+/**
+ * acpi_bus_find_device_by_name() - Locate an ACPI device by its name
+ * @name: Name of the device to match
+ *
+ * The caller is responsible for calling put_device() on the returned object.
+ *
+ * Returns:
+ * New reference to the matched device or NULL if the device can't be found.
+ */
+struct device *acpi_bus_find_device_by_name(const char *name)
+{
+ return bus_find_device_by_name(&acpi_bus_type, NULL, name);
+}
+EXPORT_SYMBOL_GPL(acpi_bus_find_device_by_name);
+
struct acpi_dev_walk_context {
int (*fn)(struct acpi_device *, void *);
void *data;
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index ccda997a9098a..959949f04f7d9 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -37,6 +37,7 @@
#include <linux/kfifo.h>
#include <linux/platform_device.h>
#include <linux/gfp.h>
+#include <linux/string.h>
#include <linux/string_choices.h>
#include <linux/uaccess.h>
@@ -1120,8 +1121,8 @@ static int sonypi_acpi_probe(struct platform_device *pdev)
struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
sonypi_acpi_device = device;
- strcpy(acpi_device_name(device), "Sony laptop hotkeys");
- strcpy(acpi_device_class(device), "sony/hotkey");
+ strscpy(acpi_device_name(device), "Sony laptop hotkeys");
+ strscpy(acpi_device_class(device), "sony/hotkey");
return 0;
}
diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
index 3f5e96900b67a..d34d74df3dc0b 100644
--- a/drivers/hid/hid-asus.c
+++ b/drivers/hid/hid-asus.c
@@ -965,6 +965,12 @@ static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi)
}
}
+ if (drvdata->quirks & QUIRK_HID_FN_LOCK) {
+ drvdata->fn_lock = true;
+ INIT_WORK(&drvdata->fn_lock_sync_work, asus_sync_fn_lock);
+ asus_kbd_set_fn_lock(hdev, true);
+ }
+
if (drvdata->tp) {
int ret;
diff --git a/drivers/platform/arm64/Kconfig b/drivers/platform/arm64/Kconfig
index 10f905d7d6bfa..e32e01b2a9bdd 100644
--- a/drivers/platform/arm64/Kconfig
+++ b/drivers/platform/arm64/Kconfig
@@ -90,4 +90,17 @@ config EC_LENOVO_THINKPAD_T14S
Say M or Y here to include this support.
+config EC_QCOM_HAMOA
+ tristate "Embedded Controller driver for Qualcomm Hamoa/Glymur reference devices"
+ depends on ARCH_QCOM || COMPILE_TEST
+ depends on I2C
+ depends on THERMAL || THERMAL=n
+ help
+ Say M or Y here to enable the Embedded Controller driver for Qualcomm
+ Snapdragon-based Hamoa/Glymur reference devices. The driver handles fan
+ control, temperature sensors, access to EC state changes and supports
+ reporting suspend entry/exit to the EC.
+
+ This driver currently supports Hamoa/Purwa/Glymur reference devices.
+
endif # ARM64_PLATFORM_DEVICES
diff --git a/drivers/platform/arm64/Makefile b/drivers/platform/arm64/Makefile
index 60c131cff6a15..7681be4a46e94 100644
--- a/drivers/platform/arm64/Makefile
+++ b/drivers/platform/arm64/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_EC_ACER_ASPIRE1) += acer-aspire1-ec.o
obj-$(CONFIG_EC_HUAWEI_GAOKUN) += huawei-gaokun-ec.o
obj-$(CONFIG_EC_LENOVO_YOGA_C630) += lenovo-yoga-c630.o
obj-$(CONFIG_EC_LENOVO_THINKPAD_T14S) += lenovo-thinkpad-t14s.o
+obj-$(CONFIG_EC_QCOM_HAMOA) += qcom-hamoa-ec.o
diff --git a/drivers/platform/arm64/qcom-hamoa-ec.c b/drivers/platform/arm64/qcom-hamoa-ec.c
new file mode 100644
index 0000000000000..a018f7bf35d2a
--- /dev/null
+++ b/drivers/platform/arm64/qcom-hamoa-ec.c
@@ -0,0 +1,451 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024 Maya Matuszczyk <maccraft123mc@gmail.com>
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/device.h>
+#include <linux/dev_printk.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pm.h>
+#include <linux/slab.h>
+#include <linux/thermal.h>
+
+#define EC_SCI_EVT_READ_CMD 0x05
+#define EC_FW_VERSION_CMD 0x0e
+#define EC_MODERN_STANDBY_CMD 0x23
+#define EC_FAN_DBG_CONTROL_CMD 0x30
+#define EC_SCI_EVT_CONTROL_CMD 0x35
+#define EC_THERMAL_CAP_CMD 0x42
+
+#define EC_FW_VERSION_RESP_LEN 4
+#define EC_THERMAL_CAP_RESP_LEN 3
+#define EC_FAN_DEBUG_CMD_LEN 6
+#define EC_FAN_SPEED_DATA_SIZE 4
+
+#define EC_MODERN_STANDBY_ENTER 0x01
+#define EC_MODERN_STANDBY_EXIT 0x00
+
+#define EC_FAN_DEBUG_MODE_OFF 0
+#define EC_FAN_DEBUG_MODE_ON BIT(0)
+#define EC_FAN_ON BIT(1)
+#define EC_FAN_DEBUG_TYPE_PWM BIT(2)
+#define EC_MAX_FAN_CNT 2
+#define EC_FAN_NAME_SIZE 20
+#define EC_FAN_MAX_PWM 255
+
+enum qcom_ec_sci_events {
+ EC_FAN1_STATUS_CHANGE_EVT = 0x30,
+ EC_FAN2_STATUS_CHANGE_EVT,
+ EC_FAN1_SPEED_CHANGE_EVT,
+ EC_FAN2_SPEED_CHANGE_EVT,
+ EC_NEW_LUT_SET_EVT,
+ EC_FAN_PROFILE_SWITCH_EVT,
+ EC_THERMISTOR_1_THRESHOLD_CROSS_EVT,
+ EC_THERMISTOR_2_THRESHOLD_CROSS_EVT,
+ EC_THERMISTOR_3_THRESHOLD_CROSS_EVT,
+ /* Reserved: 0x39 - 0x3c/0x3f */
+ EC_RECOVERED_FROM_RESET_EVT = 0x3d,
+};
+
+struct qcom_ec_version {
+ u8 main_version;
+ u8 sub_version;
+ u8 test_version;
+};
+
+struct qcom_ec_thermal_cap {
+#define EC_THERMAL_FAN_CNT(x) (FIELD_GET(GENMASK(1, 0), (x)))
+#define EC_THERMAL_FAN_TYPE(x) (FIELD_GET(GENMASK(4, 2), (x)))
+#define EC_THERMAL_THERMISTOR_MASK(x) (FIELD_GET(GENMASK(7, 0), (x)))
+ u8 fan_cnt;
+ u8 fan_type;
+ u8 thermistor_mask;
+};
+
+struct qcom_ec_cooling_dev {
+ struct thermal_cooling_device *cdev;
+ struct device *parent_dev;
+ u8 fan_id;
+ u8 state;
+};
+
+struct qcom_ec {
+ struct qcom_ec_cooling_dev *ec_cdev;
+ struct qcom_ec_thermal_cap thermal_cap;
+ struct qcom_ec_version version;
+ struct i2c_client *client;
+};
+
+static int qcom_ec_read(struct qcom_ec *ec, u8 cmd, u8 resp_len, u8 *resp)
+{
+ int ret;
+
+ ret = i2c_smbus_read_i2c_block_data(ec->client, cmd, resp_len, resp);
+ if (ret < 0)
+ return ret;
+ else if (ret == 0 || ret == 0xff)
+ return -EOPNOTSUPP;
+
+ if (resp[0] >= resp_len)
+ return -EINVAL;
+
+ return 0;
+}
+
+/*
+ * EC Device Firmware Version:
+ *
+ * Read Response:
+ * ----------------------------------------------------------------------
+ * | Offset | Name | Description |
+ * ----------------------------------------------------------------------
+ * | 0x00 | Byte count | Number of bytes in response |
+ * | | | (excluding byte count) |
+ * ----------------------------------------------------------------------
+ * | 0x01 | Test-version | Test-version of EC firmware |
+ * ----------------------------------------------------------------------
+ * | 0x02 | Sub-version | Sub-version of EC firmware |
+ * ----------------------------------------------------------------------
+ * | 0x03 | Main-version | Main-version of EC firmware |
+ * ----------------------------------------------------------------------
+ *
+ */
+static int qcom_ec_read_fw_version(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct qcom_ec *ec = i2c_get_clientdata(client);
+ struct qcom_ec_version *version = &ec->version;
+ u8 resp[EC_FW_VERSION_RESP_LEN];
+ int ret;
+
+ ret = qcom_ec_read(ec, EC_FW_VERSION_CMD, EC_FW_VERSION_RESP_LEN, resp);
+ if (ret < 0)
+ return ret;
+
+ version->main_version = resp[3];
+ version->sub_version = resp[2];
+ version->test_version = resp[1];
+
+ dev_dbg(dev, "EC Version %d.%d.%d\n",
+ version->main_version, version->sub_version, version->test_version);
+
+ return 0;
+}
+
+/*
+ * EC Device Thermal Capabilities:
+ *
+ * Read Response:
+ * ------------------------------------------------------------------------------
+ * | Offset | Name | Description |
+ * ------------------------------------------------------------------------------
+ * | 0x00 | Byte count | Number of bytes in response |
+ * | | | (excluding byte count) |
+ * ------------------------------------------------------------------------------
+ * | 0x02 (LSB) | EC Thermal | Bit 0-1: Number of fans |
+ * | 0x03 | Capabilities | Bit 2-4: Type of fan |
+ * | | | Bit 5-6: Reserved |
+ * | | | Bit 7: Data Valid/Invalid |
+ * | | | (Valid - 1, Invalid - 0) |
+ * | | | Bit 8-15: Thermistor 0 - 7 presence |
+ * | | | (1 present, 0 absent) |
+ * ------------------------------------------------------------------------------
+ *
+ */
+static int qcom_ec_thermal_capabilities(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct qcom_ec *ec = i2c_get_clientdata(client);
+ struct qcom_ec_thermal_cap *cap = &ec->thermal_cap;
+ u8 resp[EC_THERMAL_CAP_RESP_LEN];
+ int ret;
+
+ ret = qcom_ec_read(ec, EC_THERMAL_CAP_CMD, EC_THERMAL_CAP_RESP_LEN, resp);
+ if (ret < 0)
+ return ret;
+
+ cap->fan_cnt = min(EC_MAX_FAN_CNT, EC_THERMAL_FAN_CNT(resp[1]));
+ cap->fan_type = EC_THERMAL_FAN_TYPE(resp[1]);
+ cap->thermistor_mask = EC_THERMAL_THERMISTOR_MASK(resp[2]);
+
+ dev_dbg(dev, "Fan count: %d Fan Type: %d Thermistor Mask: %x\n",
+ cap->fan_cnt, cap->fan_type, cap->thermistor_mask);
+
+ return 0;
+}
+
+static irqreturn_t qcom_ec_irq(int irq, void *data)
+{
+ struct qcom_ec *ec = data;
+ struct device *dev = &ec->client->dev;
+ int val;
+
+ val = i2c_smbus_read_byte_data(ec->client, EC_SCI_EVT_READ_CMD);
+ if (val < 0) {
+ dev_err_ratelimited(dev, "Failed to read EC SCI Event: %d\n", val);
+ return IRQ_HANDLED;
+ }
+
+ switch (val) {
+ case EC_FAN1_STATUS_CHANGE_EVT:
+ dev_dbg_ratelimited(dev, "Fan1 status changed\n");
+ break;
+ case EC_FAN2_STATUS_CHANGE_EVT:
+ dev_dbg_ratelimited(dev, "Fan2 status changed\n");
+ break;
+ case EC_FAN1_SPEED_CHANGE_EVT:
+ dev_dbg_ratelimited(dev, "Fan1 speed crossed low/high trip point\n");
+ break;
+ case EC_FAN2_SPEED_CHANGE_EVT:
+ dev_dbg_ratelimited(dev, "Fan2 speed crossed low/high trip point\n");
+ break;
+ case EC_NEW_LUT_SET_EVT:
+ dev_dbg_ratelimited(dev, "New LUT set\n");
+ break;
+ case EC_FAN_PROFILE_SWITCH_EVT:
+ dev_dbg_ratelimited(dev, "FAN Profile switched\n");
+ break;
+ case EC_THERMISTOR_1_THRESHOLD_CROSS_EVT:
+ dev_dbg_ratelimited(dev, "Thermistor 1 threshold crossed\n");
+ break;
+ case EC_THERMISTOR_2_THRESHOLD_CROSS_EVT:
+ dev_dbg_ratelimited(dev, "Thermistor 2 threshold crossed\n");
+ break;
+ case EC_THERMISTOR_3_THRESHOLD_CROSS_EVT:
+ dev_dbg_ratelimited(dev, "Thermistor 3 threshold crossed\n");
+ break;
+ case EC_RECOVERED_FROM_RESET_EVT:
+ dev_dbg_ratelimited(dev, "EC recovered from reset\n");
+ break;
+ default:
+ dev_notice_ratelimited(dev, "Unknown EC event: %d\n", val);
+ break;
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int qcom_ec_sci_evt_control(struct device *dev, bool enable)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+
+ return i2c_smbus_write_byte_data(client, EC_SCI_EVT_CONTROL_CMD, enable ? 1 : 0);
+}
+
+static int qcom_ec_fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long *state)
+{
+ *state = EC_FAN_MAX_PWM;
+
+ return 0;
+}
+
+static int qcom_ec_fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long *state)
+{
+ struct qcom_ec_cooling_dev *ec_cdev = cdev->devdata;
+
+ *state = ec_cdev->state;
+
+ return 0;
+}
+
+/*
+ * Fan Debug control command:
+ *
+ * Command Payload:
+ * --------------------------------------------------------------------------------------
+ * | Offset | Name | Description |
+ * --------------------------------------------------------------------------------------
+ * | 0x00 | Command | Fan control command |
+ * --------------------------------------------------------------------------------------
+ * | 0x01 | Fan ID | 0x1 : Fan 1 |
+ * | | | 0x2 : Fan 2 |
+ * --------------------------------------------------------------------------------------
+ * | 0x02 | Byte count = 4| Size of data to set fan speed |
+ * --------------------------------------------------------------------------------------
+ * | 0x03 | Mode | Bit 0: Debug Mode On/Off (0 - OFF, 1 - ON ) |
+ * | | | Bit 1: Fan On/Off (0 - Off, 1 - ON) |
+ * | | | Bit 2: Debug Type (0 - RPM, 1 - PWM) |
+ * --------------------------------------------------------------------------------------
+ * | 0x04 (LSB) | Speed in RPM | RPM value, if mode selected is RPM |
+ * | 0x05 | | |
+ * --------------------------------------------------------------------------------------
+ * | 0x06 | Speed in PWM | PWM value, if mode selected is PWM (0 - 255) |
+ * ______________________________________________________________________________________
+ *
+ */
+static int qcom_ec_fan_debug_mode_off(struct qcom_ec_cooling_dev *ec_cdev)
+{
+ struct device *dev = ec_cdev->parent_dev;
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 request[6] = { ec_cdev->fan_id, EC_FAN_SPEED_DATA_SIZE,
+ EC_FAN_DEBUG_MODE_OFF, 0, 0, 0 };
+ int ret;
+
+ ret = i2c_smbus_write_i2c_block_data(client, EC_FAN_DBG_CONTROL_CMD,
+ sizeof(request), request);
+ if (ret) {
+ dev_err(dev, "Failed to turn off fan%d debug mode: %d\n",
+ ec_cdev->fan_id, ret);
+ }
+
+ return ret;
+}
+
+static int qcom_ec_fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
+{
+ struct qcom_ec_cooling_dev *ec_cdev = cdev->devdata;
+ struct device *dev = ec_cdev->parent_dev;
+ struct i2c_client *client = to_i2c_client(dev);
+ u8 request[6] = { ec_cdev->fan_id, EC_FAN_SPEED_DATA_SIZE,
+ EC_FAN_DEBUG_MODE_ON | EC_FAN_ON | EC_FAN_DEBUG_TYPE_PWM,
+ 0, 0, state };
+ int ret;
+
+ ret = i2c_smbus_write_i2c_block_data(client, EC_FAN_DBG_CONTROL_CMD,
+ sizeof(request), request);
+ if (ret) {
+ dev_err(dev, "Failed to set fan pwm: %d\n", ret);
+ return ret;
+ }
+
+ ec_cdev->state = state;
+
+ return 0;
+}
+
+static const struct thermal_cooling_device_ops qcom_ec_thermal_ops = {
+ .get_max_state = qcom_ec_fan_get_max_state,
+ .get_cur_state = qcom_ec_fan_get_cur_state,
+ .set_cur_state = qcom_ec_fan_set_cur_state,
+};
+
+static int qcom_ec_resume(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+
+ return i2c_smbus_write_byte_data(client, EC_MODERN_STANDBY_CMD,
+ EC_MODERN_STANDBY_EXIT);
+}
+
+static int qcom_ec_suspend(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+
+ return i2c_smbus_write_byte_data(client, EC_MODERN_STANDBY_CMD,
+ EC_MODERN_STANDBY_ENTER);
+}
+
+static int qcom_ec_probe(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ struct qcom_ec *ec;
+ unsigned int i;
+ int ret;
+
+ ec = devm_kzalloc(dev, sizeof(*ec), GFP_KERNEL);
+ if (!ec)
+ return -ENOMEM;
+
+ ec->client = client;
+
+ ret = devm_request_threaded_irq(dev, client->irq, NULL, qcom_ec_irq,
+ IRQF_ONESHOT, "qcom_ec", ec);
+ if (ret < 0)
+ return ret;
+
+ i2c_set_clientdata(client, ec);
+
+ ret = qcom_ec_read_fw_version(dev);
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "Failed to read EC firmware version\n");
+
+ ret = qcom_ec_sci_evt_control(dev, true);
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "Failed to enable SCI events\n");
+
+ ret = qcom_ec_thermal_capabilities(dev);
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "Failed to read thermal capabilities\n");
+
+ if (ec->thermal_cap.fan_cnt == 0) {
+ dev_warn(dev, FW_BUG "Failed to get fan count, firmware update required\n");
+ return 0;
+ }
+
+ ec->ec_cdev = devm_kcalloc(dev, ec->thermal_cap.fan_cnt, sizeof(*ec->ec_cdev), GFP_KERNEL);
+ if (!ec->ec_cdev)
+ return -ENOMEM;
+
+ for (i = 0; i < ec->thermal_cap.fan_cnt; i++) {
+ struct qcom_ec_cooling_dev *ec_cdev = &ec->ec_cdev[i];
+ char name[EC_FAN_NAME_SIZE];
+
+ scnprintf(name, sizeof(name), "qcom_ec_fan_%u", i);
+ ec_cdev->fan_id = i + 1;
+ ec_cdev->parent_dev = dev;
+
+ ec_cdev->cdev = devm_thermal_of_cooling_device_register(dev, NULL, name, ec_cdev,
+ &qcom_ec_thermal_ops);
+ if (IS_ERR(ec_cdev->cdev)) {
+ return dev_err_probe(dev, PTR_ERR(ec_cdev->cdev),
+ "Failed to register fan%d cooling device\n", i);
+ }
+ }
+
+ return 0;
+}
+
+static void qcom_ec_remove(struct i2c_client *client)
+{
+ struct qcom_ec *ec = i2c_get_clientdata(client);
+ struct device *dev = &client->dev;
+ int ret;
+
+ ret = qcom_ec_sci_evt_control(dev, false);
+ if (ret < 0)
+ dev_err(dev, "Failed to disable SCI events: %d\n", ret);
+
+ for (int i = 0; i < ec->thermal_cap.fan_cnt; i++) {
+ struct qcom_ec_cooling_dev *ec_cdev = &ec->ec_cdev[i];
+
+ qcom_ec_fan_debug_mode_off(ec_cdev);
+ }
+}
+
+static const struct of_device_id qcom_ec_of_match[] = {
+ { .compatible = "qcom,hamoa-crd-ec" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, qcom_ec_of_match);
+
+static const struct i2c_device_id qcom_ec_i2c_id_table[] = {
+ { "qcom-hamoa-ec", },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, qcom_ec_i2c_id_table);
+
+static DEFINE_SIMPLE_DEV_PM_OPS(qcom_ec_pm_ops,
+ qcom_ec_suspend,
+ qcom_ec_resume);
+
+static struct i2c_driver qcom_ec_i2c_driver = {
+ .driver = {
+ .name = "qcom-hamoa-ec",
+ .of_match_table = qcom_ec_of_match,
+ .pm = &qcom_ec_pm_ops,
+ },
+ .probe = qcom_ec_probe,
+ .remove = qcom_ec_remove,
+ .id_table = qcom_ec_i2c_id_table,
+};
+module_i2c_driver(qcom_ec_i2c_driver);
+
+MODULE_DESCRIPTION("QCOM Hamoa Embedded Controller");
+MODULE_LICENSE("GPL");
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 7a4956088300c..b54b5212b2047 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -346,6 +346,7 @@ config AYANEO_EC
config MERAKI_MX100
tristate "Cisco Meraki MX100 Platform Driver"
depends on GPIOLIB
+ depends on LPC_ICH
depends on GPIO_ICH
depends on LEDS_CLASS
select LEDS_GPIO
diff --git a/drivers/platform/x86/amd/hfi/hfi.c b/drivers/platform/x86/amd/hfi/hfi.c
index 83863a5e0fbc6..e0ebcb0c4acde 100644
--- a/drivers/platform/x86/amd/hfi/hfi.c
+++ b/drivers/platform/x86/amd/hfi/hfi.c
@@ -33,7 +33,8 @@
#define AMD_HFI_DRIVER "amd_hfi"
#define AMD_HFI_MAILBOX_COUNT 1
-#define AMD_HETERO_RANKING_TABLE_VER 2
+#define AMD_HETERO_RANKING_TABLE_MIN_VER 2
+#define AMD_HETERO_RANKING_TABLE_MAX_VER 3
#define AMD_HETERO_CPUID_27 0x80000027
@@ -158,7 +159,8 @@ static int amd_hfi_fill_metadata(struct amd_hfi_data *amd_hfi_data)
dev_err(amd_hfi_data->dev, "invalid signature in shared memory\n");
return -EINVAL;
}
- if (amd_hfi_data->shmem->version_number != AMD_HETERO_RANKING_TABLE_VER) {
+ if (amd_hfi_data->shmem->version_number < AMD_HETERO_RANKING_TABLE_MIN_VER ||
+ amd_hfi_data->shmem->version_number > AMD_HETERO_RANKING_TABLE_MAX_VER) {
dev_err(amd_hfi_data->dev, "invalid version %d\n",
amd_hfi_data->shmem->version_number);
return -EINVAL;
diff --git a/drivers/platform/x86/barco-p50-gpio.c b/drivers/platform/x86/barco-p50-gpio.c
index 2a6d8607c4026..e1400382465dc 100644
--- a/drivers/platform/x86/barco-p50-gpio.c
+++ b/drivers/platform/x86/barco-p50-gpio.c
@@ -124,7 +124,6 @@ static const struct software_node vendor_key_node = {
};
static const struct software_node *p50_swnodes[] = {
- &gpiochip_node,
&gpio_leds_node,
&identify_led_node,
&gpio_keys_node,
@@ -424,6 +423,13 @@ MODULE_DEVICE_TABLE(dmi, dmi_ids);
static int __init p50_module_init(void)
{
struct resource res = DEFINE_RES_IO(P50_GPIO_IO_PORT_BASE, P50_PORT_CMD + 1);
+ struct platform_device_info pdevinfo = {
+ .name = DRIVER_NAME,
+ .id = PLATFORM_DEVID_NONE,
+ .res = &res,
+ .num_res = 1,
+ .swnode = &gpiochip_node,
+ };
int ret;
if (!dmi_first_match(dmi_ids))
@@ -433,7 +439,7 @@ static int __init p50_module_init(void)
if (ret)
return ret;
- gpio_pdev = platform_device_register_simple(DRIVER_NAME, PLATFORM_DEVID_NONE, &res, 1);
+ gpio_pdev = platform_device_register_full(&pdevinfo);
if (IS_ERR(gpio_pdev)) {
pr_err("failed registering %s: %ld\n", DRIVER_NAME, PTR_ERR(gpio_pdev));
platform_driver_unregister(&p50_gpio_driver);
diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c
index e6eed3d65580a..05890815795d5 100644
--- a/drivers/platform/x86/classmate-laptop.c
+++ b/drivers/platform/x86/classmate-laptop.c
@@ -13,6 +13,7 @@
#include <linux/input.h>
#include <linux/rfkill.h>
#include <linux/sysfs.h>
+#include <linux/platform_device.h>
struct cmpc_accel {
int sensitivity;
@@ -38,8 +39,8 @@ struct cmpc_accel {
typedef void (*input_device_init)(struct input_dev *dev);
-static int cmpc_add_acpi_notify_device(struct acpi_device *acpi, char *name,
- input_device_init idev_init)
+static int cmpc_add_notify_device(struct device *dev, char *name,
+ input_device_init idev_init)
{
struct input_dev *inputdev;
int error;
@@ -48,22 +49,20 @@ static int cmpc_add_acpi_notify_device(struct acpi_device *acpi, char *name,
if (!inputdev)
return -ENOMEM;
inputdev->name = name;
- inputdev->dev.parent = &acpi->dev;
+ inputdev->dev.parent = dev;
idev_init(inputdev);
error = input_register_device(inputdev);
if (error) {
input_free_device(inputdev);
return error;
}
- dev_set_drvdata(&acpi->dev, inputdev);
+ dev_set_drvdata(dev, inputdev);
return 0;
}
-static int cmpc_remove_acpi_notify_device(struct acpi_device *acpi)
+static void cmpc_remove_notify_device(struct device *dev)
{
- struct input_dev *inputdev = dev_get_drvdata(&acpi->dev);
- input_unregister_device(inputdev);
- return 0;
+ input_unregister_device(dev_get_drvdata(dev));
}
/*
@@ -179,15 +178,17 @@ static acpi_status cmpc_get_accel_v4(acpi_handle handle,
return status;
}
-static void cmpc_accel_handler_v4(struct acpi_device *dev, u32 event)
+static void cmpc_accel_handler_v4(acpi_handle handle, u32 event, void *data)
{
+ struct device *dev = data;
+
if (event == 0x81) {
int16_t x, y, z;
acpi_status status;
- status = cmpc_get_accel_v4(dev->handle, &x, &y, &z);
+ status = cmpc_get_accel_v4(ACPI_HANDLE(dev), &x, &y, &z);
if (ACPI_SUCCESS(status)) {
- struct input_dev *inputdev = dev_get_drvdata(&dev->dev);
+ struct input_dev *inputdev = dev_get_drvdata(dev);
input_report_abs(inputdev, ABS_X, x);
input_report_abs(inputdev, ABS_Y, y);
@@ -317,18 +318,17 @@ static struct device_attribute cmpc_accel_g_select_attr_v4 = {
static int cmpc_accel_open_v4(struct input_dev *input)
{
- struct acpi_device *acpi;
+ acpi_handle handle = ACPI_HANDLE(input->dev.parent);
struct cmpc_accel *accel;
- acpi = to_acpi_device(input->dev.parent);
accel = dev_get_drvdata(&input->dev);
if (!accel)
return -ENXIO;
- cmpc_accel_set_sensitivity_v4(acpi->handle, accel->sensitivity);
- cmpc_accel_set_g_select_v4(acpi->handle, accel->g_select);
+ cmpc_accel_set_sensitivity_v4(handle, accel->sensitivity);
+ cmpc_accel_set_g_select_v4(handle, accel->g_select);
- if (ACPI_SUCCESS(cmpc_start_accel_v4(acpi->handle))) {
+ if (ACPI_SUCCESS(cmpc_start_accel_v4(handle))) {
accel->inputdev_state = CMPC_ACCEL_DEV_STATE_OPEN;
return 0;
}
@@ -337,13 +337,11 @@ static int cmpc_accel_open_v4(struct input_dev *input)
static void cmpc_accel_close_v4(struct input_dev *input)
{
- struct acpi_device *acpi;
struct cmpc_accel *accel;
- acpi = to_acpi_device(input->dev.parent);
accel = dev_get_drvdata(&input->dev);
- cmpc_stop_accel_v4(acpi->handle);
+ cmpc_stop_accel_v4(ACPI_HANDLE(input->dev.parent));
accel->inputdev_state = CMPC_ACCEL_DEV_STATE_CLOSED;
}
@@ -367,7 +365,7 @@ static int cmpc_accel_suspend_v4(struct device *dev)
accel = dev_get_drvdata(&inputdev->dev);
if (accel->inputdev_state == CMPC_ACCEL_DEV_STATE_OPEN)
- return cmpc_stop_accel_v4(to_acpi_device(dev)->handle);
+ return cmpc_stop_accel_v4(ACPI_HANDLE(dev));
return 0;
}
@@ -381,12 +379,12 @@ static int cmpc_accel_resume_v4(struct device *dev)
accel = dev_get_drvdata(&inputdev->dev);
if (accel->inputdev_state == CMPC_ACCEL_DEV_STATE_OPEN) {
- cmpc_accel_set_sensitivity_v4(to_acpi_device(dev)->handle,
- accel->sensitivity);
- cmpc_accel_set_g_select_v4(to_acpi_device(dev)->handle,
- accel->g_select);
+ acpi_handle handle = ACPI_HANDLE(dev);
- if (ACPI_FAILURE(cmpc_start_accel_v4(to_acpi_device(dev)->handle)))
+ cmpc_accel_set_sensitivity_v4(handle, accel->sensitivity);
+ cmpc_accel_set_g_select_v4(handle, accel->g_select);
+
+ if (ACPI_FAILURE(cmpc_start_accel_v4(handle)))
return -EIO;
}
@@ -394,18 +392,30 @@ static int cmpc_accel_resume_v4(struct device *dev)
}
#endif
-static int cmpc_accel_add_v4(struct acpi_device *acpi)
+static int cmpc_accel_probe_v4(struct platform_device *pdev)
{
int error;
struct input_dev *inputdev;
struct cmpc_accel *accel;
+ struct acpi_device *acpi;
- accel = kmalloc_obj(*accel);
+ acpi = ACPI_COMPANION(&pdev->dev);
+ if (!acpi)
+ return -ENODEV;
+
+ accel = devm_kzalloc(&pdev->dev, sizeof(*accel), GFP_KERNEL);
if (!accel)
return -ENOMEM;
accel->inputdev_state = CMPC_ACCEL_DEV_STATE_CLOSED;
+ error = cmpc_add_notify_device(&pdev->dev, "cmpc_accel_v4", cmpc_accel_idev_init_v4);
+ if (error)
+ return error;
+
+ inputdev = dev_get_drvdata(&pdev->dev);
+ dev_set_drvdata(&acpi->dev, inputdev);
+
accel->sensitivity = CMPC_ACCEL_SENSITIVITY_DEFAULT;
cmpc_accel_set_sensitivity_v4(acpi->handle, accel->sensitivity);
@@ -420,30 +430,35 @@ static int cmpc_accel_add_v4(struct acpi_device *acpi)
if (error)
goto failed_g_select;
- error = cmpc_add_acpi_notify_device(acpi, "cmpc_accel_v4",
- cmpc_accel_idev_init_v4);
+ error = acpi_dev_install_notify_handler(acpi, ACPI_DEVICE_NOTIFY,
+ cmpc_accel_handler_v4, &pdev->dev);
if (error)
- goto failed_input;
+ goto failed_notify_handler;
- inputdev = dev_get_drvdata(&acpi->dev);
dev_set_drvdata(&inputdev->dev, accel);
return 0;
-failed_input:
+failed_notify_handler:
device_remove_file(&acpi->dev, &cmpc_accel_g_select_attr_v4);
failed_g_select:
device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v4);
failed_sensitivity:
- kfree(accel);
+ dev_set_drvdata(&acpi->dev, NULL);
+ cmpc_remove_notify_device(&pdev->dev);
return error;
}
-static void cmpc_accel_remove_v4(struct acpi_device *acpi)
+static void cmpc_accel_remove_v4(struct platform_device *pdev)
{
- device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v4);
+ struct acpi_device *acpi = ACPI_COMPANION(&pdev->dev);
+
+ acpi_dev_remove_notify_handler(acpi, ACPI_DEVICE_NOTIFY,
+ cmpc_accel_handler_v4);
device_remove_file(&acpi->dev, &cmpc_accel_g_select_attr_v4);
- cmpc_remove_acpi_notify_device(acpi);
+ device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v4);
+ dev_set_drvdata(&acpi->dev, NULL);
+ cmpc_remove_notify_device(&pdev->dev);
}
static SIMPLE_DEV_PM_OPS(cmpc_accel_pm, cmpc_accel_suspend_v4,
@@ -454,16 +469,14 @@ static const struct acpi_device_id cmpc_accel_device_ids_v4[] = {
{"", 0}
};
-static struct acpi_driver cmpc_accel_acpi_driver_v4 = {
- .name = "cmpc_accel_v4",
- .class = "cmpc_accel_v4",
- .ids = cmpc_accel_device_ids_v4,
- .ops = {
- .add = cmpc_accel_add_v4,
- .remove = cmpc_accel_remove_v4,
- .notify = cmpc_accel_handler_v4,
+static struct platform_driver cmpc_accel_acpi_driver_v4 = {
+ .probe = cmpc_accel_probe_v4,
+ .remove = cmpc_accel_remove_v4,
+ .driver = {
+ .name = "cmpc_accel_v4",
+ .acpi_match_table = cmpc_accel_device_ids_v4,
+ .pm = &cmpc_accel_pm,
},
- .drv.pm = &cmpc_accel_pm,
};
@@ -543,15 +556,17 @@ static acpi_status cmpc_get_accel(acpi_handle handle,
return status;
}
-static void cmpc_accel_handler(struct acpi_device *dev, u32 event)
+static void cmpc_accel_handler(acpi_handle handle, u32 event, void *data)
{
+ struct device *dev = data;
+
if (event == 0x81) {
unsigned char x, y, z;
acpi_status status;
- status = cmpc_get_accel(dev->handle, &x, &y, &z);
+ status = cmpc_get_accel(ACPI_HANDLE(dev), &x, &y, &z);
if (ACPI_SUCCESS(status)) {
- struct input_dev *inputdev = dev_get_drvdata(&dev->dev);
+ struct input_dev *inputdev = dev_get_drvdata(dev);
input_report_abs(inputdev, ABS_X, x);
input_report_abs(inputdev, ABS_Y, y);
@@ -618,20 +633,14 @@ static struct device_attribute cmpc_accel_sensitivity_attr = {
static int cmpc_accel_open(struct input_dev *input)
{
- struct acpi_device *acpi;
-
- acpi = to_acpi_device(input->dev.parent);
- if (ACPI_SUCCESS(cmpc_start_accel(acpi->handle)))
+ if (ACPI_SUCCESS(cmpc_start_accel(ACPI_HANDLE(input->dev.parent))))
return 0;
return -EIO;
}
static void cmpc_accel_close(struct input_dev *input)
{
- struct acpi_device *acpi;
-
- acpi = to_acpi_device(input->dev.parent);
- cmpc_stop_accel(acpi->handle);
+ cmpc_stop_accel(ACPI_HANDLE(input->dev.parent));
}
static void cmpc_accel_idev_init(struct input_dev *inputdev)
@@ -644,16 +653,28 @@ static void cmpc_accel_idev_init(struct input_dev *inputdev)
inputdev->close = cmpc_accel_close;
}
-static int cmpc_accel_add(struct acpi_device *acpi)
+static int cmpc_accel_probe(struct platform_device *pdev)
{
int error;
struct input_dev *inputdev;
struct cmpc_accel *accel;
+ struct acpi_device *acpi;
- accel = kmalloc_obj(*accel);
+ acpi = ACPI_COMPANION(&pdev->dev);
+ if (!acpi)
+ return -ENODEV;
+
+ accel = devm_kzalloc(&pdev->dev, sizeof(*accel), GFP_KERNEL);
if (!accel)
return -ENOMEM;
+ error = cmpc_add_notify_device(&pdev->dev, "cmpc_accel", cmpc_accel_idev_init);
+ if (error)
+ return error;
+
+ inputdev = dev_get_drvdata(&pdev->dev);
+ dev_set_drvdata(&acpi->dev, inputdev);
+
accel->sensitivity = CMPC_ACCEL_SENSITIVITY_DEFAULT;
cmpc_accel_set_sensitivity(acpi->handle, accel->sensitivity);
@@ -661,27 +682,32 @@ static int cmpc_accel_add(struct acpi_device *acpi)
if (error)
goto failed_file;
- error = cmpc_add_acpi_notify_device(acpi, "cmpc_accel",
- cmpc_accel_idev_init);
+ error = acpi_dev_install_notify_handler(acpi, ACPI_DEVICE_NOTIFY,
+ cmpc_accel_handler, &pdev->dev);
if (error)
- goto failed_input;
+ goto failed_notify_handler;
- inputdev = dev_get_drvdata(&acpi->dev);
dev_set_drvdata(&inputdev->dev, accel);
return 0;
-failed_input:
+failed_notify_handler:
device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr);
failed_file:
- kfree(accel);
+ dev_set_drvdata(&acpi->dev, NULL);
+ cmpc_remove_notify_device(&pdev->dev);
return error;
}
-static void cmpc_accel_remove(struct acpi_device *acpi)
+static void cmpc_accel_remove(struct platform_device *pdev)
{
+ struct acpi_device *acpi = ACPI_COMPANION(&pdev->dev);
+
+ acpi_dev_remove_notify_handler(acpi, ACPI_DEVICE_NOTIFY,
+ cmpc_accel_handler);
device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr);
- cmpc_remove_acpi_notify_device(acpi);
+ dev_set_drvdata(&acpi->dev, NULL);
+ cmpc_remove_notify_device(&pdev->dev);
}
static const struct acpi_device_id cmpc_accel_device_ids[] = {
@@ -689,15 +715,13 @@ static const struct acpi_device_id cmpc_accel_device_ids[] = {
{"", 0}
};
-static struct acpi_driver cmpc_accel_acpi_driver = {
- .name = "cmpc_accel",
- .class = "cmpc_accel",
- .ids = cmpc_accel_device_ids,
- .ops = {
- .add = cmpc_accel_add,
- .remove = cmpc_accel_remove,
- .notify = cmpc_accel_handler,
- }
+static struct platform_driver cmpc_accel_acpi_driver = {
+ .probe = cmpc_accel_probe,
+ .remove = cmpc_accel_remove,
+ .driver = {
+ .name = "cmpc_accel",
+ .acpi_match_table = cmpc_accel_device_ids,
+ },
};
@@ -722,13 +746,14 @@ static acpi_status cmpc_get_tablet(acpi_handle handle,
return status;
}
-static void cmpc_tablet_handler(struct acpi_device *dev, u32 event)
+static void cmpc_tablet_handler(acpi_handle handle, u32 event, void *data)
{
+ struct device *dev = data;
unsigned long long val = 0;
- struct input_dev *inputdev = dev_get_drvdata(&dev->dev);
+ struct input_dev *inputdev = dev_get_drvdata(dev);
if (event == 0x81) {
- if (ACPI_SUCCESS(cmpc_get_tablet(dev->handle, &val))) {
+ if (ACPI_SUCCESS(cmpc_get_tablet(ACPI_HANDLE(dev), &val))) {
input_report_switch(inputdev, SW_TABLET_MODE, !val);
input_sync(inputdev);
}
@@ -737,28 +762,44 @@ static void cmpc_tablet_handler(struct acpi_device *dev, u32 event)
static void cmpc_tablet_idev_init(struct input_dev *inputdev)
{
+ acpi_handle handle = ACPI_HANDLE(inputdev->dev.parent);
unsigned long long val = 0;
- struct acpi_device *acpi;
set_bit(EV_SW, inputdev->evbit);
set_bit(SW_TABLET_MODE, inputdev->swbit);
- acpi = to_acpi_device(inputdev->dev.parent);
- if (ACPI_SUCCESS(cmpc_get_tablet(acpi->handle, &val))) {
+ if (ACPI_SUCCESS(cmpc_get_tablet(handle, &val))) {
input_report_switch(inputdev, SW_TABLET_MODE, !val);
input_sync(inputdev);
}
}
-static int cmpc_tablet_add(struct acpi_device *acpi)
+static int cmpc_tablet_probe(struct platform_device *pdev)
{
- return cmpc_add_acpi_notify_device(acpi, "cmpc_tablet",
- cmpc_tablet_idev_init);
+ struct acpi_device *acpi;
+ int error;
+
+ acpi = ACPI_COMPANION(&pdev->dev);
+ if (!acpi)
+ return -ENODEV;
+
+ error = cmpc_add_notify_device(&pdev->dev, "cmpc_tablet", cmpc_tablet_idev_init);
+ if (error)
+ return error;
+
+ error = acpi_dev_install_notify_handler(acpi, ACPI_DEVICE_NOTIFY,
+ cmpc_tablet_handler, &pdev->dev);
+ if (error)
+ cmpc_remove_notify_device(&pdev->dev);
+
+ return error;
}
-static void cmpc_tablet_remove(struct acpi_device *acpi)
+static void cmpc_tablet_remove(struct platform_device *pdev)
{
- cmpc_remove_acpi_notify_device(acpi);
+ acpi_dev_remove_notify_handler(ACPI_COMPANION(&pdev->dev),
+ ACPI_DEVICE_NOTIFY, cmpc_tablet_handler);
+ cmpc_remove_notify_device(&pdev->dev);
}
#ifdef CONFIG_PM_SLEEP
@@ -767,7 +808,7 @@ static int cmpc_tablet_resume(struct device *dev)
struct input_dev *inputdev = dev_get_drvdata(dev);
unsigned long long val = 0;
- if (ACPI_SUCCESS(cmpc_get_tablet(to_acpi_device(dev)->handle, &val))) {
+ if (ACPI_SUCCESS(cmpc_get_tablet(ACPI_HANDLE(dev), &val))) {
input_report_switch(inputdev, SW_TABLET_MODE, !val);
input_sync(inputdev);
}
@@ -782,16 +823,14 @@ static const struct acpi_device_id cmpc_tablet_device_ids[] = {
{"", 0}
};
-static struct acpi_driver cmpc_tablet_acpi_driver = {
- .name = "cmpc_tablet",
- .class = "cmpc_tablet",
- .ids = cmpc_tablet_device_ids,
- .ops = {
- .add = cmpc_tablet_add,
- .remove = cmpc_tablet_remove,
- .notify = cmpc_tablet_handler,
+static struct platform_driver cmpc_tablet_acpi_driver = {
+ .probe = cmpc_tablet_probe,
+ .remove = cmpc_tablet_remove,
+ .driver = {
+ .name = "cmpc_tablet",
+ .acpi_match_table = cmpc_tablet_device_ids,
+ .pm = &cmpc_tablet_pm,
},
- .drv.pm = &cmpc_tablet_pm,
};
@@ -958,11 +997,16 @@ struct ipml200_dev {
struct rfkill *rf;
};
-static int cmpc_ipml_add(struct acpi_device *acpi)
+static int cmpc_ipml_probe(struct platform_device *pdev)
{
int retval;
struct ipml200_dev *ipml;
struct backlight_properties props;
+ acpi_handle handle;
+
+ handle = ACPI_HANDLE(&pdev->dev);
+ if (!handle)
+ return -ENODEV;
ipml = kmalloc_obj(*ipml);
if (ipml == NULL)
@@ -971,16 +1015,16 @@ static int cmpc_ipml_add(struct acpi_device *acpi)
memset(&props, 0, sizeof(struct backlight_properties));
props.type = BACKLIGHT_PLATFORM;
props.max_brightness = 7;
- ipml->bd = backlight_device_register("cmpc_bl", &acpi->dev,
- acpi->handle, &cmpc_bl_ops,
+ ipml->bd = backlight_device_register("cmpc_bl", &pdev->dev,
+ handle, &cmpc_bl_ops,
&props);
if (IS_ERR(ipml->bd)) {
retval = PTR_ERR(ipml->bd);
goto out_bd;
}
- ipml->rf = rfkill_alloc("cmpc_rfkill", &acpi->dev, RFKILL_TYPE_WLAN,
- &cmpc_rfkill_ops, acpi->handle);
+ ipml->rf = rfkill_alloc("cmpc_rfkill", &pdev->dev, RFKILL_TYPE_WLAN,
+ &cmpc_rfkill_ops, handle);
/*
* If RFKILL is disabled, rfkill_alloc will return ERR_PTR(-ENODEV).
* This is OK, however, since all other uses of the device will not
@@ -994,7 +1038,7 @@ static int cmpc_ipml_add(struct acpi_device *acpi)
}
}
- dev_set_drvdata(&acpi->dev, ipml);
+ platform_set_drvdata(pdev, ipml);
return 0;
out_bd:
@@ -1002,11 +1046,11 @@ out_bd:
return retval;
}
-static void cmpc_ipml_remove(struct acpi_device *acpi)
+static void cmpc_ipml_remove(struct platform_device *pdev)
{
struct ipml200_dev *ipml;
- ipml = dev_get_drvdata(&acpi->dev);
+ ipml = platform_get_drvdata(pdev);
backlight_device_unregister(ipml->bd);
@@ -1023,14 +1067,13 @@ static const struct acpi_device_id cmpc_ipml_device_ids[] = {
{"", 0}
};
-static struct acpi_driver cmpc_ipml_acpi_driver = {
- .name = "cmpc",
- .class = "cmpc",
- .ids = cmpc_ipml_device_ids,
- .ops = {
- .add = cmpc_ipml_add,
- .remove = cmpc_ipml_remove
- }
+static struct platform_driver cmpc_ipml_acpi_driver = {
+ .probe = cmpc_ipml_probe,
+ .remove = cmpc_ipml_remove,
+ .driver = {
+ .name = "cmpc",
+ .acpi_match_table = cmpc_ipml_device_ids,
+ },
};
@@ -1053,14 +1096,15 @@ static int cmpc_keys_codes[] = {
KEY_MAX
};
-static void cmpc_keys_handler(struct acpi_device *dev, u32 event)
+static void cmpc_keys_handler(acpi_handle handle, u32 event, void *data)
{
+ struct device *dev = data;
struct input_dev *inputdev;
int code = KEY_MAX;
if ((event & 0x0F) < ARRAY_SIZE(cmpc_keys_codes))
code = cmpc_keys_codes[event & 0x0F];
- inputdev = dev_get_drvdata(&dev->dev);
+ inputdev = dev_get_drvdata(dev);
input_report_key(inputdev, code, !(event & 0x10));
input_sync(inputdev);
}
@@ -1074,15 +1118,32 @@ static void cmpc_keys_idev_init(struct input_dev *inputdev)
set_bit(cmpc_keys_codes[i], inputdev->keybit);
}
-static int cmpc_keys_add(struct acpi_device *acpi)
+static int cmpc_keys_probe(struct platform_device *pdev)
{
- return cmpc_add_acpi_notify_device(acpi, "cmpc_keys",
- cmpc_keys_idev_init);
+ struct acpi_device *acpi;
+ int error;
+
+ acpi = ACPI_COMPANION(&pdev->dev);
+ if (!acpi)
+ return -ENODEV;
+
+ error = cmpc_add_notify_device(&pdev->dev, "cmpc_keys", cmpc_keys_idev_init);
+ if (error)
+ return error;
+
+ error = acpi_dev_install_notify_handler(acpi, ACPI_DEVICE_NOTIFY,
+ cmpc_keys_handler, &pdev->dev);
+ if (error)
+ cmpc_remove_notify_device(&pdev->dev);
+
+ return error;
}
-static void cmpc_keys_remove(struct acpi_device *acpi)
+static void cmpc_keys_remove(struct platform_device *pdev)
{
- cmpc_remove_acpi_notify_device(acpi);
+ acpi_dev_remove_notify_handler(ACPI_COMPANION(&pdev->dev),
+ ACPI_DEVICE_NOTIFY, cmpc_keys_handler);
+ cmpc_remove_notify_device(&pdev->dev);
}
static const struct acpi_device_id cmpc_keys_device_ids[] = {
@@ -1090,15 +1151,13 @@ static const struct acpi_device_id cmpc_keys_device_ids[] = {
{"", 0}
};
-static struct acpi_driver cmpc_keys_acpi_driver = {
- .name = "cmpc_keys",
- .class = "cmpc_keys",
- .ids = cmpc_keys_device_ids,
- .ops = {
- .add = cmpc_keys_add,
- .remove = cmpc_keys_remove,
- .notify = cmpc_keys_handler,
- }
+static struct platform_driver cmpc_keys_acpi_driver = {
+ .probe = cmpc_keys_probe,
+ .remove = cmpc_keys_remove,
+ .driver = {
+ .name = "cmpc_keys",
+ .acpi_match_table = cmpc_keys_device_ids,
+ },
};
@@ -1110,39 +1169,39 @@ static int cmpc_init(void)
{
int r;
- r = acpi_bus_register_driver(&cmpc_keys_acpi_driver);
+ r = platform_driver_register(&cmpc_keys_acpi_driver);
if (r)
goto failed_keys;
- r = acpi_bus_register_driver(&cmpc_ipml_acpi_driver);
+ r = platform_driver_register(&cmpc_ipml_acpi_driver);
if (r)
goto failed_bl;
- r = acpi_bus_register_driver(&cmpc_tablet_acpi_driver);
+ r = platform_driver_register(&cmpc_tablet_acpi_driver);
if (r)
goto failed_tablet;
- r = acpi_bus_register_driver(&cmpc_accel_acpi_driver);
+ r = platform_driver_register(&cmpc_accel_acpi_driver);
if (r)
goto failed_accel;
- r = acpi_bus_register_driver(&cmpc_accel_acpi_driver_v4);
+ r = platform_driver_register(&cmpc_accel_acpi_driver_v4);
if (r)
goto failed_accel_v4;
return r;
failed_accel_v4:
- acpi_bus_unregister_driver(&cmpc_accel_acpi_driver);
+ platform_driver_unregister(&cmpc_accel_acpi_driver);
failed_accel:
- acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver);
+ platform_driver_unregister(&cmpc_tablet_acpi_driver);
failed_tablet:
- acpi_bus_unregister_driver(&cmpc_ipml_acpi_driver);
+ platform_driver_unregister(&cmpc_ipml_acpi_driver);
failed_bl:
- acpi_bus_unregister_driver(&cmpc_keys_acpi_driver);
+ platform_driver_unregister(&cmpc_keys_acpi_driver);
failed_keys:
return r;
@@ -1150,11 +1209,11 @@ failed_keys:
static void cmpc_exit(void)
{
- acpi_bus_unregister_driver(&cmpc_accel_acpi_driver_v4);
- acpi_bus_unregister_driver(&cmpc_accel_acpi_driver);
- acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver);
- acpi_bus_unregister_driver(&cmpc_ipml_acpi_driver);
- acpi_bus_unregister_driver(&cmpc_keys_acpi_driver);
+ platform_driver_unregister(&cmpc_accel_acpi_driver_v4);
+ platform_driver_unregister(&cmpc_accel_acpi_driver);
+ platform_driver_unregister(&cmpc_tablet_acpi_driver);
+ platform_driver_unregister(&cmpc_ipml_acpi_driver);
+ platform_driver_unregister(&cmpc_keys_acpi_driver);
}
module_init(cmpc_init);
diff --git a/drivers/platform/x86/dell/alienware-wmi-base.c b/drivers/platform/x86/dell/alienware-wmi-base.c
index 64562b92314fa..19cadf21203a6 100644
--- a/drivers/platform/x86/dell/alienware-wmi-base.c
+++ b/drivers/platform/x86/dell/alienware-wmi-base.c
@@ -12,8 +12,13 @@
#include <linux/cleanup.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
#include <linux/dmi.h>
#include <linux/leds.h>
+
+#include <asm/byteorder.h>
+
#include "alienware-wmi.h"
MODULE_AUTHOR("Mario Limonciello <mario.limonciello@outlook.com>");
@@ -150,22 +155,22 @@ u8 alienware_interface;
int alienware_wmi_command(struct wmi_device *wdev, u32 method_id,
void *in_args, size_t in_size, u32 *out_data)
{
- struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
- struct acpi_buffer in = {in_size, in_args};
- acpi_status ret;
+ struct wmi_buffer out, in = {
+ .data = in_args,
+ .length = in_size,
+ };
+ int ret;
- ret = wmidev_evaluate_method(wdev, 0, method_id, &in, out_data ? &out : NULL);
- if (ACPI_FAILURE(ret))
- return -EIO;
+ if (!out_data)
+ return wmidev_invoke_procedure(wdev, 0, method_id, &in);
- union acpi_object *obj __free(kfree) = out.pointer;
+ ret = wmidev_invoke_method(wdev, 0, method_id, &in, &out,
+ sizeof(*out_data));
+ if (ret)
+ return ret;
- if (out_data) {
- if (obj && obj->type == ACPI_TYPE_INTEGER)
- *out_data = (u32)obj->integer.value;
- else
- return -ENOMSG;
- }
+ __le32 *data __free(kfree) = out.data;
+ *out_data = le32_to_cpu(*data);
return 0;
}
diff --git a/drivers/platform/x86/dell/dell-wmi-sysman/biosattr-interface.c b/drivers/platform/x86/dell/dell-wmi-sysman/biosattr-interface.c
index c2dd2de6bc203..db278ff4cc4d4 100644
--- a/drivers/platform/x86/dell/dell-wmi-sysman/biosattr-interface.c
+++ b/drivers/platform/x86/dell/dell-wmi-sysman/biosattr-interface.c
@@ -13,8 +13,8 @@
#define SETBIOSDEFAULTS_METHOD_ID 0x03
#define SETATTRIBUTE_METHOD_ID 0x04
-static int call_biosattributes_interface(struct wmi_device *wdev, char *in_args, size_t size,
- int method_id)
+static int call_biosattributes_interface(struct wmi_device *wdev, u8 *in_args,
+ size_t size, int method_id)
{
struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
struct acpi_buffer input;
@@ -51,7 +51,7 @@ int set_attribute(const char *a_name, const char *a_value)
{
size_t security_area_size, buffer_size;
size_t a_name_size, a_value_size;
- char *buffer = NULL, *start;
+ u8 *buffer = NULL, *start;
int ret;
mutex_lock(&wmi_priv.mutex);
@@ -109,7 +109,7 @@ int set_bios_defaults(u8 deftype)
{
size_t security_area_size, buffer_size;
size_t integer_area_size = sizeof(u8);
- char *buffer = NULL;
+ u8 *buffer = NULL;
u8 *defaultType;
int ret;
diff --git a/drivers/platform/x86/dell/dell-wmi-sysman/dell-wmi-sysman.h b/drivers/platform/x86/dell/dell-wmi-sysman/dell-wmi-sysman.h
index 5278a93fdaf79..3bddedad5eba2 100644
--- a/drivers/platform/x86/dell/dell-wmi-sysman/dell-wmi-sysman.h
+++ b/drivers/platform/x86/dell/dell-wmi-sysman/dell-wmi-sysman.h
@@ -190,8 +190,8 @@ int init_bios_attr_set_interface(void);
int map_wmi_error(int error_code);
size_t calculate_string_buffer(const char *str);
size_t calculate_security_buffer(const char *authentication);
-void populate_security_buffer(char *buffer, const char *authentication);
-ssize_t populate_string_buffer(char *buffer, size_t buffer_len, const char *str);
+void populate_security_buffer(u8 *buffer, const char *authentication);
+ssize_t populate_string_buffer(u8 *buffer, size_t buffer_len, const char *str);
int set_new_password(const char *password_type, const char *new);
int init_bios_attr_pass_interface(void);
void exit_bios_attr_pass_interface(void);
diff --git a/drivers/platform/x86/dell/dell-wmi-sysman/passwordattr-interface.c b/drivers/platform/x86/dell/dell-wmi-sysman/passwordattr-interface.c
index e586f7957946b..026c134b3f977 100644
--- a/drivers/platform/x86/dell/dell-wmi-sysman/passwordattr-interface.c
+++ b/drivers/platform/x86/dell/dell-wmi-sysman/passwordattr-interface.c
@@ -8,7 +8,7 @@
#include <linux/wmi.h>
#include "dell-wmi-sysman.h"
-static int call_password_interface(struct wmi_device *wdev, char *in_args, size_t size)
+static int call_password_interface(struct wmi_device *wdev, u8 *in_args, size_t size)
{
struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
struct acpi_buffer input;
@@ -42,7 +42,7 @@ int set_new_password(const char *password_type, const char *new)
{
size_t password_type_size, current_password_size, new_size;
size_t security_area_size, buffer_size;
- char *buffer = NULL, *start;
+ u8 *buffer = NULL, *start;
char *current_password;
int ret;
diff --git a/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c b/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c
index 51d25fdc13897..ab46a023cc34d 100644
--- a/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c
+++ b/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c
@@ -36,7 +36,7 @@ static int reset_option = -1;
* @buffer_len: length of the destination buffer
* @str: the string to insert into buffer
*/
-ssize_t populate_string_buffer(char *buffer, size_t buffer_len, const char *str)
+ssize_t populate_string_buffer(u8 *buffer, size_t buffer_len, const char *str)
{
u16 *length = (u16 *)buffer;
u16 *target = length + 1;
@@ -87,10 +87,10 @@ size_t calculate_security_buffer(const char *authentication)
*
* Currently only supported type is PLAIN TEXT
*/
-void populate_security_buffer(char *buffer, const char *authentication)
+void populate_security_buffer(u8 *buffer, const char *authentication)
{
size_t seclen = strlen(authentication);
- char *auth = buffer + sizeof(u32) * 2;
+ u8 *auth = buffer + sizeof(u32) * 2;
u32 *sectype = (u32 *) buffer;
u32 *seclenp = sectype + 1;
diff --git a/drivers/platform/x86/dell/dell_rbu.c b/drivers/platform/x86/dell/dell_rbu.c
index 3fa9de9aa47b8..768b15f406d3b 100644
--- a/drivers/platform/x86/dell/dell_rbu.c
+++ b/drivers/platform/x86/dell/dell_rbu.c
@@ -562,9 +562,9 @@ static ssize_t image_type_write(struct file *filp, struct kobject *kobj,
buffer[count] = '\0';
if (strstr(buffer, "mono"))
- strcpy(image_type, "mono");
+ strscpy(image_type, "mono");
else if (strstr(buffer, "packet"))
- strcpy(image_type, "packet");
+ strscpy(image_type, "packet");
else if (strstr(buffer, "init")) {
/*
* If due to the user error the driver gets in a bad
diff --git a/drivers/platform/x86/intel/pmc/Makefile b/drivers/platform/x86/intel/pmc/Makefile
index bb960c8721d77..23853e867c912 100644
--- a/drivers/platform/x86/intel/pmc/Makefile
+++ b/drivers/platform/x86/intel/pmc/Makefile
@@ -4,7 +4,8 @@
#
intel_pmc_core-y := core.o spt.o cnp.o icl.o \
- tgl.o adl.o mtl.o arl.o lnl.o ptl.o wcl.o
+ tgl.o adl.o mtl.o arl.o \
+ lnl.o ptl.o wcl.o nvl.o
obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core.o
intel_pmc_core_pltdrv-y := pltdrv.o
obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core_pltdrv.o
diff --git a/drivers/platform/x86/intel/pmc/arl.c b/drivers/platform/x86/intel/pmc/arl.c
index eb23bc68340ab..11609d593383b 100644
--- a/drivers/platform/x86/intel/pmc/arl.c
+++ b/drivers/platform/x86/intel/pmc/arl.c
@@ -672,6 +672,9 @@ static struct pmc_info arl_pmc_info_list[] = {
{}
};
+static const u8 arl_pmc_list[] = {PMC_IDX_MAIN, PMC_IDX_IOE, PMC_IDX_PCH};
+static const u8 arl_h_pmc_list[] = {PMC_IDX_MAIN, PMC_IDX_IOE};
+
#define ARL_NPU_PCI_DEV 0xad1d
#define ARL_GNA_PCI_DEV 0xae4c
#define ARL_H_NPU_PCI_DEV 0x7d1d
@@ -720,8 +723,9 @@ static int arl_h_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_
static u32 ARL_PMT_DMU_GUIDS[] = {ARL_PMT_DMU_GUID, 0x0};
struct pmc_dev_info arl_pmc_dev = {
- .pci_func = 0,
.dmu_guids = ARL_PMT_DMU_GUIDS,
+ .num_pmcs = ARRAY_SIZE(arl_pmc_list),
+ .pmc_list = arl_pmc_list,
.regmap_list = arl_pmc_info_list,
.map = &arl_socs_reg_map,
.sub_req_show = &pmc_core_substate_req_regs_fops,
@@ -729,12 +733,15 @@ struct pmc_dev_info arl_pmc_dev = {
.resume = arl_resume,
.init = arl_core_init,
.sub_req = pmc_core_pmt_get_lpm_req,
+ .ssram_hidden = true,
+ .die_c6_offset = MTL_PMT_DMU_DIE_C6_OFFSET,
};
static u32 ARL_H_PMT_DMU_GUIDS[] = {ARL_PMT_DMU_GUID, ARL_H_PMT_DMU_GUID, 0x0};
struct pmc_dev_info arl_h_pmc_dev = {
- .pci_func = 2,
.dmu_guids = ARL_H_PMT_DMU_GUIDS,
+ .num_pmcs = ARRAY_SIZE(arl_h_pmc_list),
+ .pmc_list = arl_h_pmc_list,
.regmap_list = arl_pmc_info_list,
.map = &mtl_socm_reg_map,
.sub_req_show = &pmc_core_substate_req_regs_fops,
@@ -742,4 +749,6 @@ struct pmc_dev_info arl_h_pmc_dev = {
.resume = arl_h_resume,
.init = arl_h_core_init,
.sub_req = pmc_core_pmt_get_lpm_req,
+ .ssram_hidden = true,
+ .die_c6_offset = MTL_PMT_DMU_DIE_C6_OFFSET,
};
diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c
index e5cb70ba57076..825ba5fa0bcb8 100644
--- a/drivers/platform/x86/intel/pmc/core.c
+++ b/drivers/platform/x86/intel/pmc/core.c
@@ -1072,6 +1072,44 @@ static int pmc_core_die_c6_us_show(struct seq_file *s, void *unused)
}
DEFINE_SHOW_ATTRIBUTE(pmc_core_die_c6_us);
+static int pmc_core_pkgc_counters_show(struct seq_file *s,
+ struct telem_endpoint *ep,
+ u32 offset, const char **counters)
+{
+ unsigned int i;
+ u32 counter;
+ int ret;
+
+ for (i = 0; counters[i]; i++) {
+ ret = pmt_telem_read32(ep, offset + i, &counter, 1);
+ if (ret)
+ return ret;
+ seq_printf(s, "%-30s %-30u\n", counters[i], counter);
+ }
+
+ return 0;
+}
+
+static int pmc_core_pkgc_ltr_blocker_show(struct seq_file *s, void *unused)
+{
+ struct pmc_dev *pmcdev = s->private;
+
+ return pmc_core_pkgc_counters_show(s, pmcdev->pc_ep,
+ pmcdev->pkgc_ltr_blocker_offset,
+ pmcdev->pkgc_ltr_blocker_counters);
+}
+DEFINE_SHOW_ATTRIBUTE(pmc_core_pkgc_ltr_blocker);
+
+static int pmc_core_pkgc_blocker_residency_show(struct seq_file *s, void *unused)
+{
+ struct pmc_dev *pmcdev = s->private;
+
+ return pmc_core_pkgc_counters_show(s, pmcdev->pc_ep,
+ pmcdev->pkgc_blocker_offset,
+ pmcdev->pkgc_blocker_counters);
+}
+DEFINE_SHOW_ATTRIBUTE(pmc_core_pkgc_blocker_residency);
+
static int pmc_core_lpm_latch_mode_show(struct seq_file *s, void *unused)
{
struct pmc_dev *pmcdev = s->private;
@@ -1323,28 +1361,45 @@ static struct telem_endpoint *pmc_core_register_endpoint(struct pci_dev *pcidev,
return ERR_PTR(-ENODEV);
}
-void pmc_core_punit_pmt_init(struct pmc_dev *pmcdev, u32 *guids)
+void pmc_core_punit_pmt_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info)
{
struct telem_endpoint *ep;
- struct pci_dev *pcidev;
- pcidev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(10, 0));
+ struct pci_dev *pcidev __free(pci_dev_put) = pci_get_domain_bus_and_slot(0, 0,
+ PCI_DEVFN(10, 0));
if (!pcidev) {
dev_err(&pmcdev->pdev->dev, "PUNIT PMT device not found.");
return;
}
- ep = pmc_core_register_endpoint(pcidev, guids);
- pci_dev_put(pcidev);
- if (IS_ERR(ep)) {
- dev_err(&pmcdev->pdev->dev,
- "pmc_core: couldn't get DMU telem endpoint %ld",
- PTR_ERR(ep));
- return;
+ if (pmc_dev_info->dmu_guids) {
+ ep = pmc_core_register_endpoint(pcidev, pmc_dev_info->dmu_guids);
+ if (IS_ERR(ep)) {
+ dev_err(&pmcdev->pdev->dev,
+ "pmc_core: couldn't get DMU telem endpoint %ld",
+ PTR_ERR(ep));
+ return;
+ }
+
+ pmcdev->punit_ep = ep;
+ pmcdev->die_c6_offset = pmc_dev_info->die_c6_offset;
}
- pmcdev->punit_ep = ep;
- pmcdev->die_c6_offset = MTL_PMT_DMU_DIE_C6_OFFSET;
+ if (pmc_dev_info->pc_guid) {
+ ep = pmt_telem_find_and_register_endpoint(&pcidev->dev, pmc_dev_info->pc_guid, 0);
+ if (IS_ERR(ep)) {
+ dev_err(&pmcdev->pdev->dev,
+ "pmc_core: couldn't get Package C-state telem endpoint %ld",
+ PTR_ERR(ep));
+ return;
+ }
+
+ pmcdev->pc_ep = ep;
+ pmcdev->pkgc_ltr_blocker_counters = pmc_dev_info->pkgc_ltr_blocker_counters;
+ pmcdev->pkgc_ltr_blocker_offset = pmc_dev_info->pkgc_ltr_blocker_offset;
+ pmcdev->pkgc_blocker_counters = pmc_dev_info->pkgc_blocker_counters;
+ pmcdev->pkgc_blocker_offset = pmc_dev_info->pkgc_blocker_offset;
+ }
}
void pmc_core_set_device_d3(unsigned int device)
@@ -1468,6 +1523,16 @@ static void pmc_core_dbgfs_register(struct pmc_dev *pmcdev, struct pmc_dev_info
pmcdev->dbgfs_dir, pmcdev,
&pmc_core_die_c6_us_fops);
}
+
+ if (pmcdev->pc_ep) {
+ debugfs_create_file("pkgc_ltr_blocker_show", 0444,
+ pmcdev->dbgfs_dir, pmcdev,
+ &pmc_core_pkgc_ltr_blocker_fops);
+ debugfs_create_file("pkgc_blocker_residency_show", 0444,
+ pmcdev->dbgfs_dir, pmcdev,
+ &pmc_core_pkgc_blocker_residency_fops);
+ }
+
}
/*
@@ -1582,17 +1647,13 @@ int pmc_core_pmt_get_blk_sub_req(struct pmc_dev *pmcdev, struct pmc *pmc,
static int pmc_core_get_telem_info(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info)
{
- struct pci_dev *pcidev __free(pci_dev_put) = NULL;
struct telem_endpoint *ep;
unsigned int pmc_idx;
int ret;
- pcidev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(20, pmc_dev_info->pci_func));
- if (!pcidev)
- return -ENODEV;
-
for (pmc_idx = 0; pmc_idx < ARRAY_SIZE(pmcdev->pmcs); ++pmc_idx) {
struct pmc *pmc;
+ u16 devid;
pmc = pmcdev->pmcs[pmc_idx];
if (!pmc)
@@ -1601,6 +1662,16 @@ static int pmc_core_get_telem_info(struct pmc_dev *pmcdev, struct pmc_dev_info *
if (!pmc->map->lpm_req_guid)
return -ENXIO;
+ if (pmc_dev_info->ssram_hidden)
+ devid = pmcdev->pmcs[PMC_IDX_MAIN]->devid;
+ else
+ devid = pmc->devid;
+
+ struct pci_dev *pcidev __free(pci_dev_put) =
+ pci_get_device(PCI_VENDOR_ID_INTEL, devid, NULL);
+ if (!pcidev)
+ return -ENODEV;
+
ep = pmt_telem_find_and_register_endpoint(&pcidev->dev, pmc->map->lpm_req_guid, 0);
if (IS_ERR(ep)) {
dev_dbg(&pmcdev->pdev->dev, "couldn't get telem endpoint %pe", ep);
@@ -1651,6 +1722,7 @@ static int pmc_core_pmc_add(struct pmc_dev *pmcdev, unsigned int pmc_idx)
pmc->map = map;
pmc->base_addr = pmc_ssram_telemetry.base_addr;
+ pmc->devid = pmc_ssram_telemetry.devid;
pmc->regbase = ioremap(pmc->base_addr, pmc->map->regmap_length);
if (!pmc->regbase) {
@@ -1663,16 +1735,17 @@ static int pmc_core_pmc_add(struct pmc_dev *pmcdev, unsigned int pmc_idx)
return 0;
}
-static int pmc_core_ssram_get_reg_base(struct pmc_dev *pmcdev)
+static int pmc_core_ssram_get_reg_base(struct pmc_dev *pmcdev, u8 num_pmcs, const u8 *pmc_list)
{
+ unsigned int i;
int ret;
- ret = pmc_core_pmc_add(pmcdev, PMC_IDX_MAIN);
- if (ret)
- return ret;
-
- pmc_core_pmc_add(pmcdev, PMC_IDX_IOE);
- pmc_core_pmc_add(pmcdev, PMC_IDX_PCH);
+ for (i = 0; i < num_pmcs; ++i) {
+ /* Non-MAIN PMCs are allowed to fail */
+ ret = pmc_core_pmc_add(pmcdev, pmc_list[i]);
+ if (ret && (pmc_list[i] == PMC_IDX_MAIN))
+ return ret;
+ }
return 0;
}
@@ -1694,7 +1767,9 @@ int generic_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info)
ssram = pmc_dev_info->regmap_list != NULL;
if (ssram) {
pmcdev->regmap_list = pmc_dev_info->regmap_list;
- ret = pmc_core_ssram_get_reg_base(pmcdev);
+ ret = pmc_core_ssram_get_reg_base(pmcdev,
+ pmc_dev_info->num_pmcs,
+ pmc_dev_info->pmc_list);
/*
* EAGAIN error code indicates Intel PMC SSRAM Telemetry driver
* has not finished probe and PMC info is not available yet. Try
@@ -1718,8 +1793,8 @@ int generic_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info)
}
pmc_core_get_low_power_modes(pmcdev);
- if (pmc_dev_info->dmu_guids)
- pmc_core_punit_pmt_init(pmcdev, pmc_dev_info->dmu_guids);
+ if (pmc_dev_info->dmu_guids || pmc_dev_info->pc_guid)
+ pmc_core_punit_pmt_init(pmcdev, pmc_dev_info);
if (ssram) {
ret = pmc_core_get_telem_info(pmcdev, pmc_dev_info);
@@ -1740,6 +1815,9 @@ unmap_regbase:
if (pmcdev->punit_ep)
pmt_telem_unregister_endpoint(pmcdev->punit_ep);
+ if (pmcdev->pc_ep)
+ pmt_telem_unregister_endpoint(pmcdev->pc_ep);
+
return ret;
}
@@ -1772,6 +1850,8 @@ static const struct x86_cpu_id intel_pmc_core_ids[] = {
X86_MATCH_VFM(INTEL_LUNARLAKE_M, &lnl_pmc_dev),
X86_MATCH_VFM(INTEL_PANTHERLAKE_L, &ptl_pmc_dev),
X86_MATCH_VFM(INTEL_WILDCATLAKE_L, &wcl_pmc_dev),
+ X86_MATCH_VFM(INTEL_NOVALAKE, &nvl_s_pmc_dev),
+ X86_MATCH_VFM(INTEL_NOVALAKE_L, &nvl_h_pmc_dev),
{}
};
@@ -1836,6 +1916,9 @@ static void pmc_core_clean_structure(struct platform_device *pdev)
if (pmcdev->punit_ep)
pmt_telem_unregister_endpoint(pmcdev->punit_ep);
+ if (pmcdev->pc_ep)
+ pmt_telem_unregister_endpoint(pmcdev->pc_ep);
+
platform_set_drvdata(pdev, NULL);
}
diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h
index 118c8740ad3aa..55cf567febe4f 100644
--- a/drivers/platform/x86/intel/pmc/core.h
+++ b/drivers/platform/x86/intel/pmc/core.h
@@ -46,7 +46,7 @@ struct telem_endpoint;
#define SPT_PMC_SLP_S0_RES_COUNTER_STEP 0x68
#define PMC_BASE_ADDR_MASK ~(SPT_PMC_MMIO_REG_LEN - 1)
#define MTPMC_MASK 0xffff0000
-#define PPFEAR_MAX_NUM_ENTRIES 12
+#define PPFEAR_MAX_NUM_ENTRIES 13
#define SPT_PPFEAR_NUM_ENTRIES 5
#define SPT_PMC_READ_DISABLE_BIT 0x16
#define SPT_PMC_MSG_FULL_STS_BIT 0x18
@@ -307,6 +307,29 @@ enum ppfear_regs {
#define WCL_NUM_S0IX_BLOCKER 94
#define WCL_BLK_REQ_OFFSET 50
+/* Nova Lake */
+#define NVL_PCDH_PPFEAR_NUM_ENTRIES 13
+#define NVL_PCDH_PMC_MMIO_REG_LEN 0x363c
+#define NVL_PCDS_PMC_MMIO_REG_LEN 0x3118
+#define NVL_PCHS_PMC_MMIO_REG_LEN 0x30d8
+#define NVL_LPM_PRI_OFFSET 0x17a4
+#define NVL_LPM_EN_OFFSET 0x17a0
+#define NVL_LPM_RESIDENCY_OFFSET 0x17a8
+#define NVL_LPM_LIVE_STATUS_OFFSET 0x1760
+#define NVL_LPM_NUM_MAPS 15
+#define NVL_PCDH_NUM_S0IX_BLOCKER 107
+#define NVL_PCDS_NUM_S0IX_BLOCKER 71
+#define NVL_PCHS_NUM_S0IX_BLOCKER 54
+#define NVL_PCDS_PMC_LTR_RESERVED 0x1bac
+#define NVL_PCDH_BLK_REQ_OFFSET 53
+#define NVL_PCDS_BLK_REQ_OFFSET 18
+#define NVL_PCHS_BLK_REQ_OFFSET 46
+#define NVL_PMT_PC_GUID 0x13000101
+#define NVL_PMT_DMU_GUID 0x1a000101
+#define NVL_LTR_BLK_OFFSET 64
+#define NVL_PKGC_BLK_OFFSET 4
+#define NVL_PMT_DMU_DIE_C6_OFFSET 25
+
/* SSRAM PMC Device ID */
/* LNL */
#define PMC_DEVID_LNL_SOCM 0xa87f
@@ -329,6 +352,11 @@ enum ppfear_regs {
#define PMC_DEVID_MTL_IOEP 0x7ecf
#define PMC_DEVID_MTL_IOEM 0x7ebf
+/* NVL */
+#define PMC_DEVID_NVL_PCDH 0xd37e
+#define PMC_DEVID_NVL_PCDS 0xd47e
+#define PMC_DEVID_NVL_PCHS 0x6e27
+
extern const char *pmc_lpm_modes[];
struct pmc_bit_map {
@@ -425,6 +453,7 @@ struct pmc_info {
* @ltr_ign: Holds LTR ignore data while suspended
* @num_lpm_modes: Count of enabled modes
* @lpm_en_modes: Array of enabled modes from lowest to highest priority
+ * @devid: Device ID of the SSRAM device
*
* pmc contains info about one power management controller device.
*/
@@ -436,6 +465,7 @@ struct pmc {
u32 ltr_ign;
u8 num_lpm_modes;
u8 lpm_en_modes[LPM_MAX_NUM_MODES];
+ u16 devid;
};
/**
@@ -453,6 +483,11 @@ struct pmc {
* @suspend: Function to perform platform specific suspend
* @resume: Function to perform platform specific resume
*
+ * @pkgc_ltr_blocker_counters: Array of PKGC LTR blocker counters
+ * @pkgc_ltr_blocker_offset: Offset to PKGC LTR blockers in telemetry region
+ * @pkgc_blocker_counters: Array of PKGC blocker counters
+ * @pkgc_blocker_offset: Offset to PKGC blocker in telemetry region
+ *
* pmc_dev contains info about power management controller device.
*/
struct pmc_dev {
@@ -471,8 +506,14 @@ struct pmc_dev {
u8 num_of_pkgc;
u32 die_c6_offset;
+ struct telem_endpoint *pc_ep;
struct telem_endpoint *punit_ep;
struct pmc_info *regmap_list;
+
+ const char **pkgc_ltr_blocker_counters;
+ u32 pkgc_ltr_blocker_offset;
+ const char **pkgc_blocker_counters;
+ u32 pkgc_blocker_offset;
};
enum pmc_index {
@@ -484,29 +525,45 @@ enum pmc_index {
/**
* struct pmc_dev_info - Structure to keep PMC device info
- * @pci_func: Function number of the primary PMC
* @dmu_guids: List of Die Management Unit GUID
+ * @pc_guid: GUID for telemetry region to read PKGC blocker info
+ * @pkgc_ltr_blocker_offset: Offset to PKGC LTR blockers in telemetry region
+ * @pkgc_blocker_offset:Offset to PKGC blocker in telemetry region
+ * @num_pmcs: Number of entries in @pmc_list
+ * @pmc_list: Index list of available PMC
* @regmap_list: Pointer to a list of pmc_info structure that could be
* available for the platform. When set, this field implies
* SSRAM support.
* @map: Pointer to a pmc_reg_map struct that contains platform
* specific attributes of the primary PMC
* @sub_req_show: File operations to show substate requirements
+ * @pkgc_ltr_blocker_counters: Array of PKGC LTR blocker counters
+ * @pkgc_blocker_counters: Array of PKGC blocker counters
* @suspend: Function to perform platform specific suspend
* @resume: Function to perform platform specific resume
* @init: Function to perform platform specific init action
* @sub_req: Function to achieve low power mode substate requirements
+ * @ssram_hidden: Some SSRAM devices are hidden on this platform
+ * @die_c6_offset: Telemetry offset to read Die C6 residency
*/
struct pmc_dev_info {
- u8 pci_func;
u32 *dmu_guids;
+ u32 pc_guid;
+ u32 pkgc_ltr_blocker_offset;
+ u32 pkgc_blocker_offset;
+ u8 num_pmcs;
+ const u8 *pmc_list;
struct pmc_info *regmap_list;
const struct pmc_reg_map *map;
const struct file_operations *sub_req_show;
+ const char **pkgc_ltr_blocker_counters;
+ const char **pkgc_blocker_counters;
void (*suspend)(struct pmc_dev *pmcdev);
int (*resume)(struct pmc_dev *pmcdev);
int (*init)(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info);
int (*sub_req)(struct pmc_dev *pmcdev, struct pmc *pmc, struct telem_endpoint *ep);
+ bool ssram_hidden;
+ u32 die_c6_offset;
};
extern const struct pmc_bit_map msr_map[];
@@ -529,13 +586,14 @@ extern const struct pmc_reg_map mtl_ioep_reg_map;
extern const struct pmc_bit_map ptl_pcdp_clocksource_status_map[];
extern const struct pmc_bit_map ptl_pcdp_vnn_req_status_3_map[];
extern const struct pmc_bit_map ptl_pcdp_signal_status_map[];
+extern const struct pmc_bit_map ptl_pcdp_ltr_show_map[];
void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev);
int pmc_core_send_ltr_ignore(struct pmc_dev *pmcdev, u32 value, int ignore);
int pmc_core_resume_common(struct pmc_dev *pmcdev);
int get_primary_reg_base(struct pmc *pmc);
-void pmc_core_punit_pmt_init(struct pmc_dev *pmcdev, u32 *guids);
+void pmc_core_punit_pmt_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info);
void pmc_core_set_device_d3(unsigned int device);
int generic_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info);
@@ -552,6 +610,8 @@ extern struct pmc_dev_info arl_h_pmc_dev;
extern struct pmc_dev_info lnl_pmc_dev;
extern struct pmc_dev_info ptl_pmc_dev;
extern struct pmc_dev_info wcl_pmc_dev;
+extern struct pmc_dev_info nvl_s_pmc_dev;
+extern struct pmc_dev_info nvl_h_pmc_dev;
void cnl_suspend(struct pmc_dev *pmcdev);
int cnl_resume(struct pmc_dev *pmcdev);
diff --git a/drivers/platform/x86/intel/pmc/lnl.c b/drivers/platform/x86/intel/pmc/lnl.c
index 1cd81ee54dcf8..5ff4922825d91 100644
--- a/drivers/platform/x86/intel/pmc/lnl.c
+++ b/drivers/platform/x86/intel/pmc/lnl.c
@@ -544,6 +544,8 @@ static struct pmc_info lnl_pmc_info_list[] = {
{}
};
+static const u8 lnl_pmc_list[] = {PMC_IDX_MAIN};
+
#define LNL_NPU_PCI_DEV 0x643e
#define LNL_IPU_PCI_DEV 0x645d
@@ -571,7 +573,8 @@ static int lnl_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_in
}
struct pmc_dev_info lnl_pmc_dev = {
- .pci_func = 2,
+ .num_pmcs = ARRAY_SIZE(lnl_pmc_list),
+ .pmc_list = lnl_pmc_list,
.regmap_list = lnl_pmc_info_list,
.map = &lnl_socm_reg_map,
.sub_req_show = &pmc_core_substate_req_regs_fops,
@@ -579,4 +582,5 @@ struct pmc_dev_info lnl_pmc_dev = {
.resume = lnl_resume,
.init = lnl_core_init,
.sub_req = pmc_core_pmt_get_lpm_req,
+ .ssram_hidden = true,
};
diff --git a/drivers/platform/x86/intel/pmc/mtl.c b/drivers/platform/x86/intel/pmc/mtl.c
index 57508cbf9cd42..9abeabd3dbe27 100644
--- a/drivers/platform/x86/intel/pmc/mtl.c
+++ b/drivers/platform/x86/intel/pmc/mtl.c
@@ -965,6 +965,8 @@ static struct pmc_info mtl_pmc_info_list[] = {
{}
};
+static const u8 mtl_pmc_list[] = {PMC_IDX_MAIN, PMC_IDX_IOE};
+
#define MTL_GNA_PCI_DEV 0x7e4c
#define MTL_IPU_PCI_DEV 0x7d19
#define MTL_VPU_PCI_DEV 0x7d1d
@@ -994,8 +996,9 @@ static int mtl_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_in
static u32 MTL_PMT_DMU_GUIDS[] = {MTL_PMT_DMU_GUID, 0x0};
struct pmc_dev_info mtl_pmc_dev = {
- .pci_func = 2,
.dmu_guids = MTL_PMT_DMU_GUIDS,
+ .num_pmcs = ARRAY_SIZE(mtl_pmc_list),
+ .pmc_list = mtl_pmc_list,
.regmap_list = mtl_pmc_info_list,
.map = &mtl_socm_reg_map,
.sub_req_show = &pmc_core_substate_req_regs_fops,
@@ -1003,4 +1006,6 @@ struct pmc_dev_info mtl_pmc_dev = {
.resume = mtl_resume,
.init = mtl_core_init,
.sub_req = pmc_core_pmt_get_lpm_req,
+ .ssram_hidden = true,
+ .die_c6_offset = MTL_PMT_DMU_DIE_C6_OFFSET,
};
diff --git a/drivers/platform/x86/intel/pmc/nvl.c b/drivers/platform/x86/intel/pmc/nvl.c
new file mode 100644
index 0000000000000..8dabf2511dd9d
--- /dev/null
+++ b/drivers/platform/x86/intel/pmc/nvl.c
@@ -0,0 +1,1539 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * This file contains platform specific structure definitions
+ * and init function used by Nova Lake PCH.
+ *
+ * Copyright (c) 2026, Intel Corporation.
+ */
+
+#include <linux/bits.h>
+#include <linux/pci.h>
+
+#include "core.h"
+
+/* PMC SSRAM PMT Telemetry GUIDS */
+#define PCDH_LPM_REQ_GUID 0x01093101
+#define PCHS_LPM_REQ_GUID 0x01092101
+#define PCDS_LPM_REQ_GUID 0x01091102
+
+/*
+ * Die Mapping to Product.
+ * Product PCDDie PCHDie
+ * NVL-H PCD-H None
+ * NVL-S PCD-S PCH-S
+ */
+
+static const struct pmc_bit_map nvl_pcdh_pfear_map[] = {
+ {"PMC_PGD0", BIT(0)},
+ {"FUSE_OSSE_PGD0", BIT(1)},
+ {"SPI_PGD0", BIT(2)},
+ {"XHCI_PGD0", BIT(3)},
+ {"SPA_PGD0", BIT(4)},
+ {"SPB_PGD0", BIT(5)},
+ {"MPFPW2_PGD0", BIT(6)},
+ {"GBE_PGD0", BIT(7)},
+
+ {"SBR16B20_PGD0", BIT(0)},
+ {"DBG_SBR_PGD0", BIT(1)},
+ {"SBR16B7_PGD0", BIT(2)},
+ {"STRC_PGD0", BIT(3)},
+ {"SBR16B8_PGD0", BIT(4)},
+ {"D2D_DISP_PGD1", BIT(5)},
+ {"LPSS_PGD0", BIT(6)},
+ {"LPC_PGD0", BIT(7)},
+
+ {"SMB_PGD0", BIT(0)},
+ {"ISH_PGD0", BIT(1)},
+ {"SBR16B2_PGD0", BIT(2)},
+ {"NPK_PGD0", BIT(3)},
+ {"D2D_NOC_PGD1", BIT(4)},
+ {"DBG_SBR16B_PGD0", BIT(5)},
+ {"FUSE_PGD0", BIT(6)},
+ {"SBR16B0_PGD0", BIT(7)},
+
+ {"P2SB0_PGD0", BIT(0)},
+ {"OTG_PGD0", BIT(1)},
+ {"EXI_PGD0", BIT(2)},
+ {"CSE_PGD0", BIT(3)},
+ {"CSME_KVM_PGD0", BIT(4)},
+ {"CSME_PMT_PGD0", BIT(5)},
+ {"CSME_CLINK_PGD0", BIT(6)},
+ {"SBR16B21_PGD0", BIT(7)},
+
+ {"CSME_USBR_PGD0", BIT(0)},
+ {"SBR16B22_PGD0", BIT(1)},
+ {"CSME_SMT1_PGD0", BIT(2)},
+ {"MPFPW1_PGD0", BIT(3)},
+ {"CSME_SMS2_PGD0", BIT(4)},
+ {"CSME_SMS_PGD0", BIT(5)},
+ {"CSME_RTC_PGD0", BIT(6)},
+ {"CSMEPSF_PGD0", BIT(7)},
+
+ {"D2D_NOC_PGD0", BIT(0)},
+ {"ESE_PGD0", BIT(1)},
+ {"SBR16B6_PGD0", BIT(2)},
+ {"P2SB1_PGD0", BIT(3)},
+ {"SBR16B3_PGD0", BIT(4)},
+ {"OSSE_SMT1_PGD0", BIT(5)},
+ {"D2D_DISP_PGD0", BIT(6)},
+ {"SNPS_USB2_A_PGD0", BIT(7)},
+
+ {"U3FPW1_PGD0", BIT(0)},
+ {"FIA_X_PGD0", BIT(1)},
+ {"PSF4_PGD0", BIT(2)},
+ {"CNVI_PGD0", BIT(3)},
+ {"UFSX2_PGD0", BIT(4)},
+ {"ENDBG_PGD0", BIT(5)},
+ {"DBC_PGD0", BIT(6)},
+ {"FIA_PG_PGD0", BIT(7)},
+
+ {"D2D_IPU_PGD0", BIT(0)},
+ {"NPK_PGD1", BIT(1)},
+ {"FIACPCB_X_PGD0", BIT(2)},
+ {"SBR8B4_PGD0", BIT(3)},
+ {"DBG_PSF_PGD0", BIT(4)},
+ {"PSF6_PGD0", BIT(5)},
+ {"UFSPW1_PGD0", BIT(6)},
+ {"FIA_U_PGD0", BIT(7)},
+
+ {"PSF8_PGD0", BIT(0)},
+ {"SBR16B9_PGD0", BIT(1)},
+ {"PSF0_PGD0", BIT(2)},
+ {"FIACPCB_U_PGD0", BIT(3)},
+ {"TAM_PGD0", BIT(4)},
+ {"D2D_NOC_PGD2", BIT(5)},
+ {"SBR8B2_PGD0", BIT(6)},
+ {"THC0_PGD0", BIT(7)},
+
+ {"THC1_PGD0", BIT(0)},
+ {"PMC_PGD1", BIT(1)},
+ {"DISP_PGA1_PGD0", BIT(2)},
+ {"TCSS_PGD0", BIT(3)},
+ {"DISP_PGA_PGD0", BIT(4)},
+ {"SBR16B1_PGD0", BIT(5)},
+ {"SBRG_PGD0", BIT(6)},
+ {"PSF5_PGD0", BIT(7)},
+
+ {"SBR8B3_PGD0", BIT(0)},
+ {"ACE_PGD0", BIT(1)},
+ {"ACE_PGD1", BIT(2)},
+ {"ACE_PGD2", BIT(3)},
+ {"ACE_PGD3", BIT(4)},
+ {"ACE_PGD4", BIT(5)},
+ {"ACE_PGD5", BIT(6)},
+ {"ACE_PGD6", BIT(7)},
+
+ {"ACE_PGD7", BIT(0)},
+ {"ACE_PGD8", BIT(1)},
+ {"ACE_PGD9", BIT(2)},
+ {"ACE_PGD10", BIT(3)},
+ {"FIACPCB_PG_PGD0", BIT(4)},
+ {"SNPS_USB2_B_PGD0", BIT(5)},
+ {"OSSE_PGD0", BIT(6)},
+ {"SBR8B0_PGD0", BIT(7)},
+
+ {"SBR16B4_PGD0", BIT(0)},
+ {"CSME_PTIO_PGD0", BIT(1)},
+ {}
+};
+
+static const struct pmc_bit_map *ext_nvl_pcdh_pfear_map[] = {
+ nvl_pcdh_pfear_map,
+ NULL
+};
+
+static const struct pmc_bit_map nvl_pcdh_clocksource_status_map[] = {
+ {"AON2_OFF_STS", BIT(0), 1},
+ {"AON3_OFF_STS", BIT(1), 0},
+ {"AON4_OFF_STS", BIT(2), 1},
+ {"AON5_OFF_STS", BIT(3), 1},
+ {"AON1_OFF_STS", BIT(4), 0},
+ {"XTAL_LVM_OFF_STS", BIT(5), 0},
+ {"MPFPW1_0_PLL_OFF_STS", BIT(6), 1},
+ {"D2D_PLL_OFF_STS", BIT(7), 1},
+ {"USB3_PLL_OFF_STS", BIT(8), 1},
+ {"AON3_SPL_OFF_STS", BIT(9), 1},
+ {"MPFPW2_0_PLL_OFF_STS", BIT(12), 1},
+ {"XTAL_AGGR_OFF_STS", BIT(17), 1},
+ {"USB2_PLL_OFF_STS", BIT(18), 0},
+ {"DDI2_PLL_OFF_STS", BIT(19), 1},
+ {"SE_TCSS_PLL_OFF_STS", BIT(20), 1},
+ {"DDI_PLL_OFF_STS", BIT(21), 1},
+ {"FILTER_PLL_OFF_STS", BIT(22), 1},
+ {"ACE_PLL_OFF_STS", BIT(24), 0},
+ {"FABRIC_PLL_OFF_STS", BIT(25), 1},
+ {"SOC_PLL_OFF_STS", BIT(26), 1},
+ {"REF_PLL_OFF_STS", BIT(28), 1},
+ {"IMG_PLL_OFF_STS", BIT(29), 1},
+ {"GENLOCK_FILTER_PLL_OFF_STS", BIT(30), 1},
+ {"RTC_PLL_OFF_STS", BIT(31), 0},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcdh_power_gating_status_0_map[] = {
+ {"PMC_PGD0_PG_STS", BIT(0), 0},
+ {"FUSE_OSSE_PGD0_PG_STS", BIT(1), 0},
+ {"ESPISPI_PGD0_PG_STS", BIT(2), 0},
+ {"XHCI_PGD0_PG_STS", BIT(3), 1},
+ {"SPA_PGD0_PG_STS", BIT(4), 1},
+ {"SPB_PGD0_PG_STS", BIT(5), 1},
+ {"MPFPW2_PGD0_PG_STS", BIT(6), 0},
+ {"GBE_PGD0_PG_STS", BIT(7), 1},
+ {"SBR16B20_PGD0_PG_STS", BIT(8), 0},
+ {"DBG_PGD0_PG_STS", BIT(9), 0},
+ {"SBR16B7_PGD0_PG_STS", BIT(10), 0},
+ {"STRC_PGD0_PG_STS", BIT(11), 0},
+ {"SBR16B8_PGD0_PG_STS", BIT(12), 0},
+ {"D2D_DISP_PGD1_PG_STS", BIT(13), 1},
+ {"LPSS_PGD0_PG_STS", BIT(14), 1},
+ {"LPC_PGD0_PG_STS", BIT(15), 0},
+ {"SMB_PGD0_PG_STS", BIT(16), 0},
+ {"ISH_PGD0_PG_STS", BIT(17), 0},
+ {"SBR16B2_PGD0_PG_STS", BIT(18), 0},
+ {"NPK_PGD0_PG_STS", BIT(19), 0},
+ {"D2D_NOC_PGD1_PG_STS", BIT(20), 1},
+ {"DBG_SBR16B_PGD0_PG_STS", BIT(21), 0},
+ {"FUSE_PGD0_PG_STS", BIT(22), 0},
+ {"SBR16B0_PGD0_PG_STS", BIT(23), 0},
+ {"P2SB0_PGD0_PG_STS", BIT(24), 1},
+ {"XDCI_PGD0_PG_STS", BIT(25), 1},
+ {"EXI_PGD0_PG_STS", BIT(26), 0},
+ {"CSE_PGD0_PG_STS", BIT(27), 1},
+ {"KVMCC_PGD0_PG_STS", BIT(28), 1},
+ {"PMT_PGD0_PG_STS", BIT(29), 1},
+ {"CLINK_PGD0_PG_STS", BIT(30), 1},
+ {"SBR16B21_PGD0_PG_STS", BIT(31), 0},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcdh_power_gating_status_1_map[] = {
+ {"USBR0_PGD0_PG_STS", BIT(0), 1},
+ {"SBR16B22_PGD0_PG_STS", BIT(1), 0},
+ {"SMT1_PGD0_PG_STS", BIT(2), 1},
+ {"MPFPW1_PGD0_PG_STS", BIT(3), 0},
+ {"SMS2_PGD0_PG_STS", BIT(4), 1},
+ {"SMS1_PGD0_PG_STS", BIT(5), 1},
+ {"CSMERTC_PGD0_PG_STS", BIT(6), 0},
+ {"CSMEPSF_PGD0_PG_STS", BIT(7), 0},
+ {"D2D_NOC_PGD0_PG_STS", BIT(8), 0},
+ {"ESE_PGD0_PG_STS", BIT(9), 1},
+ {"SBR16B6_PGD0_PG_STS", BIT(10), 0},
+ {"P2SB1_PGD0_PG_STS", BIT(11), 1},
+ {"SBR16B3_PGD0_PG_STS", BIT(12), 0},
+ {"OSSE_SMT1_PGD0_PG_STS", BIT(13), 1},
+ {"D2D_DISP_PGD0_PG_STS", BIT(14), 1},
+ {"SNPA_USB2_A_PGD0_PG_STS", BIT(15), 0},
+ {"U3FPW1_PGD0_PG_STS", BIT(16), 0},
+ {"FIA_X_PGD0_PG_STS", BIT(17), 0},
+ {"PSF4_PGD0_PG_STS", BIT(18), 0},
+ {"CNVI_PGD0_PG_STS", BIT(19), 0},
+ {"UFSX2_PGD0_PG_STS", BIT(20), 1},
+ {"ENDBG_PGD0_PG_STS", BIT(21), 0},
+ {"DBC_PGD0_PG_STS", BIT(22), 0},
+ {"FIA_PG_PGD0_PG_STS", BIT(23), 0},
+ {"D2D_IPU_PGD0_PG_STS", BIT(24), 1},
+ {"NPK_PGD1_PG_STS", BIT(25), 0},
+ {"FIACPCB_X_PGD0_PG_STS", BIT(26), 0},
+ {"SBR8B4_PGD0_PG_STS", BIT(27), 0},
+ {"DBG_PSF_PGD0_PG_STS", BIT(28), 0},
+ {"PSF6_PGD0_PG_STS", BIT(29), 0},
+ {"UFSPW1_PGD0_PG_STS", BIT(30), 0},
+ {"FIA_U_PGD0_PG_STS", BIT(31), 0},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcdh_power_gating_status_2_map[] = {
+ {"PSF8_PGD0_PG_STS", BIT(0), 0},
+ {"SBR16B9_PGD0_PG_STS", BIT(1), 0},
+ {"PSF0_PGD0_PG_STS", BIT(2), 0},
+ {"FIACPCB_U_PGD0_PG_STS", BIT(3), 0},
+ {"TAM_PGD0_PG_STS", BIT(4), 1},
+ {"D2D_NOC_PGD2_PG_STS", BIT(5), 1},
+ {"SBR8B2_PGD0_PG_STS", BIT(6), 0},
+ {"THC0_PGD0_PG_STS", BIT(7), 1},
+ {"THC1_PGD0_PG_STS", BIT(8), 1},
+ {"PMC_PGD1_PG_STS", BIT(9), 0},
+ {"DISP_PGA1_PGD0_PG_STS", BIT(10), 0},
+ {"TCSS_PGD0_PG_STS", BIT(11), 0},
+ {"DISP_PGA_PGD0_PG_STS", BIT(12), 0},
+ {"SBR16B1_PGD0_PG_STS", BIT(13), 0},
+ {"SBRG_PGD0_PG_STS", BIT(14), 0},
+ {"PSF5_PGD0_PG_STS", BIT(15), 0},
+ {"SBR8B3_PGD0_PG_STS", BIT(16), 0},
+ {"ACE_PGD0_PG_STS", BIT(17), 0},
+ {"ACE_PGD1_PG_STS", BIT(18), 0},
+ {"ACE_PGD2_PG_STS", BIT(19), 0},
+ {"ACE_PGD3_PG_STS", BIT(20), 0},
+ {"ACE_PGD4_PG_STS", BIT(21), 0},
+ {"ACE_PGD5_PG_STS", BIT(22), 0},
+ {"ACE_PGD6_PG_STS", BIT(23), 0},
+ {"ACE_PGD7_PG_STS", BIT(24), 0},
+ {"ACE_PGD8_PG_STS", BIT(25), 0},
+ {"ACE_PGD9_PG_STS", BIT(26), 0},
+ {"ACE_PGD10_PG_STS", BIT(27), 0},
+ {"FIACPCB_PG_PGD0_PG_STS", BIT(28), 0},
+ {"SNPS_USB2_B_PGD0_PG_STS", BIT(29), 0},
+ {"OSSE_PGD0_PG_STS", BIT(30), 1},
+ {"SBR8B0_PGD0_PG_STS", BIT(31), 0},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcdh_power_gating_status_3_map[] = {
+ {"SBR16B4_PGD0_PG_STS", BIT(0), 0},
+ {"PTIO_PGD0_PG_STS", BIT(1), 1},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcdh_d3_status_0_map[] = {
+ {"LPSS_D3_STS", BIT(3), 1},
+ {"XDCI_D3_STS", BIT(4), 1},
+ {"XHCI_D3_STS", BIT(5), 1},
+ {"OSSE_D3_STS", BIT(6), 0},
+ {"SPA_D3_STS", BIT(12), 0},
+ {"SPB_D3_STS", BIT(13), 0},
+ {"ESPISPI_D3_STS", BIT(18), 0},
+ {"PSTH_D3_STS", BIT(21), 0},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcdh_d3_status_1_map[] = {
+ {"OSSE_SMT1_D3_STS", BIT(0), 0},
+ {"GBE_D3_STS", BIT(19), 0},
+ {"ITSS_D3_STS", BIT(23), 0},
+ {"CNVI_D3_STS", BIT(27), 0},
+ {"UFSX2_D3_STS", BIT(28), 0},
+ {"ESE_D3_STS", BIT(29), 0},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcdh_d3_status_2_map[] = {
+ {"CSMERTC_D3_STS", BIT(1), 0},
+ {"CSE_D3_STS", BIT(4), 0},
+ {"KVMCC_D3_STS", BIT(5), 0},
+ {"USBR0_D3_STS", BIT(6), 0},
+ {"ISH_D3_STS", BIT(7), 0},
+ {"SMT1_D3_STS", BIT(8), 0},
+ {"SMT2_D3_STS", BIT(9), 0},
+ {"SMT3_D3_STS", BIT(10), 0},
+ {"OSSE_SMT2_D3_STS", BIT(11), 0},
+ {"CLINK_D3_STS", BIT(14), 0},
+ {"PTIO_D3_STS", BIT(16), 0},
+ {"PMT_D3_STS", BIT(17), 0},
+ {"SMS1_D3_STS", BIT(18), 0},
+ {"SMS2_D3_STS", BIT(19), 0},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcdh_d3_status_3_map[] = {
+ {"THC0_D3_STS", BIT(14), 1},
+ {"THC1_D3_STS", BIT(15), 1},
+ {"OSSE_SMT3_D3_STS", BIT(16), 0},
+ {"ACE_D3_STS", BIT(23), 0},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcdh_vnn_req_status_0_map[] = {
+ {"LPSS_VNN_REQ_STS", BIT(3), 1},
+ {"OSSE_VNN_REQ_STS", BIT(6), 1},
+ {"ESPISPI_VNN_REQ_STS", BIT(18), 1},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcdh_vnn_req_status_1_map[] = {
+ {"OSSE_SMT1_VNN_REQ_STS", BIT(0), 1},
+ {"NPK_VNN_REQ_STS", BIT(4), 1},
+ {"DFXAGG_VNN_REQ_STS", BIT(8), 0},
+ {"EXI_VNN_REQ_STS", BIT(9), 1},
+ {"P2D_VNN_REQ_STS", BIT(18), 1},
+ {"GBE_VNN_REQ_STS", BIT(19), 1},
+ {"SMB_VNN_REQ_STS", BIT(25), 1},
+ {"LPC_VNN_REQ_STS", BIT(26), 0},
+ {"ESE_VNN_REQ_STS", BIT(29), 1},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcdh_vnn_req_status_2_map[] = {
+ {"CSMERTC_VNN_REQ_STS", BIT(1), 1},
+ {"CSE_VNN_REQ_STS", BIT(4), 1},
+ {"ISH_VNN_REQ_STS", BIT(7), 1},
+ {"SMT1_VNN_REQ_STS", BIT(8), 1},
+ {"CLINK_VNN_REQ_STS", BIT(14), 1},
+ {"SMS1_VNN_REQ_STS", BIT(18), 1},
+ {"SMS2_VNN_REQ_STS", BIT(19), 1},
+ {"GPIOCOM4_VNN_REQ_STS", BIT(20), 1},
+ {"GPIOCOM3_VNN_REQ_STS", BIT(21), 1},
+ {"DISP_SHIM_VNN_REQ_STS", BIT(22), 1},
+ {"GPIOCOM1_VNN_REQ_STS", BIT(23), 1},
+ {"GPIOCOM0_VNN_REQ_STS", BIT(24), 1},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcdh_vnn_req_status_3_map[] = {
+ {"DTS0_VNN_REQ_STS", BIT(7), 0},
+ {"GPIOCOM5_VNN_REQ_STS", BIT(11), 1},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcdh_vnn_misc_status_map[] = {
+ {"CPU_C10_REQ_STS", BIT(0), 0},
+ {"TS_OFF_REQ_STS", BIT(1), 0},
+ {"PNDE_MET_REQ_STS", BIT(2), 1},
+ {"PG5_PMA0_REQ_STS", BIT(3), 1},
+ {"FW_THROTTLE_ALLOWED_REQ_STS", BIT(4), 0},
+ {"VNN_SOC_REQ_STS", BIT(6), 1},
+ {"ISH_VNNAON_REQ_STS", BIT(7), 0},
+ {"D2D_NOC_CFI_QACTIVE_REQ_STS", BIT(8), 1},
+ {"D2D_NOC_GPSB_QACTIVE_REQ_STS", BIT(9), 1},
+ {"D2D_IPU_QACTIVE_REQ_STS", BIT(10), 1},
+ {"PLT_GREATER_REQ_STS", BIT(11), 1},
+ {"ALL_SBR_IDLE_REQ_STS", BIT(12), 0},
+ {"PMC_IDLE_FB_OCP_REQ_STS", BIT(13), 0},
+ {"PM_SYNC_STATES_REQ_STS", BIT(14), 0},
+ {"EA_REQ_STS", BIT(15), 0},
+ {"MPHY_CORE_OFF_REQ_STS", BIT(16), 0},
+ {"BRK_EV_EN_REQ_STS", BIT(17), 0},
+ {"AUTO_DEMO_EN_REQ_STS", BIT(18), 0},
+ {"ITSS_CLK_SRC_REQ_STS", BIT(19), 1},
+ {"ARC_IDLE_REQ_STS", BIT(21), 0},
+ {"PG5_PMA1_REQ_STS", BIT(22), 1},
+ {"FIA_DEEP_PM_REQ_STS", BIT(23), 0},
+ {"XDCI_ATTACHED_REQ_STS", BIT(24), 1},
+ {"ARC_INTERRUPT_WAKE_REQ_STS", BIT(25), 0},
+ {"D2D_DISP_DDI_QACTIVE_REQ_STS", BIT(26), 1},
+ {"PRE_WAKE0_REQ_STS", BIT(27), 1},
+ {"PRE_WAKE1_REQ_STS", BIT(28), 1},
+ {"PRE_WAKE2_REQ_STS", BIT(29), 1},
+ {"PG5_PMA2_GVNN", BIT(30), 1},
+ {"D2D_DISP_EDP_QACTIVE_REQ_STS", BIT(31), 1},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcdh_rsc_status_map[] = {
+ {"CORE", 0, 1},
+ {"Memory", 0, 1},
+ {"PRIM_D2D", 0, 1},
+ {"PSF0", 0, 1},
+ {"PSF4", 0, 1},
+ {"PSF6", 0, 1},
+ {"PSF8", 0, 1},
+ {"SB", 0, 1},
+ {}
+};
+
+static const struct pmc_bit_map *nvl_pcdh_lpm_maps[] = {
+ nvl_pcdh_clocksource_status_map,
+ nvl_pcdh_power_gating_status_0_map,
+ nvl_pcdh_power_gating_status_1_map,
+ nvl_pcdh_power_gating_status_2_map,
+ nvl_pcdh_power_gating_status_3_map,
+ nvl_pcdh_d3_status_0_map,
+ nvl_pcdh_d3_status_1_map,
+ nvl_pcdh_d3_status_2_map,
+ nvl_pcdh_d3_status_3_map,
+ nvl_pcdh_vnn_req_status_0_map,
+ nvl_pcdh_vnn_req_status_1_map,
+ nvl_pcdh_vnn_req_status_2_map,
+ nvl_pcdh_vnn_req_status_3_map,
+ nvl_pcdh_vnn_misc_status_map,
+ ptl_pcdp_signal_status_map,
+ NULL
+};
+
+static const struct pmc_bit_map *nvl_pcdh_blk_maps[] = {
+ nvl_pcdh_power_gating_status_0_map,
+ nvl_pcdh_power_gating_status_1_map,
+ nvl_pcdh_power_gating_status_2_map,
+ nvl_pcdh_power_gating_status_3_map,
+ nvl_pcdh_rsc_status_map,
+ nvl_pcdh_vnn_req_status_0_map,
+ nvl_pcdh_vnn_req_status_1_map,
+ nvl_pcdh_vnn_req_status_2_map,
+ nvl_pcdh_vnn_req_status_3_map,
+ nvl_pcdh_d3_status_0_map,
+ nvl_pcdh_d3_status_1_map,
+ nvl_pcdh_d3_status_2_map,
+ nvl_pcdh_d3_status_3_map,
+ nvl_pcdh_clocksource_status_map,
+ nvl_pcdh_vnn_misc_status_map,
+ ptl_pcdp_signal_status_map,
+ NULL
+};
+
+static const struct pmc_bit_map nvl_pcds_pfear_map[] = {
+ {"PMC_PGD0", BIT(0)},
+ {"FUSE_OSSE_PGD0", BIT(1)},
+ {"SPI_PGD0", BIT(2)},
+ {"XHCI_PGD0", BIT(3)},
+ {"SPA_PGD0", BIT(4)},
+ {"SPB_PGD0", BIT(5)},
+ {"RSVD6", BIT(6)},
+ {"GBE_PGD0", BIT(7)},
+
+ {"RSVD8", BIT(0)},
+ {"RSVD9", BIT(1)},
+ {"SBR16B7_PGD0", BIT(2)},
+ {"SBR16B21_PGD0", BIT(3)},
+ {"RSVD12", BIT(4)},
+ {"D2D_DISP_PGD1", BIT(5)},
+ {"LPSS_PGD0", BIT(6)},
+ {"LPC_PGD0", BIT(7)},
+
+ {"SMB_PGD0", BIT(0)},
+ {"ISH_PGD0", BIT(1)},
+ {"SBR16B1_PGD0", BIT(2)},
+ {"NPK_PGD0", BIT(3)},
+ {"D2D_NOC_PGD1", BIT(4)},
+ {"DBG_SBR16B_PGD0", BIT(5)},
+ {"FUSE_PGD0", BIT(6)},
+ {"RSVD23", BIT(7)},
+
+ {"P2SB0_PGD0", BIT(0)},
+ {"OTG_PGD0", BIT(1)},
+ {"EXI_PGD0", BIT(2)},
+ {"CSE_PGD0", BIT(3)},
+ {"CSME_KVM_PGD0", BIT(4)},
+ {"CSME_PMT_PGD0", BIT(5)},
+ {"CSME_CLINK_PGD0", BIT(6)},
+ {"CSME_PTIO_PGD0", BIT(7)},
+
+ {"CSME_USBR_PGD0", BIT(0)},
+ {"SBR16B22_PGD0", BIT(1)},
+ {"CSME_SMT1_PGD0", BIT(2)},
+ {"P2SB1_PGD0", BIT(3)},
+ {"CSME_SMS2_PGD0", BIT(4)},
+ {"CSME_SMS_PGD0", BIT(5)},
+ {"CSME_RTC_PGD0", BIT(6)},
+ {"CSMEPSF_PGD0", BIT(7)},
+
+ {"D2D_NOC_PGD0", BIT(0)},
+ {"RSVD41", BIT(1)},
+ {"RSVD42", BIT(2)},
+ {"RSVD43", BIT(3)},
+ {"SBR16B2_PGD0", BIT(4)},
+ {"OSSE_SMT1_PGD0", BIT(5)},
+ {"D2D_DISP_PGD0", BIT(6)},
+ {"RSVD47_PGD0", BIT(7)},
+
+ {"RSVD48", BIT(0)},
+ {"DBG_PSF_PGD0", BIT(1)},
+ {"RSVD50", BIT(2)},
+ {"CNVI_PGD0", BIT(3)},
+ {"UFSX2_PGD0", BIT(4)},
+ {"ENDBG_PGD0", BIT(5)},
+ {"DBC_PGD0", BIT(6)},
+ {"SBR16B4_PGD0", BIT(7)},
+
+ {"RSVD56", BIT(0)},
+ {"NPK_PGD1", BIT(1)},
+ {"RSVD58", BIT(2)},
+ {"SBR16B20_PGD0", BIT(3)},
+ {"RSVD60", BIT(4)},
+ {"SBR8B20_PGD0", BIT(5)},
+ {"RSVD62", BIT(6)},
+ {"FIA_U_PGD0", BIT(7)},
+
+ {"PSF8_PGD0", BIT(0)},
+ {"RSVD65", BIT(1)},
+ {"RSVD66", BIT(2)},
+ {"FIACPCB_U_PGD0", BIT(3)},
+ {"TAM_PGD0", BIT(4)},
+ {"D2D_NOC_PGD2", BIT(5)},
+ {"SBR8B2_PGD0", BIT(6)},
+ {"THC0_PGD0", BIT(7)},
+
+ {"THC1_PGD0", BIT(0)},
+ {"PMC_PGD1", BIT(1)},
+ {"SBR16B3_PGD0", BIT(2)},
+ {"TCSS_PGD0", BIT(3)},
+ {"DISP_PGA_PGD0", BIT(4)},
+ {"RSVD77", BIT(5)},
+ {"RSVD78", BIT(6)},
+ {"RSVD79", BIT(7)},
+
+ {"SBRG_PGD0", BIT(0)},
+ {"RSVD81", BIT(1)},
+ {"SBR16B0_PGD0", BIT(2)},
+ {"SBR8B0_PGD0", BIT(3)},
+ {"PSF7_PGD0", BIT(4)},
+ {"RSVD85", BIT(5)},
+ {"RSVD86", BIT(6)},
+ {"RSVD87", BIT(7)},
+
+ {"SBR16B6_PGD0", BIT(0)},
+ {"PSD0_PGD0", BIT(1)},
+ {"STRC_PGD0", BIT(2)},
+ {"RSVD91", BIT(3)},
+ {"DBG_SBR_PGD0", BIT(4)},
+ {"RSVD93", BIT(5)},
+ {"OSSE_PGD0", BIT(6)},
+ {"DISP_PGA1_PGD0", BIT(7)},
+ {}
+};
+
+static const struct pmc_bit_map *ext_nvl_pcds_pfear_map[] = {
+ nvl_pcds_pfear_map,
+ NULL
+};
+
+static const struct pmc_bit_map nvl_pcds_ltr_show_map[] = {
+ {"SOUTHPORT_A", CNP_PMC_LTR_SPA},
+ {"SOUTHPORT_B", CNP_PMC_LTR_SPB},
+ {"SATA", CNP_PMC_LTR_SATA},
+ {"GIGABIT_ETHERNET", CNP_PMC_LTR_GBE},
+ {"XHCI", CNP_PMC_LTR_XHCI},
+ {"SOUTHPORT_F", ADL_PMC_LTR_SPF},
+ {"ME", CNP_PMC_LTR_ME},
+ {"SATA1", CNP_PMC_LTR_EVA},
+ {"SOUTHPORT_C", CNP_PMC_LTR_SPC},
+ {"HD_AUDIO", CNP_PMC_LTR_AZ},
+ {"CNV", CNP_PMC_LTR_CNV},
+ {"LPSS", CNP_PMC_LTR_LPSS},
+ {"SOUTHPORT_D", CNP_PMC_LTR_SPD},
+ {"SOUTHPORT_E", CNP_PMC_LTR_SPE},
+ {"SATA2", PTL_PMC_LTR_SATA2},
+ {"ESPI", CNP_PMC_LTR_ESPI},
+ {"SCC", CNP_PMC_LTR_SCC},
+ {"ISH", CNP_PMC_LTR_ISH},
+ {"UFSX2", CNP_PMC_LTR_UFSX2},
+ {"EMMC", CNP_PMC_LTR_EMMC},
+ {"WIGIG", ICL_PMC_LTR_WIGIG},
+ {"THC0", TGL_PMC_LTR_THC0},
+ {"THC1", TGL_PMC_LTR_THC1},
+ {"SOUTHPORT_G", MTL_PMC_LTR_SPG},
+ {"RSVD", NVL_PCDS_PMC_LTR_RESERVED},
+ {"IOE_PMC", MTL_PMC_LTR_IOE_PMC},
+ {"DMI3", ARL_PMC_LTR_DMI3},
+ {"OSSE", LNL_PMC_LTR_OSSE},
+
+ /* Below two cannot be used for LTR_IGNORE */
+ {"CURRENT_PLATFORM", PTL_PMC_LTR_CUR_PLT},
+ {"AGGREGATED_SYSTEM", PTL_PMC_LTR_CUR_ASLT},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcds_clocksource_status_map[] = {
+ {"AON2_OFF_STS", BIT(0), 1},
+ {"AON3_OFF_STS", BIT(1), 0},
+ {"AON4_OFF_STS", BIT(2), 1},
+ {"AON5_OFF_STS", BIT(3), 1},
+ {"AON1_OFF_STS", BIT(4), 0},
+ {"XTAL_LVM_OFF_STS", BIT(5), 0},
+ {"D2D_OFF_STS", BIT(8), 1},
+ {"AON3_SPL_OFF_STS", BIT(9), 1},
+ {"XTAL_AGGR_OFF_STS", BIT(17), 1},
+ {"BCLK_EXT_INJ_OFF_STS", BIT(18), 1},
+ {"DDI2_PLL_OFF_STS", BIT(19), 1},
+ {"SE_TCSS_PLL_OFF_STS", BIT(20), 1},
+ {"DDI_PLL_OFF_STS", BIT(21), 1},
+ {"FILTER_PLL_OFF_STS", BIT(22), 1},
+ {"PHY_OC_EXT_INJ_OFF_STS", BIT(23), 1},
+ {"ACE_PLL_OFF_STS", BIT(24), 0},
+ {"FABRIC_PLL_OFF_STS", BIT(25), 1},
+ {"SOC_PLL_OFF_STS", BIT(26), 1},
+ {"REF_PLL_OFF_STS", BIT(28), 1},
+ {"GENLOCK_FILTER_PLL_OFF_STS", BIT(30), 1},
+ {"RTC_PLL_OFF_STS", BIT(31), 0},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcds_power_gating_status_0_map[] = {
+ {"PMC_PGD0_PG_STS", BIT(0), 0},
+ {"FUSE_OSSE_PGD0_PG_STS", BIT(1), 0},
+ {"ESPISPI_PGD0_PG_STS", BIT(2), 0},
+ {"XHCI_PGD0_PG_STS", BIT(3), 0},
+ {"SPA_PGD0_PG_STS", BIT(4), 0},
+ {"SPB_PGD0_PG_STS", BIT(5), 0},
+ {"RSVD_6", BIT(6), 0},
+ {"GBE_PGD0_PG_STS", BIT(7), 0},
+ {"RSVD_8", BIT(8), 0},
+ {"RSVD_9", BIT(9), 0},
+ {"SBR16B7_PGD0_PG_STS", BIT(10), 0},
+ {"SBR16B21_PGD0_PG_STS", BIT(11), 0},
+ {"RSVD_12", BIT(12), 0},
+ {"D2D_DISP_PGD1_PG_STS", BIT(13), 1},
+ {"LPSS_PGD0_PG_STS", BIT(14), 0},
+ {"LPC_PGD0_PG_STS", BIT(15), 0},
+ {"SMB_PGD0_PG_STS", BIT(16), 0},
+ {"ISH_PGD0_PG_STS", BIT(17), 0},
+ {"SBR16B1_PGD0_PG_STS", BIT(18), 0},
+ {"NPK_PGD0_PG_STS", BIT(19), 0},
+ {"D2D_NOC_PGD1_PG_STS", BIT(20), 1},
+ {"DBG_SBR16B_PGD0_PG_STS", BIT(21), 0},
+ {"FUSE_PGD0_PG_STS", BIT(22), 0},
+ {"RSVD_23", BIT(23), 0},
+ {"P2SB0_PGD0_PG_STS", BIT(24), 1},
+ {"XDCI_PGD0_PG_STS", BIT(25), 0},
+ {"EXI_PGD0_PG_STS", BIT(26), 0},
+ {"CSE_PGD0_PG_STS", BIT(27), 1},
+ {"KVMCC_PGD0_PG_STS", BIT(28), 0},
+ {"PMT_PGD0_PG_STS", BIT(29), 0},
+ {"CLINK_PGD0_PG_STS", BIT(30), 0},
+ {"PTIO_PGD0_PG_STS", BIT(31), 0},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcds_power_gating_status_1_map[] = {
+ {"USBR0_PGD0_PG_STS", BIT(0), 0},
+ {"SBR16B22_PGD0_PG_STS", BIT(1), 0},
+ {"SMT1_PGD0_PG_STS", BIT(2), 0},
+ {"P2SB1_PGD0_PG_STS", BIT(3), 1},
+ {"SMS2_PGD0_PG_STS", BIT(4), 0},
+ {"SMS1_PGD0_PG_STS", BIT(5), 0},
+ {"CSMERTC_PGD0_PG_STS", BIT(6), 0},
+ {"CSMEPSF_PGD0_PG_STS", BIT(7), 0},
+ {"D2D_NOC_PGD0_PG_STS", BIT(8), 0},
+ {"RSVD_9", BIT(9), 0},
+ {"RSVD_10", BIT(10), 0},
+ {"RSVD_11", BIT(11), 0},
+ {"SBR16B2_PGD0_PG_STS", BIT(12), 0},
+ {"OSSE_SMT1_PGD0_PG_STS", BIT(13), 1},
+ {"D2D_DISP_PGD0_PG_STS", BIT(14), 1},
+ {"RSVD_15", BIT(15), 0},
+ {"RSVD_16", BIT(16), 0},
+ {"DBG_PSF_PGD0_PG_STS", BIT(17), 0},
+ {"RSVD_18", BIT(18), 0},
+ {"CNVI_PGD0_PG_STS", BIT(19), 0},
+ {"UFSX2_PGD0_PG_STS", BIT(20), 0},
+ {"ENDBG_PGD0_PG_STS", BIT(21), 0},
+ {"DBC_PGD0_PG_STS", BIT(22), 0},
+ {"SBR16B4_PGD0_PG_STS", BIT(23), 0},
+ {"RSVD_24", BIT(24), 0},
+ {"NPK_PGD1_PG_STS", BIT(25), 0},
+ {"RSVD_26", BIT(26), 0},
+ {"SBR16B20_PGD0_PG_STS", BIT(27), 0},
+ {"RSVD_28", BIT(28), 0},
+ {"SBR8B20_PGD0_PG_STS", BIT(29), 0},
+ {"RSVD_30", BIT(30), 0},
+ {"FIA_U_PGD0_PG_STS", BIT(31), 0},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcds_power_gating_status_2_map[] = {
+ {"PSF8_PGD0_PG_STS", BIT(0), 0},
+ {"RSVD_1", BIT(1), 0},
+ {"RSVD_2", BIT(2), 0},
+ {"FIACPCB_U_PGD0_PG_STS", BIT(3), 0},
+ {"TAM_PGD0_PG_STS", BIT(4), 1},
+ {"D2D_NOC_PGD2_PG_STS", BIT(5), 1},
+ {"SBR8B2_PGD0_PG_STS", BIT(6), 0},
+ {"THC0_PGD0_PG_STS", BIT(7), 0},
+ {"THC1_PGD0_PG_STS", BIT(8), 0},
+ {"PMC_PGD1_PG_STS", BIT(9), 0},
+ {"SBR16B3_PGD0_PG_STS", BIT(10), 0},
+ {"TCSS_PGD0_PG_STS", BIT(11), 0},
+ {"DISP_PGA_PGD0_PG_STS", BIT(12), 0},
+ {"RSVD_13", BIT(13), 0},
+ {"RSVD_14", BIT(14), 0},
+ {"RSVD_15", BIT(15), 0},
+ {"SBRG_PGD0_PG_STS", BIT(16), 0},
+ {"RSVD_17", BIT(17), 0},
+ {"SBR16B0_PGD0_PG_STS", BIT(18), 0},
+ {"SBR8B0_PGD0_PG_STS", BIT(19), 0},
+ {"PSF7_PGD0_PG_STS", BIT(20), 0},
+ {"RSVD_21", BIT(21), 0},
+ {"RSVD_22", BIT(22), 0},
+ {"RSVD_23", BIT(23), 0},
+ {"SBR16B6_PGD0_PG_STS", BIT(24), 0},
+ {"PSF0_PGD0_PG_STS", BIT(25), 0},
+ {"STRC_PGD0_PG_STS", BIT(26), 0},
+ {"RSVD_27", BIT(27), 0},
+ {"DBG_SBR_PGD0_PG_STS", BIT(28), 0},
+ {"RSVD_29", BIT(29), 0},
+ {"OSSE_PGD0_PG_STS", BIT(30), 1},
+ {"DISP_PGA1_PGD0_PG_STS", BIT(31), 0},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcds_d3_status_0_map[] = {
+ {"LPSS_D3_STS", BIT(3), 1},
+ {"XDCI_D3_STS", BIT(4), 1},
+ {"XHCI_D3_STS", BIT(5), 1},
+ {"SPA_D3_STS", BIT(12), 0},
+ {"SPB_D3_STS", BIT(13), 0},
+ {"ESPISPI_D3_STS", BIT(18), 0},
+ {"PSTH_D3_STS", BIT(21), 0},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcds_d3_status_1_map[] = {
+ {"OSSE_D3_STS", BIT(14), 0},
+ {"GBE_D3_STS", BIT(19), 0},
+ {"ITSS_D3_STS", BIT(23), 0},
+ {"CNVI_D3_STS", BIT(27), 0},
+ {"UFSX2_D3_STS", BIT(28), 0},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcds_d3_status_2_map[] = {
+ {"CSMERTC_D3_STS", BIT(1), 0},
+ {"CSE_D3_STS", BIT(4), 0},
+ {"KVMCC_D3_STS", BIT(5), 0},
+ {"USBR0_D3_STS", BIT(6), 0},
+ {"ISH_D3_STS", BIT(7), 0},
+ {"SMT1_D3_STS", BIT(8), 0},
+ {"SMT2_D3_STS", BIT(9), 0},
+ {"SMT3_D3_STS", BIT(10), 0},
+ {"OSSE_SMT1_D3_STS", BIT(12), 0},
+ {"CLINK_D3_STS", BIT(14), 0},
+ {"PTIO_D3_STS", BIT(16), 0},
+ {"PMT_D3_STS", BIT(17), 0},
+ {"SMS1_D3_STS", BIT(18), 0},
+ {"SMS2_D3_STS", BIT(19), 0},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcds_d3_status_3_map[] = {
+ {"OSSE_SMT2_D3_STS", BIT(0), 0},
+ {"THC0_D3_STS", BIT(14), 1},
+ {"THC1_D3_STS", BIT(15), 1},
+ {"OSSE_SMT3_D3_STS", BIT(19), 0},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcds_vnn_req_status_0_map[] = {
+ {"LPSS_VNN_REQ_STS", BIT(3), 0},
+ {"ESPISPI_VNN_REQ_STS", BIT(18), 1},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcds_vnn_req_status_1_map[] = {
+ {"NPK_VNN_REQ_STS", BIT(4), 1},
+ {"DFXAGG_VNN_REQ_STS", BIT(8), 0},
+ {"EXI_VNN_REQ_STS", BIT(9), 1},
+ {"OSSE_VNN_REQ_STS", BIT(14), 1},
+ {"P2D_VNN_REQ_STS", BIT(18), 1},
+ {"GBE_VNN_REQ_STS", BIT(19), 0},
+ {"SMB_VNN_REQ_STS", BIT(25), 1},
+ {"LPC_VNN_REQ_STS", BIT(26), 0},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcds_vnn_req_status_2_map[] = {
+ {"CSMERTC_VNN_REQ_STS", BIT(1), 0},
+ {"CSE_VNN_REQ_STS", BIT(4), 1},
+ {"ISH_VNN_REQ_STS", BIT(7), 0},
+ {"SMT1_VNN_REQ_STS", BIT(8), 0},
+ {"OSSE_SMT1_VNN_REQ_STS", BIT(12), 1},
+ {"CLINK_VNN_REQ_STS", BIT(14), 0},
+ {"SMS1_VNN_REQ_STS", BIT(18), 0},
+ {"SMS2_VNN_REQ_STS", BIT(19), 0},
+ {"GPIOCOM4_VNN_REQ_STS", BIT(20), 0},
+ {"GPIOCOM3_VNN_REQ_STS", BIT(21), 1},
+ {"GPIOCOM1_VNN_REQ_STS", BIT(23), 1},
+ {"GPIOCOM0_VNN_REQ_STS", BIT(24), 1},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcds_vnn_req_status_3_map[] = {
+ {"DISP_SHIM_VNN_REQ_STS", BIT(4), 1},
+ {"DTS0_VNN_REQ_STS", BIT(7), 0},
+ {"GPIOCOM5_VNN_REQ_STS", BIT(11), 0},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcds_vnn_misc_status_map[] = {
+ {"CPU_C10_REQ_STS", BIT(0), 0},
+ {"TS_OFF_REQ_STS", BIT(1), 0},
+ {"PNDE_MET_REQ_STS", BIT(2), 1},
+ {"PG5_PMA0_REQ_STS", BIT(3), 1},
+ {"FW_THROTTLE_ALLOWED_REQ_STS", BIT(4), 0},
+ {"VNN_SOC_REQ_STS", BIT(6), 1},
+ {"ISH_VNNAON_REQ_STS", BIT(7), 0},
+ {"D2D_NOC_CFI_QACTIVE_REQ_STS", BIT(8), 1},
+ {"D2D_NOC_GPSB_QACTIVE_REQ_STS", BIT(9), 1},
+ {"PLT_GREATER_REQ_STS", BIT(11), 1},
+ {"ALL_SBR_IDLE_REQ_STS", BIT(12), 0},
+ {"PMC_IDLE_FB_OCP_REQ_STS", BIT(13), 0},
+ {"PM_SYNC_STATES_REQ_STS", BIT(14), 0},
+ {"EA_REQ_STS", BIT(15), 0},
+ {"MPHY_CORE_OFF_REQ_STS", BIT(16), 0},
+ {"BRK_EV_EN_REQ_STS", BIT(17), 0},
+ {"AUTO_DEMO_EN_REQ_STS", BIT(18), 0},
+ {"ITSS_CLK_SRC_REQ_STS", BIT(19), 1},
+ {"ARC_IDLE_REQ_STS", BIT(21), 0},
+ {"PG5_PMA1_REQ_STS", BIT(22), 1},
+ {"DG5_PMA0_REQ_STS", BIT(23), 1},
+ {"ARC_INTERRUPT_WAKE_REQ_STS", BIT(25), 0},
+ {"D2D_DISP_DDI_QACTIVE_REQ_STS", BIT(26), 1},
+ {"PRE_WAKE0_REQ_STS", BIT(27), 1},
+ {"PRE_WAKE1_REQ_STS", BIT(28), 1},
+ {"PRE_WAKE2_REQ_STS", BIT(29), 1},
+ {"D2D_DISP_EDP_QACTIVE_REQ_STS", BIT(31), 1},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcds_rsc_status_map[] = {
+ {"CORE", 0, 1},
+ {"Memory", 0, 1},
+ {"PRIM_D2D", 0, 1},
+ {"PSF0", 0, 1},
+ {"SB", 0, 1},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pcds_signal_status_map[] = {
+ {"LSX_Wake0_STS", BIT(0), 0},
+ {"LSX_Wake1_STS", BIT(1), 0},
+ {"LSX_Wake2_STS", BIT(2), 0},
+ {"LSX_Wake3_STS", BIT(3), 0},
+ {"LSX_Wake4_STS", BIT(4), 0},
+ {"LSX_Wake5_STS", BIT(5), 0},
+ {"LSX_Wake6_STS", BIT(6), 0},
+ {"LSX_Wake7_STS", BIT(7), 0},
+ {"LPSS_Wake0_STS", BIT(8), 1},
+ {"LPSS_Wake1_STS", BIT(9), 1},
+ {"Int_Timer_SS_Wake0_STS", BIT(10), 1},
+ {"Int_Timer_SS_Wake1_STS", BIT(11), 1},
+ {"Int_Timer_SS_Wake2_STS", BIT(12), 1},
+ {"Int_Timer_SS_Wake3_STS", BIT(13), 1},
+ {"Int_Timer_SS_Wake4_STS", BIT(14), 1},
+ {"Int_Timer_SS_Wake5_STS", BIT(15), 1},
+ {}
+};
+
+static const struct pmc_bit_map *nvl_pcds_lpm_maps[] = {
+ nvl_pcds_clocksource_status_map,
+ nvl_pcds_power_gating_status_0_map,
+ nvl_pcds_power_gating_status_1_map,
+ nvl_pcds_power_gating_status_2_map,
+ nvl_pcds_d3_status_0_map,
+ nvl_pcds_d3_status_1_map,
+ nvl_pcds_d3_status_2_map,
+ nvl_pcds_d3_status_3_map,
+ nvl_pcds_vnn_req_status_0_map,
+ nvl_pcds_vnn_req_status_1_map,
+ nvl_pcds_vnn_req_status_2_map,
+ nvl_pcds_vnn_req_status_3_map,
+ nvl_pcds_vnn_misc_status_map,
+ nvl_pcds_signal_status_map,
+ NULL
+};
+
+static const struct pmc_bit_map *nvl_pcds_blk_maps[] = {
+ nvl_pcds_power_gating_status_0_map,
+ nvl_pcds_power_gating_status_1_map,
+ nvl_pcds_power_gating_status_2_map,
+ nvl_pcds_rsc_status_map,
+ nvl_pcds_vnn_req_status_0_map,
+ nvl_pcds_vnn_req_status_1_map,
+ nvl_pcds_vnn_req_status_2_map,
+ nvl_pcds_vnn_req_status_3_map,
+ nvl_pcds_d3_status_0_map,
+ nvl_pcds_d3_status_1_map,
+ nvl_pcds_d3_status_2_map,
+ nvl_pcds_d3_status_3_map,
+ nvl_pcds_clocksource_status_map,
+ nvl_pcds_vnn_misc_status_map,
+ nvl_pcds_signal_status_map,
+ NULL
+};
+
+static const struct pmc_bit_map nvl_pchs_pfear_map[] = {
+ {"PMC_PGD0", BIT(0)},
+ {"FIA_D_PGD0", BIT(1)},
+ {"SPI_PGD0", BIT(2)},
+ {"XHCI_PGD0", BIT(3)},
+ {"SPA_PGD0", BIT(4)},
+ {"SPB_PGD0", BIT(5)},
+ {"MPFPW2_PGD0", BIT(6)},
+ {"GBE_PGD0", BIT(7)},
+
+ {"RSVD8", BIT(0)},
+ {"PSF3_PGD0", BIT(1)},
+ {"SBR5_PGD0", BIT(2)},
+ {"SBR0_PGD0", BIT(3)},
+ {"RSVD12", BIT(4)},
+ {"D2D_DISP_PGD1", BIT(5)},
+ {"LPSS_PGD0", BIT(6)},
+ {"LPC_PGD0", BIT(7)},
+
+ {"SMB_PGD0", BIT(0)},
+ {"ISH_PGD0", BIT(1)},
+ {"P2SB_PGD0", BIT(2)},
+ {"NPK_PGD0", BIT(3)},
+ {"D2D_NOC_PGD1", BIT(4)},
+ {"EAH_PGD0", BIT(5)},
+ {"FUSE_PGD0", BIT(6)},
+ {"SBR8_PGD0", BIT(7)},
+
+ {"PSF7_PGD0", BIT(0)},
+ {"OTG_PGD0", BIT(1)},
+ {"EXI_PGD0", BIT(2)},
+ {"CSE_PGD0", BIT(3)},
+ {"CSME_KVM_PGD0", BIT(4)},
+ {"CSME_PMT_PGD0", BIT(5)},
+ {"CSME_CLINK_PGD0", BIT(6)},
+ {"CSME_PTIO_PGD0", BIT(7)},
+
+ {"CSME_USBR_PGD0", BIT(0)},
+ {"SBR1_PGD0", BIT(1)},
+ {"CSME_SMT1_PGD0", BIT(2)},
+ {"MPFPW1_PGD0", BIT(3)},
+ {"CSME_SMS2_PGD0", BIT(4)},
+ {"CSME_SMS_PGD0", BIT(5)},
+ {"CSME_RTC_PGD0", BIT(6)},
+ {"CSMEPSF_PGD0", BIT(7)},
+
+ {"D2D_NOC_PGD0", BIT(0)},
+ {"ESE_PGD0", BIT(1)},
+ {"SBR2_PGD0", BIT(2)},
+ {"SBR3_PGD0", BIT(3)},
+ {"SBR4_PGD0", BIT(4)},
+ {"RSVD45", BIT(5)},
+ {"D2D_DISP_PGD0", BIT(6)},
+ {"PSF1_PGD0", BIT(7)},
+
+ {"U3FPW1_PGD0", BIT(0)},
+ {"DMI3FPW_PGD0", BIT(1)},
+ {"PSF4_PGD0", BIT(2)},
+ {"CNVI_PGD0", BIT(3)},
+ {"RSVD52", BIT(4)},
+ {"ENDBG_PGD0", BIT(5)},
+ {"DBC_PGD0", BIT(6)},
+ {"SMT4_PGD0", BIT(7)},
+
+ {"RSVD56", BIT(0)},
+ {"NPK_PGD1", BIT(1)},
+ {"RSVD58", BIT(2)},
+ {"DMI3_PGD0", BIT(3)},
+ {"RSVD60", BIT(4)},
+ {"FIACPCB_D_PGD0", BIT(5)},
+ {"RSVD62", BIT(6)},
+ {"FIA_U_PGD0", BIT(7)},
+
+ {"FIACPCB_PGS_PGD0", BIT(0)},
+ {"FIA_PGS_PGD0", BIT(1)},
+ {"RSVD66", BIT(2)},
+ {"FIACPCB_U_PGD0", BIT(3)},
+ {"TAM_PGD0", BIT(4)},
+ {"D2D_NOC_PGD2", BIT(5)},
+ {"PSF2_PGD0", BIT(6)},
+ {"THC0_PGD0", BIT(7)},
+
+ {"THC1_PGD0", BIT(0)},
+ {"PMC_PGD1", BIT(1)},
+ {"SBR9_PGD0", BIT(2)},
+ {"U3FPW2_PGD0", BIT(3)},
+ {"RSVD76", BIT(4)},
+ {"DBG_PSF_PGD0", BIT(5)},
+ {"DBG_SBR_PGD0", BIT(6)},
+ {"SBR6_PGD0", BIT(7)},
+
+ {"SPC_PGD0", BIT(0)},
+ {"ACE_PGD0", BIT(1)},
+ {"ACE_PGD1", BIT(2)},
+ {"ACE_PGD2", BIT(3)},
+ {"ACE_PGD3", BIT(4)},
+ {"ACE_PGD4", BIT(5)},
+ {"ACE_PGD5", BIT(6)},
+ {"ACE_PGD6", BIT(7)},
+
+ {"ACE_PGD7", BIT(0)},
+ {"ACE_PGD8", BIT(1)},
+ {"ACE_PGD9", BIT(2)},
+ {"ACE_PGD10", BIT(3)},
+ {"U3FPW3_PGD0", BIT(4)},
+ {"SBR7_PGD0", BIT(5)},
+ {"OSSE_PGD0", BIT(6)},
+ {"ST_PGD0", BIT(7)},
+ {}
+};
+
+static const struct pmc_bit_map *ext_nvl_pchs_pfear_map[] = {
+ nvl_pchs_pfear_map,
+ NULL
+};
+
+static const struct pmc_bit_map nvl_pchs_clocksource_status_map[] = {
+ {"AON2_OFF_STS", BIT(0), 1},
+ {"AON3_OFF_STS", BIT(1), 0},
+ {"AON4_OFF_STS", BIT(2), 0},
+ {"AON2_SPL_OFF_STS", BIT(3), 0},
+ {"AONL_OFF_STS", BIT(4), 0},
+ {"XTAL_LVM_OFF_STS", BIT(5), 0},
+ {"AON5_OFF_STS", BIT(6), 0},
+ {"USB3_PLL_OFF_STS", BIT(8), 1},
+ {"MAIN_CRO_OFF_STS", BIT(11), 0},
+ {"MAIN_DIVIDER_OFF_STS", BIT(12), 1},
+ {"REF_PLL_NON_OC_OFF_STS", BIT(13), 1},
+ {"DMI_PLL_OFF_STS", BIT(14), 1},
+ {"PHY_EXT_INJ_OFF_STS", BIT(15), 1},
+ {"AON6_MCRO_OFF_STS", BIT(16), 0},
+ {"XTAL_AGGR_OFF_STS", BIT(17), 0},
+ {"USB2_PLL_OFF_STS", BIT(18), 1},
+ {"GBE_PLL_OFF_STS", BIT(21), 1},
+ {"SATA_PLL_OFF_STS", BIT(22), 1},
+ {"PCIE0_PLL_OFF_STS", BIT(23), 1},
+ {"PCIE1_PLL_OFF_STS", BIT(24), 1},
+ {"FABRIC_PLL_OFF_STS", BIT(25), 1},
+ {"PCIE2_PLL_OFF_STS", BIT(26), 1},
+ {"REF_PLL_OFF_STS", BIT(28), 1},
+ {"REF38P4_PLL_OFF_STS", BIT(31), 1},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pchs_power_gating_status_0_map[] = {
+ {"PMC_PGD0_PG_STS", BIT(0), 0},
+ {"FIA_D_PGD0_PG_STS", BIT(1), 0},
+ {"ESPISPI_PGD0_PG_STS", BIT(2), 0},
+ {"XHCI_PGD0_PG_STS", BIT(3), 0},
+ {"SPA_PGD0_PG_STS", BIT(4), 1},
+ {"SPB_PGD0_PG_STS", BIT(5), 1},
+ {"MPFPW2_PGD0_PG_STS", BIT(6), 0},
+ {"GBE_PGD0_PG_STS", BIT(7), 1},
+ {"RSVD_8", BIT(8), 0},
+ {"PSF3_PGD0_PG_STS", BIT(9), 0},
+ {"SBR5_PGD0_PG_STS", BIT(10), 0},
+ {"SBR0_PGD0_PG_STS", BIT(11), 0},
+ {"RSVD_12", BIT(12), 0},
+ {"D2D_DISP_PGD1_PG_STS", BIT(13), 0},
+ {"LPSS_PGD0_PG_STS", BIT(14), 1},
+ {"LPC_PGD0_PG_STS", BIT(15), 0},
+ {"SMB_PGD0_PG_STS", BIT(16), 0},
+ {"ISH_PGD0_PG_STS", BIT(17), 0},
+ {"P2S_PGD0_PG_STS", BIT(18), 0},
+ {"NPK_PGD0_PG_STS", BIT(19), 0},
+ {"D2D_NOC_PGD1_PG_STS", BIT(20), 0},
+ {"EAH_PGD0_PG_STS", BIT(21), 0},
+ {"FUSE_PGD0_PG_STS", BIT(22), 0},
+ {"SBR8_PGD0_PG_STS", BIT(23), 0},
+ {"PSF7_PGD0_PG_STS", BIT(24), 0},
+ {"XDCI_PGD0_PG_STS", BIT(25), 1},
+ {"EXI_PGD0_PG_STS", BIT(26), 0},
+ {"CSE_PGD0_PG_STS", BIT(27), 1},
+ {"KVMCC_PGD0_PG_STS", BIT(28), 1},
+ {"PMT_PGD0_PG_STS", BIT(29), 1},
+ {"CLINK_PGD0_PG_STS", BIT(30), 1},
+ {"PTIO_PGD0_PG_STS", BIT(31), 1},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pchs_power_gating_status_1_map[] = {
+ {"USBR0_PGD0_PG_STS", BIT(0), 1},
+ {"SBR1_PGD0_PG_STS", BIT(1), 0},
+ {"SMT1_PGD0_PG_STS", BIT(2), 1},
+ {"MPFPW1_PGD0_PG_STS", BIT(3), 0},
+ {"SMS2_PGD0_PG_STS", BIT(4), 1},
+ {"SMS1_PGD0_PG_STS", BIT(5), 1},
+ {"CSMERTC_PGD0_PG_STS", BIT(6), 0},
+ {"CSMEPSF_PGD0_PG_STS", BIT(7), 0},
+ {"D2D_NOC_PGD0_PG_STS", BIT(8), 0},
+ {"ESE_PGD0_PG_STS", BIT(9), 1},
+ {"SBR2_PGD0_PG_STS", BIT(10), 0},
+ {"SBR3_PGD0_PG_STS", BIT(11), 0},
+ {"SBR4_PGD0_PG_STS", BIT(12), 0},
+ {"RSVD_13", BIT(13), 0},
+ {"D2D_DISP_PGD0_PG_STS", BIT(14), 0},
+ {"PSF1_PGD0_PG_STS", BIT(15), 0},
+ {"U3FPW1_PGD0_PG_STS", BIT(16), 0},
+ {"DMI3FPW_PGD0_PG_STS", BIT(17), 0},
+ {"PSF4_PGD0_PG_STS", BIT(18), 0},
+ {"CNVI_PGD0_PG_STS", BIT(19), 0},
+ {"RSVD_20", BIT(20), 0},
+ {"ENDBG_PGD0_PG_STS", BIT(21), 0},
+ {"DBC_PGD0_PG_STS", BIT(22), 0},
+ {"SMT4_PGD0_PG_STS", BIT(23), 1},
+ {"RSVD_24", BIT(24), 0},
+ {"NPK_PGD1_PG_STS", BIT(25), 0},
+ {"RSVD_26", BIT(26), 0},
+ {"DMI3_PGD0_PG_STS", BIT(27), 1},
+ {"RSVD_28", BIT(28), 0},
+ {"FIACPCB_D_PGD0_PG_STS", BIT(29), 0},
+ {"RSVD_30", BIT(30), 0},
+ {"FIA_U_PGD0_PG_STS", BIT(31), 0},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pchs_power_gating_status_2_map[] = {
+ {"FIACPCB_PGS_PGD0_PG_STS", BIT(0), 0},
+ {"FIA_PGS_PGD0_PG_STS", BIT(1), 0},
+ {"RSVD_2", BIT(2), 0},
+ {"FIACPCB_U_PGD0_PG_STS", BIT(3), 0},
+ {"TAM_PGD0_PG_STS", BIT(4), 0},
+ {"D2D_NOC_PGD2_PG_STS", BIT(5), 0},
+ {"PSF2_PGD0_PG_STS", BIT(6), 0},
+ {"THC0_PGD0_PG_STS", BIT(7), 1},
+ {"THC1_PGD0_PG_STS", BIT(8), 1},
+ {"PMC_PGD1_PG_STS", BIT(9), 0},
+ {"SBR9_PGA0_PGD0_PG_STS", BIT(10), 0},
+ {"U3FPW2_PGD0_PG_STS", BIT(11), 0},
+ {"RSVD_12", BIT(12), 0},
+ {"DBG_PSF_PGD0_PG_STS", BIT(13), 0},
+ {"DBG_SBR_PGD0_PG_STS", BIT(14), 0},
+ {"SBR6_PGD0_PG_STS", BIT(15), 0},
+ {"SPC_PGD0_PG_STS", BIT(16), 1},
+ {"ACE_PGD0_PG_STS", BIT(17), 0},
+ {"ACE_PGD1_PG_STS", BIT(18), 0},
+ {"ACE_PGD2_PG_STS", BIT(19), 0},
+ {"ACE_PGD3_PG_STS", BIT(20), 0},
+ {"ACE_PGD4_PG_STS", BIT(21), 0},
+ {"ACE_PGD5_PG_STS", BIT(22), 0},
+ {"ACE_PGD6_PG_STS", BIT(23), 0},
+ {"ACE_PGD7_PG_STS", BIT(24), 0},
+ {"ACE_PGD8_PG_STS", BIT(25), 0},
+ {"ACE_PGD9_PG_STS", BIT(26), 0},
+ {"ACE_PGD10_PG_STS", BIT(27), 0},
+ {"U3FPW3_PGD0_PG_STS", BIT(28), 0},
+ {"SBR7_PGD0_PG_STS", BIT(29), 0},
+ {"OSSE_PGD0_PG_STS", BIT(30), 0},
+ {"SATA_PGD0_PG_STS", BIT(31), 1},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pchs_d3_status_0_map[] = {
+ {"LPSS_D3_STS", BIT(3), 1},
+ {"XDCI_D3_STS", BIT(4), 1},
+ {"XHCI_D3_STS", BIT(5), 0},
+ {"SPA_D3_STS", BIT(12), 0},
+ {"SPB_D3_STS", BIT(13), 0},
+ {"SPC_D3_STS", BIT(14), 0},
+ {"ESPISPI_D3_STS", BIT(18), 0},
+ {"SATA_D3_STS", BIT(20), 1},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pchs_d3_status_1_map[] = {
+ {"OSSE_D3_STS", BIT(6), 0},
+ {"GBE_D3_STS", BIT(19), 0},
+ {"ITSS_D3_STS", BIT(23), 0},
+ {"P2S_D3_STS", BIT(24), 0},
+ {"CNVI_D3_STS", BIT(27), 0},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pchs_d3_status_2_map[] = {
+ {"CSMERTC_D3_STS", BIT(1), 0},
+ {"CSE_D3_STS", BIT(4), 0},
+ {"KVMCC_D3_STS", BIT(5), 0},
+ {"USBR0_D3_STS", BIT(6), 0},
+ {"ISH_D3_STS", BIT(7), 0},
+ {"SMT1_D3_STS", BIT(8), 0},
+ {"SMT2_D3_STS", BIT(9), 0},
+ {"SMT3_D3_STS", BIT(10), 0},
+ {"SMT4_D3_STS", BIT(11), 0},
+ {"SMT5_D3_STS", BIT(12), 0},
+ {"SMT6_D3_STS", BIT(13), 0},
+ {"CLINK_D3_STS", BIT(14), 0},
+ {"PTIO_D3_STS", BIT(16), 0},
+ {"PMT_D3_STS", BIT(17), 0},
+ {"SMS1_D3_STS", BIT(18), 0},
+ {"SMS2_D3_STS", BIT(19), 0},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pchs_d3_status_3_map[] = {
+ {"THC0_D3_STS", BIT(14), 0},
+ {"THC1_D3_STS", BIT(15), 0},
+ {"ACE_D3_STS", BIT(23), 0},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pchs_vnn_req_status_1_map[] = {
+ {"NPK_VNN_REQ_STS", BIT(4), 0},
+ {"OSSE_VNN_REQ_STS", BIT(6), 0},
+ {"DFXAGG_VNN_REQ_STS", BIT(8), 0},
+ {"EXI_VNN_REQ_STS", BIT(9), 0},
+ {"GBE_VNN_REQ_STS", BIT(19), 0},
+ {"SMB_VNN_REQ_STS", BIT(25), 0},
+ {"LPC_VNN_REQ_STS", BIT(26), 0},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pchs_vnn_req_status_2_map[] = {
+ {"CSMERTC_VNN_REQ_STS", BIT(1), 0},
+ {"CSE_VNN_REQ_STS", BIT(4), 0},
+ {"ISH_VNN_REQ_STS", BIT(7), 0},
+ {"SMT1_VNN_REQ_STS", BIT(8), 0},
+ {"SMT4_VNN_REQ_STS", BIT(11), 0},
+ {"CLINK_VNN_REQ_STS", BIT(14), 0},
+ {"SMS1_VNN_REQ_STS", BIT(18), 0},
+ {"SMS2_VNN_REQ_STS", BIT(19), 0},
+ {"GPIOCOM4_VNN_REQ_STS", BIT(20), 0},
+ {"GPIOCOM3_VNN_REQ_STS", BIT(21), 0},
+ {"GPIOCOM2_VNN_REQ_STS", BIT(22), 0},
+ {"GPIOCOM1_VNN_REQ_STS", BIT(23), 0},
+ {"GPIOCOM0_VNN_REQ_STS", BIT(24), 0},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pchs_vnn_misc_status_map[] = {
+ {"CPU_C10_REQ_STS", BIT(0), 0},
+ {"TS_OFF_REQ_STS", BIT(1), 0},
+ {"PNDE_MET_REQ_STS", BIT(2), 1},
+ {"PG5_PMA0_GVNN_REQ_STS", BIT(3), 1},
+ {"FW_THROTTLE_ALLOWED_REQ_STS", BIT(4), 0},
+ {"DMI_IN_L1_REQ_STS", BIT(6), 0},
+ {"ISH_VNNAON_REQ_STS", BIT(7), 0},
+ {"PLT_GREATER_REQ_STS", BIT(11), 1},
+ {"ALL_SBR_IDLE_REQ_STS", BIT(12), 0},
+ {"PMC_IDLE_FB_OCP_REQ_STS", BIT(13), 0},
+ {"PM_SYNC_STATES_REQ_STS", BIT(14), 0},
+ {"EA_REQ_STS", BIT(15), 0},
+ {"DMI_CLKREQ_B_REQ_STS", BIT(16), 0},
+ {"BRK_EV_EN_REQ_STS", BIT(17), 0},
+ {"AUTO_DEMO_EN_REQ_STS", BIT(18), 0},
+ {"ITSS_CLK_SRC_REQ_STS", BIT(19), 1},
+ {"ARC_IDLE_REQ_STS", BIT(21), 0},
+ {"PG5_PMA1_GVNN_REQ_STS", BIT(22), 1},
+ {"FIA_DEEP_PM_REQ_STS", BIT(23), 0},
+ {"XDCI_ATTACHED_REQ_STS", BIT(24), 0},
+ {"ARC_INTERRUPT_WAKE_REQ_STS", BIT(25), 0},
+ {"PRE_WAKE0_REQ_STS", BIT(27), 1},
+ {"PRE_WAKE1_REQ_STS", BIT(28), 1},
+ {"PRE_WAKE2_EN_REQ_STS", BIT(29), 0},
+ {"PG5_PMA2_GVNN_REQ_STS", BIT(30), 1},
+ {}
+};
+
+static const struct pmc_bit_map nvl_pchs_rsc_status_map[] = {
+ {"Memory", 0, 1},
+ {"Memory_NS", 0, 1},
+ {"PSF1", 0, 1},
+ {"PSF2", 0, 1},
+ {"PSF3", 0, 1},
+ {"REF_PLL", 0, 1},
+ {"SB", 0, 1},
+ {}
+};
+
+static const struct pmc_bit_map *nvl_pchs_lpm_maps[] = {
+ nvl_pchs_clocksource_status_map,
+ nvl_pchs_power_gating_status_0_map,
+ nvl_pchs_power_gating_status_1_map,
+ nvl_pchs_power_gating_status_2_map,
+ nvl_pchs_d3_status_0_map,
+ nvl_pchs_d3_status_1_map,
+ nvl_pchs_d3_status_2_map,
+ nvl_pchs_d3_status_3_map,
+ nvl_pcds_vnn_req_status_0_map,
+ nvl_pchs_vnn_req_status_1_map,
+ nvl_pchs_vnn_req_status_2_map,
+ nvl_pcdh_vnn_req_status_3_map,
+ nvl_pchs_vnn_misc_status_map,
+ ptl_pcdp_signal_status_map,
+ NULL
+};
+
+static const struct pmc_bit_map *nvl_pchs_blk_maps[] = {
+ nvl_pchs_power_gating_status_0_map,
+ nvl_pchs_power_gating_status_1_map,
+ nvl_pchs_power_gating_status_2_map,
+ nvl_pchs_rsc_status_map,
+ nvl_pchs_d3_status_0_map,
+ nvl_pchs_clocksource_status_map,
+ nvl_pchs_vnn_misc_status_map,
+ NULL
+};
+
+static const struct pmc_reg_map nvl_pcdh_reg_map = {
+ .pfear_sts = ext_nvl_pcdh_pfear_map,
+ .slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET,
+ .slp_s0_res_counter_step = TGL_PMC_SLP_S0_RES_COUNTER_STEP,
+ .ltr_show_sts = ptl_pcdp_ltr_show_map,
+ .msr_sts = msr_map,
+ .ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET,
+ .regmap_length = NVL_PCDH_PMC_MMIO_REG_LEN,
+ .ppfear0_offset = CNP_PMC_HOST_PPFEAR0A,
+ .ppfear_buckets = NVL_PCDH_PPFEAR_NUM_ENTRIES,
+ .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET,
+ .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT,
+ .lpm_num_maps = NVL_LPM_NUM_MAPS,
+ .ltr_ignore_max = LNL_NUM_IP_IGN_ALLOWED,
+ .lpm_res_counter_step_x2 = TGL_PMC_LPM_RES_COUNTER_STEP_X2,
+ .etr3_offset = ETR3_OFFSET,
+ .lpm_sts_latch_en_offset = MTL_LPM_STATUS_LATCH_EN_OFFSET,
+ .lpm_priority_offset = NVL_LPM_PRI_OFFSET,
+ .lpm_en_offset = NVL_LPM_EN_OFFSET,
+ .lpm_residency_offset = NVL_LPM_RESIDENCY_OFFSET,
+ .lpm_sts = nvl_pcdh_lpm_maps,
+ .lpm_status_offset = MTL_LPM_STATUS_OFFSET,
+ .lpm_live_status_offset = NVL_LPM_LIVE_STATUS_OFFSET,
+ .s0ix_blocker_maps = nvl_pcdh_blk_maps,
+ .s0ix_blocker_offset = LNL_S0IX_BLOCKER_OFFSET,
+ .num_s0ix_blocker = NVL_PCDH_NUM_S0IX_BLOCKER,
+ .blocker_req_offset = NVL_PCDH_BLK_REQ_OFFSET,
+ .lpm_req_guid = PCDH_LPM_REQ_GUID,
+};
+
+static const struct pmc_reg_map nvl_pcds_reg_map = {
+ .pfear_sts = ext_nvl_pcds_pfear_map,
+ .slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET,
+ .slp_s0_res_counter_step = TGL_PMC_SLP_S0_RES_COUNTER_STEP,
+ .ltr_show_sts = nvl_pcds_ltr_show_map,
+ .msr_sts = msr_map,
+ .ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET,
+ .regmap_length = NVL_PCDS_PMC_MMIO_REG_LEN,
+ .ppfear0_offset = CNP_PMC_HOST_PPFEAR0A,
+ .ppfear_buckets = LNL_PPFEAR_NUM_ENTRIES,
+ .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET,
+ .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT,
+ .lpm_num_maps = PTL_LPM_NUM_MAPS,
+ .ltr_ignore_max = LNL_NUM_IP_IGN_ALLOWED,
+ .lpm_res_counter_step_x2 = TGL_PMC_LPM_RES_COUNTER_STEP_X2,
+ .etr3_offset = ETR3_OFFSET,
+ .lpm_sts_latch_en_offset = MTL_LPM_STATUS_LATCH_EN_OFFSET,
+ .lpm_priority_offset = MTL_LPM_PRI_OFFSET,
+ .lpm_en_offset = MTL_LPM_EN_OFFSET,
+ .lpm_residency_offset = MTL_LPM_RESIDENCY_OFFSET,
+ .lpm_sts = nvl_pcds_lpm_maps,
+ .lpm_status_offset = MTL_LPM_STATUS_OFFSET,
+ .lpm_live_status_offset = MTL_LPM_LIVE_STATUS_OFFSET,
+ .s0ix_blocker_maps = nvl_pcds_blk_maps,
+ .s0ix_blocker_offset = LNL_S0IX_BLOCKER_OFFSET,
+ .num_s0ix_blocker = NVL_PCDS_NUM_S0IX_BLOCKER,
+ .lpm_req_guid = PCDS_LPM_REQ_GUID,
+ .blocker_req_offset = NVL_PCDS_BLK_REQ_OFFSET,
+};
+
+static const struct pmc_reg_map nvl_pchs_reg_map = {
+ .pfear_sts = ext_nvl_pchs_pfear_map,
+ .slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET,
+ .slp_s0_res_counter_step = TGL_PMC_SLP_S0_RES_COUNTER_STEP,
+ .ltr_show_sts = ptl_pcdp_ltr_show_map,
+ .msr_sts = msr_map,
+ .ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET,
+ .regmap_length = NVL_PCHS_PMC_MMIO_REG_LEN,
+ .ppfear0_offset = CNP_PMC_HOST_PPFEAR0A,
+ .ppfear_buckets = LNL_PPFEAR_NUM_ENTRIES,
+ .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET,
+ .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT,
+ .lpm_num_maps = PTL_LPM_NUM_MAPS,
+ .ltr_ignore_max = LNL_NUM_IP_IGN_ALLOWED,
+ .lpm_res_counter_step_x2 = TGL_PMC_LPM_RES_COUNTER_STEP_X2,
+ .etr3_offset = ETR3_OFFSET,
+ .lpm_sts_latch_en_offset = MTL_LPM_STATUS_LATCH_EN_OFFSET,
+ .lpm_priority_offset = MTL_LPM_PRI_OFFSET,
+ .lpm_en_offset = MTL_LPM_EN_OFFSET,
+ .lpm_residency_offset = MTL_LPM_RESIDENCY_OFFSET,
+ .lpm_sts = nvl_pchs_lpm_maps,
+ .lpm_status_offset = MTL_LPM_STATUS_OFFSET,
+ .lpm_live_status_offset = MTL_LPM_LIVE_STATUS_OFFSET,
+ .s0ix_blocker_maps = nvl_pchs_blk_maps,
+ .s0ix_blocker_offset = LNL_S0IX_BLOCKER_OFFSET,
+ .num_s0ix_blocker = NVL_PCHS_NUM_S0IX_BLOCKER,
+ .blocker_req_offset = NVL_PCHS_BLK_REQ_OFFSET,
+ .lpm_req_guid = PCHS_LPM_REQ_GUID,
+};
+
+static struct pmc_info nvl_pmc_info_list[] = {
+ {
+ .devid = PMC_DEVID_NVL_PCDH,
+ .map = &nvl_pcdh_reg_map,
+ },
+ {
+ .devid = PMC_DEVID_NVL_PCDS,
+ .map = &nvl_pcds_reg_map,
+ },
+ {
+ .devid = PMC_DEVID_NVL_PCHS,
+ .map = &nvl_pchs_reg_map,
+ },
+ {}
+};
+
+static const char *nvl_ltr_block_counter_arr[] = {
+ "PKGC_PREVENT_LTR_IADOMAIN",
+ "PKGC_PREVENT_LTR_GDIE",
+ "PKGC_PREVENT_LTR_PCH",
+ "PKGC_PREVENT_LTR_DISPLAY",
+ "PKGC_PREVENT_LTR_IPU",
+ NULL
+};
+
+static const char *nvl_pkgc_blocker_residency[] = {
+ "PKGC_BLOCK_RESIDENCY_INVALID",
+ "PKGC_BLOCK_RESIDENCY_MISC",
+ "PKGC_BLOCK_RESIDENCY_CDIE_MISC",
+ "PKGC_BLOCK_RESIDENCY_MEDIA_MISC",
+ "PKGC_BLOCK_RESIDENCY_GT_MISC",
+ "PKGC_BLOCK_RESIDENCY_HUBATOM_MISC",
+ "PKGC_BLOCK_RESIDENCY_IPU_BUSY",
+ "PKGC_BLOCK_RESIDENCY_IPU_LTR",
+ "PKGC_BLOCK_RESIDENCY_IPU_TIMER",
+ "PKGC_BLOCK_RESIDENCY_DISP_BUSY",
+ "PKGC_BLOCK_RESIDENCY_DISP_LTR",
+ "PKGC_BLOCK_RESIDENCY_DISP_TIMER",
+ "PKGC_BLOCK_RESIDENCY_VPU_BUSY",
+ "PKGC_BLOCK_RESIDENCY_VPU_TIMER",
+ "PKGC_BLOCK_RESIDENCY_PMC_BUSY",
+ "PKGC_BLOCK_RESIDENCY_PMC_LTR",
+ "PKGC_BLOCK_RESIDENCY_PMC_TIMER",
+ "PKGC_BLOCK_RESIDENCY_HUBATOM_ARAT",
+ "PKGC_BLOCK_RESIDENCY_CDIE0_ARAT",
+ "PKGC_BLOCK_RESIDENCY_CDIE1_ARAT",
+ "PKGC_BLOCK_RESIDENCY_GT_ARAT",
+ "PKGC_BLOCK_RESIDENCY_MEDIA_ARAT",
+ "PKGC_BLOCK_RESIDENCY_DEMOTION",
+ "PKGC_BLOCK_RESIDENCY_THERMALS",
+ "PKGC_BLOCK_RESIDENCY_SNCU",
+ "PKGC_BLOCK_RESIDENCY_SVTU",
+ "PKGC_BLOCK_RESIDENCY_IAA",
+ "PKGC_BLOCK_RESIDENCY_IOC",
+ NULL,
+};
+
+static const u8 nvl_pmc_list[] = {PMC_IDX_MAIN, PMC_IDX_PCH};
+
+#define NVL_NPU_PCI_DEV 0xd71d
+
+/*
+ * Set power state of select devices that do not have drivers to D3
+ * so that they do not block Package C entry.
+ */
+static void nvl_d3_fixup(void)
+{
+ pmc_core_set_device_d3(NVL_NPU_PCI_DEV);
+}
+
+static int nvl_resume(struct pmc_dev *pmcdev)
+{
+ nvl_d3_fixup();
+ return cnl_resume(pmcdev);
+}
+
+static int nvl_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info)
+{
+ nvl_d3_fixup();
+ return generic_core_init(pmcdev, pmc_dev_info);
+}
+
+static u32 nvl_pmt_dmu_guids[] = {NVL_PMT_DMU_GUID, 0x0};
+struct pmc_dev_info nvl_s_pmc_dev = {
+ .num_pmcs = ARRAY_SIZE(nvl_pmc_list),
+ .pmc_list = nvl_pmc_list,
+ .regmap_list = nvl_pmc_info_list,
+ .map = &nvl_pcds_reg_map,
+ .sub_req_show = &pmc_core_substate_blk_req_fops,
+ .suspend = cnl_suspend,
+ .resume = nvl_resume,
+ .init = nvl_core_init,
+ .sub_req = pmc_core_pmt_get_blk_sub_req,
+ .dmu_guids = nvl_pmt_dmu_guids,
+ .pc_guid = NVL_PMT_PC_GUID,
+ .pkgc_ltr_blocker_offset = NVL_LTR_BLK_OFFSET,
+ .pkgc_ltr_blocker_counters = nvl_ltr_block_counter_arr,
+ .pkgc_blocker_offset = NVL_PKGC_BLK_OFFSET,
+ .pkgc_blocker_counters = nvl_pkgc_blocker_residency,
+ .ssram_hidden = false,
+ .die_c6_offset = NVL_PMT_DMU_DIE_C6_OFFSET,
+};
+
+struct pmc_dev_info nvl_h_pmc_dev = {
+ .num_pmcs = ARRAY_SIZE(nvl_pmc_list),
+ .pmc_list = nvl_pmc_list,
+ .regmap_list = nvl_pmc_info_list,
+ .map = &nvl_pcdh_reg_map,
+ .sub_req_show = &pmc_core_substate_blk_req_fops,
+ .suspend = cnl_suspend,
+ .resume = nvl_resume,
+ .init = nvl_core_init,
+ .sub_req = pmc_core_pmt_get_blk_sub_req,
+ .dmu_guids = nvl_pmt_dmu_guids,
+ .pc_guid = NVL_PMT_PC_GUID,
+ .pkgc_ltr_blocker_offset = NVL_LTR_BLK_OFFSET,
+ .pkgc_ltr_blocker_counters = nvl_ltr_block_counter_arr,
+ .pkgc_blocker_offset = NVL_PKGC_BLK_OFFSET,
+ .pkgc_blocker_counters = nvl_pkgc_blocker_residency,
+ .ssram_hidden = false,
+ .die_c6_offset = NVL_PMT_DMU_DIE_C6_OFFSET,
+};
diff --git a/drivers/platform/x86/intel/pmc/ptl.c b/drivers/platform/x86/intel/pmc/ptl.c
index 1f48e2bbc699f..a7d5d4f77934f 100644
--- a/drivers/platform/x86/intel/pmc/ptl.c
+++ b/drivers/platform/x86/intel/pmc/ptl.c
@@ -137,7 +137,7 @@ static const struct pmc_bit_map *ext_ptl_pcdp_pfear_map[] = {
NULL
};
-static const struct pmc_bit_map ptl_pcdp_ltr_show_map[] = {
+const struct pmc_bit_map ptl_pcdp_ltr_show_map[] = {
{"SOUTHPORT_A", CNP_PMC_LTR_SPA},
{"SOUTHPORT_B", CNP_PMC_LTR_SPB},
{"SATA", CNP_PMC_LTR_SATA},
@@ -543,6 +543,8 @@ static struct pmc_info ptl_pmc_info_list[] = {
{}
};
+static const u8 ptl_pmc_list[] = {PMC_IDX_MAIN};
+
#define PTL_NPU_PCI_DEV 0xb03e
#define PTL_IPU_PCI_DEV 0xb05d
@@ -569,7 +571,8 @@ static int ptl_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_in
}
struct pmc_dev_info ptl_pmc_dev = {
- .pci_func = 2,
+ .num_pmcs = ARRAY_SIZE(ptl_pmc_list),
+ .pmc_list = ptl_pmc_list,
.regmap_list = ptl_pmc_info_list,
.map = &ptl_pcdp_reg_map,
.sub_req_show = &pmc_core_substate_blk_req_fops,
@@ -577,4 +580,5 @@ struct pmc_dev_info ptl_pmc_dev = {
.resume = ptl_resume,
.init = ptl_core_init,
.sub_req = pmc_core_pmt_get_blk_sub_req,
+ .ssram_hidden = true,
};
diff --git a/drivers/platform/x86/intel/pmc/wcl.c b/drivers/platform/x86/intel/pmc/wcl.c
index a45707e6364f2..d34ac916907dc 100644
--- a/drivers/platform/x86/intel/pmc/wcl.c
+++ b/drivers/platform/x86/intel/pmc/wcl.c
@@ -469,6 +469,8 @@ static struct pmc_info wcl_pmc_info_list[] = {
{}
};
+static const u8 wcl_pmc_list[] = {PMC_IDX_MAIN};
+
#define WCL_NPU_PCI_DEV 0xfd3e
/*
@@ -493,12 +495,14 @@ static int wcl_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_in
}
struct pmc_dev_info wcl_pmc_dev = {
- .pci_func = 2,
.regmap_list = wcl_pmc_info_list,
+ .num_pmcs = ARRAY_SIZE(wcl_pmc_list),
+ .pmc_list = wcl_pmc_list,
.map = &wcl_pcdn_reg_map,
.sub_req_show = &pmc_core_substate_blk_req_fops,
.suspend = cnl_suspend,
.resume = wcl_resume,
.init = wcl_core_init,
.sub_req = pmc_core_pmt_get_blk_sub_req,
+ .ssram_hidden = true,
};
diff --git a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c
index 7070c94324e0e..3b554418a7a3c 100644
--- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c
+++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c
@@ -29,6 +29,13 @@ static ssize_t show_domain_id(struct kobject *kobj, struct kobj_attribute *attr,
return sysfs_emit(buf, "%u\n", data->domain_id);
}
+static ssize_t show_instance_id(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+ struct uncore_data *data = container_of(attr, struct uncore_data, instance_id_kobj_attr);
+
+ return sysfs_emit(buf, "%u\n", data->instance_id);
+}
+
static ssize_t show_fabric_cluster_id(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct uncore_data *data = container_of(attr, struct uncore_data, fabric_cluster_id_kobj_attr);
@@ -200,6 +207,9 @@ static int create_attr_group(struct uncore_data *data, char *name)
if (data->domain_id != UNCORE_DOMAIN_ID_INVALID) {
init_attribute_root_ro(domain_id);
data->uncore_attrs[index++] = &data->domain_id_kobj_attr.attr;
+ init_attribute_root_ro(instance_id);
+ data->uncore_attrs[index++] = &data->instance_id_kobj_attr.attr;
+
init_attribute_root_ro(fabric_cluster_id);
data->uncore_attrs[index++] = &data->fabric_cluster_id_kobj_attr.attr;
init_attribute_root_ro(package_id);
@@ -268,7 +278,7 @@ int uncore_freq_add_entry(struct uncore_data *data, int cpu)
if (ret < 0)
goto uncore_unlock;
- data->instance_id = ret;
+ data->seqnum_id = ret;
scnprintf(data->name, sizeof(data->name), "uncore%02d", ret);
} else {
scnprintf(data->name, sizeof(data->name), "package_%02d_die_%02d",
@@ -281,7 +291,7 @@ int uncore_freq_add_entry(struct uncore_data *data, int cpu)
ret = create_attr_group(data, data->name);
if (ret) {
if (data->domain_id != UNCORE_DOMAIN_ID_INVALID)
- ida_free(&intel_uncore_ida, data->instance_id);
+ ida_free(&intel_uncore_ida, data->seqnum_id);
} else {
data->control_cpu = cpu;
data->valid = true;
@@ -301,7 +311,7 @@ void uncore_freq_remove_die_entry(struct uncore_data *data)
data->control_cpu = -1;
data->valid = false;
if (data->domain_id != UNCORE_DOMAIN_ID_INVALID)
- ida_free(&intel_uncore_ida, data->instance_id);
+ ida_free(&intel_uncore_ida, data->seqnum_id);
mutex_unlock(&uncore_lock);
}
diff --git a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.h b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.h
index 0abe850ef54ea..e319448dc1a44 100644
--- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.h
+++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.h
@@ -35,7 +35,8 @@
* @die_id: Die id for this instance
* @domain_id: Power domain id for this instance
* @cluster_id: cluster id in a domain
- * @instance_id: Unique instance id to append to directory name
+ * @seqnum_id: Unique sequential id to append to directory name
+ * @instance_id: Die indices or feature instances for a single TPMI device
* @name: Sysfs entry name for this instance
* @agent_type_mask: Bit mask of all hardware agents for this domain
* @uncore_attr_group: Attribute group storage
@@ -56,6 +57,7 @@
* @elc_floor_freq_khz_kobj_attr: Storage for kobject attribute elc_floor_freq_khz
* @agent_types_kobj_attr: Storage for kobject attribute agent_type
* @die_id_kobj_attr: Attribute storage for die_id information
+ * @instance_id_kobj_attr: Attribute storage for instance_id value
* @uncore_attrs: Attribute storage for group creation
*
* This structure is used to encapsulate all data related to uncore sysfs
@@ -71,6 +73,7 @@ struct uncore_data {
int die_id;
int domain_id;
int cluster_id;
+ int seqnum_id;
int instance_id;
char name[32];
u16 agent_type_mask;
@@ -90,7 +93,8 @@ struct uncore_data {
struct kobj_attribute elc_floor_freq_khz_kobj_attr;
struct kobj_attribute agent_types_kobj_attr;
struct kobj_attribute die_id_kobj_attr;
- struct attribute *uncore_attrs[15];
+ struct kobj_attribute instance_id_kobj_attr;
+ struct attribute *uncore_attrs[16];
};
#define UNCORE_DOMAIN_ID_INVALID -1
diff --git a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c
index 88015a2c6a0d1..44e2a90004df3 100644
--- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c
+++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-tpmi.c
@@ -385,7 +385,19 @@ static u8 io_die_index_next;
/* Lock to protect io_die_start, io_die_index_next */
static DEFINE_MUTEX(domain_lock);
-static void set_domain_id(int id, int num_resources,
+static inline void set_instance_id(int id, struct tpmi_uncore_cluster_info *cluster_info)
+{
+ /*
+ * On non-partitioned systems domain_id can be used for mapping both
+ * CPUs to compute die IDs and physical die indexes to MMIO mapped
+ * memory. However on partitioned systems domain_id loses the second
+ * association. Therefore instance_id should be used for that instead,
+ * while domain_id should still be used to match CPUs to compute dies.
+ */
+ cluster_info->uncore_data.instance_id = id;
+}
+
+static void set_domain_id(int id, int num_resources,
struct oobmsm_plat_info *plat_info,
struct tpmi_uncore_cluster_info *cluster_info)
{
@@ -690,6 +702,7 @@ static int uncore_probe(struct auxiliary_device *auxdev, const struct auxiliary_
set_cdie_id(i, cluster_info, plat_info);
set_domain_id(i, num_resources, plat_info, cluster_info);
+ set_instance_id(i, cluster_info);
cluster_info->uncore_root = tpmi_uncore;
diff --git a/drivers/platform/x86/intel/vsec.c b/drivers/platform/x86/intel/vsec.c
index 18e4a892bf0f0..1657834fd2759 100644
--- a/drivers/platform/x86/intel/vsec.c
+++ b/drivers/platform/x86/intel/vsec.c
@@ -112,7 +112,6 @@ static void intel_vsec_dev_release(struct device *dev)
ida_free(intel_vsec_dev->ida, intel_vsec_dev->auxdev.id);
kfree(intel_vsec_dev->acpi_disc);
- kfree(intel_vsec_dev->resource);
kfree(intel_vsec_dev);
}
@@ -225,7 +224,6 @@ int intel_vsec_add_aux(struct device *parent,
ret = xa_alloc(&auxdev_array, &intel_vsec_dev->id, intel_vsec_dev,
PMT_XA_LIMIT, GFP_KERNEL);
if (ret < 0) {
- kfree(intel_vsec_dev->resource);
kfree(intel_vsec_dev);
return ret;
}
@@ -233,7 +231,6 @@ int intel_vsec_add_aux(struct device *parent,
id = ida_alloc(intel_vsec_dev->ida, GFP_KERNEL);
if (id < 0) {
xa_erase(&auxdev_array, intel_vsec_dev->id);
- kfree(intel_vsec_dev->resource);
kfree(intel_vsec_dev);
return id;
}
@@ -282,7 +279,7 @@ static int intel_vsec_add_dev(struct device *dev, struct intel_vsec_header *head
unsigned long cap_id, u64 base_addr)
{
struct intel_vsec_device __free(kfree) *intel_vsec_dev = NULL;
- struct resource __free(kfree) *res = NULL;
+ struct resource *res;
struct resource *tmp;
struct device *parent;
unsigned long quirks = info->quirks;
@@ -306,13 +303,12 @@ static int intel_vsec_add_dev(struct device *dev, struct intel_vsec_header *head
return -EINVAL;
}
- intel_vsec_dev = kzalloc_obj(*intel_vsec_dev);
+ intel_vsec_dev = kzalloc_flex(*intel_vsec_dev, resource, header->num_entries);
if (!intel_vsec_dev)
return -ENOMEM;
- res = kzalloc_objs(*res, header->num_entries);
- if (!res)
- return -ENOMEM;
+ intel_vsec_dev->num_resources = header->num_entries;
+ res = intel_vsec_dev->resource;
if (quirks & VSEC_QUIRK_TABLE_SHIFT)
header->offset >>= TABLE_OFFSET_SHIFT;
@@ -342,8 +338,6 @@ static int intel_vsec_add_dev(struct device *dev, struct intel_vsec_header *head
}
intel_vsec_dev->dev = dev;
- intel_vsec_dev->resource = no_free_ptr(res);
- intel_vsec_dev->num_resources = header->num_entries;
intel_vsec_dev->quirks = info->quirks;
intel_vsec_dev->base_addr = info->base_addr;
intel_vsec_dev->priv_data = info->priv_data;
diff --git a/drivers/platform/x86/intel/vsec_tpmi.c b/drivers/platform/x86/intel/vsec_tpmi.c
index 88f14d0ad4102..3b76cccb975f6 100644
--- a/drivers/platform/x86/intel/vsec_tpmi.c
+++ b/drivers/platform/x86/intel/vsec_tpmi.c
@@ -634,15 +634,12 @@ static int tpmi_create_device(struct intel_tpmi_info *tpmi_info,
if (!name)
return -EOPNOTSUPP;
- res = kzalloc_objs(*res, pfs->pfs_header.num_entries);
- if (!res)
+ feature_vsec_dev = kzalloc_flex(*feature_vsec_dev, resource, pfs->pfs_header.num_entries);
+ if (!feature_vsec_dev)
return -ENOMEM;
- feature_vsec_dev = kzalloc_obj(*feature_vsec_dev);
- if (!feature_vsec_dev) {
- kfree(res);
- return -ENOMEM;
- }
+ feature_vsec_dev->num_resources = pfs->pfs_header.num_entries;
+ res = feature_vsec_dev->resource;
snprintf(feature_id_name, sizeof(feature_id_name), "tpmi-%s", name);
@@ -655,8 +652,6 @@ static int tpmi_create_device(struct intel_tpmi_info *tpmi_info,
}
feature_vsec_dev->dev = vsec_dev->dev;
- feature_vsec_dev->resource = res;
- feature_vsec_dev->num_resources = pfs->pfs_header.num_entries;
feature_vsec_dev->priv_data = &tpmi_info->plat_info;
feature_vsec_dev->priv_data_size = sizeof(tpmi_info->plat_info);
feature_vsec_dev->ida = &intel_vsec_tpmi_ida;
diff --git a/drivers/platform/x86/lenovo/thinkpad_acpi.c b/drivers/platform/x86/lenovo/thinkpad_acpi.c
index e1cee42a1683e..445e1403308ee 100644
--- a/drivers/platform/x86/lenovo/thinkpad_acpi.c
+++ b/drivers/platform/x86/lenovo/thinkpad_acpi.c
@@ -38,6 +38,7 @@
#include <linux/backlight.h>
#include <linux/bitfield.h>
#include <linux/bitops.h>
+#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/dmi.h>
#include <linux/freezer.h>
@@ -2469,7 +2470,7 @@ static int hotkey_kthread(void *data)
bool was_frozen;
if (tpacpi_lifecycle == TPACPI_LIFE_EXITING)
- goto exit;
+ return 0;
set_freezable();
@@ -2526,7 +2527,6 @@ static int hotkey_kthread(void *data)
si ^= 1;
}
-exit:
return 0;
}
@@ -11217,6 +11217,26 @@ static ssize_t hwdd_status_show(struct device *dev,
return sysfs_emit(buf, "0\n");
}
+
+/* sysfs type-c damage detection raw data - accessed via debugfs*/
+static int hwdd_raw_show(struct seq_file *m, void *v)
+{
+ unsigned int damage_status;
+ int err;
+
+ if (!ucdd_supported)
+ return -ENODEV;
+
+ /* Get USB TYPE-C damage status */
+ err = hwdd_command(HWDD_GET_DMG_USBC, &damage_status);
+ if (err)
+ return err;
+
+ seq_printf(m, "HWDD: 0x%x\n", damage_status);
+ return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(hwdd_raw);
+
static DEVICE_ATTR_RO(hwdd_status);
static DEVICE_ATTR_RO(hwdd_detail);
@@ -11504,6 +11524,20 @@ static const char * __init str_supported(int is_supported)
}
#endif /* CONFIG_THINKPAD_ACPI_DEBUG */
+static struct dentry *tpacpi_dbg;
+static void tpacpi_debugfs_init(void)
+{
+ tpacpi_dbg = debugfs_create_dir("tpacpi", NULL);
+
+ /* HWDD raw data */
+ debugfs_create_file("hwdd-raw", 0444, tpacpi_dbg, NULL, &hwdd_raw_fops);
+}
+
+static void tpacpi_debugfs_remove(void)
+{
+ debugfs_remove_recursive(tpacpi_dbg);
+}
+
static void ibm_exit(struct ibm_struct *ibm)
{
dbg_printk(TPACPI_DBG_EXIT, "removing %s\n", ibm->name);
@@ -12068,6 +12102,8 @@ static void thinkpad_acpi_module_exit(void)
remove_proc_entry(TPACPI_PROC_DIR, acpi_root_dir);
if (tpacpi_wq)
destroy_workqueue(tpacpi_wq);
+ if (tpacpi_dbg)
+ tpacpi_debugfs_remove();
kfree(thinkpad_id.bios_version_str);
kfree(thinkpad_id.ec_version_str);
@@ -12198,6 +12234,8 @@ static int __init thinkpad_acpi_module_init(void)
return -ENODEV;
}
+ tpacpi_debugfs_init();
+
dmi_id = dmi_first_match(fwbug_list);
if (dmi_id)
tp_features.quirks = dmi_id->driver_data;
diff --git a/drivers/platform/x86/meraki-mx100.c b/drivers/platform/x86/meraki-mx100.c
index 8c5276d985123..9f4caa1f3a923 100644
--- a/drivers/platform/x86/meraki-mx100.c
+++ b/drivers/platform/x86/meraki-mx100.c
@@ -20,16 +20,11 @@
#include <linux/input-event-codes.h>
#include <linux/io.h>
#include <linux/kernel.h>
+#include <linux/mfd/lpc_ich.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/property.h>
-#define TINK_GPIO_DRIVER_NAME "gpio_ich"
-
-static const struct software_node gpio_ich_node = {
- .name = TINK_GPIO_DRIVER_NAME,
-};
-
/* LEDs */
static const struct software_node tink_gpio_leds_node = {
.name = "meraki-mx100-leds",
@@ -38,7 +33,7 @@ static const struct software_node tink_gpio_leds_node = {
static const struct property_entry tink_internet_led_props[] = {
PROPERTY_ENTRY_STRING("label", "mx100:green:internet"),
PROPERTY_ENTRY_STRING("linux,default-trigger", "default-on"),
- PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 11, GPIO_ACTIVE_LOW),
+ PROPERTY_ENTRY_GPIO("gpios", &lpc_ich_gpio_swnode, 11, GPIO_ACTIVE_LOW),
{ }
};
@@ -50,7 +45,7 @@ static const struct software_node tink_internet_led_node = {
static const struct property_entry tink_lan2_led_props[] = {
PROPERTY_ENTRY_STRING("label", "mx100:green:lan2"),
- PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 18, GPIO_ACTIVE_HIGH),
+ PROPERTY_ENTRY_GPIO("gpios", &lpc_ich_gpio_swnode, 18, GPIO_ACTIVE_HIGH),
{ }
};
@@ -62,7 +57,7 @@ static const struct software_node tink_lan2_led_node = {
static const struct property_entry tink_lan3_led_props[] = {
PROPERTY_ENTRY_STRING("label", "mx100:green:lan3"),
- PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 20, GPIO_ACTIVE_HIGH),
+ PROPERTY_ENTRY_GPIO("gpios", &lpc_ich_gpio_swnode, 20, GPIO_ACTIVE_HIGH),
{ }
};
@@ -74,7 +69,7 @@ static const struct software_node tink_lan3_led_node = {
static const struct property_entry tink_lan4_led_props[] = {
PROPERTY_ENTRY_STRING("label", "mx100:green:lan4"),
- PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 22, GPIO_ACTIVE_HIGH),
+ PROPERTY_ENTRY_GPIO("gpios", &lpc_ich_gpio_swnode, 22, GPIO_ACTIVE_HIGH),
{ }
};
@@ -86,7 +81,7 @@ static const struct software_node tink_lan4_led_node = {
static const struct property_entry tink_lan5_led_props[] = {
PROPERTY_ENTRY_STRING("label", "mx100:green:lan5"),
- PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 23, GPIO_ACTIVE_HIGH),
+ PROPERTY_ENTRY_GPIO("gpios", &lpc_ich_gpio_swnode, 23, GPIO_ACTIVE_HIGH),
{ }
};
@@ -98,7 +93,7 @@ static const struct software_node tink_lan5_led_node = {
static const struct property_entry tink_lan6_led_props[] = {
PROPERTY_ENTRY_STRING("label", "mx100:green:lan6"),
- PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 32, GPIO_ACTIVE_HIGH),
+ PROPERTY_ENTRY_GPIO("gpios", &lpc_ich_gpio_swnode, 32, GPIO_ACTIVE_HIGH),
{ }
};
@@ -110,7 +105,7 @@ static const struct software_node tink_lan6_led_node = {
static const struct property_entry tink_lan7_led_props[] = {
PROPERTY_ENTRY_STRING("label", "mx100:green:lan7"),
- PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 34, GPIO_ACTIVE_HIGH),
+ PROPERTY_ENTRY_GPIO("gpios", &lpc_ich_gpio_swnode, 34, GPIO_ACTIVE_HIGH),
{ }
};
@@ -122,7 +117,7 @@ static const struct software_node tink_lan7_led_node = {
static const struct property_entry tink_lan8_led_props[] = {
PROPERTY_ENTRY_STRING("label", "mx100:green:lan8"),
- PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 35, GPIO_ACTIVE_HIGH),
+ PROPERTY_ENTRY_GPIO("gpios", &lpc_ich_gpio_swnode, 35, GPIO_ACTIVE_HIGH),
{ }
};
@@ -134,7 +129,7 @@ static const struct software_node tink_lan8_led_node = {
static const struct property_entry tink_lan9_led_props[] = {
PROPERTY_ENTRY_STRING("label", "mx100:green:lan9"),
- PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 36, GPIO_ACTIVE_HIGH),
+ PROPERTY_ENTRY_GPIO("gpios", &lpc_ich_gpio_swnode, 36, GPIO_ACTIVE_HIGH),
{ }
};
@@ -146,7 +141,7 @@ static const struct software_node tink_lan9_led_node = {
static const struct property_entry tink_lan10_led_props[] = {
PROPERTY_ENTRY_STRING("label", "mx100:green:lan10"),
- PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 37, GPIO_ACTIVE_HIGH),
+ PROPERTY_ENTRY_GPIO("gpios", &lpc_ich_gpio_swnode, 37, GPIO_ACTIVE_HIGH),
{ }
};
@@ -158,7 +153,7 @@ static const struct software_node tink_lan10_led_node = {
static const struct property_entry tink_lan11_led_props[] = {
PROPERTY_ENTRY_STRING("label", "mx100:green:lan11"),
- PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 48, GPIO_ACTIVE_HIGH),
+ PROPERTY_ENTRY_GPIO("gpios", &lpc_ich_gpio_swnode, 48, GPIO_ACTIVE_HIGH),
{ }
};
@@ -170,7 +165,7 @@ static const struct software_node tink_lan11_led_node = {
static const struct property_entry tink_ha_green_led_props[] = {
PROPERTY_ENTRY_STRING("label", "mx100:green:ha"),
- PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 16, GPIO_ACTIVE_LOW),
+ PROPERTY_ENTRY_GPIO("gpios", &lpc_ich_gpio_swnode, 16, GPIO_ACTIVE_LOW),
{ }
};
@@ -182,7 +177,7 @@ static const struct software_node tink_ha_green_led_node = {
static const struct property_entry tink_ha_orange_led_props[] = {
PROPERTY_ENTRY_STRING("label", "mx100:orange:ha"),
- PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 7, GPIO_ACTIVE_LOW),
+ PROPERTY_ENTRY_GPIO("gpios", &lpc_ich_gpio_swnode, 7, GPIO_ACTIVE_LOW),
{ }
};
@@ -194,7 +189,7 @@ static const struct software_node tink_ha_orange_led_node = {
static const struct property_entry tink_usb_green_led_props[] = {
PROPERTY_ENTRY_STRING("label", "mx100:green:usb"),
- PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 21, GPIO_ACTIVE_LOW),
+ PROPERTY_ENTRY_GPIO("gpios", &lpc_ich_gpio_swnode, 21, GPIO_ACTIVE_LOW),
{ }
};
@@ -206,7 +201,7 @@ static const struct software_node tink_usb_green_led_node = {
static const struct property_entry tink_usb_orange_led_props[] = {
PROPERTY_ENTRY_STRING("label", "mx100:orange:usb"),
- PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 19, GPIO_ACTIVE_LOW),
+ PROPERTY_ENTRY_GPIO("gpios", &lpc_ich_gpio_swnode, 19, GPIO_ACTIVE_LOW),
{ }
};
@@ -230,7 +225,7 @@ static const struct software_node tink_gpio_keys_node = {
static const struct property_entry tink_reset_key_props[] = {
PROPERTY_ENTRY_U32("linux,code", KEY_RESTART),
PROPERTY_ENTRY_STRING("label", "Reset"),
- PROPERTY_ENTRY_GPIO("gpios", &gpio_ich_node, 60, GPIO_ACTIVE_LOW),
+ PROPERTY_ENTRY_GPIO("gpios", &lpc_ich_gpio_swnode, 60, GPIO_ACTIVE_LOW),
PROPERTY_ENTRY_U32("linux,input-type", EV_KEY),
PROPERTY_ENTRY_U32("debounce-interval", 100),
{ }
@@ -243,7 +238,6 @@ static const struct software_node tink_reset_key_node = {
};
static const struct software_node *tink_swnodes[] = {
- &gpio_ich_node,
/* LEDs nodes */
&tink_gpio_leds_node,
&tink_internet_led_node,
@@ -348,3 +342,4 @@ MODULE_AUTHOR("Chris Blake <chrisrblake93@gmail.com>");
MODULE_DESCRIPTION("Cisco Meraki MX100 Platform Driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:meraki-mx100");
+MODULE_IMPORT_NS("LPC_ICH");
diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c
index b83113c26f885..719add753cb3d 100644
--- a/drivers/platform/x86/panasonic-laptop.c
+++ b/drivers/platform/x86/panasonic-laptop.c
@@ -246,11 +246,11 @@ struct pcc_acpi {
int ac_brightness;
int dc_brightness;
int current_brightness;
- u32 *sinf;
struct acpi_device *device;
struct input_dev *input_dev;
struct backlight_device *backlight;
struct platform_device *platform;
+ u32 sinf[] __counted_by(num_sifr);
};
/*
@@ -1007,21 +1007,15 @@ static int acpi_pcc_hotkey_probe(struct platform_device *pdev)
*/
num_sifr++;
- pcc = kzalloc_obj(struct pcc_acpi);
+ pcc = kzalloc_flex(*pcc, sinf, num_sifr);
if (!pcc) {
pr_err("Couldn't allocate mem for pcc");
return -ENOMEM;
}
- pcc->sinf = kcalloc(num_sifr + 1, sizeof(u32), GFP_KERNEL);
- if (!pcc->sinf) {
- result = -ENOMEM;
- goto out_hotkey;
- }
-
+ pcc->num_sifr = num_sifr;
pcc->device = device;
pcc->handle = device->handle;
- pcc->num_sifr = num_sifr;
device->driver_data = pcc;
strscpy(acpi_device_name(device), ACPI_PCC_DEVICE_NAME);
strscpy(acpi_device_class(device), ACPI_PCC_CLASS);
@@ -1029,7 +1023,7 @@ static int acpi_pcc_hotkey_probe(struct platform_device *pdev)
result = acpi_pcc_init_input(pcc);
if (result) {
pr_err("Error installing keyinput handler\n");
- goto out_sinf;
+ goto out_hotkey;
}
if (!acpi_pcc_retrieve_biosdata(pcc)) {
@@ -1110,10 +1104,8 @@ out_backlight:
backlight_device_unregister(pcc->backlight);
out_input:
input_unregister_device(pcc->input_dev);
-out_sinf:
- device->driver_data = NULL;
- kfree(pcc->sinf);
out_hotkey:
+ device->driver_data = NULL;
kfree(pcc);
return result;
@@ -1143,7 +1135,6 @@ static void acpi_pcc_hotkey_remove(struct platform_device *pdev)
device->driver_data = NULL;
- kfree(pcc->sinf);
kfree(pcc);
}
diff --git a/drivers/platform/x86/pcengines-apuv2.c b/drivers/platform/x86/pcengines-apuv2.c
index 3f19589d1ba03..8ac5f719c5a39 100644
--- a/drivers/platform/x86/pcengines-apuv2.c
+++ b/drivers/platform/x86/pcengines-apuv2.c
@@ -262,7 +262,7 @@ static struct platform_device * __init apu_create_pdev(const char *name,
.id = PLATFORM_DEVID_NONE,
.data = data,
.size_data = size,
- .fwnode = software_node_fwnode(swnode),
+ .swnode = swnode,
};
struct platform_device *pdev;
int err;
diff --git a/drivers/platform/x86/pmc_atom.c b/drivers/platform/x86/pmc_atom.c
index 48c2a0e59d185..046933f6d1b6f 100644
--- a/drivers/platform/x86/pmc_atom.c
+++ b/drivers/platform/x86/pmc_atom.c
@@ -570,8 +570,8 @@ static int pmc_setup_dev(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Data for PCI driver interface used by pci_match_id() call below */
static const struct pci_device_id pmc_pci_ids[] = {
- { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_VLV_PMC), (kernel_ulong_t)&byt_data },
- { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_CHT_PMC), (kernel_ulong_t)&cht_data },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_VLV_PMC), .driver_data = (kernel_ulong_t)&byt_data },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_CHT_PMC), .driver_data = (kernel_ulong_t)&cht_data },
{}
};
diff --git a/drivers/platform/x86/sel3350-platform.c b/drivers/platform/x86/sel3350-platform.c
index 02e2081e2333b..f3a3142356325 100644
--- a/drivers/platform/x86/sel3350-platform.c
+++ b/drivers/platform/x86/sel3350-platform.c
@@ -9,6 +9,8 @@
*/
#include <linux/acpi.h>
+#include <linux/array_size.h>
+#include <linux/err.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/machine.h>
#include <linux/leds.h>
@@ -30,19 +32,82 @@
#define SEL_PS_B_DETECT "sel_ps_b_detect"
#define SEL_PS_B_GOOD "sel_ps_b_good"
+#define AUX_LED_GRN1 "sel_aux_led_grn1"
+#define AUX_LED_GRN2 "sel_aux_led_grn2"
+#define AUX_LED_GRN3 "sel_aux_led_grn3"
+#define AUX_LED_GRN4 "sel_aux_led_grn4"
+#define ALARM_STATE_USER "sel_alarm_state_user"
+#define ENABLE_STATE_USER "sel_enable_state_user"
+#define AUX_LED_RED1 "sel_aux_led_red1"
+#define AUX_LED_RED2 "sel_aux_led_red2"
+#define AUX_LED_RED3 "sel_aux_led_red3"
+#define AUX_LED_RED4 "sel_aux_led_red4"
+
+static const char *const sel3350_leds_gpio_names[] = {
+ AUX_LED_GRN1,
+ AUX_LED_GRN2,
+ AUX_LED_GRN3,
+ AUX_LED_GRN4,
+ ALARM_STATE_USER,
+ ENABLE_STATE_USER,
+ AUX_LED_RED1,
+ AUX_LED_RED2,
+ AUX_LED_RED3,
+ AUX_LED_RED4,
+};
+
/* LEDs */
-static const struct gpio_led sel3350_leds[] = {
- { .name = "sel:green:aux1" },
- { .name = "sel:green:aux2" },
- { .name = "sel:green:aux3" },
- { .name = "sel:green:aux4" },
- { .name = "sel:red:alarm" },
+static struct gpio_led sel3350_leds[] = {
+ { .name = "sel:green:aux1",
+ .default_state = LEDS_GPIO_DEFSTATE_KEEP,
+ .retain_state_suspended = 1,
+ .retain_state_shutdown = 1,
+ },
+ { .name = "sel:green:aux2",
+ .default_state = LEDS_GPIO_DEFSTATE_KEEP,
+ .retain_state_suspended = 1,
+ .retain_state_shutdown = 1,
+ },
+ { .name = "sel:green:aux3",
+ .default_state = LEDS_GPIO_DEFSTATE_KEEP,
+ .retain_state_suspended = 1,
+ .retain_state_shutdown = 1,
+ },
+ { .name = "sel:green:aux4",
+ .default_state = LEDS_GPIO_DEFSTATE_KEEP,
+ .retain_state_suspended = 1,
+ .retain_state_shutdown = 1,
+ },
+ { .name = "sel:red:alarm",
+ .default_state = LEDS_GPIO_DEFSTATE_KEEP,
+ .retain_state_suspended = 1,
+ .retain_state_shutdown = 1,
+ },
{ .name = "sel:green:enabled",
- .default_state = LEDS_GPIO_DEFSTATE_ON },
- { .name = "sel:red:aux1" },
- { .name = "sel:red:aux2" },
- { .name = "sel:red:aux3" },
- { .name = "sel:red:aux4" },
+ .default_state = LEDS_GPIO_DEFSTATE_KEEP,
+ .retain_state_suspended = 1,
+ .retain_state_shutdown = 1,
+ },
+ { .name = "sel:red:aux1",
+ .default_state = LEDS_GPIO_DEFSTATE_KEEP,
+ .retain_state_suspended = 1,
+ .retain_state_shutdown = 1,
+ },
+ { .name = "sel:red:aux2",
+ .default_state = LEDS_GPIO_DEFSTATE_KEEP,
+ .retain_state_suspended = 1,
+ .retain_state_shutdown = 1,
+ },
+ { .name = "sel:red:aux3",
+ .default_state = LEDS_GPIO_DEFSTATE_KEEP,
+ .retain_state_suspended = 1,
+ .retain_state_shutdown = 1,
+ },
+ { .name = "sel:red:aux4",
+ .default_state = LEDS_GPIO_DEFSTATE_KEEP,
+ .retain_state_suspended = 1,
+ .retain_state_shutdown = 1,
+ },
};
static const struct gpio_led_platform_data sel3350_leds_pdata = {
@@ -50,25 +115,6 @@ static const struct gpio_led_platform_data sel3350_leds_pdata = {
.leds = sel3350_leds,
};
-/* Map GPIOs to LEDs */
-static struct gpiod_lookup_table sel3350_leds_table = {
- .dev_id = "leds-gpio",
- .table = {
- GPIO_LOOKUP_IDX(BXT_NW, 49, NULL, 0, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX(BXT_NW, 50, NULL, 1, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX(BXT_NW, 51, NULL, 2, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX(BXT_NW, 52, NULL, 3, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX(BXT_W, 20, NULL, 4, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX(BXT_W, 21, NULL, 5, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX(BXT_SW, 37, NULL, 6, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX(BXT_SW, 38, NULL, 7, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX(BXT_SW, 39, NULL, 8, GPIO_ACTIVE_HIGH),
- GPIO_LOOKUP_IDX(BXT_SW, 40, NULL, 9, GPIO_ACTIVE_HIGH),
- {},
- }
-};
-
-/* Map GPIOs to power supplies */
static struct gpiod_lookup_table sel3350_gpios_table = {
.dev_id = B2093_GPIO_ACPI_ID ":00",
.table = {
@@ -76,6 +122,16 @@ static struct gpiod_lookup_table sel3350_gpios_table = {
GPIO_LOOKUP(BXT_NW, 45, SEL_PS_A_GOOD, GPIO_ACTIVE_LOW),
GPIO_LOOKUP(BXT_NW, 46, SEL_PS_B_DETECT, GPIO_ACTIVE_LOW),
GPIO_LOOKUP(BXT_NW, 47, SEL_PS_B_GOOD, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP(BXT_NW, 49, AUX_LED_GRN1, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP(BXT_NW, 50, AUX_LED_GRN2, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP(BXT_NW, 51, AUX_LED_GRN3, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP(BXT_NW, 52, AUX_LED_GRN4, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP(BXT_W, 20, ALARM_STATE_USER, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP(BXT_W, 21, ENABLE_STATE_USER, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP(BXT_SW, 37, AUX_LED_RED1, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP(BXT_SW, 38, AUX_LED_RED2, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP(BXT_SW, 39, AUX_LED_RED3, GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP(BXT_SW, 40, AUX_LED_RED4, GPIO_ACTIVE_HIGH),
{},
}
};
@@ -149,6 +205,7 @@ struct sel3350_data {
static int sel3350_probe(struct platform_device *pdev)
{
int rs;
+ int i;
struct sel3350_data *sel3350;
struct power_supply_config ps_cfg = {};
@@ -158,9 +215,19 @@ static int sel3350_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, sel3350);
- gpiod_add_lookup_table(&sel3350_leds_table);
gpiod_add_lookup_table(&sel3350_gpios_table);
+ for (i = 0; i < ARRAY_SIZE(sel3350_leds); ++i) {
+ sel3350_leds[i].gpiod = devm_gpiod_get(&pdev->dev,
+ sel3350_leds_gpio_names[i],
+ GPIOD_ASIS);
+ if (IS_ERR_OR_NULL(sel3350_leds[i].gpiod)) {
+ rs = -EPROBE_DEFER;
+ goto err_gpio_loop;
+ }
+ gpiod_set_consumer_name(sel3350_leds[i].gpiod, sel3350_leds[i].name);
+ }
+
sel3350->leds_pdev = platform_device_register_data(
NULL,
"leds-gpio",
@@ -209,11 +276,15 @@ static int sel3350_probe(struct platform_device *pdev)
return 0;
+err_gpio_loop:
+ while (i--)
+ devm_gpiod_put(&pdev->dev, sel3350_leds[i].gpiod);
+ goto err_platform;
+
err_ps:
platform_device_unregister(sel3350->leds_pdev);
err_platform:
gpiod_remove_lookup_table(&sel3350_gpios_table);
- gpiod_remove_lookup_table(&sel3350_leds_table);
return rs;
}
@@ -224,7 +295,6 @@ static void sel3350_remove(struct platform_device *pdev)
platform_device_unregister(sel3350->leds_pdev);
gpiod_remove_lookup_table(&sel3350_gpios_table);
- gpiod_remove_lookup_table(&sel3350_leds_table);
}
static const struct acpi_device_id sel3350_device_ids[] = {
diff --git a/drivers/platform/x86/x86-android-tablets/core.c b/drivers/platform/x86/x86-android-tablets/core.c
index 021009e9085be..5db794d65eb5f 100644
--- a/drivers/platform/x86/x86-android-tablets/core.c
+++ b/drivers/platform/x86/x86-android-tablets/core.c
@@ -11,8 +11,10 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/acpi.h>
+#include <linux/bug.h>
#include <linux/device.h>
#include <linux/dmi.h>
+#include <linux/fwnode.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/machine.h>
#include <linux/irq.h>
@@ -360,6 +362,61 @@ static const struct software_node *cherryview_gpiochip_node_group[] = {
NULL
};
+static void gpio_secondary_unset(void *data)
+{
+ struct device *dev = data;
+
+ set_secondary_fwnode(dev, NULL);
+}
+
+static void gpio_secondary_unregister_node_group(void *data)
+{
+ const struct software_node **nodes = data;
+
+ software_node_unregister_node_group(nodes);
+}
+
+static int gpio_secondary_fwnode_init(struct device *parent)
+{
+ const struct software_node *const *swnode;
+ struct fwnode_handle *fwnode;
+ int ret;
+
+ if (!gpiochip_node_group)
+ return 0;
+
+ ret = software_node_register_node_group(gpiochip_node_group);
+ if (ret)
+ return ret;
+
+ ret = devm_add_action_or_reset(parent,
+ gpio_secondary_unregister_node_group,
+ gpiochip_node_group);
+ if (ret)
+ return ret;
+
+ for (swnode = gpiochip_node_group; *swnode; swnode++) {
+ struct device *dev __free(put_device) =
+ acpi_bus_find_device_by_name((*swnode)->name);
+ if (!dev)
+ return dev_err_probe(parent,
+ -ENODEV, "Failed to find the required GPIO controller: %s\n",
+ (*swnode)->name);
+
+ fwnode = software_node_fwnode(*swnode);
+ if (WARN_ON(!fwnode))
+ return -ENOENT;
+
+ set_secondary_fwnode(dev, fwnode);
+
+ ret = devm_add_action_or_reset(parent, gpio_secondary_unset, dev);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
static void x86_android_tablet_remove(struct platform_device *pdev)
{
int i;
@@ -391,7 +448,6 @@ static void x86_android_tablet_remove(struct platform_device *pdev)
software_node_unregister_node_group(gpio_button_swnodes);
software_node_unregister_node_group(swnode_group);
- software_node_unregister_node_group(gpiochip_node_group);
}
static __init int x86_android_tablet_probe(struct platform_device *pdev)
@@ -427,9 +483,11 @@ static __init int x86_android_tablet_probe(struct platform_device *pdev)
break;
}
- ret = software_node_register_node_group(gpiochip_node_group);
- if (ret)
+ ret = gpio_secondary_fwnode_init(&pdev->dev);
+ if (ret) {
+ x86_android_tablet_remove(pdev);
return ret;
+ }
ret = software_node_register_node_group(dev_info->swnode_group);
if (ret) {
diff --git a/drivers/platform/x86/xo15-ebook.c b/drivers/platform/x86/xo15-ebook.c
index 4d1b1b310cc56..e40e385c52bd4 100644
--- a/drivers/platform/x86/xo15-ebook.c
+++ b/drivers/platform/x86/xo15-ebook.c
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <linux/input.h>
#include <linux/acpi.h>
+#include <linux/platform_device.h>
#define MODULE_NAME "xo15-ebook"
@@ -38,15 +39,16 @@ MODULE_DEVICE_TABLE(acpi, ebook_device_ids);
struct ebook_switch {
struct input_dev *input;
char phys[32]; /* for input device */
+ bool gpe_enabled;
};
-static int ebook_send_state(struct acpi_device *device)
+static int ebook_send_state(struct device *dev)
{
- struct ebook_switch *button = acpi_driver_data(device);
+ struct ebook_switch *button = dev_get_drvdata(dev);
unsigned long long state;
acpi_status status;
- status = acpi_evaluate_integer(device->handle, "EBK", NULL, &state);
+ status = acpi_evaluate_integer(ACPI_HANDLE(dev), "EBK", NULL, &state);
if (ACPI_FAILURE(status))
return -EIO;
@@ -56,16 +58,15 @@ static int ebook_send_state(struct acpi_device *device)
return 0;
}
-static void ebook_switch_notify(struct acpi_device *device, u32 event)
+static void ebook_switch_notify(acpi_handle handle, u32 event, void *data)
{
switch (event) {
case ACPI_FIXED_HARDWARE_EVENT:
case XO15_EBOOK_NOTIFY_STATUS:
- ebook_send_state(device);
+ ebook_send_state(data);
break;
default:
- acpi_handle_debug(device->handle,
- "Unsupported event [0x%x]\n", event);
+ acpi_handle_debug(handle, "Unsupported event [0x%x]\n", event);
break;
}
}
@@ -73,37 +74,36 @@ static void ebook_switch_notify(struct acpi_device *device, u32 event)
#ifdef CONFIG_PM_SLEEP
static int ebook_switch_resume(struct device *dev)
{
- return ebook_send_state(to_acpi_device(dev));
+ return ebook_send_state(dev);
}
#endif
static SIMPLE_DEV_PM_OPS(ebook_switch_pm, NULL, ebook_switch_resume);
-static int ebook_switch_add(struct acpi_device *device)
+static int ebook_switch_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
+ struct acpi_device *device = ACPI_COMPANION(dev);
const struct acpi_device_id *id;
struct ebook_switch *button;
struct input_dev *input;
int error;
- button = kzalloc_obj(struct ebook_switch);
+ button = devm_kzalloc(dev, sizeof(*button), GFP_KERNEL);
if (!button)
return -ENOMEM;
- device->driver_data = button;
+ platform_set_drvdata(pdev, button);
- button->input = input = input_allocate_device();
- if (!input) {
- error = -ENOMEM;
- goto err_free_button;
- }
+ input = devm_input_allocate_device(dev);
+ if (!input)
+ return -ENOMEM;
+
+ button->input = input;
id = acpi_match_acpi_device(ebook_device_ids, device);
- if (!id) {
- dev_err(&device->dev, "Unsupported hid\n");
- error = -ENODEV;
- goto err_free_input;
- }
+ if (!id)
+ return dev_err_probe(dev, -ENODEV, "Unsupported hid\n");
strscpy(acpi_device_name(device), XO15_EBOOK_DEVICE_NAME);
strscpy(acpi_device_class(device), XO15_EBOOK_CLASS "/" XO15_EBOOK_SUBCLASS);
@@ -113,50 +113,51 @@ static int ebook_switch_add(struct acpi_device *device)
input->name = acpi_device_name(device);
input->phys = button->phys;
input->id.bustype = BUS_HOST;
- input->dev.parent = &device->dev;
input->evbit[0] = BIT_MASK(EV_SW);
set_bit(SW_TABLET_MODE, input->swbit);
error = input_register_device(input);
if (error)
- goto err_free_input;
+ return error;
- ebook_send_state(device);
+ error = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY,
+ ebook_switch_notify, dev);
+ if (error)
+ return error;
+
+ ebook_send_state(dev);
if (device->wakeup.flags.valid) {
/* Button's GPE is run-wake GPE */
acpi_enable_gpe(device->wakeup.gpe_device,
device->wakeup.gpe_number);
- device_set_wakeup_enable(&device->dev, true);
+ button->gpe_enabled = true;
}
return 0;
-
- err_free_input:
- input_free_device(input);
- err_free_button:
- kfree(button);
- return error;
}
-static void ebook_switch_remove(struct acpi_device *device)
+static void ebook_switch_remove(struct platform_device *pdev)
{
- struct ebook_switch *button = acpi_driver_data(device);
+ struct ebook_switch *button = platform_get_drvdata(pdev);
+ struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
+
+ if (button->gpe_enabled)
+ acpi_disable_gpe(device->wakeup.gpe_device,
+ device->wakeup.gpe_number);
- input_unregister_device(button->input);
- kfree(button);
+ acpi_dev_remove_notify_handler(device, ACPI_DEVICE_NOTIFY,
+ ebook_switch_notify);
}
-static struct acpi_driver xo15_ebook_driver = {
- .name = MODULE_NAME,
- .class = XO15_EBOOK_CLASS,
- .ids = ebook_device_ids,
- .ops = {
- .add = ebook_switch_add,
- .remove = ebook_switch_remove,
- .notify = ebook_switch_notify,
+static struct platform_driver xo15_ebook_driver = {
+ .probe = ebook_switch_probe,
+ .remove = ebook_switch_remove,
+ .driver = {
+ .name = MODULE_NAME,
+ .acpi_match_table = ebook_device_ids,
+ .pm = &ebook_switch_pm,
},
- .drv.pm = &ebook_switch_pm,
};
-module_acpi_driver(xo15_ebook_driver);
+module_platform_driver(xo15_ebook_driver);