summaryrefslogtreecommitdiff
path: root/drivers/platform/x86
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/x86')
-rw-r--r--drivers/platform/x86/Kconfig41
-rw-r--r--drivers/platform/x86/Makefile7
-rw-r--r--drivers/platform/x86/amd/Makefile2
-rw-r--r--drivers/platform/x86/amd/hsmp/Kconfig2
-rw-r--r--drivers/platform/x86/amd/hsmp/Makefile6
-rw-r--r--drivers/platform/x86/amd/hsmp/acpi.c7
-rw-r--r--drivers/platform/x86/amd/hsmp/hsmp.c1
-rw-r--r--drivers/platform/x86/amd/hsmp/hsmp.h3
-rw-r--r--drivers/platform/x86/amd/hsmp/plat.c36
-rw-r--r--drivers/platform/x86/amd/pmc/Makefile6
-rw-r--r--drivers/platform/x86/amd/pmc/pmc.c113
-rw-r--r--drivers/platform/x86/amd/pmc/pmc.h82
-rw-r--r--drivers/platform/x86/amd/pmf/Makefile8
-rw-r--r--drivers/platform/x86/amd/pmf/acpi.c2
-rw-r--r--drivers/platform/x86/asus-tf103c-dock.c2
-rw-r--r--drivers/platform/x86/compal-laptop.c1
-rw-r--r--drivers/platform/x86/dell/Kconfig30
-rw-r--r--drivers/platform/x86/dell/Makefile45
-rw-r--r--drivers/platform/x86/dell/alienware-wmi-base.c491
-rw-r--r--drivers/platform/x86/dell/alienware-wmi-legacy.c95
-rw-r--r--drivers/platform/x86/dell/alienware-wmi-wmax.c768
-rw-r--r--drivers/platform/x86/dell/alienware-wmi.c1249
-rw-r--r--drivers/platform/x86/dell/alienware-wmi.h117
-rw-r--r--drivers/platform/x86/dell/dell-uart-backlight.c2
-rw-r--r--drivers/platform/x86/dell/dell-wmi-ddv.c84
-rw-r--r--drivers/platform/x86/dell/dell-wmi-sysman/Makefile2
-rw-r--r--drivers/platform/x86/hp/hp-bioscfg/Makefile2
-rw-r--r--drivers/platform/x86/hp/hp-bioscfg/bioscfg.c15
-rw-r--r--drivers/platform/x86/ideapad-laptop.c23
-rw-r--r--drivers/platform/x86/intel/ifs/Makefile2
-rw-r--r--drivers/platform/x86/intel/int3472/discrete.c48
-rw-r--r--drivers/platform/x86/intel/pmc/Makefile2
-rw-r--r--drivers/platform/x86/intel/pmc/adl.c56
-rw-r--r--drivers/platform/x86/intel/pmc/arl.c137
-rw-r--r--drivers/platform/x86/intel/pmc/cnp.c29
-rw-r--r--drivers/platform/x86/intel/pmc/core.c115
-rw-r--r--drivers/platform/x86/intel/pmc/core.h199
-rw-r--r--drivers/platform/x86/intel/pmc/icl.c24
-rw-r--r--drivers/platform/x86/intel/pmc/lnl.c67
-rw-r--r--drivers/platform/x86/intel/pmc/mtl.c109
-rw-r--r--drivers/platform/x86/intel/pmc/ptl.c550
-rw-r--r--drivers/platform/x86/intel/pmc/spt.c45
-rw-r--r--drivers/platform/x86/intel/pmc/tgl.c59
-rw-r--r--drivers/platform/x86/lenovo-wmi-hotkey-utilities.c212
-rw-r--r--drivers/platform/x86/lenovo-yoga-tab2-pro-1380-fastcharger.c2
-rw-r--r--drivers/platform/x86/mlx-platform.c6666
-rw-r--r--drivers/platform/x86/samsung-galaxybook.c1425
-rw-r--r--drivers/platform/x86/think-lmi.c51
-rw-r--r--drivers/platform/x86/think-lmi.h2
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c181
-rw-r--r--drivers/platform/x86/wmi.c143
-rw-r--r--drivers/platform/x86/x86-android-tablets/Kconfig1
52 files changed, 4505 insertions, 8862 deletions
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 0258dd879d64..43407e76476b 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -475,6 +475,17 @@ config IDEAPAD_LAPTOP
This is a driver for Lenovo IdeaPad netbooks contains drivers for
rfkill switch, hotkey, fan control and backlight control.
+config LENOVO_WMI_HOTKEY_UTILITIES
+ tristate "Lenovo Hotkey Utility WMI extras driver"
+ depends on ACPI_WMI
+ select NEW_LEDS
+ select LEDS_CLASS
+ imply IDEAPAD_LAPTOP
+ help
+ This driver provides WMI support for Lenovo customized hotkeys function,
+ such as LED control for audio/mic mute event for Ideapad, YOGA, XiaoXin,
+ Gaming, ThinkBook and so on.
+
config LENOVO_YMC
tristate "Lenovo Yoga Tablet Mode Control"
depends on ACPI_WMI
@@ -778,6 +789,23 @@ config BARCO_P50_GPIO
To compile this driver as a module, choose M here: the module
will be called barco-p50-gpio.
+config SAMSUNG_GALAXYBOOK
+ tristate "Samsung Galaxy Book driver"
+ depends on ACPI
+ depends on ACPI_BATTERY
+ depends on INPUT
+ depends on LEDS_CLASS
+ depends on SERIO_I8042
+ select ACPI_PLATFORM_PROFILE
+ select FW_ATTR_CLASS
+ help
+ This is a driver for Samsung Galaxy Book series notebooks. It adds
+ support for the keyboard backlight control, performance mode control,
+ function keys, and various firmware attributes.
+
+ For more information about this driver, see
+ <file:Documentation/admin-guide/laptops/samsung-galaxybook.rst>.
+
config SAMSUNG_LAPTOP
tristate "Samsung Laptop driver"
depends on RFKILL || RFKILL = n
@@ -1012,19 +1040,6 @@ config SERIAL_MULTI_INSTANTIATE
To compile this driver as a module, choose M here: the module
will be called serial-multi-instantiate.
-config MLX_PLATFORM
- tristate "Mellanox Technologies platform support"
- depends on ACPI && I2C && PCI
- select REGMAP
- help
- This option enables system support for the Mellanox Technologies
- platform. The Mellanox systems provide data center networking
- solutions based on Virtual Protocol Interconnect (VPI) technology
- enable seamless connectivity to 56/100Gb/s InfiniBand or 10/40/56GbE
- connection.
-
- If you have a Mellanox system, say Y or M here.
-
config TOUCHSCREEN_DMI
bool "DMI based touchscreen configuration info"
depends on ACPI && DMI && I2C=y && TOUCHSCREEN_SILEAD
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index e1b142947067..650dfbebb6c8 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -61,6 +61,7 @@ obj-$(CONFIG_UV_SYSFS) += uv_sysfs.o
# IBM Thinkpad and Lenovo
obj-$(CONFIG_IBM_RTL) += ibm_rtl.o
obj-$(CONFIG_IDEAPAD_LAPTOP) += ideapad-laptop.o
+obj-$(CONFIG_LENOVO_WMI_HOTKEY_UTILITIES) += lenovo-wmi-hotkey-utilities.o
obj-$(CONFIG_LENOVO_YMC) += lenovo-ymc.o
obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o
obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o
@@ -95,8 +96,9 @@ obj-$(CONFIG_PCENGINES_APU2) += pcengines-apuv2.o
obj-$(CONFIG_BARCO_P50_GPIO) += barco-p50-gpio.o
# Samsung
-obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop.o
-obj-$(CONFIG_SAMSUNG_Q10) += samsung-q10.o
+obj-$(CONFIG_SAMSUNG_GALAXYBOOK) += samsung-galaxybook.o
+obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop.o
+obj-$(CONFIG_SAMSUNG_Q10) += samsung-q10.o
# Toshiba
obj-$(CONFIG_TOSHIBA_BT_RFKILL) += toshiba_bluetooth.o
@@ -122,7 +124,6 @@ obj-$(CONFIG_TOPSTAR_LAPTOP) += topstar-laptop.o
# Platform drivers
obj-$(CONFIG_FW_ATTR_CLASS) += firmware_attributes_class.o
obj-$(CONFIG_SERIAL_MULTI_INSTANTIATE) += serial-multi-instantiate.o
-obj-$(CONFIG_MLX_PLATFORM) += mlx-platform.o
obj-$(CONFIG_TOUCHSCREEN_DMI) += touchscreen_dmi.o
obj-$(CONFIG_WIRELESS_HOTKEY) += wireless-hotkey.o
obj-$(CONFIG_X86_ANDROID_TABLETS) += x86-android-tablets/
diff --git a/drivers/platform/x86/amd/Makefile b/drivers/platform/x86/amd/Makefile
index 56f62fc9c97b..c6c40bdcbded 100644
--- a/drivers/platform/x86/amd/Makefile
+++ b/drivers/platform/x86/amd/Makefile
@@ -5,7 +5,7 @@
#
obj-$(CONFIG_AMD_3D_VCACHE) += amd_3d_vcache.o
-amd_3d_vcache-objs := x3d_vcache.o
+amd_3d_vcache-y := x3d_vcache.o
obj-$(CONFIG_AMD_PMC) += pmc/
obj-$(CONFIG_AMD_HSMP) += hsmp/
obj-$(CONFIG_AMD_PMF) += pmf/
diff --git a/drivers/platform/x86/amd/hsmp/Kconfig b/drivers/platform/x86/amd/hsmp/Kconfig
index 7d10d4462a45..d6f7a62d55b5 100644
--- a/drivers/platform/x86/amd/hsmp/Kconfig
+++ b/drivers/platform/x86/amd/hsmp/Kconfig
@@ -7,7 +7,7 @@ config AMD_HSMP
tristate
menu "AMD HSMP Driver"
- depends on AMD_NB || COMPILE_TEST
+ depends on AMD_NODE || COMPILE_TEST
config AMD_HSMP_ACPI
tristate "AMD HSMP ACPI device driver"
diff --git a/drivers/platform/x86/amd/hsmp/Makefile b/drivers/platform/x86/amd/hsmp/Makefile
index 3175d8885e87..0759bbcd13f6 100644
--- a/drivers/platform/x86/amd/hsmp/Makefile
+++ b/drivers/platform/x86/amd/hsmp/Makefile
@@ -5,8 +5,8 @@
#
obj-$(CONFIG_AMD_HSMP) += hsmp_common.o
-hsmp_common-objs := hsmp.o
+hsmp_common-y := hsmp.o
obj-$(CONFIG_AMD_HSMP_PLAT) += amd_hsmp.o
-amd_hsmp-objs := plat.o
+amd_hsmp-y := plat.o
obj-$(CONFIG_AMD_HSMP_ACPI) += hsmp_acpi.o
-hsmp_acpi-objs := acpi.o
+hsmp_acpi-y := acpi.o
diff --git a/drivers/platform/x86/amd/hsmp/acpi.c b/drivers/platform/x86/amd/hsmp/acpi.c
index 444b43be35a2..c1eccb3c80c5 100644
--- a/drivers/platform/x86/amd/hsmp/acpi.c
+++ b/drivers/platform/x86/amd/hsmp/acpi.c
@@ -10,7 +10,6 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <asm/amd_hsmp.h>
-#include <asm/amd_nb.h>
#include <linux/acpi.h>
#include <linux/device.h>
@@ -24,6 +23,8 @@
#include <uapi/asm-generic/errno-base.h>
+#include <asm/amd_node.h>
+
#include "hsmp.h"
#define DRIVER_NAME "amd_hsmp"
@@ -321,8 +322,8 @@ static int hsmp_acpi_probe(struct platform_device *pdev)
return -ENOMEM;
if (!hsmp_pdev->is_probed) {
- hsmp_pdev->num_sockets = amd_nb_num();
- if (hsmp_pdev->num_sockets == 0 || hsmp_pdev->num_sockets > MAX_AMD_SOCKETS)
+ hsmp_pdev->num_sockets = amd_num_nodes();
+ if (hsmp_pdev->num_sockets == 0 || hsmp_pdev->num_sockets > MAX_AMD_NUM_NODES)
return -ENODEV;
hsmp_pdev->sock = devm_kcalloc(&pdev->dev, hsmp_pdev->num_sockets,
diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c
index 03164e30b3a5..a3ac09a90de4 100644
--- a/drivers/platform/x86/amd/hsmp/hsmp.c
+++ b/drivers/platform/x86/amd/hsmp/hsmp.c
@@ -8,7 +8,6 @@
*/
#include <asm/amd_hsmp.h>
-#include <asm/amd_nb.h>
#include <linux/acpi.h>
#include <linux/delay.h>
diff --git a/drivers/platform/x86/amd/hsmp/hsmp.h b/drivers/platform/x86/amd/hsmp/hsmp.h
index e852f0a947e4..af8b21f821d6 100644
--- a/drivers/platform/x86/amd/hsmp/hsmp.h
+++ b/drivers/platform/x86/amd/hsmp/hsmp.h
@@ -21,8 +21,6 @@
#define HSMP_ATTR_GRP_NAME_SIZE 10
-#define MAX_AMD_SOCKETS 8
-
#define HSMP_CDEV_NAME "hsmp_cdev"
#define HSMP_DEVNODE_NAME "hsmp"
@@ -41,7 +39,6 @@ struct hsmp_socket {
void __iomem *virt_base_addr;
struct semaphore hsmp_sem;
char name[HSMP_ATTR_GRP_NAME_SIZE];
- struct pci_dev *root;
struct device *dev;
u16 sock_ind;
int (*amd_hsmp_rdwr)(struct hsmp_socket *sock, u32 off, u32 *val, bool rw);
diff --git a/drivers/platform/x86/amd/hsmp/plat.c b/drivers/platform/x86/amd/hsmp/plat.c
index 02ca85762b68..b9782a078dbd 100644
--- a/drivers/platform/x86/amd/hsmp/plat.c
+++ b/drivers/platform/x86/amd/hsmp/plat.c
@@ -10,14 +10,16 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <asm/amd_hsmp.h>
-#include <asm/amd_nb.h>
+#include <linux/build_bug.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/sysfs.h>
+#include <asm/amd_node.h>
+
#include "hsmp.h"
#define DRIVER_NAME "amd_hsmp"
@@ -34,28 +36,12 @@
#define SMN_HSMP_MSG_RESP 0x0010980
#define SMN_HSMP_MSG_DATA 0x00109E0
-#define HSMP_INDEX_REG 0xc4
-#define HSMP_DATA_REG 0xc8
-
static struct hsmp_plat_device *hsmp_pdev;
static int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset,
u32 *value, bool write)
{
- int ret;
-
- if (!sock->root)
- return -ENODEV;
-
- ret = pci_write_config_dword(sock->root, HSMP_INDEX_REG,
- sock->mbinfo.base_addr + offset);
- if (ret)
- return ret;
-
- ret = (write ? pci_write_config_dword(sock->root, HSMP_DATA_REG, *value)
- : pci_read_config_dword(sock->root, HSMP_DATA_REG, value));
-
- return ret;
+ return amd_smn_hsmp_rdwr(sock->sock_ind, sock->mbinfo.base_addr + offset, value, write);
}
static ssize_t hsmp_metric_tbl_plat_read(struct file *filp, struct kobject *kobj,
@@ -95,7 +81,12 @@ static umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
* Static array of 8 + 1(for NULL) elements is created below
* to create sysfs groups for sockets.
* is_bin_visible function is used to show / hide the necessary groups.
+ *
+ * Validate the maximum number against MAX_AMD_NUM_NODES. If this changes,
+ * then the attributes and groups below must be adjusted.
*/
+static_assert(MAX_AMD_NUM_NODES == 8);
+
#define HSMP_BIN_ATTR(index, _list) \
static const struct bin_attribute attr##index = { \
.attr = { .name = HSMP_METRICS_TABLE_NAME, .mode = 0444}, \
@@ -159,10 +150,7 @@ static int init_platform_device(struct device *dev)
int ret, i;
for (i = 0; i < hsmp_pdev->num_sockets; i++) {
- if (!node_to_amd_nb(i))
- return -ENODEV;
sock = &hsmp_pdev->sock[i];
- sock->root = node_to_amd_nb(i)->root;
sock->sock_ind = i;
sock->dev = dev;
sock->mbinfo.base_addr = SMN_HSMP_BASE;
@@ -305,11 +293,11 @@ static int __init hsmp_plt_init(void)
return -ENOMEM;
/*
- * amd_nb_num() returns number of SMN/DF interfaces present in the system
+ * amd_num_nodes() returns number of SMN/DF interfaces present in the system
* if we have N SMN/DF interfaces that ideally means N sockets
*/
- hsmp_pdev->num_sockets = amd_nb_num();
- if (hsmp_pdev->num_sockets == 0 || hsmp_pdev->num_sockets > MAX_AMD_SOCKETS)
+ hsmp_pdev->num_sockets = amd_num_nodes();
+ if (hsmp_pdev->num_sockets == 0 || hsmp_pdev->num_sockets > MAX_AMD_NUM_NODES)
return ret;
ret = platform_driver_register(&amd_hsmp_driver);
diff --git a/drivers/platform/x86/amd/pmc/Makefile b/drivers/platform/x86/amd/pmc/Makefile
index 255d94ddf999..bb6905c4cae9 100644
--- a/drivers/platform/x86/amd/pmc/Makefile
+++ b/drivers/platform/x86/amd/pmc/Makefile
@@ -4,6 +4,6 @@
# AMD Power Management Controller Driver
#
-amd-pmc-objs := pmc.o pmc-quirks.o mp1_stb.o
-obj-$(CONFIG_AMD_PMC) += amd-pmc.o
-amd-pmc-$(CONFIG_AMD_MP2_STB) += mp2_stb.o
+obj-$(CONFIG_AMD_PMC) += amd-pmc.o
+amd-pmc-y := pmc.o pmc-quirks.o mp1_stb.o
+amd-pmc-$(CONFIG_AMD_MP2_STB) += mp2_stb.o
diff --git a/drivers/platform/x86/amd/pmc/pmc.c b/drivers/platform/x86/amd/pmc/pmc.c
index e6124498b195..d789d6cab794 100644
--- a/drivers/platform/x86/amd/pmc/pmc.c
+++ b/drivers/platform/x86/amd/pmc/pmc.c
@@ -32,70 +32,6 @@
#include "pmc.h"
-/* SMU communication registers */
-#define AMD_PMC_REGISTER_RESPONSE 0x980
-#define AMD_PMC_REGISTER_ARGUMENT 0x9BC
-
-/* PMC Scratch Registers */
-#define AMD_PMC_SCRATCH_REG_CZN 0x94
-#define AMD_PMC_SCRATCH_REG_YC 0xD14
-#define AMD_PMC_SCRATCH_REG_1AH 0xF14
-
-/* STB Registers */
-#define AMD_PMC_STB_S2IDLE_PREPARE 0xC6000001
-#define AMD_PMC_STB_S2IDLE_RESTORE 0xC6000002
-#define AMD_PMC_STB_S2IDLE_CHECK 0xC6000003
-
-/* Base address of SMU for mapping physical address to virtual address */
-#define AMD_PMC_MAPPING_SIZE 0x01000
-#define AMD_PMC_BASE_ADDR_OFFSET 0x10000
-#define AMD_PMC_BASE_ADDR_LO 0x13B102E8
-#define AMD_PMC_BASE_ADDR_HI 0x13B102EC
-#define AMD_PMC_BASE_ADDR_LO_MASK GENMASK(15, 0)
-#define AMD_PMC_BASE_ADDR_HI_MASK GENMASK(31, 20)
-
-/* SMU Response Codes */
-#define AMD_PMC_RESULT_OK 0x01
-#define AMD_PMC_RESULT_CMD_REJECT_BUSY 0xFC
-#define AMD_PMC_RESULT_CMD_REJECT_PREREQ 0xFD
-#define AMD_PMC_RESULT_CMD_UNKNOWN 0xFE
-#define AMD_PMC_RESULT_FAILED 0xFF
-
-/* FCH SSC Registers */
-#define FCH_S0I3_ENTRY_TIME_L_OFFSET 0x30
-#define FCH_S0I3_ENTRY_TIME_H_OFFSET 0x34
-#define FCH_S0I3_EXIT_TIME_L_OFFSET 0x38
-#define FCH_S0I3_EXIT_TIME_H_OFFSET 0x3C
-#define FCH_SSC_MAPPING_SIZE 0x800
-#define FCH_BASE_PHY_ADDR_LOW 0xFED81100
-#define FCH_BASE_PHY_ADDR_HIGH 0x00000000
-
-/* SMU Message Definations */
-#define SMU_MSG_GETSMUVERSION 0x02
-#define SMU_MSG_LOG_GETDRAM_ADDR_HI 0x04
-#define SMU_MSG_LOG_GETDRAM_ADDR_LO 0x05
-#define SMU_MSG_LOG_START 0x06
-#define SMU_MSG_LOG_RESET 0x07
-#define SMU_MSG_LOG_DUMP_DATA 0x08
-#define SMU_MSG_GET_SUP_CONSTRAINTS 0x09
-
-#define PMC_MSG_DELAY_MIN_US 50
-#define RESPONSE_REGISTER_LOOP_MAX 20000
-
-#define DELAY_MIN_US 2000
-#define DELAY_MAX_US 3000
-
-enum amd_pmc_def {
- MSG_TEST = 0x01,
- MSG_OS_HINT_PCO,
- MSG_OS_HINT_RN,
-};
-
-struct amd_pmc_bit_map {
- const char *name;
- u32 bit_mask;
-};
-
static const struct amd_pmc_bit_map soc15_ip_blk_v2[] = {
{"DISPLAY", BIT(0)},
{"CPU", BIT(1)},
@@ -165,23 +101,6 @@ static inline void amd_pmc_reg_write(struct amd_pmc_dev *dev, int reg_offset, u3
iowrite32(val, dev->regbase + reg_offset);
}
-struct smu_metrics {
- u32 table_version;
- u32 hint_count;
- u32 s0i3_last_entry_status;
- u32 timein_s0i2;
- u64 timeentering_s0i3_lastcapture;
- u64 timeentering_s0i3_totaltime;
- u64 timeto_resume_to_os_lastcapture;
- u64 timeto_resume_to_os_totaltime;
- u64 timein_s0i3_lastcapture;
- u64 timein_s0i3_totaltime;
- u64 timein_swdrips_lastcapture;
- u64 timein_swdrips_totaltime;
- u64 timecondition_notmet_lastcapture[32];
- u64 timecondition_notmet_totaltime[32];
-} __packed;
-
static void amd_pmc_get_ip_info(struct amd_pmc_dev *dev)
{
switch (dev->cpu_id) {
@@ -247,11 +166,12 @@ static int amd_pmc_setup_smu_logging(struct amd_pmc_dev *dev)
static int get_metrics_table(struct amd_pmc_dev *pdev, struct smu_metrics *table)
{
- if (!pdev->smu_virt_addr) {
- int ret = amd_pmc_setup_smu_logging(pdev);
+ int rc;
- if (ret)
- return ret;
+ if (!pdev->smu_virt_addr) {
+ rc = amd_pmc_setup_smu_logging(pdev);
+ if (rc)
+ return rc;
}
if (pdev->cpu_id == AMD_CPU_ID_PCO)
@@ -300,10 +220,10 @@ static ssize_t smu_fw_version_show(struct device *d, struct device_attribute *at
char *buf)
{
struct amd_pmc_dev *dev = dev_get_drvdata(d);
+ int rc;
if (!dev->major) {
- int rc = amd_pmc_get_smu_version(dev);
-
+ rc = amd_pmc_get_smu_version(dev);
if (rc)
return rc;
}
@@ -314,10 +234,10 @@ static ssize_t smu_program_show(struct device *d, struct device_attribute *attr,
char *buf)
{
struct amd_pmc_dev *dev = dev_get_drvdata(d);
+ int rc;
if (!dev->major) {
- int rc = amd_pmc_get_smu_version(dev);
-
+ rc = amd_pmc_get_smu_version(dev);
if (rc)
return rc;
}
@@ -778,14 +698,14 @@ static struct acpi_s2idle_dev_ops amd_pmc_s2idle_dev_ops = {
static int amd_pmc_suspend_handler(struct device *dev)
{
struct amd_pmc_dev *pdev = dev_get_drvdata(dev);
+ int rc;
/*
* Must be called only from the same set of dev_pm_ops handlers
* as i8042_pm_suspend() is called: currently just from .suspend.
*/
if (pdev->disable_8042_wakeup && !disable_workarounds) {
- int rc = amd_pmc_wa_irq1(pdev);
-
+ rc = amd_pmc_wa_irq1(pdev);
if (rc) {
dev_err(pdev->dev, "failed to adjust keyboard wakeup: %d\n", rc);
return rc;
@@ -808,6 +728,7 @@ static const struct pci_device_id pmc_pci_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_PCO) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_RV) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_SP) },
+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_SHP) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M20H_ROOT) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M60H_ROOT) },
{ }
@@ -823,7 +744,6 @@ static int amd_pmc_probe(struct platform_device *pdev)
u32 val;
dev->dev = &pdev->dev;
-
rdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
if (!rdev || !pci_match_id(pmc_pci_ids, rdev)) {
err = -ENODEV;
@@ -831,8 +751,7 @@ static int amd_pmc_probe(struct platform_device *pdev)
}
dev->cpu_id = rdev->device;
-
- if (dev->cpu_id == AMD_CPU_ID_SP) {
+ if (dev->cpu_id == AMD_CPU_ID_SP || dev->cpu_id == AMD_CPU_ID_SHP) {
dev_warn_once(dev->dev, "S0i3 is not supported on this hardware\n");
err = -ENODEV;
goto err_pci_dev_put;
@@ -847,7 +766,6 @@ static int amd_pmc_probe(struct platform_device *pdev)
}
base_addr_lo = val & AMD_PMC_BASE_ADDR_HI_MASK;
-
err = amd_smn_read(0, AMD_PMC_BASE_ADDR_HI, &val);
if (err) {
dev_err(dev->dev, "error reading 0x%x\n", AMD_PMC_BASE_ADDR_HI);
@@ -865,7 +783,9 @@ static int amd_pmc_probe(struct platform_device *pdev)
goto err_pci_dev_put;
}
- mutex_init(&dev->lock);
+ err = devm_mutex_init(dev->dev, &dev->lock);
+ if (err)
+ goto err_pci_dev_put;
/* Get num of IP blocks within the SoC */
amd_pmc_get_ip_info(dev);
@@ -904,7 +824,6 @@ static void amd_pmc_remove(struct platform_device *pdev)
pci_dev_put(dev->rdev);
if (IS_ENABLED(CONFIG_AMD_MP2_STB))
amd_mp2_stb_deinit(dev);
- mutex_destroy(&dev->lock);
}
static const struct acpi_device_id amd_pmc_acpi_ids[] = {
diff --git a/drivers/platform/x86/amd/pmc/pmc.h b/drivers/platform/x86/amd/pmc/pmc.h
index f43f0253b0f5..62f3e51020fd 100644
--- a/drivers/platform/x86/amd/pmc/pmc.h
+++ b/drivers/platform/x86/amd/pmc/pmc.h
@@ -14,6 +14,59 @@
#include <linux/types.h>
#include <linux/mutex.h>
+/* SMU communication registers */
+#define AMD_PMC_REGISTER_RESPONSE 0x980
+#define AMD_PMC_REGISTER_ARGUMENT 0x9BC
+
+/* PMC Scratch Registers */
+#define AMD_PMC_SCRATCH_REG_CZN 0x94
+#define AMD_PMC_SCRATCH_REG_YC 0xD14
+#define AMD_PMC_SCRATCH_REG_1AH 0xF14
+
+/* STB Registers */
+#define AMD_PMC_STB_S2IDLE_PREPARE 0xC6000001
+#define AMD_PMC_STB_S2IDLE_RESTORE 0xC6000002
+#define AMD_PMC_STB_S2IDLE_CHECK 0xC6000003
+
+/* Base address of SMU for mapping physical address to virtual address */
+#define AMD_PMC_MAPPING_SIZE 0x01000
+#define AMD_PMC_BASE_ADDR_OFFSET 0x10000
+#define AMD_PMC_BASE_ADDR_LO 0x13B102E8
+#define AMD_PMC_BASE_ADDR_HI 0x13B102EC
+#define AMD_PMC_BASE_ADDR_LO_MASK GENMASK(15, 0)
+#define AMD_PMC_BASE_ADDR_HI_MASK GENMASK(31, 20)
+
+/* SMU Response Codes */
+#define AMD_PMC_RESULT_OK 0x01
+#define AMD_PMC_RESULT_CMD_REJECT_BUSY 0xFC
+#define AMD_PMC_RESULT_CMD_REJECT_PREREQ 0xFD
+#define AMD_PMC_RESULT_CMD_UNKNOWN 0xFE
+#define AMD_PMC_RESULT_FAILED 0xFF
+
+/* FCH SSC Registers */
+#define FCH_S0I3_ENTRY_TIME_L_OFFSET 0x30
+#define FCH_S0I3_ENTRY_TIME_H_OFFSET 0x34
+#define FCH_S0I3_EXIT_TIME_L_OFFSET 0x38
+#define FCH_S0I3_EXIT_TIME_H_OFFSET 0x3C
+#define FCH_SSC_MAPPING_SIZE 0x800
+#define FCH_BASE_PHY_ADDR_LOW 0xFED81100
+#define FCH_BASE_PHY_ADDR_HIGH 0x00000000
+
+/* SMU Message Definations */
+#define SMU_MSG_GETSMUVERSION 0x02
+#define SMU_MSG_LOG_GETDRAM_ADDR_HI 0x04
+#define SMU_MSG_LOG_GETDRAM_ADDR_LO 0x05
+#define SMU_MSG_LOG_START 0x06
+#define SMU_MSG_LOG_RESET 0x07
+#define SMU_MSG_LOG_DUMP_DATA 0x08
+#define SMU_MSG_GET_SUP_CONSTRAINTS 0x09
+
+#define PMC_MSG_DELAY_MIN_US 50
+#define RESPONSE_REGISTER_LOOP_MAX 20000
+
+#define DELAY_MIN_US 2000
+#define DELAY_MAX_US 3000
+
enum s2d_msg_port {
MSG_PORT_PMC,
MSG_PORT_S2D,
@@ -65,6 +118,34 @@ struct amd_pmc_dev {
struct stb_arg stb_arg;
};
+struct amd_pmc_bit_map {
+ const char *name;
+ u32 bit_mask;
+};
+
+struct smu_metrics {
+ u32 table_version;
+ u32 hint_count;
+ u32 s0i3_last_entry_status;
+ u32 timein_s0i2;
+ u64 timeentering_s0i3_lastcapture;
+ u64 timeentering_s0i3_totaltime;
+ u64 timeto_resume_to_os_lastcapture;
+ u64 timeto_resume_to_os_totaltime;
+ u64 timein_s0i3_lastcapture;
+ u64 timein_s0i3_totaltime;
+ u64 timein_swdrips_lastcapture;
+ u64 timein_swdrips_totaltime;
+ u64 timecondition_notmet_lastcapture[32];
+ u64 timecondition_notmet_totaltime[32];
+} __packed;
+
+enum amd_pmc_def {
+ MSG_TEST = 0x01,
+ MSG_OS_HINT_PCO,
+ MSG_OS_HINT_RN,
+};
+
void amd_pmc_process_restore_quirks(struct amd_pmc_dev *dev);
void amd_pmc_quirks_init(struct amd_pmc_dev *dev);
void amd_mp2_stb_init(struct amd_pmc_dev *dev);
@@ -79,6 +160,7 @@ void amd_mp2_stb_deinit(struct amd_pmc_dev *dev);
#define AMD_CPU_ID_CB 0x14D8
#define AMD_CPU_ID_PS 0x14E8
#define AMD_CPU_ID_SP 0x14A4
+#define AMD_CPU_ID_SHP 0x153A
#define PCI_DEVICE_ID_AMD_1AH_M20H_ROOT 0x1507
#define PCI_DEVICE_ID_AMD_1AH_M60H_ROOT 0x1122
#define PCI_DEVICE_ID_AMD_MP2_STB 0x172c
diff --git a/drivers/platform/x86/amd/pmf/Makefile b/drivers/platform/x86/amd/pmf/Makefile
index 6b26e48ce8ad..5978464e0eb7 100644
--- a/drivers/platform/x86/amd/pmf/Makefile
+++ b/drivers/platform/x86/amd/pmf/Makefile
@@ -4,7 +4,7 @@
# AMD Platform Management Framework
#
-obj-$(CONFIG_AMD_PMF) += amd-pmf.o
-amd-pmf-objs := core.o acpi.o sps.o \
- auto-mode.o cnqf.o \
- tee-if.o spc.o
+obj-$(CONFIG_AMD_PMF) += amd-pmf.o
+amd-pmf-y := core.o acpi.o sps.o \
+ auto-mode.o cnqf.o \
+ tee-if.o spc.o
diff --git a/drivers/platform/x86/amd/pmf/acpi.c b/drivers/platform/x86/amd/pmf/acpi.c
index dd5780a1d06e..f75f7ecd8cd9 100644
--- a/drivers/platform/x86/amd/pmf/acpi.c
+++ b/drivers/platform/x86/amd/pmf/acpi.c
@@ -220,7 +220,7 @@ static void apmf_sbios_heartbeat_notify(struct work_struct *work)
if (!info)
return;
- schedule_delayed_work(&dev->heart_beat, msecs_to_jiffies(dev->hb_interval * 1000));
+ schedule_delayed_work(&dev->heart_beat, secs_to_jiffies(dev->hb_interval));
kfree(info);
}
diff --git a/drivers/platform/x86/asus-tf103c-dock.c b/drivers/platform/x86/asus-tf103c-dock.c
index ca4670d0dc67..f09a3fc6524a 100644
--- a/drivers/platform/x86/asus-tf103c-dock.c
+++ b/drivers/platform/x86/asus-tf103c-dock.c
@@ -856,7 +856,7 @@ static int tf103c_dock_probe(struct i2c_client *client)
/* 5. Setup irqchip for touchpad IRQ pass-through */
dock->tp_irqchip.name = KBUILD_MODNAME;
- dock->tp_irq_domain = irq_domain_add_linear(NULL, 1, &irq_domain_simple_ops, NULL);
+ dock->tp_irq_domain = irq_domain_create_linear(NULL, 1, &irq_domain_simple_ops, NULL);
if (!dock->tp_irq_domain)
return -ENOMEM;
diff --git a/drivers/platform/x86/compal-laptop.c b/drivers/platform/x86/compal-laptop.c
index 58754bc5b5b1..abbebd4bfb15 100644
--- a/drivers/platform/x86/compal-laptop.c
+++ b/drivers/platform/x86/compal-laptop.c
@@ -69,7 +69,6 @@
#include <linux/hwmon-sysfs.h>
#include <linux/power_supply.h>
#include <linux/sysfs.h>
-#include <linux/fb.h>
#include <acpi/video.h>
/* ======= */
diff --git a/drivers/platform/x86/dell/Kconfig b/drivers/platform/x86/dell/Kconfig
index d09060aedd3f..f8a0dffcaab7 100644
--- a/drivers/platform/x86/dell/Kconfig
+++ b/drivers/platform/x86/dell/Kconfig
@@ -18,15 +18,35 @@ config ALIENWARE_WMI
tristate "Alienware Special feature control"
default m
depends on ACPI
+ depends on ACPI_WMI
+ depends on DMI
depends on LEDS_CLASS
depends on NEW_LEDS
- depends on ACPI_WMI
+ help
+ This is a driver for controlling Alienware WMI driven features.
+
+ On legacy devices, it exposes an interface for controlling the AlienFX
+ zones on Alienware machines that don't contain a dedicated
+ AlienFX USB MCU such as the X51 and X51-R2.
+
+ On newer devices, it exposes the AWCC thermal control interface through
+ known Kernel APIs.
+
+config ALIENWARE_WMI_LEGACY
+ bool "Alienware Legacy WMI device driver"
+ default y
+ depends on ALIENWARE_WMI
+ help
+ Legacy Alienware WMI driver with AlienFX LED control capabilities.
+
+config ALIENWARE_WMI_WMAX
+ bool "Alienware WMAX WMI device driver"
+ default y
+ depends on ALIENWARE_WMI
select ACPI_PLATFORM_PROFILE
help
- This is a driver for controlling Alienware BIOS driven
- features. It exposes an interface for controlling the AlienFX
- zones on Alienware machines that don't contain a dedicated AlienFX
- USB MCU such as the X51 and X51-R2.
+ Alienware WMI driver with AlienFX LED, HDMI, amplifier, deep sleep and
+ AWCC thermal control capabilities.
config DCDBAS
tristate "Dell Systems Management Base Driver"
diff --git a/drivers/platform/x86/dell/Makefile b/drivers/platform/x86/dell/Makefile
index bb3cbd470a46..c7501c25e627 100644
--- a/drivers/platform/x86/dell/Makefile
+++ b/drivers/platform/x86/dell/Makefile
@@ -4,24 +4,27 @@
# Dell x86 Platform-Specific Drivers
#
-obj-$(CONFIG_ALIENWARE_WMI) += alienware-wmi.o
-obj-$(CONFIG_DCDBAS) += dcdbas.o
-obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o
-obj-$(CONFIG_DELL_RBTN) += dell-rbtn.o
-obj-$(CONFIG_DELL_RBU) += dell_rbu.o
-obj-$(CONFIG_DELL_PC) += dell-pc.o
-obj-$(CONFIG_DELL_SMBIOS) += dell-smbios.o
-dell-smbios-objs := dell-smbios-base.o
-dell-smbios-$(CONFIG_DELL_SMBIOS_WMI) += dell-smbios-wmi.o
-dell-smbios-$(CONFIG_DELL_SMBIOS_SMM) += dell-smbios-smm.o
-obj-$(CONFIG_DELL_SMO8800) += dell-smo8800.o
-obj-$(CONFIG_DELL_SMO8800) += dell-lis3lv02d.o
-obj-$(CONFIG_DELL_UART_BACKLIGHT) += dell-uart-backlight.o
-obj-$(CONFIG_DELL_WMI) += dell-wmi.o
-dell-wmi-objs := dell-wmi-base.o
-dell-wmi-$(CONFIG_DELL_WMI_PRIVACY) += dell-wmi-privacy.o
-obj-$(CONFIG_DELL_WMI_AIO) += dell-wmi-aio.o
-obj-$(CONFIG_DELL_WMI_DESCRIPTOR) += dell-wmi-descriptor.o
-obj-$(CONFIG_DELL_WMI_DDV) += dell-wmi-ddv.o
-obj-$(CONFIG_DELL_WMI_LED) += dell-wmi-led.o
-obj-$(CONFIG_DELL_WMI_SYSMAN) += dell-wmi-sysman/
+obj-$(CONFIG_ALIENWARE_WMI) += alienware-wmi.o
+alienware-wmi-y := alienware-wmi-base.o
+alienware-wmi-$(CONFIG_ALIENWARE_WMI_LEGACY) += alienware-wmi-legacy.o
+alienware-wmi-$(CONFIG_ALIENWARE_WMI_WMAX) += alienware-wmi-wmax.o
+obj-$(CONFIG_DCDBAS) += dcdbas.o
+obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o
+obj-$(CONFIG_DELL_RBTN) += dell-rbtn.o
+obj-$(CONFIG_DELL_RBU) += dell_rbu.o
+obj-$(CONFIG_DELL_PC) += dell-pc.o
+obj-$(CONFIG_DELL_SMBIOS) += dell-smbios.o
+dell-smbios-y := dell-smbios-base.o
+dell-smbios-$(CONFIG_DELL_SMBIOS_WMI) += dell-smbios-wmi.o
+dell-smbios-$(CONFIG_DELL_SMBIOS_SMM) += dell-smbios-smm.o
+obj-$(CONFIG_DELL_SMO8800) += dell-smo8800.o
+obj-$(CONFIG_DELL_SMO8800) += dell-lis3lv02d.o
+obj-$(CONFIG_DELL_UART_BACKLIGHT) += dell-uart-backlight.o
+obj-$(CONFIG_DELL_WMI) += dell-wmi.o
+dell-wmi-y := dell-wmi-base.o
+dell-wmi-$(CONFIG_DELL_WMI_PRIVACY) += dell-wmi-privacy.o
+obj-$(CONFIG_DELL_WMI_AIO) += dell-wmi-aio.o
+obj-$(CONFIG_DELL_WMI_DESCRIPTOR) += dell-wmi-descriptor.o
+obj-$(CONFIG_DELL_WMI_DDV) += dell-wmi-ddv.o
+obj-$(CONFIG_DELL_WMI_LED) += dell-wmi-led.o
+obj-$(CONFIG_DELL_WMI_SYSMAN) += dell-wmi-sysman/
diff --git a/drivers/platform/x86/dell/alienware-wmi-base.c b/drivers/platform/x86/dell/alienware-wmi-base.c
new file mode 100644
index 000000000000..64562b92314f
--- /dev/null
+++ b/drivers/platform/x86/dell/alienware-wmi-base.c
@@ -0,0 +1,491 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Alienware special feature control
+ *
+ * Copyright (C) 2014 Dell Inc <Dell.Client.Kernel@dell.com>
+ * Copyright (C) 2025 Kurt Borja <kuurtb@gmail.com>
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/acpi.h>
+#include <linux/cleanup.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/dmi.h>
+#include <linux/leds.h>
+#include "alienware-wmi.h"
+
+MODULE_AUTHOR("Mario Limonciello <mario.limonciello@outlook.com>");
+MODULE_AUTHOR("Kurt Borja <kuurtb@gmail.com>");
+MODULE_DESCRIPTION("Alienware special feature control");
+MODULE_LICENSE("GPL");
+
+struct alienfx_quirks *alienfx;
+
+static struct alienfx_quirks quirk_inspiron5675 = {
+ .num_zones = 2,
+ .hdmi_mux = false,
+ .amplifier = false,
+ .deepslp = false,
+};
+
+static struct alienfx_quirks quirk_unknown = {
+ .num_zones = 2,
+ .hdmi_mux = false,
+ .amplifier = false,
+ .deepslp = false,
+};
+
+static struct alienfx_quirks quirk_x51_r1_r2 = {
+ .num_zones = 3,
+ .hdmi_mux = false,
+ .amplifier = false,
+ .deepslp = false,
+};
+
+static struct alienfx_quirks quirk_x51_r3 = {
+ .num_zones = 4,
+ .hdmi_mux = false,
+ .amplifier = true,
+ .deepslp = false,
+};
+
+static struct alienfx_quirks quirk_asm100 = {
+ .num_zones = 2,
+ .hdmi_mux = true,
+ .amplifier = false,
+ .deepslp = false,
+};
+
+static struct alienfx_quirks quirk_asm200 = {
+ .num_zones = 2,
+ .hdmi_mux = true,
+ .amplifier = false,
+ .deepslp = true,
+};
+
+static struct alienfx_quirks quirk_asm201 = {
+ .num_zones = 2,
+ .hdmi_mux = true,
+ .amplifier = true,
+ .deepslp = true,
+};
+
+static int __init dmi_matched(const struct dmi_system_id *dmi)
+{
+ alienfx = dmi->driver_data;
+ return 1;
+}
+
+static const struct dmi_system_id alienware_quirks[] __initconst = {
+ {
+ .callback = dmi_matched,
+ .ident = "Alienware ASM100",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "ASM100"),
+ },
+ .driver_data = &quirk_asm100,
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Alienware ASM200",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "ASM200"),
+ },
+ .driver_data = &quirk_asm200,
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Alienware ASM201",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "ASM201"),
+ },
+ .driver_data = &quirk_asm201,
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Alienware X51 R1",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51"),
+ },
+ .driver_data = &quirk_x51_r1_r2,
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Alienware X51 R2",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51 R2"),
+ },
+ .driver_data = &quirk_x51_r1_r2,
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Alienware X51 R3",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51 R3"),
+ },
+ .driver_data = &quirk_x51_r3,
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Dell Inc. Inspiron 5675",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5675"),
+ },
+ .driver_data = &quirk_inspiron5675,
+ },
+ {}
+};
+
+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;
+
+ ret = wmidev_evaluate_method(wdev, 0, method_id, &in, out_data ? &out : NULL);
+ if (ACPI_FAILURE(ret))
+ return -EIO;
+
+ union acpi_object *obj __free(kfree) = out.pointer;
+
+ if (out_data) {
+ if (obj && obj->type == ACPI_TYPE_INTEGER)
+ *out_data = (u32)obj->integer.value;
+ else
+ return -ENOMSG;
+ }
+
+ return 0;
+}
+
+/*
+ * Helpers used for zone control
+ */
+static int parse_rgb(const char *buf, struct color_platform *colors)
+{
+ long unsigned int rgb;
+ int ret;
+ union color_union {
+ struct color_platform cp;
+ int package;
+ } repackager;
+
+ ret = kstrtoul(buf, 16, &rgb);
+ if (ret)
+ return ret;
+
+ /* RGB triplet notation is 24-bit hexadecimal */
+ if (rgb > 0xFFFFFF)
+ return -EINVAL;
+
+ repackager.package = rgb & 0x0f0f0f0f;
+ pr_debug("alienware-wmi: r: %d g:%d b: %d\n",
+ repackager.cp.red, repackager.cp.green, repackager.cp.blue);
+ *colors = repackager.cp;
+ return 0;
+}
+
+/*
+ * Individual RGB zone control
+ */
+static ssize_t zone_show(struct device *dev, struct device_attribute *attr,
+ char *buf, u8 location)
+{
+ struct alienfx_priv *priv = dev_get_drvdata(dev);
+ struct color_platform *colors = &priv->colors[location];
+
+ return sprintf(buf, "red: %d, green: %d, blue: %d\n",
+ colors->red, colors->green, colors->blue);
+
+}
+
+static ssize_t zone_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count, u8 location)
+{
+ struct alienfx_priv *priv = dev_get_drvdata(dev);
+ struct color_platform *colors = &priv->colors[location];
+ struct alienfx_platdata *pdata = dev_get_platdata(dev);
+ int ret;
+
+ ret = parse_rgb(buf, colors);
+ if (ret)
+ return ret;
+
+ ret = pdata->ops.upd_led(priv, pdata->wdev, location);
+
+ return ret ? ret : count;
+}
+
+static ssize_t zone00_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return zone_show(dev, attr, buf, 0);
+}
+
+static ssize_t zone00_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return zone_store(dev, attr, buf, count, 0);
+}
+
+static DEVICE_ATTR_RW(zone00);
+
+static ssize_t zone01_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return zone_show(dev, attr, buf, 1);
+}
+
+static ssize_t zone01_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return zone_store(dev, attr, buf, count, 1);
+}
+
+static DEVICE_ATTR_RW(zone01);
+
+static ssize_t zone02_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return zone_show(dev, attr, buf, 2);
+}
+
+static ssize_t zone02_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return zone_store(dev, attr, buf, count, 2);
+}
+
+static DEVICE_ATTR_RW(zone02);
+
+static ssize_t zone03_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return zone_show(dev, attr, buf, 3);
+}
+
+static ssize_t zone03_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return zone_store(dev, attr, buf, count, 3);
+}
+
+static DEVICE_ATTR_RW(zone03);
+
+/*
+ * Lighting control state device attribute (Global)
+ */
+static ssize_t lighting_control_state_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct alienfx_priv *priv = dev_get_drvdata(dev);
+
+ if (priv->lighting_control_state == LEGACY_BOOTING)
+ return sysfs_emit(buf, "[booting] running suspend\n");
+ else if (priv->lighting_control_state == LEGACY_SUSPEND)
+ return sysfs_emit(buf, "booting running [suspend]\n");
+
+ return sysfs_emit(buf, "booting [running] suspend\n");
+}
+
+static ssize_t lighting_control_state_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct alienfx_priv *priv = dev_get_drvdata(dev);
+ u8 val;
+
+ if (strcmp(buf, "booting\n") == 0)
+ val = LEGACY_BOOTING;
+ else if (strcmp(buf, "suspend\n") == 0)
+ val = LEGACY_SUSPEND;
+ else if (alienware_interface == LEGACY)
+ val = LEGACY_RUNNING;
+ else
+ val = WMAX_RUNNING;
+
+ priv->lighting_control_state = val;
+ pr_debug("alienware-wmi: updated control state to %d\n",
+ priv->lighting_control_state);
+
+ return count;
+}
+
+static DEVICE_ATTR_RW(lighting_control_state);
+
+static umode_t zone_attr_visible(struct kobject *kobj,
+ struct attribute *attr, int n)
+{
+ if (n < alienfx->num_zones + 1)
+ return attr->mode;
+
+ return 0;
+}
+
+static bool zone_group_visible(struct kobject *kobj)
+{
+ return alienfx->num_zones > 0;
+}
+DEFINE_SYSFS_GROUP_VISIBLE(zone);
+
+static struct attribute *zone_attrs[] = {
+ &dev_attr_lighting_control_state.attr,
+ &dev_attr_zone00.attr,
+ &dev_attr_zone01.attr,
+ &dev_attr_zone02.attr,
+ &dev_attr_zone03.attr,
+ NULL
+};
+
+static struct attribute_group zone_attribute_group = {
+ .name = "rgb_zones",
+ .is_visible = SYSFS_GROUP_VISIBLE(zone),
+ .attrs = zone_attrs,
+};
+
+/*
+ * LED Brightness (Global)
+ */
+static void global_led_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ struct alienfx_priv *priv = container_of(led_cdev, struct alienfx_priv,
+ global_led);
+ struct alienfx_platdata *pdata = dev_get_platdata(&priv->pdev->dev);
+ int ret;
+
+ priv->global_brightness = brightness;
+
+ ret = pdata->ops.upd_brightness(priv, pdata->wdev, brightness);
+ if (ret)
+ pr_err("LED brightness update failed\n");
+}
+
+static enum led_brightness global_led_get(struct led_classdev *led_cdev)
+{
+ struct alienfx_priv *priv = container_of(led_cdev, struct alienfx_priv,
+ global_led);
+
+ return priv->global_brightness;
+}
+
+/*
+ * Platform Driver
+ */
+static int alienfx_probe(struct platform_device *pdev)
+{
+ struct alienfx_priv *priv;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ if (alienware_interface == WMAX)
+ priv->lighting_control_state = WMAX_RUNNING;
+ else
+ priv->lighting_control_state = LEGACY_RUNNING;
+
+ priv->pdev = pdev;
+ priv->global_led.name = "alienware::global_brightness";
+ priv->global_led.brightness_set = global_led_set;
+ priv->global_led.brightness_get = global_led_get;
+ priv->global_led.max_brightness = 0x0F;
+ priv->global_brightness = priv->global_led.max_brightness;
+ platform_set_drvdata(pdev, priv);
+
+ return devm_led_classdev_register(&pdev->dev, &priv->global_led);
+}
+
+static const struct attribute_group *alienfx_groups[] = {
+ &zone_attribute_group,
+ WMAX_DEV_GROUPS
+ NULL
+};
+
+static struct platform_driver platform_driver = {
+ .driver = {
+ .name = "alienware-wmi",
+ .dev_groups = alienfx_groups,
+ },
+ .probe = alienfx_probe,
+};
+
+static void alienware_alienfx_remove(void *data)
+{
+ struct platform_device *pdev = data;
+
+ platform_device_unregister(pdev);
+}
+
+int alienware_alienfx_setup(struct alienfx_platdata *pdata)
+{
+ struct device *dev = &pdata->wdev->dev;
+ struct platform_device *pdev;
+ int ret;
+
+ pdev = platform_device_register_data(NULL, "alienware-wmi",
+ PLATFORM_DEVID_NONE, pdata,
+ sizeof(*pdata));
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ dev_set_drvdata(dev, pdev);
+ ret = devm_add_action_or_reset(dev, alienware_alienfx_remove, pdev);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int __init alienware_wmi_init(void)
+{
+ int ret;
+
+ dmi_check_system(alienware_quirks);
+ if (!alienfx)
+ alienfx = &quirk_unknown;
+
+ ret = platform_driver_register(&platform_driver);
+ if (ret < 0)
+ return ret;
+
+ if (wmi_has_guid(WMAX_CONTROL_GUID)) {
+ alienware_interface = WMAX;
+ ret = alienware_wmax_wmi_init();
+ } else {
+ alienware_interface = LEGACY;
+ ret = alienware_legacy_wmi_init();
+ }
+
+ if (ret < 0)
+ platform_driver_unregister(&platform_driver);
+
+ return ret;
+}
+
+module_init(alienware_wmi_init);
+
+static void __exit alienware_wmi_exit(void)
+{
+ if (alienware_interface == WMAX)
+ alienware_wmax_wmi_exit();
+ else
+ alienware_legacy_wmi_exit();
+
+ platform_driver_unregister(&platform_driver);
+}
+
+module_exit(alienware_wmi_exit);
diff --git a/drivers/platform/x86/dell/alienware-wmi-legacy.c b/drivers/platform/x86/dell/alienware-wmi-legacy.c
new file mode 100644
index 000000000000..4a84a2fe918b
--- /dev/null
+++ b/drivers/platform/x86/dell/alienware-wmi-legacy.c
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Alienware LEGACY WMI device driver
+ *
+ * Copyright (C) 2025 Kurt Borja <kuurtb@gmail.com>
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/wmi.h>
+#include "alienware-wmi.h"
+
+struct legacy_led_args {
+ struct color_platform colors;
+ u8 brightness;
+ u8 state;
+} __packed;
+
+
+/*
+ * Legacy WMI driver
+ */
+static int legacy_wmi_update_led(struct alienfx_priv *priv,
+ struct wmi_device *wdev, u8 location)
+{
+ struct legacy_led_args legacy_args = {
+ .colors = priv->colors[location],
+ .brightness = priv->global_brightness,
+ .state = 0,
+ };
+ struct acpi_buffer input;
+ acpi_status status;
+
+ if (legacy_args.state != LEGACY_RUNNING) {
+ legacy_args.state = priv->lighting_control_state;
+
+ input.length = sizeof(legacy_args);
+ input.pointer = &legacy_args;
+
+ status = wmi_evaluate_method(LEGACY_POWER_CONTROL_GUID, 0,
+ location + 1, &input, NULL);
+ if (ACPI_FAILURE(status))
+ return -EIO;
+
+ return 0;
+ }
+
+ return alienware_wmi_command(wdev, location + 1, &legacy_args,
+ sizeof(legacy_args), NULL);
+}
+
+static int legacy_wmi_update_brightness(struct alienfx_priv *priv,
+ struct wmi_device *wdev, u8 brightness)
+{
+ return legacy_wmi_update_led(priv, wdev, 0);
+}
+
+static int legacy_wmi_probe(struct wmi_device *wdev, const void *context)
+{
+ struct alienfx_platdata pdata = {
+ .wdev = wdev,
+ .ops = {
+ .upd_led = legacy_wmi_update_led,
+ .upd_brightness = legacy_wmi_update_brightness,
+ },
+ };
+
+ return alienware_alienfx_setup(&pdata);
+}
+
+static const struct wmi_device_id alienware_legacy_device_id_table[] = {
+ { LEGACY_CONTROL_GUID, NULL },
+ { },
+};
+MODULE_DEVICE_TABLE(wmi, alienware_legacy_device_id_table);
+
+static struct wmi_driver alienware_legacy_wmi_driver = {
+ .driver = {
+ .name = "alienware-wmi-alienfx",
+ .probe_type = PROBE_PREFER_ASYNCHRONOUS,
+ },
+ .id_table = alienware_legacy_device_id_table,
+ .probe = legacy_wmi_probe,
+ .no_singleton = true,
+};
+
+int __init alienware_legacy_wmi_init(void)
+{
+ return wmi_driver_register(&alienware_legacy_wmi_driver);
+}
+
+void __exit alienware_legacy_wmi_exit(void)
+{
+ wmi_driver_unregister(&alienware_legacy_wmi_driver);
+}
diff --git a/drivers/platform/x86/dell/alienware-wmi-wmax.c b/drivers/platform/x86/dell/alienware-wmi-wmax.c
new file mode 100644
index 000000000000..3d3014b5adf0
--- /dev/null
+++ b/drivers/platform/x86/dell/alienware-wmi-wmax.c
@@ -0,0 +1,768 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Alienware WMAX WMI device driver
+ *
+ * Copyright (C) 2014 Dell Inc <Dell.Client.Kernel@dell.com>
+ * Copyright (C) 2025 Kurt Borja <kuurtb@gmail.com>
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/dmi.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_profile.h>
+#include <linux/wmi.h>
+#include "alienware-wmi.h"
+
+#define WMAX_METHOD_HDMI_SOURCE 0x1
+#define WMAX_METHOD_HDMI_STATUS 0x2
+#define WMAX_METHOD_HDMI_CABLE 0x5
+#define WMAX_METHOD_AMPLIFIER_CABLE 0x6
+#define WMAX_METHOD_DEEP_SLEEP_CONTROL 0x0B
+#define WMAX_METHOD_DEEP_SLEEP_STATUS 0x0C
+#define WMAX_METHOD_BRIGHTNESS 0x3
+#define WMAX_METHOD_ZONE_CONTROL 0x4
+#define WMAX_METHOD_THERMAL_INFORMATION 0x14
+#define WMAX_METHOD_THERMAL_CONTROL 0x15
+#define WMAX_METHOD_GAME_SHIFT_STATUS 0x25
+
+#define WMAX_THERMAL_MODE_GMODE 0xAB
+
+#define WMAX_FAILURE_CODE 0xFFFFFFFF
+#define WMAX_THERMAL_TABLE_MASK GENMASK(7, 4)
+#define WMAX_THERMAL_MODE_MASK GENMASK(3, 0)
+#define WMAX_SENSOR_ID_MASK BIT(8)
+
+static bool force_platform_profile;
+module_param_unsafe(force_platform_profile, bool, 0);
+MODULE_PARM_DESC(force_platform_profile, "Forces auto-detecting thermal profiles without checking if WMI thermal backend is available");
+
+static bool force_gmode;
+module_param_unsafe(force_gmode, bool, 0);
+MODULE_PARM_DESC(force_gmode, "Forces G-Mode when performance profile is selected");
+
+struct awcc_quirks {
+ bool pprof;
+ bool gmode;
+};
+
+static struct awcc_quirks g_series_quirks = {
+ .pprof = true,
+ .gmode = true,
+};
+
+static struct awcc_quirks generic_quirks = {
+ .pprof = true,
+ .gmode = false,
+};
+
+static struct awcc_quirks empty_quirks;
+
+static const struct dmi_system_id awcc_dmi_table[] __initconst = {
+ {
+ .ident = "Alienware m16 R1 AMD",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m16 R1 AMD"),
+ },
+ .driver_data = &generic_quirks,
+ },
+ {
+ .ident = "Alienware m17 R5",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"),
+ },
+ .driver_data = &generic_quirks,
+ },
+ {
+ .ident = "Alienware m18 R2",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m18 R2"),
+ },
+ .driver_data = &generic_quirks,
+ },
+ {
+ .ident = "Alienware x15 R1",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x15 R1"),
+ },
+ .driver_data = &generic_quirks,
+ },
+ {
+ .ident = "Alienware x17 R2",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x17 R2"),
+ },
+ .driver_data = &generic_quirks,
+ },
+ {
+ .ident = "Dell Inc. G15 5510",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5510"),
+ },
+ .driver_data = &g_series_quirks,
+ },
+ {
+ .ident = "Dell Inc. G15 5511",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5511"),
+ },
+ .driver_data = &g_series_quirks,
+ },
+ {
+ .ident = "Dell Inc. G15 5515",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5515"),
+ },
+ .driver_data = &g_series_quirks,
+ },
+ {
+ .ident = "Dell Inc. G3 3500",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "G3 3500"),
+ },
+ .driver_data = &g_series_quirks,
+ },
+ {
+ .ident = "Dell Inc. G3 3590",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "G3 3590"),
+ },
+ .driver_data = &g_series_quirks,
+ },
+ {
+ .ident = "Dell Inc. G5 5500",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "G5 5500"),
+ },
+ .driver_data = &g_series_quirks,
+ },
+};
+
+enum WMAX_THERMAL_INFORMATION_OPERATIONS {
+ WMAX_OPERATION_SYS_DESCRIPTION = 0x02,
+ WMAX_OPERATION_LIST_IDS = 0x03,
+ WMAX_OPERATION_CURRENT_PROFILE = 0x0B,
+};
+
+enum WMAX_THERMAL_CONTROL_OPERATIONS {
+ WMAX_OPERATION_ACTIVATE_PROFILE = 0x01,
+};
+
+enum WMAX_GAME_SHIFT_STATUS_OPERATIONS {
+ WMAX_OPERATION_TOGGLE_GAME_SHIFT = 0x01,
+ WMAX_OPERATION_GET_GAME_SHIFT_STATUS = 0x02,
+};
+
+enum WMAX_THERMAL_TABLES {
+ WMAX_THERMAL_TABLE_BASIC = 0x90,
+ WMAX_THERMAL_TABLE_USTT = 0xA0,
+};
+
+enum wmax_thermal_mode {
+ THERMAL_MODE_USTT_BALANCED,
+ THERMAL_MODE_USTT_BALANCED_PERFORMANCE,
+ THERMAL_MODE_USTT_COOL,
+ THERMAL_MODE_USTT_QUIET,
+ THERMAL_MODE_USTT_PERFORMANCE,
+ THERMAL_MODE_USTT_LOW_POWER,
+ THERMAL_MODE_BASIC_QUIET,
+ THERMAL_MODE_BASIC_BALANCED,
+ THERMAL_MODE_BASIC_BALANCED_PERFORMANCE,
+ THERMAL_MODE_BASIC_PERFORMANCE,
+ THERMAL_MODE_LAST,
+};
+
+struct wmax_led_args {
+ u32 led_mask;
+ struct color_platform colors;
+ u8 state;
+} __packed;
+
+struct wmax_brightness_args {
+ u32 led_mask;
+ u32 percentage;
+};
+
+struct wmax_basic_args {
+ u8 arg;
+};
+
+struct wmax_u32_args {
+ u8 operation;
+ u8 arg1;
+ u8 arg2;
+ u8 arg3;
+};
+
+struct awcc_priv {
+ struct wmi_device *wdev;
+ struct device *ppdev;
+ enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
+};
+
+static const enum platform_profile_option wmax_mode_to_platform_profile[THERMAL_MODE_LAST] = {
+ [THERMAL_MODE_USTT_BALANCED] = PLATFORM_PROFILE_BALANCED,
+ [THERMAL_MODE_USTT_BALANCED_PERFORMANCE] = PLATFORM_PROFILE_BALANCED_PERFORMANCE,
+ [THERMAL_MODE_USTT_COOL] = PLATFORM_PROFILE_COOL,
+ [THERMAL_MODE_USTT_QUIET] = PLATFORM_PROFILE_QUIET,
+ [THERMAL_MODE_USTT_PERFORMANCE] = PLATFORM_PROFILE_PERFORMANCE,
+ [THERMAL_MODE_USTT_LOW_POWER] = PLATFORM_PROFILE_LOW_POWER,
+ [THERMAL_MODE_BASIC_QUIET] = PLATFORM_PROFILE_QUIET,
+ [THERMAL_MODE_BASIC_BALANCED] = PLATFORM_PROFILE_BALANCED,
+ [THERMAL_MODE_BASIC_BALANCED_PERFORMANCE] = PLATFORM_PROFILE_BALANCED_PERFORMANCE,
+ [THERMAL_MODE_BASIC_PERFORMANCE] = PLATFORM_PROFILE_PERFORMANCE,
+};
+
+static struct awcc_quirks *awcc;
+
+/*
+ * The HDMI mux sysfs node indicates the status of the HDMI input mux.
+ * It can toggle between standard system GPU output and HDMI input.
+ */
+static ssize_t cable_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct alienfx_platdata *pdata = dev_get_platdata(dev);
+ struct wmax_basic_args in_args = {
+ .arg = 0,
+ };
+ u32 out_data;
+ int ret;
+
+ ret = alienware_wmi_command(pdata->wdev, WMAX_METHOD_HDMI_CABLE,
+ &in_args, sizeof(in_args), &out_data);
+ if (!ret) {
+ if (out_data == 0)
+ return sysfs_emit(buf, "[unconnected] connected unknown\n");
+ else if (out_data == 1)
+ return sysfs_emit(buf, "unconnected [connected] unknown\n");
+ }
+
+ pr_err("alienware-wmi: unknown HDMI cable status: %d\n", ret);
+ return sysfs_emit(buf, "unconnected connected [unknown]\n");
+}
+
+static ssize_t source_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct alienfx_platdata *pdata = dev_get_platdata(dev);
+ struct wmax_basic_args in_args = {
+ .arg = 0,
+ };
+ u32 out_data;
+ int ret;
+
+ ret = alienware_wmi_command(pdata->wdev, WMAX_METHOD_HDMI_STATUS,
+ &in_args, sizeof(in_args), &out_data);
+ if (!ret) {
+ if (out_data == 1)
+ return sysfs_emit(buf, "[input] gpu unknown\n");
+ else if (out_data == 2)
+ return sysfs_emit(buf, "input [gpu] unknown\n");
+ }
+
+ pr_err("alienware-wmi: unknown HDMI source status: %u\n", ret);
+ return sysfs_emit(buf, "input gpu [unknown]\n");
+}
+
+static ssize_t source_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct alienfx_platdata *pdata = dev_get_platdata(dev);
+ struct wmax_basic_args args;
+ int ret;
+
+ if (strcmp(buf, "gpu\n") == 0)
+ args.arg = 1;
+ else if (strcmp(buf, "input\n") == 0)
+ args.arg = 2;
+ else
+ args.arg = 3;
+ pr_debug("alienware-wmi: setting hdmi to %d : %s", args.arg, buf);
+
+ ret = alienware_wmi_command(pdata->wdev, WMAX_METHOD_HDMI_SOURCE, &args,
+ sizeof(args), NULL);
+ if (ret < 0)
+ pr_err("alienware-wmi: HDMI toggle failed: results: %u\n", ret);
+
+ return count;
+}
+
+static DEVICE_ATTR_RO(cable);
+static DEVICE_ATTR_RW(source);
+
+static bool hdmi_group_visible(struct kobject *kobj)
+{
+ return alienware_interface == WMAX && alienfx->hdmi_mux;
+}
+DEFINE_SIMPLE_SYSFS_GROUP_VISIBLE(hdmi);
+
+static struct attribute *hdmi_attrs[] = {
+ &dev_attr_cable.attr,
+ &dev_attr_source.attr,
+ NULL,
+};
+
+const struct attribute_group wmax_hdmi_attribute_group = {
+ .name = "hdmi",
+ .is_visible = SYSFS_GROUP_VISIBLE(hdmi),
+ .attrs = hdmi_attrs,
+};
+
+/*
+ * Alienware GFX amplifier support
+ * - Currently supports reading cable status
+ * - Leaving expansion room to possibly support dock/undock events later
+ */
+static ssize_t status_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct alienfx_platdata *pdata = dev_get_platdata(dev);
+ struct wmax_basic_args in_args = {
+ .arg = 0,
+ };
+ u32 out_data;
+ int ret;
+
+ ret = alienware_wmi_command(pdata->wdev, WMAX_METHOD_AMPLIFIER_CABLE,
+ &in_args, sizeof(in_args), &out_data);
+ if (!ret) {
+ if (out_data == 0)
+ return sysfs_emit(buf, "[unconnected] connected unknown\n");
+ else if (out_data == 1)
+ return sysfs_emit(buf, "unconnected [connected] unknown\n");
+ }
+
+ pr_err("alienware-wmi: unknown amplifier cable status: %d\n", ret);
+ return sysfs_emit(buf, "unconnected connected [unknown]\n");
+}
+
+static DEVICE_ATTR_RO(status);
+
+static bool amplifier_group_visible(struct kobject *kobj)
+{
+ return alienware_interface == WMAX && alienfx->amplifier;
+}
+DEFINE_SIMPLE_SYSFS_GROUP_VISIBLE(amplifier);
+
+static struct attribute *amplifier_attrs[] = {
+ &dev_attr_status.attr,
+ NULL,
+};
+
+const struct attribute_group wmax_amplifier_attribute_group = {
+ .name = "amplifier",
+ .is_visible = SYSFS_GROUP_VISIBLE(amplifier),
+ .attrs = amplifier_attrs,
+};
+
+/*
+ * Deep Sleep Control support
+ * - Modifies BIOS setting for deep sleep control allowing extra wakeup events
+ */
+static ssize_t deepsleep_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct alienfx_platdata *pdata = dev_get_platdata(dev);
+ struct wmax_basic_args in_args = {
+ .arg = 0,
+ };
+ u32 out_data;
+ int ret;
+
+ ret = alienware_wmi_command(pdata->wdev, WMAX_METHOD_DEEP_SLEEP_STATUS,
+ &in_args, sizeof(in_args), &out_data);
+ if (!ret) {
+ if (out_data == 0)
+ return sysfs_emit(buf, "[disabled] s5 s5_s4\n");
+ else if (out_data == 1)
+ return sysfs_emit(buf, "disabled [s5] s5_s4\n");
+ else if (out_data == 2)
+ return sysfs_emit(buf, "disabled s5 [s5_s4]\n");
+ }
+
+ pr_err("alienware-wmi: unknown deep sleep status: %d\n", ret);
+ return sysfs_emit(buf, "disabled s5 s5_s4 [unknown]\n");
+}
+
+static ssize_t deepsleep_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct alienfx_platdata *pdata = dev_get_platdata(dev);
+ struct wmax_basic_args args;
+ int ret;
+
+ if (strcmp(buf, "disabled\n") == 0)
+ args.arg = 0;
+ else if (strcmp(buf, "s5\n") == 0)
+ args.arg = 1;
+ else
+ args.arg = 2;
+ pr_debug("alienware-wmi: setting deep sleep to %d : %s", args.arg, buf);
+
+ ret = alienware_wmi_command(pdata->wdev, WMAX_METHOD_DEEP_SLEEP_CONTROL,
+ &args, sizeof(args), NULL);
+ if (!ret)
+ pr_err("alienware-wmi: deep sleep control failed: results: %u\n", ret);
+
+ return count;
+}
+
+static DEVICE_ATTR_RW(deepsleep);
+
+static bool deepsleep_group_visible(struct kobject *kobj)
+{
+ return alienware_interface == WMAX && alienfx->deepslp;
+}
+DEFINE_SIMPLE_SYSFS_GROUP_VISIBLE(deepsleep);
+
+static struct attribute *deepsleep_attrs[] = {
+ &dev_attr_deepsleep.attr,
+ NULL,
+};
+
+const struct attribute_group wmax_deepsleep_attribute_group = {
+ .name = "deepsleep",
+ .is_visible = SYSFS_GROUP_VISIBLE(deepsleep),
+ .attrs = deepsleep_attrs,
+};
+
+/*
+ * Thermal Profile control
+ * - Provides thermal profile control through the Platform Profile API
+ */
+static bool is_wmax_thermal_code(u32 code)
+{
+ if (code & WMAX_SENSOR_ID_MASK)
+ return false;
+
+ if ((code & WMAX_THERMAL_MODE_MASK) >= THERMAL_MODE_LAST)
+ return false;
+
+ if ((code & WMAX_THERMAL_TABLE_MASK) == WMAX_THERMAL_TABLE_BASIC &&
+ (code & WMAX_THERMAL_MODE_MASK) >= THERMAL_MODE_BASIC_QUIET)
+ return true;
+
+ if ((code & WMAX_THERMAL_TABLE_MASK) == WMAX_THERMAL_TABLE_USTT &&
+ (code & WMAX_THERMAL_MODE_MASK) <= THERMAL_MODE_USTT_LOW_POWER)
+ return true;
+
+ return false;
+}
+
+static int wmax_thermal_information(struct wmi_device *wdev, u8 operation,
+ u8 arg, u32 *out_data)
+{
+ struct wmax_u32_args in_args = {
+ .operation = operation,
+ .arg1 = arg,
+ .arg2 = 0,
+ .arg3 = 0,
+ };
+ int ret;
+
+ ret = alienware_wmi_command(wdev, WMAX_METHOD_THERMAL_INFORMATION,
+ &in_args, sizeof(in_args), out_data);
+ if (ret < 0)
+ return ret;
+
+ if (*out_data == WMAX_FAILURE_CODE)
+ return -EBADRQC;
+
+ return 0;
+}
+
+static int wmax_thermal_control(struct wmi_device *wdev, u8 profile)
+{
+ struct wmax_u32_args in_args = {
+ .operation = WMAX_OPERATION_ACTIVATE_PROFILE,
+ .arg1 = profile,
+ .arg2 = 0,
+ .arg3 = 0,
+ };
+ u32 out_data;
+ int ret;
+
+ ret = alienware_wmi_command(wdev, WMAX_METHOD_THERMAL_CONTROL,
+ &in_args, sizeof(in_args), &out_data);
+ if (ret)
+ return ret;
+
+ if (out_data == WMAX_FAILURE_CODE)
+ return -EBADRQC;
+
+ return 0;
+}
+
+static int wmax_game_shift_status(struct wmi_device *wdev, u8 operation,
+ u32 *out_data)
+{
+ struct wmax_u32_args in_args = {
+ .operation = operation,
+ .arg1 = 0,
+ .arg2 = 0,
+ .arg3 = 0,
+ };
+ int ret;
+
+ ret = alienware_wmi_command(wdev, WMAX_METHOD_GAME_SHIFT_STATUS,
+ &in_args, sizeof(in_args), out_data);
+ if (ret < 0)
+ return ret;
+
+ if (*out_data == WMAX_FAILURE_CODE)
+ return -EOPNOTSUPP;
+
+ return 0;
+}
+
+static int thermal_profile_get(struct device *dev,
+ enum platform_profile_option *profile)
+{
+ struct awcc_priv *priv = dev_get_drvdata(dev);
+ u32 out_data;
+ int ret;
+
+ ret = wmax_thermal_information(priv->wdev, WMAX_OPERATION_CURRENT_PROFILE,
+ 0, &out_data);
+
+ if (ret < 0)
+ return ret;
+
+ if (out_data == WMAX_THERMAL_MODE_GMODE) {
+ *profile = PLATFORM_PROFILE_PERFORMANCE;
+ return 0;
+ }
+
+ if (!is_wmax_thermal_code(out_data))
+ return -ENODATA;
+
+ out_data &= WMAX_THERMAL_MODE_MASK;
+ *profile = wmax_mode_to_platform_profile[out_data];
+
+ return 0;
+}
+
+static int thermal_profile_set(struct device *dev,
+ enum platform_profile_option profile)
+{
+ struct awcc_priv *priv = dev_get_drvdata(dev);
+
+ if (awcc->gmode) {
+ u32 gmode_status;
+ int ret;
+
+ ret = wmax_game_shift_status(priv->wdev,
+ WMAX_OPERATION_GET_GAME_SHIFT_STATUS,
+ &gmode_status);
+
+ if (ret < 0)
+ return ret;
+
+ if ((profile == PLATFORM_PROFILE_PERFORMANCE && !gmode_status) ||
+ (profile != PLATFORM_PROFILE_PERFORMANCE && gmode_status)) {
+ ret = wmax_game_shift_status(priv->wdev,
+ WMAX_OPERATION_TOGGLE_GAME_SHIFT,
+ &gmode_status);
+
+ if (ret < 0)
+ return ret;
+ }
+ }
+
+ return wmax_thermal_control(priv->wdev,
+ priv->supported_thermal_profiles[profile]);
+}
+
+static int thermal_profile_probe(void *drvdata, unsigned long *choices)
+{
+ enum platform_profile_option profile;
+ struct awcc_priv *priv = drvdata;
+ enum wmax_thermal_mode mode;
+ u8 sys_desc[4];
+ u32 first_mode;
+ u32 out_data;
+ int ret;
+
+ ret = wmax_thermal_information(priv->wdev, WMAX_OPERATION_SYS_DESCRIPTION,
+ 0, (u32 *) &sys_desc);
+ if (ret < 0)
+ return ret;
+
+ first_mode = sys_desc[0] + sys_desc[1];
+
+ for (u32 i = 0; i < sys_desc[3]; i++) {
+ ret = wmax_thermal_information(priv->wdev, WMAX_OPERATION_LIST_IDS,
+ i + first_mode, &out_data);
+
+ if (ret == -EIO)
+ return ret;
+
+ if (ret == -EBADRQC)
+ break;
+
+ if (!is_wmax_thermal_code(out_data))
+ continue;
+
+ mode = out_data & WMAX_THERMAL_MODE_MASK;
+ profile = wmax_mode_to_platform_profile[mode];
+ priv->supported_thermal_profiles[profile] = out_data;
+
+ set_bit(profile, choices);
+ }
+
+ if (bitmap_empty(choices, PLATFORM_PROFILE_LAST))
+ return -ENODEV;
+
+ if (awcc->gmode) {
+ priv->supported_thermal_profiles[PLATFORM_PROFILE_PERFORMANCE] =
+ WMAX_THERMAL_MODE_GMODE;
+
+ set_bit(PLATFORM_PROFILE_PERFORMANCE, choices);
+ }
+
+ return 0;
+}
+
+static const struct platform_profile_ops awcc_platform_profile_ops = {
+ .probe = thermal_profile_probe,
+ .profile_get = thermal_profile_get,
+ .profile_set = thermal_profile_set,
+};
+
+static int awcc_platform_profile_init(struct wmi_device *wdev)
+{
+ struct awcc_priv *priv = dev_get_drvdata(&wdev->dev);
+
+ priv->ppdev = devm_platform_profile_register(&wdev->dev, "alienware-wmi",
+ priv, &awcc_platform_profile_ops);
+
+ return PTR_ERR_OR_ZERO(priv->ppdev);
+}
+
+static int alienware_awcc_setup(struct wmi_device *wdev)
+{
+ struct awcc_priv *priv;
+ int ret;
+
+ priv = devm_kzalloc(&wdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->wdev = wdev;
+ dev_set_drvdata(&wdev->dev, priv);
+
+ if (awcc->pprof) {
+ ret = awcc_platform_profile_init(wdev);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ * WMAX WMI driver
+ */
+static int wmax_wmi_update_led(struct alienfx_priv *priv,
+ struct wmi_device *wdev, u8 location)
+{
+ struct wmax_led_args in_args = {
+ .led_mask = 1 << location,
+ .colors = priv->colors[location],
+ .state = priv->lighting_control_state,
+ };
+
+ return alienware_wmi_command(wdev, WMAX_METHOD_ZONE_CONTROL, &in_args,
+ sizeof(in_args), NULL);
+}
+
+static int wmax_wmi_update_brightness(struct alienfx_priv *priv,
+ struct wmi_device *wdev, u8 brightness)
+{
+ struct wmax_brightness_args in_args = {
+ .led_mask = 0xFF,
+ .percentage = brightness,
+ };
+
+ return alienware_wmi_command(wdev, WMAX_METHOD_BRIGHTNESS, &in_args,
+ sizeof(in_args), NULL);
+}
+
+static int wmax_wmi_probe(struct wmi_device *wdev, const void *context)
+{
+ struct alienfx_platdata pdata = {
+ .wdev = wdev,
+ .ops = {
+ .upd_led = wmax_wmi_update_led,
+ .upd_brightness = wmax_wmi_update_brightness,
+ },
+ };
+ int ret;
+
+ if (awcc)
+ ret = alienware_awcc_setup(wdev);
+ else
+ ret = alienware_alienfx_setup(&pdata);
+
+ return ret;
+}
+
+static const struct wmi_device_id alienware_wmax_device_id_table[] = {
+ { WMAX_CONTROL_GUID, NULL },
+ { },
+};
+MODULE_DEVICE_TABLE(wmi, alienware_wmax_device_id_table);
+
+static struct wmi_driver alienware_wmax_wmi_driver = {
+ .driver = {
+ .name = "alienware-wmi-wmax",
+ .probe_type = PROBE_PREFER_ASYNCHRONOUS,
+ },
+ .id_table = alienware_wmax_device_id_table,
+ .probe = wmax_wmi_probe,
+ .no_singleton = true,
+};
+
+int __init alienware_wmax_wmi_init(void)
+{
+ const struct dmi_system_id *id;
+
+ id = dmi_first_match(awcc_dmi_table);
+ if (id)
+ awcc = id->driver_data;
+
+ if (force_platform_profile) {
+ if (!awcc)
+ awcc = &empty_quirks;
+
+ awcc->pprof = true;
+ }
+
+ if (force_gmode) {
+ if (awcc)
+ awcc->gmode = true;
+ else
+ pr_warn("force_gmode requires platform profile support\n");
+ }
+
+ return wmi_driver_register(&alienware_wmax_wmi_driver);
+}
+
+void __exit alienware_wmax_wmi_exit(void)
+{
+ wmi_driver_unregister(&alienware_wmax_wmi_driver);
+}
diff --git a/drivers/platform/x86/dell/alienware-wmi.c b/drivers/platform/x86/dell/alienware-wmi.c
deleted file mode 100644
index e252e0cf47ef..000000000000
--- a/drivers/platform/x86/dell/alienware-wmi.c
+++ /dev/null
@@ -1,1249 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Alienware AlienFX control
- *
- * Copyright (C) 2014 Dell Inc <Dell.Client.Kernel@dell.com>
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/acpi.h>
-#include <linux/bitfield.h>
-#include <linux/bits.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/platform_profile.h>
-#include <linux/dmi.h>
-#include <linux/leds.h>
-
-#define LEGACY_CONTROL_GUID "A90597CE-A997-11DA-B012-B622A1EF5492"
-#define LEGACY_POWER_CONTROL_GUID "A80593CE-A997-11DA-B012-B622A1EF5492"
-#define WMAX_CONTROL_GUID "A70591CE-A997-11DA-B012-B622A1EF5492"
-
-#define WMAX_METHOD_HDMI_SOURCE 0x1
-#define WMAX_METHOD_HDMI_STATUS 0x2
-#define WMAX_METHOD_BRIGHTNESS 0x3
-#define WMAX_METHOD_ZONE_CONTROL 0x4
-#define WMAX_METHOD_HDMI_CABLE 0x5
-#define WMAX_METHOD_AMPLIFIER_CABLE 0x6
-#define WMAX_METHOD_DEEP_SLEEP_CONTROL 0x0B
-#define WMAX_METHOD_DEEP_SLEEP_STATUS 0x0C
-#define WMAX_METHOD_THERMAL_INFORMATION 0x14
-#define WMAX_METHOD_THERMAL_CONTROL 0x15
-#define WMAX_METHOD_GAME_SHIFT_STATUS 0x25
-
-#define WMAX_THERMAL_MODE_GMODE 0xAB
-
-#define WMAX_FAILURE_CODE 0xFFFFFFFF
-
-MODULE_AUTHOR("Mario Limonciello <mario.limonciello@outlook.com>");
-MODULE_DESCRIPTION("Alienware special feature control");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("wmi:" LEGACY_CONTROL_GUID);
-MODULE_ALIAS("wmi:" WMAX_CONTROL_GUID);
-
-static bool force_platform_profile;
-module_param_unsafe(force_platform_profile, bool, 0);
-MODULE_PARM_DESC(force_platform_profile, "Forces auto-detecting thermal profiles without checking if WMI thermal backend is available");
-
-static bool force_gmode;
-module_param_unsafe(force_gmode, bool, 0);
-MODULE_PARM_DESC(force_gmode, "Forces G-Mode when performance profile is selected");
-
-enum INTERFACE_FLAGS {
- LEGACY,
- WMAX,
-};
-
-enum LEGACY_CONTROL_STATES {
- LEGACY_RUNNING = 1,
- LEGACY_BOOTING = 0,
- LEGACY_SUSPEND = 3,
-};
-
-enum WMAX_CONTROL_STATES {
- WMAX_RUNNING = 0xFF,
- WMAX_BOOTING = 0,
- WMAX_SUSPEND = 3,
-};
-
-enum WMAX_THERMAL_INFORMATION_OPERATIONS {
- WMAX_OPERATION_SYS_DESCRIPTION = 0x02,
- WMAX_OPERATION_LIST_IDS = 0x03,
- WMAX_OPERATION_CURRENT_PROFILE = 0x0B,
-};
-
-enum WMAX_THERMAL_CONTROL_OPERATIONS {
- WMAX_OPERATION_ACTIVATE_PROFILE = 0x01,
-};
-
-enum WMAX_GAME_SHIFT_STATUS_OPERATIONS {
- WMAX_OPERATION_TOGGLE_GAME_SHIFT = 0x01,
- WMAX_OPERATION_GET_GAME_SHIFT_STATUS = 0x02,
-};
-
-enum WMAX_THERMAL_TABLES {
- WMAX_THERMAL_TABLE_BASIC = 0x90,
- WMAX_THERMAL_TABLE_USTT = 0xA0,
-};
-
-enum wmax_thermal_mode {
- THERMAL_MODE_USTT_BALANCED,
- THERMAL_MODE_USTT_BALANCED_PERFORMANCE,
- THERMAL_MODE_USTT_COOL,
- THERMAL_MODE_USTT_QUIET,
- THERMAL_MODE_USTT_PERFORMANCE,
- THERMAL_MODE_USTT_LOW_POWER,
- THERMAL_MODE_BASIC_QUIET,
- THERMAL_MODE_BASIC_BALANCED,
- THERMAL_MODE_BASIC_BALANCED_PERFORMANCE,
- THERMAL_MODE_BASIC_PERFORMANCE,
- THERMAL_MODE_LAST,
-};
-
-static const enum platform_profile_option wmax_mode_to_platform_profile[THERMAL_MODE_LAST] = {
- [THERMAL_MODE_USTT_BALANCED] = PLATFORM_PROFILE_BALANCED,
- [THERMAL_MODE_USTT_BALANCED_PERFORMANCE] = PLATFORM_PROFILE_BALANCED_PERFORMANCE,
- [THERMAL_MODE_USTT_COOL] = PLATFORM_PROFILE_COOL,
- [THERMAL_MODE_USTT_QUIET] = PLATFORM_PROFILE_QUIET,
- [THERMAL_MODE_USTT_PERFORMANCE] = PLATFORM_PROFILE_PERFORMANCE,
- [THERMAL_MODE_USTT_LOW_POWER] = PLATFORM_PROFILE_LOW_POWER,
- [THERMAL_MODE_BASIC_QUIET] = PLATFORM_PROFILE_QUIET,
- [THERMAL_MODE_BASIC_BALANCED] = PLATFORM_PROFILE_BALANCED,
- [THERMAL_MODE_BASIC_BALANCED_PERFORMANCE] = PLATFORM_PROFILE_BALANCED_PERFORMANCE,
- [THERMAL_MODE_BASIC_PERFORMANCE] = PLATFORM_PROFILE_PERFORMANCE,
-};
-
-struct quirk_entry {
- u8 num_zones;
- u8 hdmi_mux;
- u8 amplifier;
- u8 deepslp;
- bool thermal;
- bool gmode;
-};
-
-static struct quirk_entry *quirks;
-
-
-static struct quirk_entry quirk_inspiron5675 = {
- .num_zones = 2,
- .hdmi_mux = 0,
- .amplifier = 0,
- .deepslp = 0,
- .thermal = false,
- .gmode = false,
-};
-
-static struct quirk_entry quirk_unknown = {
- .num_zones = 2,
- .hdmi_mux = 0,
- .amplifier = 0,
- .deepslp = 0,
- .thermal = false,
- .gmode = false,
-};
-
-static struct quirk_entry quirk_x51_r1_r2 = {
- .num_zones = 3,
- .hdmi_mux = 0,
- .amplifier = 0,
- .deepslp = 0,
- .thermal = false,
- .gmode = false,
-};
-
-static struct quirk_entry quirk_x51_r3 = {
- .num_zones = 4,
- .hdmi_mux = 0,
- .amplifier = 1,
- .deepslp = 0,
- .thermal = false,
- .gmode = false,
-};
-
-static struct quirk_entry quirk_asm100 = {
- .num_zones = 2,
- .hdmi_mux = 1,
- .amplifier = 0,
- .deepslp = 0,
- .thermal = false,
- .gmode = false,
-};
-
-static struct quirk_entry quirk_asm200 = {
- .num_zones = 2,
- .hdmi_mux = 1,
- .amplifier = 0,
- .deepslp = 1,
- .thermal = false,
- .gmode = false,
-};
-
-static struct quirk_entry quirk_asm201 = {
- .num_zones = 2,
- .hdmi_mux = 1,
- .amplifier = 1,
- .deepslp = 1,
- .thermal = false,
- .gmode = false,
-};
-
-static struct quirk_entry quirk_g_series = {
- .num_zones = 0,
- .hdmi_mux = 0,
- .amplifier = 0,
- .deepslp = 0,
- .thermal = true,
- .gmode = true,
-};
-
-static struct quirk_entry quirk_x_series = {
- .num_zones = 0,
- .hdmi_mux = 0,
- .amplifier = 0,
- .deepslp = 0,
- .thermal = true,
- .gmode = false,
-};
-
-static int __init dmi_matched(const struct dmi_system_id *dmi)
-{
- quirks = dmi->driver_data;
- return 1;
-}
-
-static const struct dmi_system_id alienware_quirks[] __initconst = {
- {
- .callback = dmi_matched,
- .ident = "Alienware ASM100",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
- DMI_MATCH(DMI_PRODUCT_NAME, "ASM100"),
- },
- .driver_data = &quirk_asm100,
- },
- {
- .callback = dmi_matched,
- .ident = "Alienware ASM200",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
- DMI_MATCH(DMI_PRODUCT_NAME, "ASM200"),
- },
- .driver_data = &quirk_asm200,
- },
- {
- .callback = dmi_matched,
- .ident = "Alienware ASM201",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
- DMI_MATCH(DMI_PRODUCT_NAME, "ASM201"),
- },
- .driver_data = &quirk_asm201,
- },
- {
- .callback = dmi_matched,
- .ident = "Alienware m16 R1 AMD",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
- DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m16 R1 AMD"),
- },
- .driver_data = &quirk_x_series,
- },
- {
- .callback = dmi_matched,
- .ident = "Alienware m17 R5",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
- DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"),
- },
- .driver_data = &quirk_x_series,
- },
- {
- .callback = dmi_matched,
- .ident = "Alienware m18 R2",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
- DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m18 R2"),
- },
- .driver_data = &quirk_x_series,
- },
- {
- .callback = dmi_matched,
- .ident = "Alienware x15 R1",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
- DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x15 R1"),
- },
- .driver_data = &quirk_x_series,
- },
- {
- .callback = dmi_matched,
- .ident = "Alienware x17 R2",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
- DMI_MATCH(DMI_PRODUCT_NAME, "Alienware x17 R2"),
- },
- .driver_data = &quirk_x_series,
- },
- {
- .callback = dmi_matched,
- .ident = "Alienware X51 R1",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
- DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51"),
- },
- .driver_data = &quirk_x51_r1_r2,
- },
- {
- .callback = dmi_matched,
- .ident = "Alienware X51 R2",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
- DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51 R2"),
- },
- .driver_data = &quirk_x51_r1_r2,
- },
- {
- .callback = dmi_matched,
- .ident = "Alienware X51 R3",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Alienware"),
- DMI_MATCH(DMI_PRODUCT_NAME, "Alienware X51 R3"),
- },
- .driver_data = &quirk_x51_r3,
- },
- {
- .callback = dmi_matched,
- .ident = "Dell Inc. G15 5510",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5510"),
- },
- .driver_data = &quirk_g_series,
- },
- {
- .callback = dmi_matched,
- .ident = "Dell Inc. G15 5511",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5511"),
- },
- .driver_data = &quirk_g_series,
- },
- {
- .callback = dmi_matched,
- .ident = "Dell Inc. G15 5515",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5515"),
- },
- .driver_data = &quirk_g_series,
- },
- {
- .callback = dmi_matched,
- .ident = "Dell Inc. G3 3500",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "G3 3500"),
- },
- .driver_data = &quirk_g_series,
- },
- {
- .callback = dmi_matched,
- .ident = "Dell Inc. G3 3590",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "G3 3590"),
- },
- .driver_data = &quirk_g_series,
- },
- {
- .callback = dmi_matched,
- .ident = "Dell Inc. G5 5500",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "G5 5500"),
- },
- .driver_data = &quirk_g_series,
- },
- {
- .callback = dmi_matched,
- .ident = "Dell Inc. Inspiron 5675",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5675"),
- },
- .driver_data = &quirk_inspiron5675,
- },
- {}
-};
-
-struct color_platform {
- u8 blue;
- u8 green;
- u8 red;
-} __packed;
-
-struct wmax_brightness_args {
- u32 led_mask;
- u32 percentage;
-};
-
-struct wmax_basic_args {
- u8 arg;
-};
-
-struct legacy_led_args {
- struct color_platform colors;
- u8 brightness;
- u8 state;
-} __packed;
-
-struct wmax_led_args {
- u32 led_mask;
- struct color_platform colors;
- u8 state;
-} __packed;
-
-struct wmax_u32_args {
- u8 operation;
- u8 arg1;
- u8 arg2;
- u8 arg3;
-};
-
-static struct platform_device *platform_device;
-static struct color_platform colors[4];
-static enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];
-
-static u8 interface;
-static u8 lighting_control_state;
-static u8 global_brightness;
-
-/*
- * Helpers used for zone control
- */
-static int parse_rgb(const char *buf, struct color_platform *colors)
-{
- long unsigned int rgb;
- int ret;
- union color_union {
- struct color_platform cp;
- int package;
- } repackager;
-
- ret = kstrtoul(buf, 16, &rgb);
- if (ret)
- return ret;
-
- /* RGB triplet notation is 24-bit hexadecimal */
- if (rgb > 0xFFFFFF)
- return -EINVAL;
-
- repackager.package = rgb & 0x0f0f0f0f;
- pr_debug("alienware-wmi: r: %d g:%d b: %d\n",
- repackager.cp.red, repackager.cp.green, repackager.cp.blue);
- *colors = repackager.cp;
- return 0;
-}
-
-/*
- * Individual RGB zone control
- */
-static int alienware_update_led(u8 location)
-{
- int method_id;
- acpi_status status;
- char *guid;
- struct acpi_buffer input;
- struct legacy_led_args legacy_args;
- struct wmax_led_args wmax_basic_args;
- if (interface == WMAX) {
- wmax_basic_args.led_mask = 1 << location;
- wmax_basic_args.colors = colors[location];
- wmax_basic_args.state = lighting_control_state;
- guid = WMAX_CONTROL_GUID;
- method_id = WMAX_METHOD_ZONE_CONTROL;
-
- input.length = sizeof(wmax_basic_args);
- input.pointer = &wmax_basic_args;
- } else {
- legacy_args.colors = colors[location];
- legacy_args.brightness = global_brightness;
- legacy_args.state = 0;
- if (lighting_control_state == LEGACY_BOOTING ||
- lighting_control_state == LEGACY_SUSPEND) {
- guid = LEGACY_POWER_CONTROL_GUID;
- legacy_args.state = lighting_control_state;
- } else
- guid = LEGACY_CONTROL_GUID;
- method_id = location + 1;
-
- input.length = sizeof(legacy_args);
- input.pointer = &legacy_args;
- }
- pr_debug("alienware-wmi: guid %s method %d\n", guid, method_id);
-
- status = wmi_evaluate_method(guid, 0, method_id, &input, NULL);
- if (ACPI_FAILURE(status))
- pr_err("alienware-wmi: zone set failure: %u\n", status);
- return ACPI_FAILURE(status);
-}
-
-static ssize_t zone_show(struct device *dev, struct device_attribute *attr,
- char *buf, u8 location)
-{
- return sprintf(buf, "red: %d, green: %d, blue: %d\n",
- colors[location].red, colors[location].green,
- colors[location].blue);
-
-}
-
-static ssize_t zone_store(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count, u8 location)
-{
- int ret;
-
- ret = parse_rgb(buf, &colors[location]);
- if (ret)
- return ret;
-
- ret = alienware_update_led(location);
-
- return ret ? ret : count;
-}
-
-static ssize_t zone00_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- return zone_show(dev, attr, buf, 0);
-}
-
-static ssize_t zone00_store(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return zone_store(dev, attr, buf, count, 0);
-}
-
-static DEVICE_ATTR_RW(zone00);
-
-static ssize_t zone01_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- return zone_show(dev, attr, buf, 1);
-}
-
-static ssize_t zone01_store(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return zone_store(dev, attr, buf, count, 1);
-}
-
-static DEVICE_ATTR_RW(zone01);
-
-static ssize_t zone02_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- return zone_show(dev, attr, buf, 2);
-}
-
-static ssize_t zone02_store(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return zone_store(dev, attr, buf, count, 2);
-}
-
-static DEVICE_ATTR_RW(zone02);
-
-static ssize_t zone03_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- return zone_show(dev, attr, buf, 3);
-}
-
-static ssize_t zone03_store(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return zone_store(dev, attr, buf, count, 3);
-}
-
-static DEVICE_ATTR_RW(zone03);
-
-/*
- * Lighting control state device attribute (Global)
- */
-static ssize_t lighting_control_state_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- if (lighting_control_state == LEGACY_BOOTING)
- return sysfs_emit(buf, "[booting] running suspend\n");
- else if (lighting_control_state == LEGACY_SUSPEND)
- return sysfs_emit(buf, "booting running [suspend]\n");
-
- return sysfs_emit(buf, "booting [running] suspend\n");
-}
-
-static ssize_t lighting_control_state_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- u8 val;
-
- if (strcmp(buf, "booting\n") == 0)
- val = LEGACY_BOOTING;
- else if (strcmp(buf, "suspend\n") == 0)
- val = LEGACY_SUSPEND;
- else if (interface == LEGACY)
- val = LEGACY_RUNNING;
- else
- val = WMAX_RUNNING;
-
- lighting_control_state = val;
- pr_debug("alienware-wmi: updated control state to %d\n",
- lighting_control_state);
-
- return count;
-}
-
-static DEVICE_ATTR_RW(lighting_control_state);
-
-static umode_t zone_attr_visible(struct kobject *kobj,
- struct attribute *attr, int n)
-{
- if (n < quirks->num_zones + 1)
- return attr->mode;
-
- return 0;
-}
-
-static bool zone_group_visible(struct kobject *kobj)
-{
- return quirks->num_zones > 0;
-}
-DEFINE_SYSFS_GROUP_VISIBLE(zone);
-
-static struct attribute *zone_attrs[] = {
- &dev_attr_lighting_control_state.attr,
- &dev_attr_zone00.attr,
- &dev_attr_zone01.attr,
- &dev_attr_zone02.attr,
- &dev_attr_zone03.attr,
- NULL
-};
-
-static struct attribute_group zone_attribute_group = {
- .name = "rgb_zones",
- .is_visible = SYSFS_GROUP_VISIBLE(zone),
- .attrs = zone_attrs,
-};
-
-/*
- * LED Brightness (Global)
- */
-static int wmax_brightness(int brightness)
-{
- acpi_status status;
- struct acpi_buffer input;
- struct wmax_brightness_args args = {
- .led_mask = 0xFF,
- .percentage = brightness,
- };
- input.length = sizeof(args);
- input.pointer = &args;
- status = wmi_evaluate_method(WMAX_CONTROL_GUID, 0,
- WMAX_METHOD_BRIGHTNESS, &input, NULL);
- if (ACPI_FAILURE(status))
- pr_err("alienware-wmi: brightness set failure: %u\n", status);
- return ACPI_FAILURE(status);
-}
-
-static void global_led_set(struct led_classdev *led_cdev,
- enum led_brightness brightness)
-{
- int ret;
- global_brightness = brightness;
- if (interface == WMAX)
- ret = wmax_brightness(brightness);
- else
- ret = alienware_update_led(0);
- if (ret)
- pr_err("LED brightness update failed\n");
-}
-
-static enum led_brightness global_led_get(struct led_classdev *led_cdev)
-{
- return global_brightness;
-}
-
-static struct led_classdev global_led = {
- .brightness_set = global_led_set,
- .brightness_get = global_led_get,
- .name = "alienware::global_brightness",
-};
-
-static int alienware_zone_init(struct platform_device *dev)
-{
- if (interface == WMAX) {
- lighting_control_state = WMAX_RUNNING;
- } else if (interface == LEGACY) {
- lighting_control_state = LEGACY_RUNNING;
- }
- global_led.max_brightness = 0x0F;
- global_brightness = global_led.max_brightness;
-
- return led_classdev_register(&dev->dev, &global_led);
-}
-
-static void alienware_zone_exit(struct platform_device *dev)
-{
- if (!quirks->num_zones)
- return;
-
- led_classdev_unregister(&global_led);
-}
-
-static acpi_status alienware_wmax_command(void *in_args, size_t in_size,
- u32 command, u32 *out_data)
-{
- acpi_status status;
- union acpi_object *obj;
- struct acpi_buffer input;
- struct acpi_buffer output;
-
- input.length = in_size;
- input.pointer = in_args;
- if (out_data) {
- output.length = ACPI_ALLOCATE_BUFFER;
- output.pointer = NULL;
- status = wmi_evaluate_method(WMAX_CONTROL_GUID, 0,
- command, &input, &output);
- if (ACPI_SUCCESS(status)) {
- obj = (union acpi_object *)output.pointer;
- if (obj && obj->type == ACPI_TYPE_INTEGER)
- *out_data = (u32)obj->integer.value;
- }
- kfree(output.pointer);
- } else {
- status = wmi_evaluate_method(WMAX_CONTROL_GUID, 0,
- command, &input, NULL);
- }
- return status;
-}
-
-/*
- * The HDMI mux sysfs node indicates the status of the HDMI input mux.
- * It can toggle between standard system GPU output and HDMI input.
- */
-static ssize_t cable_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct wmax_basic_args in_args = {
- .arg = 0,
- };
- acpi_status status;
- u32 out_data;
-
- status =
- alienware_wmax_command(&in_args, sizeof(in_args),
- WMAX_METHOD_HDMI_CABLE, &out_data);
- if (ACPI_SUCCESS(status)) {
- if (out_data == 0)
- return sysfs_emit(buf, "[unconnected] connected unknown\n");
- else if (out_data == 1)
- return sysfs_emit(buf, "unconnected [connected] unknown\n");
- }
- pr_err("alienware-wmi: unknown HDMI cable status: %d\n", status);
- return sysfs_emit(buf, "unconnected connected [unknown]\n");
-}
-
-static ssize_t source_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct wmax_basic_args in_args = {
- .arg = 0,
- };
- acpi_status status;
- u32 out_data;
-
- status =
- alienware_wmax_command(&in_args, sizeof(in_args),
- WMAX_METHOD_HDMI_STATUS, &out_data);
-
- if (ACPI_SUCCESS(status)) {
- if (out_data == 1)
- return sysfs_emit(buf, "[input] gpu unknown\n");
- else if (out_data == 2)
- return sysfs_emit(buf, "input [gpu] unknown\n");
- }
- pr_err("alienware-wmi: unknown HDMI source status: %u\n", status);
- return sysfs_emit(buf, "input gpu [unknown]\n");
-}
-
-static ssize_t source_store(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct wmax_basic_args args;
- acpi_status status;
-
- if (strcmp(buf, "gpu\n") == 0)
- args.arg = 1;
- else if (strcmp(buf, "input\n") == 0)
- args.arg = 2;
- else
- args.arg = 3;
- pr_debug("alienware-wmi: setting hdmi to %d : %s", args.arg, buf);
-
- status = alienware_wmax_command(&args, sizeof(args),
- WMAX_METHOD_HDMI_SOURCE, NULL);
-
- if (ACPI_FAILURE(status))
- pr_err("alienware-wmi: HDMI toggle failed: results: %u\n",
- status);
- return count;
-}
-
-static DEVICE_ATTR_RO(cable);
-static DEVICE_ATTR_RW(source);
-
-static bool hdmi_group_visible(struct kobject *kobj)
-{
- return quirks->hdmi_mux;
-}
-DEFINE_SIMPLE_SYSFS_GROUP_VISIBLE(hdmi);
-
-static struct attribute *hdmi_attrs[] = {
- &dev_attr_cable.attr,
- &dev_attr_source.attr,
- NULL,
-};
-
-static const struct attribute_group hdmi_attribute_group = {
- .name = "hdmi",
- .is_visible = SYSFS_GROUP_VISIBLE(hdmi),
- .attrs = hdmi_attrs,
-};
-
-/*
- * Alienware GFX amplifier support
- * - Currently supports reading cable status
- * - Leaving expansion room to possibly support dock/undock events later
- */
-static ssize_t status_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct wmax_basic_args in_args = {
- .arg = 0,
- };
- acpi_status status;
- u32 out_data;
-
- status =
- alienware_wmax_command(&in_args, sizeof(in_args),
- WMAX_METHOD_AMPLIFIER_CABLE, &out_data);
- if (ACPI_SUCCESS(status)) {
- if (out_data == 0)
- return sysfs_emit(buf, "[unconnected] connected unknown\n");
- else if (out_data == 1)
- return sysfs_emit(buf, "unconnected [connected] unknown\n");
- }
- pr_err("alienware-wmi: unknown amplifier cable status: %d\n", status);
- return sysfs_emit(buf, "unconnected connected [unknown]\n");
-}
-
-static DEVICE_ATTR_RO(status);
-
-static bool amplifier_group_visible(struct kobject *kobj)
-{
- return quirks->amplifier;
-}
-DEFINE_SIMPLE_SYSFS_GROUP_VISIBLE(amplifier);
-
-static struct attribute *amplifier_attrs[] = {
- &dev_attr_status.attr,
- NULL,
-};
-
-static const struct attribute_group amplifier_attribute_group = {
- .name = "amplifier",
- .is_visible = SYSFS_GROUP_VISIBLE(amplifier),
- .attrs = amplifier_attrs,
-};
-
-/*
- * Deep Sleep Control support
- * - Modifies BIOS setting for deep sleep control allowing extra wakeup events
- */
-static ssize_t deepsleep_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct wmax_basic_args in_args = {
- .arg = 0,
- };
- acpi_status status;
- u32 out_data;
-
- status = alienware_wmax_command(&in_args, sizeof(in_args),
- WMAX_METHOD_DEEP_SLEEP_STATUS, &out_data);
- if (ACPI_SUCCESS(status)) {
- if (out_data == 0)
- return sysfs_emit(buf, "[disabled] s5 s5_s4\n");
- else if (out_data == 1)
- return sysfs_emit(buf, "disabled [s5] s5_s4\n");
- else if (out_data == 2)
- return sysfs_emit(buf, "disabled s5 [s5_s4]\n");
- }
- pr_err("alienware-wmi: unknown deep sleep status: %d\n", status);
- return sysfs_emit(buf, "disabled s5 s5_s4 [unknown]\n");
-}
-
-static ssize_t deepsleep_store(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct wmax_basic_args args;
- acpi_status status;
-
- if (strcmp(buf, "disabled\n") == 0)
- args.arg = 0;
- else if (strcmp(buf, "s5\n") == 0)
- args.arg = 1;
- else
- args.arg = 2;
- pr_debug("alienware-wmi: setting deep sleep to %d : %s", args.arg, buf);
-
- status = alienware_wmax_command(&args, sizeof(args),
- WMAX_METHOD_DEEP_SLEEP_CONTROL, NULL);
-
- if (ACPI_FAILURE(status))
- pr_err("alienware-wmi: deep sleep control failed: results: %u\n",
- status);
- return count;
-}
-
-static DEVICE_ATTR_RW(deepsleep);
-
-static bool deepsleep_group_visible(struct kobject *kobj)
-{
- return quirks->deepslp;
-}
-DEFINE_SIMPLE_SYSFS_GROUP_VISIBLE(deepsleep);
-
-static struct attribute *deepsleep_attrs[] = {
- &dev_attr_deepsleep.attr,
- NULL,
-};
-
-static const struct attribute_group deepsleep_attribute_group = {
- .name = "deepsleep",
- .is_visible = SYSFS_GROUP_VISIBLE(deepsleep),
- .attrs = deepsleep_attrs,
-};
-
-/*
- * Thermal Profile control
- * - Provides thermal profile control through the Platform Profile API
- */
-#define WMAX_THERMAL_TABLE_MASK GENMASK(7, 4)
-#define WMAX_THERMAL_MODE_MASK GENMASK(3, 0)
-#define WMAX_SENSOR_ID_MASK BIT(8)
-
-static bool is_wmax_thermal_code(u32 code)
-{
- if (code & WMAX_SENSOR_ID_MASK)
- return false;
-
- if ((code & WMAX_THERMAL_MODE_MASK) >= THERMAL_MODE_LAST)
- return false;
-
- if ((code & WMAX_THERMAL_TABLE_MASK) == WMAX_THERMAL_TABLE_BASIC &&
- (code & WMAX_THERMAL_MODE_MASK) >= THERMAL_MODE_BASIC_QUIET)
- return true;
-
- if ((code & WMAX_THERMAL_TABLE_MASK) == WMAX_THERMAL_TABLE_USTT &&
- (code & WMAX_THERMAL_MODE_MASK) <= THERMAL_MODE_USTT_LOW_POWER)
- return true;
-
- return false;
-}
-
-static int wmax_thermal_information(u8 operation, u8 arg, u32 *out_data)
-{
- struct wmax_u32_args in_args = {
- .operation = operation,
- .arg1 = arg,
- .arg2 = 0,
- .arg3 = 0,
- };
- acpi_status status;
-
- status = alienware_wmax_command(&in_args, sizeof(in_args),
- WMAX_METHOD_THERMAL_INFORMATION,
- out_data);
-
- if (ACPI_FAILURE(status))
- return -EIO;
-
- if (*out_data == WMAX_FAILURE_CODE)
- return -EBADRQC;
-
- return 0;
-}
-
-static int wmax_thermal_control(u8 profile)
-{
- struct wmax_u32_args in_args = {
- .operation = WMAX_OPERATION_ACTIVATE_PROFILE,
- .arg1 = profile,
- .arg2 = 0,
- .arg3 = 0,
- };
- acpi_status status;
- u32 out_data;
-
- status = alienware_wmax_command(&in_args, sizeof(in_args),
- WMAX_METHOD_THERMAL_CONTROL,
- &out_data);
-
- if (ACPI_FAILURE(status))
- return -EIO;
-
- if (out_data == WMAX_FAILURE_CODE)
- return -EBADRQC;
-
- return 0;
-}
-
-static int wmax_game_shift_status(u8 operation, u32 *out_data)
-{
- struct wmax_u32_args in_args = {
- .operation = operation,
- .arg1 = 0,
- .arg2 = 0,
- .arg3 = 0,
- };
- acpi_status status;
-
- status = alienware_wmax_command(&in_args, sizeof(in_args),
- WMAX_METHOD_GAME_SHIFT_STATUS,
- out_data);
-
- if (ACPI_FAILURE(status))
- return -EIO;
-
- if (*out_data == WMAX_FAILURE_CODE)
- return -EOPNOTSUPP;
-
- return 0;
-}
-
-static int thermal_profile_get(struct device *dev,
- enum platform_profile_option *profile)
-{
- u32 out_data;
- int ret;
-
- ret = wmax_thermal_information(WMAX_OPERATION_CURRENT_PROFILE,
- 0, &out_data);
-
- if (ret < 0)
- return ret;
-
- if (out_data == WMAX_THERMAL_MODE_GMODE) {
- *profile = PLATFORM_PROFILE_PERFORMANCE;
- return 0;
- }
-
- if (!is_wmax_thermal_code(out_data))
- return -ENODATA;
-
- out_data &= WMAX_THERMAL_MODE_MASK;
- *profile = wmax_mode_to_platform_profile[out_data];
-
- return 0;
-}
-
-static int thermal_profile_set(struct device *dev,
- enum platform_profile_option profile)
-{
- if (quirks->gmode) {
- u32 gmode_status;
- int ret;
-
- ret = wmax_game_shift_status(WMAX_OPERATION_GET_GAME_SHIFT_STATUS,
- &gmode_status);
-
- if (ret < 0)
- return ret;
-
- if ((profile == PLATFORM_PROFILE_PERFORMANCE && !gmode_status) ||
- (profile != PLATFORM_PROFILE_PERFORMANCE && gmode_status)) {
- ret = wmax_game_shift_status(WMAX_OPERATION_TOGGLE_GAME_SHIFT,
- &gmode_status);
-
- if (ret < 0)
- return ret;
- }
- }
-
- return wmax_thermal_control(supported_thermal_profiles[profile]);
-}
-
-static int thermal_profile_probe(void *drvdata, unsigned long *choices)
-{
- enum platform_profile_option profile;
- enum wmax_thermal_mode mode;
- u8 sys_desc[4];
- u32 first_mode;
- u32 out_data;
- int ret;
-
- ret = wmax_thermal_information(WMAX_OPERATION_SYS_DESCRIPTION,
- 0, (u32 *) &sys_desc);
- if (ret < 0)
- return ret;
-
- first_mode = sys_desc[0] + sys_desc[1];
-
- for (u32 i = 0; i < sys_desc[3]; i++) {
- ret = wmax_thermal_information(WMAX_OPERATION_LIST_IDS,
- i + first_mode, &out_data);
-
- if (ret == -EIO)
- return ret;
-
- if (ret == -EBADRQC)
- break;
-
- if (!is_wmax_thermal_code(out_data))
- continue;
-
- mode = out_data & WMAX_THERMAL_MODE_MASK;
- profile = wmax_mode_to_platform_profile[mode];
- supported_thermal_profiles[profile] = out_data;
-
- set_bit(profile, choices);
- }
-
- if (bitmap_empty(choices, PLATFORM_PROFILE_LAST))
- return -ENODEV;
-
- if (quirks->gmode) {
- supported_thermal_profiles[PLATFORM_PROFILE_PERFORMANCE] =
- WMAX_THERMAL_MODE_GMODE;
-
- set_bit(PLATFORM_PROFILE_PERFORMANCE, choices);
- }
-
- return 0;
-}
-
-static const struct platform_profile_ops awcc_platform_profile_ops = {
- .probe = thermal_profile_probe,
- .profile_get = thermal_profile_get,
- .profile_set = thermal_profile_set,
-};
-
-static int create_thermal_profile(struct platform_device *platform_device)
-{
- struct device *ppdev;
-
- ppdev = devm_platform_profile_register(&platform_device->dev, "alienware-wmi",
- NULL, &awcc_platform_profile_ops);
-
- return PTR_ERR_OR_ZERO(ppdev);
-}
-
-/*
- * Platform Driver
- */
-static const struct attribute_group *alienfx_groups[] = {
- &zone_attribute_group,
- &hdmi_attribute_group,
- &amplifier_attribute_group,
- &deepsleep_attribute_group,
- NULL
-};
-
-static struct platform_driver platform_driver = {
- .driver = {
- .name = "alienware-wmi",
- .dev_groups = alienfx_groups,
- },
-};
-
-static int __init alienware_wmi_init(void)
-{
- int ret;
-
- if (wmi_has_guid(LEGACY_CONTROL_GUID))
- interface = LEGACY;
- else if (wmi_has_guid(WMAX_CONTROL_GUID))
- interface = WMAX;
- else {
- pr_warn("alienware-wmi: No known WMI GUID found\n");
- return -ENODEV;
- }
-
- dmi_check_system(alienware_quirks);
- if (quirks == NULL)
- quirks = &quirk_unknown;
-
- if (force_platform_profile)
- quirks->thermal = true;
-
- if (force_gmode) {
- if (quirks->thermal)
- quirks->gmode = true;
- else
- pr_warn("force_gmode requires platform profile support\n");
- }
-
- ret = platform_driver_register(&platform_driver);
- if (ret)
- goto fail_platform_driver;
- platform_device = platform_device_alloc("alienware-wmi", PLATFORM_DEVID_NONE);
- if (!platform_device) {
- ret = -ENOMEM;
- goto fail_platform_device1;
- }
- ret = platform_device_add(platform_device);
- if (ret)
- goto fail_platform_device2;
-
- if (quirks->thermal) {
- ret = create_thermal_profile(platform_device);
- if (ret)
- goto fail_prep_thermal_profile;
- }
-
- if (quirks->num_zones > 0) {
- ret = alienware_zone_init(platform_device);
- if (ret)
- goto fail_prep_zones;
- }
-
- return 0;
-
-fail_prep_zones:
- alienware_zone_exit(platform_device);
-fail_prep_thermal_profile:
- platform_device_del(platform_device);
-fail_platform_device2:
- platform_device_put(platform_device);
-fail_platform_device1:
- platform_driver_unregister(&platform_driver);
-fail_platform_driver:
- return ret;
-}
-
-module_init(alienware_wmi_init);
-
-static void __exit alienware_wmi_exit(void)
-{
- alienware_zone_exit(platform_device);
- platform_device_unregister(platform_device);
- platform_driver_unregister(&platform_driver);
-}
-
-module_exit(alienware_wmi_exit);
diff --git a/drivers/platform/x86/dell/alienware-wmi.h b/drivers/platform/x86/dell/alienware-wmi.h
new file mode 100644
index 000000000000..68d4242211ae
--- /dev/null
+++ b/drivers/platform/x86/dell/alienware-wmi.h
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Alienware WMI special features driver
+ *
+ * Copyright (C) 2014 Dell Inc <Dell.Client.Kernel@dell.com>
+ * Copyright (C) 2024 Kurt Borja <kuurtb@gmail.com>
+ */
+
+#ifndef _ALIENWARE_WMI_H_
+#define _ALIENWARE_WMI_H_
+
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+#include <linux/wmi.h>
+
+#define LEGACY_CONTROL_GUID "A90597CE-A997-11DA-B012-B622A1EF5492"
+#define LEGACY_POWER_CONTROL_GUID "A80593CE-A997-11DA-B012-B622A1EF5492"
+#define WMAX_CONTROL_GUID "A70591CE-A997-11DA-B012-B622A1EF5492"
+
+enum INTERFACE_FLAGS {
+ LEGACY,
+ WMAX,
+};
+
+enum LEGACY_CONTROL_STATES {
+ LEGACY_RUNNING = 1,
+ LEGACY_BOOTING = 0,
+ LEGACY_SUSPEND = 3,
+};
+
+enum WMAX_CONTROL_STATES {
+ WMAX_RUNNING = 0xFF,
+ WMAX_BOOTING = 0,
+ WMAX_SUSPEND = 3,
+};
+
+struct alienfx_quirks {
+ u8 num_zones;
+ bool hdmi_mux;
+ bool amplifier;
+ bool deepslp;
+};
+
+struct color_platform {
+ u8 blue;
+ u8 green;
+ u8 red;
+} __packed;
+
+struct alienfx_priv {
+ struct platform_device *pdev;
+ struct led_classdev global_led;
+ struct color_platform colors[4];
+ u8 global_brightness;
+ u8 lighting_control_state;
+};
+
+struct alienfx_ops {
+ int (*upd_led)(struct alienfx_priv *priv, struct wmi_device *wdev,
+ u8 location);
+ int (*upd_brightness)(struct alienfx_priv *priv, struct wmi_device *wdev,
+ u8 brightness);
+};
+
+struct alienfx_platdata {
+ struct wmi_device *wdev;
+ struct alienfx_ops ops;
+};
+
+extern u8 alienware_interface;
+extern struct alienfx_quirks *alienfx;
+
+int alienware_wmi_command(struct wmi_device *wdev, u32 method_id,
+ void *in_args, size_t in_size, u32 *out_data);
+
+int alienware_alienfx_setup(struct alienfx_platdata *pdata);
+
+#if IS_ENABLED(CONFIG_ALIENWARE_WMI_LEGACY)
+int __init alienware_legacy_wmi_init(void);
+void __exit alienware_legacy_wmi_exit(void);
+#else
+static inline int alienware_legacy_wmi_init(void)
+{
+ return -ENODEV;
+}
+
+static inline void alienware_legacy_wmi_exit(void)
+{
+}
+#endif
+
+#if IS_ENABLED(CONFIG_ALIENWARE_WMI_WMAX)
+extern const struct attribute_group wmax_hdmi_attribute_group;
+extern const struct attribute_group wmax_amplifier_attribute_group;
+extern const struct attribute_group wmax_deepsleep_attribute_group;
+
+#define WMAX_DEV_GROUPS &wmax_hdmi_attribute_group, \
+ &wmax_amplifier_attribute_group, \
+ &wmax_deepsleep_attribute_group,
+
+int __init alienware_wmax_wmi_init(void);
+void __exit alienware_wmax_wmi_exit(void);
+#else
+#define WMAX_DEV_GROUPS
+
+static inline int alienware_wmax_wmi_init(void)
+{
+ return -ENODEV;
+}
+
+
+static inline void alienware_wmax_wmi_exit(void)
+{
+}
+#endif
+
+#endif
diff --git a/drivers/platform/x86/dell/dell-uart-backlight.c b/drivers/platform/x86/dell/dell-uart-backlight.c
index 50002ef13d5d..8f868f845350 100644
--- a/drivers/platform/x86/dell/dell-uart-backlight.c
+++ b/drivers/platform/x86/dell/dell-uart-backlight.c
@@ -325,7 +325,7 @@ static int dell_uart_bl_serdev_probe(struct serdev_device *serdev)
return PTR_ERR_OR_ZERO(dell_bl->bl);
}
-struct serdev_device_driver dell_uart_bl_serdev_driver = {
+static struct serdev_device_driver dell_uart_bl_serdev_driver = {
.probe = dell_uart_bl_serdev_probe,
.driver = {
.name = KBUILD_MODNAME,
diff --git a/drivers/platform/x86/dell/dell-wmi-ddv.c b/drivers/platform/x86/dell/dell-wmi-ddv.c
index e75cd6e1efe6..f27739da380f 100644
--- a/drivers/platform/x86/dell/dell-wmi-ddv.c
+++ b/drivers/platform/x86/dell/dell-wmi-ddv.c
@@ -104,7 +104,6 @@ struct dell_wmi_ddv_sensors {
struct dell_wmi_ddv_data {
struct acpi_battery_hook hook;
- struct device_attribute temp_attr;
struct device_attribute eppid_attr;
struct dell_wmi_ddv_sensors fans;
struct dell_wmi_ddv_sensors temps;
@@ -651,24 +650,6 @@ static int dell_wmi_ddv_battery_index(struct acpi_device *acpi_dev, u32 *index)
return kstrtou32(uid_str, 10, index);
}
-static ssize_t temp_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct dell_wmi_ddv_data *data = container_of(attr, struct dell_wmi_ddv_data, temp_attr);
- u32 index, value;
- int ret;
-
- ret = dell_wmi_ddv_battery_index(to_acpi_device(dev->parent), &index);
- if (ret < 0)
- return ret;
-
- ret = dell_wmi_ddv_query_integer(data->wdev, DELL_DDV_BATTERY_TEMPERATURE, index, &value);
- if (ret < 0)
- return ret;
-
- /* Use 2731 instead of 2731.5 to avoid unnecessary rounding */
- return sysfs_emit(buf, "%d\n", value - 2731);
-}
-
static ssize_t eppid_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct dell_wmi_ddv_data *data = container_of(attr, struct dell_wmi_ddv_data, eppid_attr);
@@ -695,6 +676,46 @@ static ssize_t eppid_show(struct device *dev, struct device_attribute *attr, cha
return ret;
}
+static int dell_wmi_ddv_get_property(struct power_supply *psy, const struct power_supply_ext *ext,
+ void *drvdata, enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct dell_wmi_ddv_data *data = drvdata;
+ u32 index, value;
+ int ret;
+
+ ret = dell_wmi_ddv_battery_index(to_acpi_device(psy->dev.parent), &index);
+ if (ret < 0)
+ return ret;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_TEMP:
+ ret = dell_wmi_ddv_query_integer(data->wdev, DELL_DDV_BATTERY_TEMPERATURE, index,
+ &value);
+ if (ret < 0)
+ return ret;
+
+ /* Use 2732 instead of 2731.5 to avoid unnecessary rounding and to emulate
+ * the behaviour of the OEM application which seems to round down the result.
+ */
+ val->intval = value - 2732;
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+static const enum power_supply_property dell_wmi_ddv_properties[] = {
+ POWER_SUPPLY_PROP_TEMP,
+};
+
+static const struct power_supply_ext dell_wmi_ddv_extension = {
+ .name = DRIVER_NAME,
+ .properties = dell_wmi_ddv_properties,
+ .num_properties = ARRAY_SIZE(dell_wmi_ddv_properties),
+ .get_property = dell_wmi_ddv_get_property,
+};
+
static int dell_wmi_ddv_add_battery(struct power_supply *battery, struct acpi_battery_hook *hook)
{
struct dell_wmi_ddv_data *data = container_of(hook, struct dell_wmi_ddv_data, hook);
@@ -706,13 +727,14 @@ static int dell_wmi_ddv_add_battery(struct power_supply *battery, struct acpi_ba
if (ret < 0)
return 0;
- ret = device_create_file(&battery->dev, &data->temp_attr);
+ ret = device_create_file(&battery->dev, &data->eppid_attr);
if (ret < 0)
return ret;
- ret = device_create_file(&battery->dev, &data->eppid_attr);
+ ret = power_supply_register_extension(battery, &dell_wmi_ddv_extension, &data->wdev->dev,
+ data);
if (ret < 0) {
- device_remove_file(&battery->dev, &data->temp_attr);
+ device_remove_file(&battery->dev, &data->eppid_attr);
return ret;
}
@@ -724,38 +746,24 @@ static int dell_wmi_ddv_remove_battery(struct power_supply *battery, struct acpi
{
struct dell_wmi_ddv_data *data = container_of(hook, struct dell_wmi_ddv_data, hook);
- device_remove_file(&battery->dev, &data->temp_attr);
device_remove_file(&battery->dev, &data->eppid_attr);
+ power_supply_unregister_extension(battery, &dell_wmi_ddv_extension);
return 0;
}
-static void dell_wmi_ddv_battery_remove(void *data)
-{
- struct acpi_battery_hook *hook = data;
-
- battery_hook_unregister(hook);
-}
-
static int dell_wmi_ddv_battery_add(struct dell_wmi_ddv_data *data)
{
data->hook.name = "Dell DDV Battery Extension";
data->hook.add_battery = dell_wmi_ddv_add_battery;
data->hook.remove_battery = dell_wmi_ddv_remove_battery;
- sysfs_attr_init(&data->temp_attr.attr);
- data->temp_attr.attr.name = "temp";
- data->temp_attr.attr.mode = 0444;
- data->temp_attr.show = temp_show;
-
sysfs_attr_init(&data->eppid_attr.attr);
data->eppid_attr.attr.name = "eppid";
data->eppid_attr.attr.mode = 0444;
data->eppid_attr.show = eppid_show;
- battery_hook_register(&data->hook);
-
- return devm_add_action_or_reset(&data->wdev->dev, dell_wmi_ddv_battery_remove, &data->hook);
+ return devm_battery_hook_register(&data->wdev->dev, &data->hook);
}
static int dell_wmi_ddv_buffer_read(struct seq_file *seq, enum dell_ddv_method method)
diff --git a/drivers/platform/x86/dell/dell-wmi-sysman/Makefile b/drivers/platform/x86/dell/dell-wmi-sysman/Makefile
index 825fb2fbeea8..0a6df449e222 100644
--- a/drivers/platform/x86/dell/dell-wmi-sysman/Makefile
+++ b/drivers/platform/x86/dell/dell-wmi-sysman/Makefile
@@ -1,5 +1,5 @@
obj-$(CONFIG_DELL_WMI_SYSMAN) += dell-wmi-sysman.o
-dell-wmi-sysman-objs := sysman.o \
+dell-wmi-sysman-y := sysman.o \
enum-attributes.o \
int-attributes.o \
string-attributes.o \
diff --git a/drivers/platform/x86/hp/hp-bioscfg/Makefile b/drivers/platform/x86/hp/hp-bioscfg/Makefile
index 67be0d917753..7d23649b34dc 100644
--- a/drivers/platform/x86/hp/hp-bioscfg/Makefile
+++ b/drivers/platform/x86/hp/hp-bioscfg/Makefile
@@ -1,6 +1,6 @@
obj-$(CONFIG_HP_BIOSCFG) := hp-bioscfg.o
-hp-bioscfg-objs := bioscfg.o \
+hp-bioscfg-y := bioscfg.o \
biosattr-interface.o \
enum-attributes.o \
int-attributes.o \
diff --git a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c
index 0b277b7e37dd..13237890fc92 100644
--- a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c
+++ b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c
@@ -388,16 +388,13 @@ union acpi_object *hp_get_wmiobj_pointer(int instance_id, const char *guid_strin
*/
int hp_get_instance_count(const char *guid_string)
{
- union acpi_object *wmi_obj = NULL;
- int i = 0;
+ int ret;
- do {
- kfree(wmi_obj);
- wmi_obj = hp_get_wmiobj_pointer(i, guid_string);
- i++;
- } while (wmi_obj);
+ ret = wmi_instance_count(guid_string);
+ if (ret < 0)
+ return 0;
- return i - 1;
+ return ret;
}
/**
@@ -448,7 +445,7 @@ int hp_convert_hexstr_to_str(const char *input, u32 input_len, char **str, int *
return -ENOMEM;
for (i = 0; i < input_len; i += 5) {
- strncpy(tmp, input + i, strlen(tmp));
+ strscpy(tmp, input + i);
if (kstrtol(tmp, 16, &ch) == 0) {
// escape char
if (ch == '\\' ||
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
index 30bd366d7b58..17a09b7784ed 100644
--- a/drivers/platform/x86/ideapad-laptop.c
+++ b/drivers/platform/x86/ideapad-laptop.c
@@ -854,6 +854,7 @@ static const struct attribute_group ideapad_attribute_group = {
.is_visible = ideapad_is_visible,
.attrs = ideapad_attributes
};
+__ATTRIBUTE_GROUPS(ideapad_attribute);
/*
* DYTC Platform profile
@@ -1245,21 +1246,6 @@ static void ideapad_unregister_rfkill(struct ideapad_private *priv, int dev)
}
/*
- * Platform device
- */
-static int ideapad_sysfs_init(struct ideapad_private *priv)
-{
- return device_add_group(&priv->platform_device->dev,
- &ideapad_attribute_group);
-}
-
-static void ideapad_sysfs_exit(struct ideapad_private *priv)
-{
- device_remove_group(&priv->platform_device->dev,
- &ideapad_attribute_group);
-}
-
-/*
* input device
*/
#define IDEAPAD_WMI_KEY 0x100
@@ -2175,10 +2161,6 @@ static int ideapad_acpi_add(struct platform_device *pdev)
ideapad_check_features(priv);
- err = ideapad_sysfs_init(priv);
- if (err)
- return err;
-
ideapad_debugfs_init(priv);
err = ideapad_input_init(priv);
@@ -2265,7 +2247,6 @@ backlight_failed:
input_failed:
ideapad_debugfs_exit(priv);
- ideapad_sysfs_exit(priv);
return err;
}
@@ -2293,7 +2274,6 @@ static void ideapad_acpi_remove(struct platform_device *pdev)
ideapad_kbd_bl_exit(priv);
ideapad_input_exit(priv);
ideapad_debugfs_exit(priv);
- ideapad_sysfs_exit(priv);
}
#ifdef CONFIG_PM_SLEEP
@@ -2325,6 +2305,7 @@ static struct platform_driver ideapad_acpi_driver = {
.name = "ideapad_acpi",
.pm = &ideapad_pm,
.acpi_match_table = ACPI_PTR(ideapad_device_ids),
+ .dev_groups = ideapad_attribute_groups,
},
};
diff --git a/drivers/platform/x86/intel/ifs/Makefile b/drivers/platform/x86/intel/ifs/Makefile
index 30f035ef5581..c3e417bce9b6 100644
--- a/drivers/platform/x86/intel/ifs/Makefile
+++ b/drivers/platform/x86/intel/ifs/Makefile
@@ -1,3 +1,3 @@
obj-$(CONFIG_INTEL_IFS) += intel_ifs.o
-intel_ifs-objs := core.o load.o runtest.o sysfs.o
+intel_ifs-y := core.o load.o runtest.o sysfs.o
diff --git a/drivers/platform/x86/intel/int3472/discrete.c b/drivers/platform/x86/intel/int3472/discrete.c
index 092252eb95a8..30ff8f3ea1f5 100644
--- a/drivers/platform/x86/intel/int3472/discrete.c
+++ b/drivers/platform/x86/intel/int3472/discrete.c
@@ -56,7 +56,7 @@ static void skl_int3472_log_sensor_module_name(struct int3472_discrete_device *i
static int skl_int3472_fill_gpiod_lookup(struct gpiod_lookup *table_entry,
struct acpi_resource_gpio *agpio,
- const char *func, unsigned long gpio_flags)
+ const char *con_id, unsigned long gpio_flags)
{
char *path = agpio->resource_source.string_ptr;
struct acpi_device *adev;
@@ -71,14 +71,14 @@ static int skl_int3472_fill_gpiod_lookup(struct gpiod_lookup *table_entry,
if (!adev)
return -ENODEV;
- *table_entry = GPIO_LOOKUP(acpi_dev_name(adev), agpio->pin_table[0], func, gpio_flags);
+ *table_entry = GPIO_LOOKUP(acpi_dev_name(adev), agpio->pin_table[0], con_id, gpio_flags);
return 0;
}
static int skl_int3472_map_gpio_to_sensor(struct int3472_discrete_device *int3472,
struct acpi_resource_gpio *agpio,
- const char *func, unsigned long gpio_flags)
+ const char *con_id, unsigned long gpio_flags)
{
int ret;
@@ -88,7 +88,7 @@ static int skl_int3472_map_gpio_to_sensor(struct int3472_discrete_device *int347
}
ret = skl_int3472_fill_gpiod_lookup(&int3472->gpios.table[int3472->n_sensor_gpios],
- agpio, func, gpio_flags);
+ agpio, con_id, gpio_flags);
if (ret)
return ret;
@@ -101,7 +101,7 @@ static int skl_int3472_map_gpio_to_sensor(struct int3472_discrete_device *int347
static struct gpio_desc *
skl_int3472_gpiod_get_from_temp_lookup(struct int3472_discrete_device *int3472,
struct acpi_resource_gpio *agpio,
- const char *func, unsigned long gpio_flags)
+ const char *con_id, unsigned long gpio_flags)
{
struct gpio_desc *desc;
int ret;
@@ -112,12 +112,12 @@ skl_int3472_gpiod_get_from_temp_lookup(struct int3472_discrete_device *int3472,
return ERR_PTR(-ENOMEM);
lookup->dev_id = dev_name(int3472->dev);
- ret = skl_int3472_fill_gpiod_lookup(&lookup->table[0], agpio, func, gpio_flags);
+ ret = skl_int3472_fill_gpiod_lookup(&lookup->table[0], agpio, con_id, gpio_flags);
if (ret)
return ERR_PTR(ret);
gpiod_add_lookup_table(lookup);
- desc = devm_gpiod_get(int3472->dev, func, GPIOD_OUT_LOW);
+ desc = devm_gpiod_get(int3472->dev, con_id, GPIOD_OUT_LOW);
gpiod_remove_lookup_table(lookup);
return desc;
@@ -129,7 +129,7 @@ skl_int3472_gpiod_get_from_temp_lookup(struct int3472_discrete_device *int3472,
* @hid: The ACPI HID of the device without the instance number e.g. INT347E
* @type_from: The GPIO type from ACPI ?SDT
* @type_to: The assigned GPIO type, typically same as @type_from
- * @func: The function, e.g. "enable"
+ * @con_id: The name of the GPIO for the device
* @polarity_low: GPIO_ACTIVE_LOW true if the @polarity_low is true,
* GPIO_ACTIVE_HIGH otherwise
*/
@@ -138,15 +138,15 @@ struct int3472_gpio_map {
u8 type_from;
u8 type_to;
bool polarity_low;
- const char *func;
+ const char *con_id;
};
static const struct int3472_gpio_map int3472_gpio_map[] = {
{ "INT347E", INT3472_GPIO_TYPE_RESET, INT3472_GPIO_TYPE_RESET, false, "enable" },
};
-static void int3472_get_func_and_polarity(struct acpi_device *adev, u8 *type,
- const char **func, unsigned long *gpio_flags)
+static void int3472_get_con_id_and_polarity(struct acpi_device *adev, u8 *type,
+ const char **con_id, unsigned long *gpio_flags)
{
unsigned int i;
@@ -165,33 +165,33 @@ static void int3472_get_func_and_polarity(struct acpi_device *adev, u8 *type,
*type = int3472_gpio_map[i].type_to;
*gpio_flags = int3472_gpio_map[i].polarity_low ?
GPIO_ACTIVE_LOW : GPIO_ACTIVE_HIGH;
- *func = int3472_gpio_map[i].func;
+ *con_id = int3472_gpio_map[i].con_id;
return;
}
switch (*type) {
case INT3472_GPIO_TYPE_RESET:
- *func = "reset";
+ *con_id = "reset";
*gpio_flags = GPIO_ACTIVE_LOW;
break;
case INT3472_GPIO_TYPE_POWERDOWN:
- *func = "powerdown";
+ *con_id = "powerdown";
*gpio_flags = GPIO_ACTIVE_LOW;
break;
case INT3472_GPIO_TYPE_CLK_ENABLE:
- *func = "clk-enable";
+ *con_id = "clk-enable";
*gpio_flags = GPIO_ACTIVE_HIGH;
break;
case INT3472_GPIO_TYPE_PRIVACY_LED:
- *func = "privacy-led";
+ *con_id = "privacy-led";
*gpio_flags = GPIO_ACTIVE_HIGH;
break;
case INT3472_GPIO_TYPE_POWER_ENABLE:
- *func = "power-enable";
+ *con_id = "power-enable";
*gpio_flags = GPIO_ACTIVE_HIGH;
break;
default:
- *func = "unknown";
+ *con_id = "unknown";
*gpio_flags = GPIO_ACTIVE_HIGH;
break;
}
@@ -238,7 +238,7 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares,
union acpi_object *obj;
struct gpio_desc *gpio;
const char *err_msg;
- const char *func;
+ const char *con_id;
unsigned long gpio_flags;
int ret;
@@ -262,26 +262,26 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares,
type = FIELD_GET(INT3472_GPIO_DSM_TYPE, obj->integer.value);
- int3472_get_func_and_polarity(int3472->sensor, &type, &func, &gpio_flags);
+ int3472_get_con_id_and_polarity(int3472->sensor, &type, &con_id, &gpio_flags);
pin = FIELD_GET(INT3472_GPIO_DSM_PIN, obj->integer.value);
/* Pin field is not really used under Windows and wraps around at 8 bits */
if (pin != (agpio->pin_table[0] & 0xff))
dev_dbg(int3472->dev, FW_BUG "%s %s pin number mismatch _DSM %d resource %d\n",
- func, agpio->resource_source.string_ptr, pin, agpio->pin_table[0]);
+ con_id, agpio->resource_source.string_ptr, pin, agpio->pin_table[0]);
active_value = FIELD_GET(INT3472_GPIO_DSM_SENSOR_ON_VAL, obj->integer.value);
if (!active_value)
gpio_flags ^= GPIO_ACTIVE_LOW;
- dev_dbg(int3472->dev, "%s %s pin %d active-%s\n", func,
+ dev_dbg(int3472->dev, "%s %s pin %d active-%s\n", con_id,
agpio->resource_source.string_ptr, agpio->pin_table[0],
str_high_low(gpio_flags == GPIO_ACTIVE_HIGH));
switch (type) {
case INT3472_GPIO_TYPE_RESET:
case INT3472_GPIO_TYPE_POWERDOWN:
- ret = skl_int3472_map_gpio_to_sensor(int3472, agpio, func, gpio_flags);
+ ret = skl_int3472_map_gpio_to_sensor(int3472, agpio, con_id, gpio_flags);
if (ret)
err_msg = "Failed to map GPIO pin to sensor\n";
@@ -289,7 +289,7 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares,
case INT3472_GPIO_TYPE_CLK_ENABLE:
case INT3472_GPIO_TYPE_PRIVACY_LED:
case INT3472_GPIO_TYPE_POWER_ENABLE:
- gpio = skl_int3472_gpiod_get_from_temp_lookup(int3472, agpio, func, gpio_flags);
+ gpio = skl_int3472_gpiod_get_from_temp_lookup(int3472, agpio, con_id, gpio_flags);
if (IS_ERR(gpio)) {
ret = PTR_ERR(gpio);
err_msg = "Failed to get GPIO\n";
diff --git a/drivers/platform/x86/intel/pmc/Makefile b/drivers/platform/x86/intel/pmc/Makefile
index 389e5419dadf..b148b40d09f5 100644
--- a/drivers/platform/x86/intel/pmc/Makefile
+++ b/drivers/platform/x86/intel/pmc/Makefile
@@ -4,7 +4,7 @@
#
intel_pmc_core-y := core.o core_ssram.o spt.o cnp.o \
- icl.o tgl.o adl.o mtl.o arl.o lnl.o
+ icl.o tgl.o adl.o mtl.o arl.o lnl.o ptl.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/adl.c b/drivers/platform/x86/intel/pmc/adl.c
index e7878558fd90..9e7dfd6e3310 100644
--- a/drivers/platform/x86/intel/pmc/adl.c
+++ b/drivers/platform/x86/intel/pmc/adl.c
@@ -11,7 +11,7 @@
#include "core.h"
/* Alder Lake: PGD PFET Enable Ack Status Register(s) bitmap */
-const struct pmc_bit_map adl_pfear_map[] = {
+static const struct pmc_bit_map adl_pfear_map[] = {
{"SPI/eSPI", BIT(2)},
{"XHCI", BIT(3)},
{"SPA", BIT(4)},
@@ -54,7 +54,7 @@ const struct pmc_bit_map adl_pfear_map[] = {
{}
};
-const struct pmc_bit_map *ext_adl_pfear_map[] = {
+static const struct pmc_bit_map *ext_adl_pfear_map[] = {
/*
* Check intel_pmc_core_ids[] users of cnp_reg_map for
* a list of core SoCs using this.
@@ -63,7 +63,7 @@ const struct pmc_bit_map *ext_adl_pfear_map[] = {
NULL
};
-const struct pmc_bit_map adl_ltr_show_map[] = {
+static const struct pmc_bit_map adl_ltr_show_map[] = {
{"SOUTHPORT_A", CNP_PMC_LTR_SPA},
{"SOUTHPORT_B", CNP_PMC_LTR_SPB},
{"SATA", CNP_PMC_LTR_SATA},
@@ -100,7 +100,7 @@ const struct pmc_bit_map adl_ltr_show_map[] = {
{}
};
-const struct pmc_bit_map adl_clocksource_status_map[] = {
+static const struct pmc_bit_map adl_clocksource_status_map[] = {
{"CLKPART1_OFF_STS", BIT(0)},
{"CLKPART2_OFF_STS", BIT(1)},
{"CLKPART3_OFF_STS", BIT(2)},
@@ -128,7 +128,7 @@ const struct pmc_bit_map adl_clocksource_status_map[] = {
{}
};
-const struct pmc_bit_map adl_power_gating_status_0_map[] = {
+static const struct pmc_bit_map adl_power_gating_status_0_map[] = {
{"PMC_PGD0_PG_STS", BIT(0)},
{"DMI_PGD0_PG_STS", BIT(1)},
{"ESPISPI_PGD0_PG_STS", BIT(2)},
@@ -158,7 +158,7 @@ const struct pmc_bit_map adl_power_gating_status_0_map[] = {
{}
};
-const struct pmc_bit_map adl_power_gating_status_1_map[] = {
+static const struct pmc_bit_map adl_power_gating_status_1_map[] = {
{"USBR0_PGD0_PG_STS", BIT(0)},
{"SMT1_PGD0_PG_STS", BIT(2)},
{"CSMERTC_PGD0_PG_STS", BIT(6)},
@@ -170,14 +170,14 @@ const struct pmc_bit_map adl_power_gating_status_1_map[] = {
{}
};
-const struct pmc_bit_map adl_power_gating_status_2_map[] = {
+static const struct pmc_bit_map adl_power_gating_status_2_map[] = {
{"THC0_PGD0_PG_STS", BIT(7)},
{"THC1_PGD0_PG_STS", BIT(8)},
{"SPF_PGD0_PG_STS", BIT(14)},
{}
};
-const struct pmc_bit_map adl_d3_status_0_map[] = {
+static const struct pmc_bit_map adl_d3_status_0_map[] = {
{"ISH_D3_STS", BIT(2)},
{"LPSS_D3_STS", BIT(3)},
{"XDCI_D3_STS", BIT(4)},
@@ -193,13 +193,13 @@ const struct pmc_bit_map adl_d3_status_0_map[] = {
{}
};
-const struct pmc_bit_map adl_d3_status_1_map[] = {
+static const struct pmc_bit_map adl_d3_status_1_map[] = {
{"GBE_D3_STS", BIT(19)},
{"CNVI_D3_STS", BIT(27)},
{}
};
-const struct pmc_bit_map adl_d3_status_2_map[] = {
+static const struct pmc_bit_map adl_d3_status_2_map[] = {
{"CSMERTC_D3_STS", BIT(1)},
{"CSE_D3_STS", BIT(4)},
{"KVMCC_D3_STS", BIT(5)},
@@ -210,20 +210,20 @@ const struct pmc_bit_map adl_d3_status_2_map[] = {
{}
};
-const struct pmc_bit_map adl_d3_status_3_map[] = {
+static const struct pmc_bit_map adl_d3_status_3_map[] = {
{"THC0_D3_STS", BIT(14)},
{"THC1_D3_STS", BIT(15)},
{}
};
-const struct pmc_bit_map adl_vnn_req_status_0_map[] = {
+static const struct pmc_bit_map adl_vnn_req_status_0_map[] = {
{"ISH_VNN_REQ_STS", BIT(2)},
{"ESPISPI_VNN_REQ_STS", BIT(18)},
{"DSP_VNN_REQ_STS", BIT(19)},
{}
};
-const struct pmc_bit_map adl_vnn_req_status_1_map[] = {
+static const struct pmc_bit_map adl_vnn_req_status_1_map[] = {
{"NPK_VNN_REQ_STS", BIT(4)},
{"EXI_VNN_REQ_STS", BIT(9)},
{"GBE_VNN_REQ_STS", BIT(19)},
@@ -232,7 +232,7 @@ const struct pmc_bit_map adl_vnn_req_status_1_map[] = {
{}
};
-const struct pmc_bit_map adl_vnn_req_status_2_map[] = {
+static const struct pmc_bit_map adl_vnn_req_status_2_map[] = {
{"CSMERTC_VNN_REQ_STS", BIT(1)},
{"CSE_VNN_REQ_STS", BIT(4)},
{"SMT1_VNN_REQ_STS", BIT(8)},
@@ -245,12 +245,12 @@ const struct pmc_bit_map adl_vnn_req_status_2_map[] = {
{}
};
-const struct pmc_bit_map adl_vnn_req_status_3_map[] = {
+static const struct pmc_bit_map adl_vnn_req_status_3_map[] = {
{"GPIOCOM5_VNN_REQ_STS", BIT(11)},
{}
};
-const struct pmc_bit_map adl_vnn_misc_status_map[] = {
+static const struct pmc_bit_map adl_vnn_misc_status_map[] = {
{"CPU_C10_REQ_STS", BIT(0)},
{"PCIe_LPM_En_REQ_STS", BIT(3)},
{"ITH_REQ_STS", BIT(5)},
@@ -265,7 +265,7 @@ const struct pmc_bit_map adl_vnn_misc_status_map[] = {
{}
};
-const struct pmc_bit_map *adl_lpm_maps[] = {
+static const struct pmc_bit_map *adl_lpm_maps[] = {
adl_clocksource_status_map,
adl_power_gating_status_0_map,
adl_power_gating_status_1_map,
@@ -311,20 +311,8 @@ const struct pmc_reg_map adl_reg_map = {
.pson_residency_counter_step = TGL_PSON_RES_COUNTER_STEP,
};
-int adl_core_init(struct pmc_dev *pmcdev)
-{
- struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN];
- int ret;
-
- pmcdev->suspend = cnl_suspend;
- pmcdev->resume = cnl_resume;
-
- pmc->map = &adl_reg_map;
- ret = get_primary_reg_base(pmc);
- if (ret)
- return ret;
-
- pmc_core_get_low_power_modes(pmcdev);
-
- return 0;
-}
+struct pmc_dev_info adl_pmc_dev = {
+ .map = &adl_reg_map,
+ .suspend = cnl_suspend,
+ .resume = cnl_resume,
+};
diff --git a/drivers/platform/x86/intel/pmc/arl.c b/drivers/platform/x86/intel/pmc/arl.c
index 05dec4f5019f..320993bd6d31 100644
--- a/drivers/platform/x86/intel/pmc/arl.c
+++ b/drivers/platform/x86/intel/pmc/arl.c
@@ -16,10 +16,11 @@
#define IOEP_LPM_REQ_GUID 0x5077612
#define SOCS_LPM_REQ_GUID 0x8478657
#define PCHS_LPM_REQ_GUID 0x9684572
+#define SOCM_LPM_REQ_GUID 0x2625030
static const u8 ARL_LPM_REG_INDEX[] = {0, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20};
-const struct pmc_bit_map arl_socs_ltr_show_map[] = {
+static const struct pmc_bit_map arl_socs_ltr_show_map[] = {
{"SOUTHPORT_A", CNP_PMC_LTR_SPA},
{"SOUTHPORT_B", CNP_PMC_LTR_SPB},
{"SATA", CNP_PMC_LTR_SATA},
@@ -59,7 +60,7 @@ const struct pmc_bit_map arl_socs_ltr_show_map[] = {
{}
};
-const struct pmc_bit_map arl_socs_clocksource_status_map[] = {
+static const struct pmc_bit_map arl_socs_clocksource_status_map[] = {
{"AON2_OFF_STS", BIT(0)},
{"AON3_OFF_STS", BIT(1)},
{"AON4_OFF_STS", BIT(2)},
@@ -87,7 +88,7 @@ const struct pmc_bit_map arl_socs_clocksource_status_map[] = {
{}
};
-const struct pmc_bit_map arl_socs_power_gating_status_0_map[] = {
+static const struct pmc_bit_map arl_socs_power_gating_status_0_map[] = {
{"PMC_PGD0_PG_STS", BIT(0)},
{"DMI_PGD0_PG_STS", BIT(1)},
{"ESPISPI_PGD0_PG_STS", BIT(2)},
@@ -123,7 +124,7 @@ const struct pmc_bit_map arl_socs_power_gating_status_0_map[] = {
{}
};
-const struct pmc_bit_map arl_socs_power_gating_status_1_map[] = {
+static const struct pmc_bit_map arl_socs_power_gating_status_1_map[] = {
{"USBR0_PGD0_PG_STS", BIT(0)},
{"SUSRAM_PGD0_PG_STS", BIT(1)},
{"SMT1_PGD0_PG_STS", BIT(2)},
@@ -159,7 +160,7 @@ const struct pmc_bit_map arl_socs_power_gating_status_1_map[] = {
{}
};
-const struct pmc_bit_map arl_socs_power_gating_status_2_map[] = {
+static const struct pmc_bit_map arl_socs_power_gating_status_2_map[] = {
{"PSF8_PGD0_PG_STS", BIT(0)},
{"FIA_PGD0_PG_STS", BIT(1)},
{"SOC_D2D_PGD3_PG_STS", BIT(2)},
@@ -187,7 +188,7 @@ const struct pmc_bit_map arl_socs_power_gating_status_2_map[] = {
{}
};
-const struct pmc_bit_map arl_socs_d3_status_2_map[] = {
+static const struct pmc_bit_map arl_socs_d3_status_2_map[] = {
{"CSMERTC_D3_STS", BIT(1)},
{"SUSRAM_D3_STS", BIT(2)},
{"CSE_D3_STS", BIT(4)},
@@ -206,7 +207,7 @@ const struct pmc_bit_map arl_socs_d3_status_2_map[] = {
{}
};
-const struct pmc_bit_map arl_socs_d3_status_3_map[] = {
+static const struct pmc_bit_map arl_socs_d3_status_3_map[] = {
{"GBETSN_D3_STS", BIT(13)},
{"THC0_D3_STS", BIT(14)},
{"THC1_D3_STS", BIT(15)},
@@ -214,13 +215,13 @@ const struct pmc_bit_map arl_socs_d3_status_3_map[] = {
{}
};
-const struct pmc_bit_map arl_socs_vnn_req_status_3_map[] = {
+static const struct pmc_bit_map arl_socs_vnn_req_status_3_map[] = {
{"DTS0_VNN_REQ_STS", BIT(7)},
{"GPIOCOM5_VNN_REQ_STS", BIT(11)},
{}
};
-const struct pmc_bit_map *arl_socs_lpm_maps[] = {
+static const struct pmc_bit_map *arl_socs_lpm_maps[] = {
arl_socs_clocksource_status_map,
arl_socs_power_gating_status_0_map,
arl_socs_power_gating_status_1_map,
@@ -238,7 +239,7 @@ const struct pmc_bit_map *arl_socs_lpm_maps[] = {
NULL
};
-const struct pmc_bit_map arl_socs_pfear_map[] = {
+static const struct pmc_bit_map arl_socs_pfear_map[] = {
{"RSVD64", BIT(0)},
{"RSVD65", BIT(1)},
{"RSVD66", BIT(2)},
@@ -249,13 +250,13 @@ const struct pmc_bit_map arl_socs_pfear_map[] = {
{}
};
-const struct pmc_bit_map *ext_arl_socs_pfear_map[] = {
+static const struct pmc_bit_map *ext_arl_socs_pfear_map[] = {
mtl_socm_pfear_map,
arl_socs_pfear_map,
NULL
};
-const struct pmc_reg_map arl_socs_reg_map = {
+static const struct pmc_reg_map arl_socs_reg_map = {
.pfear_sts = ext_arl_socs_pfear_map,
.ppfear_buckets = ARL_SOCS_PPFEAR_NUM_ENTRIES,
.pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT,
@@ -283,7 +284,7 @@ const struct pmc_reg_map arl_socs_reg_map = {
.pson_residency_counter_step = TGL_PSON_RES_COUNTER_STEP,
};
-const struct pmc_bit_map arl_pchs_ltr_show_map[] = {
+static const struct pmc_bit_map arl_pchs_ltr_show_map[] = {
{"SOUTHPORT_A", CNP_PMC_LTR_SPA},
{"SOUTHPORT_B", CNP_PMC_LTR_SPB},
{"SATA", CNP_PMC_LTR_SATA},
@@ -323,7 +324,7 @@ const struct pmc_bit_map arl_pchs_ltr_show_map[] = {
{}
};
-const struct pmc_bit_map arl_pchs_clocksource_status_map[] = {
+static const struct pmc_bit_map arl_pchs_clocksource_status_map[] = {
{"AON2_OFF_STS", BIT(0)},
{"AON3_OFF_STS", BIT(1)},
{"AON4_OFF_STS", BIT(2)},
@@ -358,7 +359,7 @@ const struct pmc_bit_map arl_pchs_clocksource_status_map[] = {
{}
};
-const struct pmc_bit_map arl_pchs_power_gating_status_0_map[] = {
+static const struct pmc_bit_map arl_pchs_power_gating_status_0_map[] = {
{"PMC_PGD0_PG_STS", BIT(0)},
{"DMI_PGD0_PG_STS", BIT(1)},
{"ESPISPI_PGD0_PG_STS", BIT(2)},
@@ -394,7 +395,7 @@ const struct pmc_bit_map arl_pchs_power_gating_status_0_map[] = {
{}
};
-const struct pmc_bit_map arl_pchs_power_gating_status_1_map[] = {
+static const struct pmc_bit_map arl_pchs_power_gating_status_1_map[] = {
{"USBR0_PGD0_PG_STS", BIT(0)},
{"SUSRAM_PGD0_PG_STS", BIT(1)},
{"SMT1_PGD0_PG_STS", BIT(2)},
@@ -430,7 +431,7 @@ const struct pmc_bit_map arl_pchs_power_gating_status_1_map[] = {
{}
};
-const struct pmc_bit_map arl_pchs_power_gating_status_2_map[] = {
+static const struct pmc_bit_map arl_pchs_power_gating_status_2_map[] = {
{"U3FPW2_PGD0_PG_STS", BIT(0)},
{"FIA_PGD0_PG_STS", BIT(1)},
{"FIACPCB_X_PGD0_PG_STS", BIT(2)},
@@ -457,7 +458,7 @@ const struct pmc_bit_map arl_pchs_power_gating_status_2_map[] = {
{}
};
-const struct pmc_bit_map arl_pchs_d3_status_0_map[] = {
+static const struct pmc_bit_map arl_pchs_d3_status_0_map[] = {
{"SPF_D3_STS", BIT(0)},
{"LPSS_D3_STS", BIT(3)},
{"XDCI_D3_STS", BIT(4)},
@@ -474,7 +475,7 @@ const struct pmc_bit_map arl_pchs_d3_status_0_map[] = {
{}
};
-const struct pmc_bit_map arl_pchs_d3_status_1_map[] = {
+static const struct pmc_bit_map arl_pchs_d3_status_1_map[] = {
{"GBETSN1_D3_STS", BIT(14)},
{"GBE_D3_STS", BIT(19)},
{"ITSS_D3_STS", BIT(23)},
@@ -483,7 +484,7 @@ const struct pmc_bit_map arl_pchs_d3_status_1_map[] = {
{}
};
-const struct pmc_bit_map arl_pchs_d3_status_2_map[] = {
+static const struct pmc_bit_map arl_pchs_d3_status_2_map[] = {
{"CSMERTC_D3_STS", BIT(1)},
{"SUSRAM_D3_STS", BIT(2)},
{"CSE_D3_STS", BIT(4)},
@@ -504,7 +505,7 @@ const struct pmc_bit_map arl_pchs_d3_status_2_map[] = {
{}
};
-const struct pmc_bit_map arl_pchs_d3_status_3_map[] = {
+static const struct pmc_bit_map arl_pchs_d3_status_3_map[] = {
{"ESE_D3_STS", BIT(3)},
{"GBETSN_D3_STS", BIT(13)},
{"THC0_D3_STS", BIT(14)},
@@ -513,13 +514,13 @@ const struct pmc_bit_map arl_pchs_d3_status_3_map[] = {
{}
};
-const struct pmc_bit_map arl_pchs_vnn_req_status_0_map[] = {
+static const struct pmc_bit_map arl_pchs_vnn_req_status_0_map[] = {
{"FIA_VNN_REQ_STS", BIT(17)},
{"ESPISPI_VNN_REQ_STS", BIT(18)},
{}
};
-const struct pmc_bit_map arl_pchs_vnn_req_status_1_map[] = {
+static const struct pmc_bit_map arl_pchs_vnn_req_status_1_map[] = {
{"NPK_VNN_REQ_STS", BIT(4)},
{"DFXAGG_VNN_REQ_STS", BIT(8)},
{"EXI_VNN_REQ_STS", BIT(9)},
@@ -530,7 +531,7 @@ const struct pmc_bit_map arl_pchs_vnn_req_status_1_map[] = {
{}
};
-const struct pmc_bit_map arl_pchs_vnn_req_status_2_map[] = {
+static const struct pmc_bit_map arl_pchs_vnn_req_status_2_map[] = {
{"FIA2_VNN_REQ_STS", BIT(0)},
{"CSMERTC_VNN_REQ_STS", BIT(1)},
{"CSE_VNN_REQ_STS", BIT(4)},
@@ -548,7 +549,7 @@ const struct pmc_bit_map arl_pchs_vnn_req_status_2_map[] = {
{}
};
-const struct pmc_bit_map arl_pchs_vnn_req_status_3_map[] = {
+static const struct pmc_bit_map arl_pchs_vnn_req_status_3_map[] = {
{"ESE_VNN_REQ_STS", BIT(3)},
{"DTS0_VNN_REQ_STS", BIT(7)},
{"GPIOCOM5_VNN_REQ_STS", BIT(11)},
@@ -556,7 +557,7 @@ const struct pmc_bit_map arl_pchs_vnn_req_status_3_map[] = {
{}
};
-const struct pmc_bit_map arl_pchs_vnn_misc_status_map[] = {
+static const struct pmc_bit_map arl_pchs_vnn_misc_status_map[] = {
{"CPU_C10_REQ_STS", BIT(0)},
{"TS_OFF_REQ_STS", BIT(1)},
{"PNDE_MET_REQ_STS", BIT(2)},
@@ -586,7 +587,7 @@ const struct pmc_bit_map arl_pchs_vnn_misc_status_map[] = {
{}
};
-const struct pmc_bit_map arl_pchs_signal_status_map[] = {
+static const struct pmc_bit_map arl_pchs_signal_status_map[] = {
{"LSX_Wake0_STS", BIT(0)},
{"LSX_Wake1_STS", BIT(1)},
{"LSX_Wake2_STS", BIT(2)},
@@ -606,7 +607,7 @@ const struct pmc_bit_map arl_pchs_signal_status_map[] = {
{}
};
-const struct pmc_bit_map *arl_pchs_lpm_maps[] = {
+static const struct pmc_bit_map *arl_pchs_lpm_maps[] = {
arl_pchs_clocksource_status_map,
arl_pchs_power_gating_status_0_map,
arl_pchs_power_gating_status_1_map,
@@ -624,7 +625,7 @@ const struct pmc_bit_map *arl_pchs_lpm_maps[] = {
NULL
};
-const struct pmc_reg_map arl_pchs_reg_map = {
+static const struct pmc_reg_map arl_pchs_reg_map = {
.pfear_sts = ext_arl_socs_pfear_map,
.ppfear_buckets = ARL_SOCS_PPFEAR_NUM_ENTRIES,
.pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT,
@@ -650,6 +651,7 @@ const struct pmc_reg_map arl_pchs_reg_map = {
.etr3_offset = ETR3_OFFSET,
};
+#define PMC_DEVID_SOCM 0x777f
#define PMC_DEVID_SOCS 0xae7f
#define PMC_DEVID_IOEP 0x7ecf
#define PMC_DEVID_PCHS 0x7f27
@@ -669,11 +671,17 @@ static struct pmc_info arl_pmc_info_list[] = {
.devid = PMC_DEVID_PCHS,
.map = &arl_pchs_reg_map,
},
+ {
+ .guid = SOCM_LPM_REQ_GUID,
+ .devid = PMC_DEVID_SOCM,
+ .map = &mtl_socm_reg_map,
+ },
{}
};
#define ARL_NPU_PCI_DEV 0xad1d
#define ARL_GNA_PCI_DEV 0xae4c
+#define ARL_H_GNA_PCI_DEV 0x774c
/*
* Set power state of select devices that do not have drivers to D3
* so that they do not block Package C entry.
@@ -684,6 +692,12 @@ static void arl_d3_fixup(void)
pmc_core_set_device_d3(ARL_GNA_PCI_DEV);
}
+static void arl_h_d3_fixup(void)
+{
+ pmc_core_set_device_d3(ARL_NPU_PCI_DEV);
+ pmc_core_set_device_d3(ARL_H_GNA_PCI_DEV);
+}
+
static int arl_resume(struct pmc_dev *pmcdev)
{
arl_d3_fixup();
@@ -691,40 +705,41 @@ static int arl_resume(struct pmc_dev *pmcdev)
return cnl_resume(pmcdev);
}
-int arl_core_init(struct pmc_dev *pmcdev)
+static int arl_h_resume(struct pmc_dev *pmcdev)
{
- struct pmc *pmc = pmcdev->pmcs[PMC_IDX_SOC];
- int ret;
- int func = 0;
- bool ssram_init = true;
+ arl_h_d3_fixup();
+
+ return cnl_resume(pmcdev);
+}
+static int arl_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info)
+{
arl_d3_fixup();
- pmcdev->suspend = cnl_suspend;
- pmcdev->resume = arl_resume;
- pmcdev->regmap_list = arl_pmc_info_list;
+ return generic_core_init(pmcdev, pmc_dev_info);
+}
- /*
- * If ssram init fails use legacy method to at least get the
- * primary PMC
- */
- ret = pmc_core_ssram_init(pmcdev, func);
- if (ret) {
- ssram_init = false;
- pmc->map = &arl_socs_reg_map;
-
- ret = get_primary_reg_base(pmc);
- if (ret)
- return ret;
- }
-
- pmc_core_get_low_power_modes(pmcdev);
- pmc_core_punit_pmt_init(pmcdev, ARL_PMT_DMU_GUID);
-
- if (ssram_init) {
- ret = pmc_core_ssram_get_lpm_reqs(pmcdev);
- if (ret)
- return ret;
- }
-
- return 0;
+static int arl_h_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info)
+{
+ arl_h_d3_fixup();
+ return generic_core_init(pmcdev, pmc_dev_info);
}
+
+struct pmc_dev_info arl_pmc_dev = {
+ .pci_func = 0,
+ .dmu_guid = ARL_PMT_DMU_GUID,
+ .regmap_list = arl_pmc_info_list,
+ .map = &arl_socs_reg_map,
+ .suspend = cnl_suspend,
+ .resume = arl_resume,
+ .init = arl_core_init,
+};
+
+struct pmc_dev_info arl_h_pmc_dev = {
+ .pci_func = 2,
+ .dmu_guid = ARL_PMT_DMU_GUID,
+ .regmap_list = arl_pmc_info_list,
+ .map = &mtl_socm_reg_map,
+ .suspend = cnl_suspend,
+ .resume = arl_h_resume,
+ .init = arl_h_core_init,
+};
diff --git a/drivers/platform/x86/intel/pmc/cnp.c b/drivers/platform/x86/intel/pmc/cnp.c
index fc5193fdf8a8..2c5af158bbe2 100644
--- a/drivers/platform/x86/intel/pmc/cnp.c
+++ b/drivers/platform/x86/intel/pmc/cnp.c
@@ -88,7 +88,7 @@ const struct pmc_bit_map cnp_pfear_map[] = {
{}
};
-const struct pmc_bit_map *ext_cnp_pfear_map[] = {
+static const struct pmc_bit_map *ext_cnp_pfear_map[] = {
/*
* Check intel_pmc_core_ids[] users of cnp_reg_map for
* a list of core SoCs using this.
@@ -97,7 +97,7 @@ const struct pmc_bit_map *ext_cnp_pfear_map[] = {
NULL
};
-const struct pmc_bit_map cnp_slps0_dbg0_map[] = {
+static const struct pmc_bit_map cnp_slps0_dbg0_map[] = {
{"AUDIO_D3", BIT(0)},
{"OTG_D3", BIT(1)},
{"XHCI_D3", BIT(2)},
@@ -110,7 +110,7 @@ const struct pmc_bit_map cnp_slps0_dbg0_map[] = {
{}
};
-const struct pmc_bit_map cnp_slps0_dbg1_map[] = {
+static const struct pmc_bit_map cnp_slps0_dbg1_map[] = {
{"SDIO_PLL_OFF", BIT(0)},
{"USB2_PLL_OFF", BIT(1)},
{"AUDIO_PLL_OFF", BIT(2)},
@@ -127,7 +127,7 @@ const struct pmc_bit_map cnp_slps0_dbg1_map[] = {
{}
};
-const struct pmc_bit_map cnp_slps0_dbg2_map[] = {
+static const struct pmc_bit_map cnp_slps0_dbg2_map[] = {
{"MPHY_CORE_GATED", BIT(0)},
{"CSME_GATED", BIT(1)},
{"USB2_SUS_GATED", BIT(2)},
@@ -274,20 +274,9 @@ int cnl_resume(struct pmc_dev *pmcdev)
return pmc_core_resume_common(pmcdev);
}
-int cnp_core_init(struct pmc_dev *pmcdev)
-{
- struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN];
- int ret;
-
- pmcdev->suspend = cnl_suspend;
- pmcdev->resume = cnl_resume;
-
- pmc->map = &cnp_reg_map;
- ret = get_primary_reg_base(pmc);
- if (ret)
- return ret;
-
- pmc_core_get_low_power_modes(pmcdev);
+struct pmc_dev_info cnp_pmc_dev = {
+ .map = &cnp_reg_map,
+ .suspend = cnl_suspend,
+ .resume = cnl_resume,
+};
- return 0;
-}
diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c
index 1ee0fb5f8250..7a1d11f2914f 100644
--- a/drivers/platform/x86/intel/pmc/core.c
+++ b/drivers/platform/x86/intel/pmc/core.c
@@ -1345,40 +1345,80 @@ static void pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
}
}
+/*
+ * When supported, ssram init is used to achieve all available PMCs.
+ * If ssram init fails, this function uses legacy method to at least get the
+ * primary PMC.
+ */
+int generic_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info)
+{
+ struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN];
+ bool ssram;
+ int ret;
+
+ pmcdev->suspend = pmc_dev_info->suspend;
+ pmcdev->resume = pmc_dev_info->resume;
+
+ ssram = pmc_dev_info->regmap_list != NULL;
+ if (ssram) {
+ pmcdev->regmap_list = pmc_dev_info->regmap_list;
+ ret = pmc_core_ssram_init(pmcdev, pmc_dev_info->pci_func);
+ if (ret) {
+ dev_warn(&pmcdev->pdev->dev,
+ "ssram init failed, %d, using legacy init\n", ret);
+ ssram = false;
+ }
+ }
+
+ if (!ssram) {
+ pmc->map = pmc_dev_info->map;
+ ret = get_primary_reg_base(pmc);
+ if (ret)
+ return ret;
+ }
+
+ pmc_core_get_low_power_modes(pmcdev);
+ if (pmc_dev_info->dmu_guid)
+ pmc_core_punit_pmt_init(pmcdev, pmc_dev_info->dmu_guid);
+
+ if (ssram)
+ return pmc_core_ssram_get_lpm_reqs(pmcdev);
+
+ return 0;
+}
+
static const struct x86_cpu_id intel_pmc_core_ids[] = {
- X86_MATCH_VFM(INTEL_SKYLAKE_L, spt_core_init),
- X86_MATCH_VFM(INTEL_SKYLAKE, spt_core_init),
- X86_MATCH_VFM(INTEL_KABYLAKE_L, spt_core_init),
- X86_MATCH_VFM(INTEL_KABYLAKE, spt_core_init),
- X86_MATCH_VFM(INTEL_CANNONLAKE_L, cnp_core_init),
- X86_MATCH_VFM(INTEL_ICELAKE_L, icl_core_init),
- X86_MATCH_VFM(INTEL_ICELAKE_NNPI, icl_core_init),
- X86_MATCH_VFM(INTEL_COMETLAKE, cnp_core_init),
- X86_MATCH_VFM(INTEL_COMETLAKE_L, cnp_core_init),
- X86_MATCH_VFM(INTEL_TIGERLAKE_L, tgl_l_core_init),
- X86_MATCH_VFM(INTEL_TIGERLAKE, tgl_core_init),
- X86_MATCH_VFM(INTEL_ATOM_TREMONT, tgl_l_core_init),
- X86_MATCH_VFM(INTEL_ATOM_TREMONT_L, icl_core_init),
- X86_MATCH_VFM(INTEL_ROCKETLAKE, tgl_core_init),
- X86_MATCH_VFM(INTEL_ALDERLAKE_L, tgl_l_core_init),
- X86_MATCH_VFM(INTEL_ATOM_GRACEMONT, tgl_l_core_init),
- X86_MATCH_VFM(INTEL_ALDERLAKE, adl_core_init),
- X86_MATCH_VFM(INTEL_RAPTORLAKE_P, tgl_l_core_init),
- X86_MATCH_VFM(INTEL_RAPTORLAKE, adl_core_init),
- X86_MATCH_VFM(INTEL_RAPTORLAKE_S, adl_core_init),
- X86_MATCH_VFM(INTEL_METEORLAKE_L, mtl_core_init),
- X86_MATCH_VFM(INTEL_ARROWLAKE, arl_core_init),
- X86_MATCH_VFM(INTEL_LUNARLAKE_M, lnl_core_init),
+ X86_MATCH_VFM(INTEL_SKYLAKE_L, &spt_pmc_dev),
+ X86_MATCH_VFM(INTEL_SKYLAKE, &spt_pmc_dev),
+ X86_MATCH_VFM(INTEL_KABYLAKE_L, &spt_pmc_dev),
+ X86_MATCH_VFM(INTEL_KABYLAKE, &spt_pmc_dev),
+ X86_MATCH_VFM(INTEL_CANNONLAKE_L, &cnp_pmc_dev),
+ X86_MATCH_VFM(INTEL_ICELAKE_L, &icl_pmc_dev),
+ X86_MATCH_VFM(INTEL_ICELAKE_NNPI, &icl_pmc_dev),
+ X86_MATCH_VFM(INTEL_COMETLAKE, &cnp_pmc_dev),
+ X86_MATCH_VFM(INTEL_COMETLAKE_L, &cnp_pmc_dev),
+ X86_MATCH_VFM(INTEL_TIGERLAKE_L, &tgl_l_pmc_dev),
+ X86_MATCH_VFM(INTEL_TIGERLAKE, &tgl_pmc_dev),
+ X86_MATCH_VFM(INTEL_ATOM_TREMONT, &tgl_l_pmc_dev),
+ X86_MATCH_VFM(INTEL_ATOM_TREMONT_L, &icl_pmc_dev),
+ X86_MATCH_VFM(INTEL_ROCKETLAKE, &tgl_pmc_dev),
+ X86_MATCH_VFM(INTEL_ALDERLAKE_L, &tgl_l_pmc_dev),
+ X86_MATCH_VFM(INTEL_ATOM_GRACEMONT, &tgl_l_pmc_dev),
+ X86_MATCH_VFM(INTEL_ALDERLAKE, &adl_pmc_dev),
+ X86_MATCH_VFM(INTEL_RAPTORLAKE_P, &tgl_l_pmc_dev),
+ X86_MATCH_VFM(INTEL_RAPTORLAKE, &adl_pmc_dev),
+ X86_MATCH_VFM(INTEL_RAPTORLAKE_S, &adl_pmc_dev),
+ X86_MATCH_VFM(INTEL_METEORLAKE_L, &mtl_pmc_dev),
+ X86_MATCH_VFM(INTEL_ARROWLAKE, &arl_pmc_dev),
+ X86_MATCH_VFM(INTEL_ARROWLAKE_H, &arl_h_pmc_dev),
+ X86_MATCH_VFM(INTEL_ARROWLAKE_U, &arl_h_pmc_dev),
+ X86_MATCH_VFM(INTEL_LUNARLAKE_M, &lnl_pmc_dev),
+ X86_MATCH_VFM(INTEL_PANTHERLAKE_L, &ptl_pmc_dev),
{}
};
MODULE_DEVICE_TABLE(x86cpu, intel_pmc_core_ids);
-static const struct pci_device_id pmc_pci_ids[] = {
- { PCI_VDEVICE(INTEL, SPT_PMC_PCI_DEVICE_ID) },
- { }
-};
-
/*
* This quirk can be used on those platforms where
* the platform BIOS enforces 24Mhz crystal to shutdown
@@ -1452,7 +1492,7 @@ static int pmc_core_probe(struct platform_device *pdev)
static bool device_initialized;
struct pmc_dev *pmcdev;
const struct x86_cpu_id *cpu_id;
- int (*core_init)(struct pmc_dev *pmcdev);
+ struct pmc_dev_info *pmc_dev_info;
struct pmc *primary_pmc;
int ret;
@@ -1472,7 +1512,7 @@ static int pmc_core_probe(struct platform_device *pdev)
if (!cpu_id)
return -ENODEV;
- core_init = (int (*)(struct pmc_dev *))cpu_id->driver_data;
+ pmc_dev_info = (struct pmc_dev_info *)cpu_id->driver_data;
/* Primary PMC */
primary_pmc = devm_kzalloc(&pdev->dev, sizeof(*primary_pmc), GFP_KERNEL);
@@ -1489,16 +1529,13 @@ static int pmc_core_probe(struct platform_device *pdev)
if (!pmcdev->pkgc_res_cnt)
return -ENOMEM;
- /*
- * Coffee Lake has CPU ID of Kaby Lake and Cannon Lake PCH. So here
- * Sunrisepoint PCH regmap can't be used. Use Cannon Lake PCH regmap
- * in this case.
- */
- if (core_init == spt_core_init && !pci_dev_present(pmc_pci_ids))
- core_init = cnp_core_init;
-
mutex_init(&pmcdev->lock);
- ret = core_init(pmcdev);
+
+ if (pmc_dev_info->init)
+ ret = pmc_dev_info->init(pmcdev, pmc_dev_info);
+ else
+ ret = generic_core_init(pmcdev, pmc_dev_info);
+
if (ret) {
pmc_core_clean_structure(pdev);
return ret;
diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h
index b9d3291d0bf2..945a1c440cca 100644
--- a/drivers/platform/x86/intel/pmc/core.h
+++ b/drivers/platform/x86/intel/pmc/core.h
@@ -285,6 +285,14 @@ enum ppfear_regs {
#define LNL_PPFEAR_NUM_ENTRIES 12
#define LNL_S0IX_BLOCKER_OFFSET 0x2004
+/* Panther Lake Power Management Controller register offsets */
+#define PTL_LPM_NUM_MAPS 14
+#define PTL_PMC_LTR_SATA2 0x1B90
+#define PTL_PMC_LTR_PMC 0x1BA8
+#define PTL_PMC_LTR_CUR_ASLT 0x1C28
+#define PTL_PMC_LTR_CUR_PLT 0x1C2C
+#define PTL_PCD_PMC_MMIO_REG_LEN 0x31A8
+
extern const char *pmc_lpm_modes[];
struct pmc_bit_map {
@@ -430,178 +438,77 @@ struct pmc_dev {
enum pmc_index {
PMC_IDX_MAIN,
- PMC_IDX_SOC = PMC_IDX_MAIN,
PMC_IDX_IOE,
PMC_IDX_PCH,
PMC_IDX_MAX
};
+/**
+ * struct pmc_dev_info - Structure to keep PMC device info
+ * @pci_func: Function number of the primary PMC
+ * @dmu_guid: Die Management Unit GUID
+ * @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
+ * @suspend: Function to perform platform specific suspend
+ * @resume: Function to perform platform specific resume
+ * @init: Function to perform platform specific init action
+ */
+struct pmc_dev_info {
+ u8 pci_func;
+ u32 dmu_guid;
+ struct pmc_info *regmap_list;
+ const struct pmc_reg_map *map;
+ 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);
+};
+
extern const struct pmc_bit_map msr_map[];
-extern const struct pmc_bit_map spt_pll_map[];
-extern const struct pmc_bit_map spt_mphy_map[];
-extern const struct pmc_bit_map spt_pfear_map[];
-extern const struct pmc_bit_map *ext_spt_pfear_map[];
-extern const struct pmc_bit_map spt_ltr_show_map[];
-extern const struct pmc_reg_map spt_reg_map;
extern const struct pmc_bit_map cnp_pfear_map[];
-extern const struct pmc_bit_map *ext_cnp_pfear_map[];
-extern const struct pmc_bit_map cnp_slps0_dbg0_map[];
-extern const struct pmc_bit_map cnp_slps0_dbg1_map[];
-extern const struct pmc_bit_map cnp_slps0_dbg2_map[];
extern const struct pmc_bit_map *cnp_slps0_dbg_maps[];
extern const struct pmc_bit_map cnp_ltr_show_map[];
extern const struct pmc_reg_map cnp_reg_map;
-extern const struct pmc_bit_map icl_pfear_map[];
-extern const struct pmc_bit_map *ext_icl_pfear_map[];
-extern const struct pmc_reg_map icl_reg_map;
-extern const struct pmc_bit_map tgl_pfear_map[];
-extern const struct pmc_bit_map *ext_tgl_pfear_map[];
-extern const struct pmc_bit_map tgl_clocksource_status_map[];
-extern const struct pmc_bit_map tgl_power_gating_status_map[];
-extern const struct pmc_bit_map tgl_d3_status_map[];
-extern const struct pmc_bit_map tgl_vnn_req_status_map[];
-extern const struct pmc_bit_map tgl_vnn_misc_status_map[];
extern const struct pmc_bit_map tgl_signal_status_map[];
-extern const struct pmc_bit_map *tgl_lpm_maps[];
-extern const struct pmc_reg_map tgl_reg_map;
-extern const struct pmc_reg_map tgl_h_reg_map;
-extern const struct pmc_bit_map adl_pfear_map[];
-extern const struct pmc_bit_map *ext_adl_pfear_map[];
-extern const struct pmc_bit_map adl_ltr_show_map[];
-extern const struct pmc_bit_map adl_clocksource_status_map[];
-extern const struct pmc_bit_map adl_power_gating_status_0_map[];
-extern const struct pmc_bit_map adl_power_gating_status_1_map[];
-extern const struct pmc_bit_map adl_power_gating_status_2_map[];
-extern const struct pmc_bit_map adl_d3_status_0_map[];
-extern const struct pmc_bit_map adl_d3_status_1_map[];
-extern const struct pmc_bit_map adl_d3_status_2_map[];
-extern const struct pmc_bit_map adl_d3_status_3_map[];
-extern const struct pmc_bit_map adl_vnn_req_status_0_map[];
-extern const struct pmc_bit_map adl_vnn_req_status_1_map[];
-extern const struct pmc_bit_map adl_vnn_req_status_2_map[];
-extern const struct pmc_bit_map adl_vnn_req_status_3_map[];
-extern const struct pmc_bit_map adl_vnn_misc_status_map[];
-extern const struct pmc_bit_map *adl_lpm_maps[];
extern const struct pmc_reg_map adl_reg_map;
extern const struct pmc_bit_map mtl_socm_pfear_map[];
-extern const struct pmc_bit_map *ext_mtl_socm_pfear_map[];
-extern const struct pmc_bit_map mtl_socm_ltr_show_map[];
-extern const struct pmc_bit_map mtl_socm_clocksource_status_map[];
-extern const struct pmc_bit_map mtl_socm_power_gating_status_0_map[];
-extern const struct pmc_bit_map mtl_socm_power_gating_status_1_map[];
-extern const struct pmc_bit_map mtl_socm_power_gating_status_2_map[];
extern const struct pmc_bit_map mtl_socm_d3_status_0_map[];
extern const struct pmc_bit_map mtl_socm_d3_status_1_map[];
-extern const struct pmc_bit_map mtl_socm_d3_status_2_map[];
-extern const struct pmc_bit_map mtl_socm_d3_status_3_map[];
extern const struct pmc_bit_map mtl_socm_vnn_req_status_0_map[];
extern const struct pmc_bit_map mtl_socm_vnn_req_status_1_map[];
extern const struct pmc_bit_map mtl_socm_vnn_req_status_2_map[];
-extern const struct pmc_bit_map mtl_socm_vnn_req_status_3_map[];
extern const struct pmc_bit_map mtl_socm_vnn_misc_status_map[];
extern const struct pmc_bit_map mtl_socm_signal_status_map[];
-extern const struct pmc_bit_map *mtl_socm_lpm_maps[];
extern const struct pmc_reg_map mtl_socm_reg_map;
-extern const struct pmc_bit_map mtl_ioep_pfear_map[];
-extern const struct pmc_bit_map *ext_mtl_ioep_pfear_map[];
-extern const struct pmc_bit_map mtl_ioep_ltr_show_map[];
-extern const struct pmc_bit_map mtl_ioep_clocksource_status_map[];
-extern const struct pmc_bit_map mtl_ioep_power_gating_status_0_map[];
-extern const struct pmc_bit_map mtl_ioep_power_gating_status_1_map[];
-extern const struct pmc_bit_map mtl_ioep_power_gating_status_2_map[];
-extern const struct pmc_bit_map mtl_ioep_d3_status_0_map[];
-extern const struct pmc_bit_map mtl_ioep_d3_status_1_map[];
-extern const struct pmc_bit_map mtl_ioep_d3_status_2_map[];
-extern const struct pmc_bit_map mtl_ioep_d3_status_3_map[];
-extern const struct pmc_bit_map mtl_ioep_vnn_req_status_0_map[];
-extern const struct pmc_bit_map mtl_ioep_vnn_req_status_1_map[];
-extern const struct pmc_bit_map mtl_ioep_vnn_req_status_2_map[];
-extern const struct pmc_bit_map mtl_ioep_vnn_req_status_3_map[];
-extern const struct pmc_bit_map mtl_ioep_vnn_misc_status_map[];
-extern const struct pmc_bit_map *mtl_ioep_lpm_maps[];
extern const struct pmc_reg_map mtl_ioep_reg_map;
-extern const struct pmc_bit_map mtl_ioem_pfear_map[];
-extern const struct pmc_bit_map *ext_mtl_ioem_pfear_map[];
-extern const struct pmc_bit_map mtl_ioem_power_gating_status_1_map[];
-extern const struct pmc_bit_map mtl_ioem_vnn_req_status_1_map[];
-extern const struct pmc_bit_map *mtl_ioem_lpm_maps[];
-extern const struct pmc_reg_map mtl_ioem_reg_map;
-extern const struct pmc_reg_map lnl_socm_reg_map;
-
-/* LNL */
-extern const struct pmc_bit_map lnl_ltr_show_map[];
-extern const struct pmc_bit_map lnl_clocksource_status_map[];
-extern const struct pmc_bit_map lnl_power_gating_status_0_map[];
-extern const struct pmc_bit_map lnl_power_gating_status_1_map[];
-extern const struct pmc_bit_map lnl_power_gating_status_2_map[];
-extern const struct pmc_bit_map lnl_d3_status_0_map[];
-extern const struct pmc_bit_map lnl_d3_status_1_map[];
-extern const struct pmc_bit_map lnl_d3_status_2_map[];
-extern const struct pmc_bit_map lnl_d3_status_3_map[];
-extern const struct pmc_bit_map lnl_vnn_req_status_0_map[];
-extern const struct pmc_bit_map lnl_vnn_req_status_1_map[];
-extern const struct pmc_bit_map lnl_vnn_req_status_2_map[];
-extern const struct pmc_bit_map lnl_vnn_req_status_3_map[];
-extern const struct pmc_bit_map lnl_vnn_misc_status_map[];
-extern const struct pmc_bit_map *lnl_lpm_maps[];
-extern const struct pmc_bit_map *lnl_blk_maps[];
-extern const struct pmc_bit_map lnl_pfear_map[];
-extern const struct pmc_bit_map *ext_lnl_pfear_map[];
-extern const struct pmc_bit_map lnl_signal_status_map[];
-
-/* ARL */
-extern const struct pmc_bit_map arl_socs_ltr_show_map[];
-extern const struct pmc_bit_map arl_socs_clocksource_status_map[];
-extern const struct pmc_bit_map arl_socs_power_gating_status_0_map[];
-extern const struct pmc_bit_map arl_socs_power_gating_status_1_map[];
-extern const struct pmc_bit_map arl_socs_power_gating_status_2_map[];
-extern const struct pmc_bit_map arl_socs_d3_status_2_map[];
-extern const struct pmc_bit_map arl_socs_d3_status_3_map[];
-extern const struct pmc_bit_map arl_socs_vnn_req_status_3_map[];
-extern const struct pmc_bit_map *arl_socs_lpm_maps[];
-extern const struct pmc_bit_map arl_socs_pfear_map[];
-extern const struct pmc_bit_map *ext_arl_socs_pfear_map[];
-extern const struct pmc_reg_map arl_socs_reg_map;
-extern const struct pmc_bit_map arl_pchs_ltr_show_map[];
-extern const struct pmc_bit_map arl_pchs_clocksource_status_map[];
-extern const struct pmc_bit_map arl_pchs_power_gating_status_0_map[];
-extern const struct pmc_bit_map arl_pchs_power_gating_status_1_map[];
-extern const struct pmc_bit_map arl_pchs_power_gating_status_2_map[];
-extern const struct pmc_bit_map arl_pchs_d3_status_0_map[];
-extern const struct pmc_bit_map arl_pchs_d3_status_1_map[];
-extern const struct pmc_bit_map arl_pchs_d3_status_2_map[];
-extern const struct pmc_bit_map arl_pchs_d3_status_3_map[];
-extern const struct pmc_bit_map arl_pchs_vnn_req_status_0_map[];
-extern const struct pmc_bit_map arl_pchs_vnn_req_status_1_map[];
-extern const struct pmc_bit_map arl_pchs_vnn_req_status_2_map[];
-extern const struct pmc_bit_map arl_pchs_vnn_req_status_3_map[];
-extern const struct pmc_bit_map arl_pchs_vnn_misc_status_map[];
-extern const struct pmc_bit_map arl_pchs_signal_status_map[];
-extern const struct pmc_bit_map *arl_pchs_lpm_maps[];
-extern const struct pmc_reg_map arl_pchs_reg_map;
-
-extern void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev);
-extern int pmc_core_ssram_get_lpm_reqs(struct pmc_dev *pmcdev);
+
+void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev);
+int pmc_core_ssram_get_lpm_reqs(struct pmc_dev *pmcdev);
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);
-extern void pmc_core_get_low_power_modes(struct pmc_dev *pmcdev);
-extern void pmc_core_punit_pmt_init(struct pmc_dev *pmcdev, u32 guid);
-extern void pmc_core_set_device_d3(unsigned int device);
-
-extern int pmc_core_ssram_init(struct pmc_dev *pmcdev, int func);
-
-int spt_core_init(struct pmc_dev *pmcdev);
-int cnp_core_init(struct pmc_dev *pmcdev);
-int icl_core_init(struct pmc_dev *pmcdev);
-int tgl_core_init(struct pmc_dev *pmcdev);
-int tgl_l_core_init(struct pmc_dev *pmcdev);
-int tgl_core_generic_init(struct pmc_dev *pmcdev, int pch_tp);
-int adl_core_init(struct pmc_dev *pmcdev);
-int mtl_core_init(struct pmc_dev *pmcdev);
-int arl_core_init(struct pmc_dev *pmcdev);
-int lnl_core_init(struct pmc_dev *pmcdev);
+void pmc_core_get_low_power_modes(struct pmc_dev *pmcdev);
+void pmc_core_punit_pmt_init(struct pmc_dev *pmcdev, u32 guid);
+void pmc_core_set_device_d3(unsigned int device);
+
+int pmc_core_ssram_init(struct pmc_dev *pmcdev, int func);
+
+int generic_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info);
+
+extern struct pmc_dev_info spt_pmc_dev;
+extern struct pmc_dev_info cnp_pmc_dev;
+extern struct pmc_dev_info icl_pmc_dev;
+extern struct pmc_dev_info tgl_l_pmc_dev;
+extern struct pmc_dev_info tgl_pmc_dev;
+extern struct pmc_dev_info adl_pmc_dev;
+extern struct pmc_dev_info mtl_pmc_dev;
+extern struct pmc_dev_info arl_pmc_dev;
+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;
void cnl_suspend(struct pmc_dev *pmcdev);
int cnl_resume(struct pmc_dev *pmcdev);
diff --git a/drivers/platform/x86/intel/pmc/icl.c b/drivers/platform/x86/intel/pmc/icl.c
index 71b0fd6cb7d8..db7ed15bf863 100644
--- a/drivers/platform/x86/intel/pmc/icl.c
+++ b/drivers/platform/x86/intel/pmc/icl.c
@@ -10,7 +10,7 @@
#include "core.h"
-const struct pmc_bit_map icl_pfear_map[] = {
+static const struct pmc_bit_map icl_pfear_map[] = {
{"RES_65", BIT(0)},
{"RES_66", BIT(1)},
{"RES_67", BIT(2)},
@@ -22,7 +22,7 @@ const struct pmc_bit_map icl_pfear_map[] = {
{}
};
-const struct pmc_bit_map *ext_icl_pfear_map[] = {
+static const struct pmc_bit_map *ext_icl_pfear_map[] = {
/*
* Check intel_pmc_core_ids[] users of icl_reg_map for
* a list of core SoCs using this.
@@ -32,7 +32,7 @@ const struct pmc_bit_map *ext_icl_pfear_map[] = {
NULL
};
-const struct pmc_reg_map icl_reg_map = {
+static const struct pmc_reg_map icl_reg_map = {
.pfear_sts = ext_icl_pfear_map,
.slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET,
.slp_s0_res_counter_step = ICL_PMC_SLP_S0_RES_COUNTER_STEP,
@@ -50,18 +50,6 @@ const struct pmc_reg_map icl_reg_map = {
.etr3_offset = ETR3_OFFSET,
};
-int icl_core_init(struct pmc_dev *pmcdev)
-{
- struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN];
- int ret;
-
- pmc->map = &icl_reg_map;
-
- ret = get_primary_reg_base(pmc);
- if (ret)
- return ret;
-
- pmc_core_get_low_power_modes(pmcdev);
-
- return ret;
-}
+struct pmc_dev_info icl_pmc_dev = {
+ .map = &icl_reg_map,
+};
diff --git a/drivers/platform/x86/intel/pmc/lnl.c b/drivers/platform/x86/intel/pmc/lnl.c
index be029f12cdf4..da513c234714 100644
--- a/drivers/platform/x86/intel/pmc/lnl.c
+++ b/drivers/platform/x86/intel/pmc/lnl.c
@@ -13,7 +13,7 @@
#include "core.h"
-const struct pmc_bit_map lnl_ltr_show_map[] = {
+static const struct pmc_bit_map lnl_ltr_show_map[] = {
{"SOUTHPORT_A", CNP_PMC_LTR_SPA},
{"SOUTHPORT_B", CNP_PMC_LTR_SPB},
{"SATA", CNP_PMC_LTR_SATA},
@@ -55,7 +55,7 @@ const struct pmc_bit_map lnl_ltr_show_map[] = {
{}
};
-const struct pmc_bit_map lnl_power_gating_status_0_map[] = {
+static const struct pmc_bit_map lnl_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},
@@ -91,7 +91,7 @@ const struct pmc_bit_map lnl_power_gating_status_0_map[] = {
{}
};
-const struct pmc_bit_map lnl_power_gating_status_1_map[] = {
+static const struct pmc_bit_map lnl_power_gating_status_1_map[] = {
{"USBR0_PGD0_PG_STS", BIT(0), 1},
{"SUSRAM_PGD0_PG_STS", BIT(1), 1},
{"SMT1_PGD0_PG_STS", BIT(2), 1},
@@ -127,7 +127,7 @@ const struct pmc_bit_map lnl_power_gating_status_1_map[] = {
{}
};
-const struct pmc_bit_map lnl_power_gating_status_2_map[] = {
+static const struct pmc_bit_map lnl_power_gating_status_2_map[] = {
{"PSF8_PGD0_PG_STS", BIT(0), 0},
{"SBR16B2_PGD0_PG_STS", BIT(1), 0},
{"D2D_IPU_PGD0_PG_STS", BIT(2), 1},
@@ -163,7 +163,7 @@ const struct pmc_bit_map lnl_power_gating_status_2_map[] = {
{}
};
-const struct pmc_bit_map lnl_d3_status_0_map[] = {
+static const struct pmc_bit_map lnl_d3_status_0_map[] = {
{"LPSS_D3_STS", BIT(3), 1},
{"XDCI_D3_STS", BIT(4), 1},
{"XHCI_D3_STS", BIT(5), 1},
@@ -175,7 +175,7 @@ const struct pmc_bit_map lnl_d3_status_0_map[] = {
{}
};
-const struct pmc_bit_map lnl_d3_status_1_map[] = {
+static const struct pmc_bit_map lnl_d3_status_1_map[] = {
{"OSSE_SMT1_D3_STS", BIT(7), 0},
{"GBE_D3_STS", BIT(19), 0},
{"ITSS_D3_STS", BIT(23), 0},
@@ -185,7 +185,7 @@ const struct pmc_bit_map lnl_d3_status_1_map[] = {
{}
};
-const struct pmc_bit_map lnl_d3_status_2_map[] = {
+static const struct pmc_bit_map lnl_d3_status_2_map[] = {
{"ESE_D3_STS", BIT(0), 0},
{"CSMERTC_D3_STS", BIT(1), 0},
{"SUSRAM_D3_STS", BIT(2), 0},
@@ -205,7 +205,7 @@ const struct pmc_bit_map lnl_d3_status_2_map[] = {
{}
};
-const struct pmc_bit_map lnl_d3_status_3_map[] = {
+static const struct pmc_bit_map lnl_d3_status_3_map[] = {
{"THC0_D3_STS", BIT(14), 1},
{"THC1_D3_STS", BIT(15), 1},
{"OSSE_SMT3_D3_STS", BIT(21), 0},
@@ -213,14 +213,14 @@ const struct pmc_bit_map lnl_d3_status_3_map[] = {
{}
};
-const struct pmc_bit_map lnl_vnn_req_status_0_map[] = {
+static const struct pmc_bit_map lnl_vnn_req_status_0_map[] = {
{"LPSS_VNN_REQ_STS", BIT(3), 1},
{"OSSE_VNN_REQ_STS", BIT(15), 1},
{"ESPISPI_VNN_REQ_STS", BIT(18), 1},
{}
};
-const struct pmc_bit_map lnl_vnn_req_status_1_map[] = {
+static const struct pmc_bit_map lnl_vnn_req_status_1_map[] = {
{"NPK_VNN_REQ_STS", BIT(4), 1},
{"OSSE_SMT1_VNN_REQ_STS", BIT(7), 1},
{"DFXAGG_VNN_REQ_STS", BIT(8), 0},
@@ -232,7 +232,7 @@ const struct pmc_bit_map lnl_vnn_req_status_1_map[] = {
{}
};
-const struct pmc_bit_map lnl_vnn_req_status_2_map[] = {
+static const struct pmc_bit_map lnl_vnn_req_status_2_map[] = {
{"eSE_VNN_REQ_STS", BIT(0), 1},
{"CSMERTC_VNN_REQ_STS", BIT(1), 1},
{"CSE_VNN_REQ_STS", BIT(4), 1},
@@ -249,14 +249,14 @@ const struct pmc_bit_map lnl_vnn_req_status_2_map[] = {
{}
};
-const struct pmc_bit_map lnl_vnn_req_status_3_map[] = {
+static const struct pmc_bit_map lnl_vnn_req_status_3_map[] = {
{"DISP_SHIM_VNN_REQ_STS", BIT(2), 0},
{"DTS0_VNN_REQ_STS", BIT(7), 0},
{"GPIOCOM5_VNN_REQ_STS", BIT(11), 2},
{}
};
-const struct pmc_bit_map lnl_vnn_misc_status_map[] = {
+static const struct pmc_bit_map lnl_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},
@@ -292,7 +292,7 @@ const struct pmc_bit_map lnl_vnn_misc_status_map[] = {
{}
};
-const struct pmc_bit_map lnl_clocksource_status_map[] = {
+static const struct pmc_bit_map lnl_clocksource_status_map[] = {
{"AON2_OFF_STS", BIT(0), 0},
{"AON3_OFF_STS", BIT(1), 1},
{"AON4_OFF_STS", BIT(2), 1},
@@ -317,7 +317,7 @@ const struct pmc_bit_map lnl_clocksource_status_map[] = {
{}
};
-const struct pmc_bit_map lnl_signal_status_map[] = {
+static const struct pmc_bit_map lnl_signal_status_map[] = {
{"LSX_Wake0_STS", BIT(0), 0},
{"LSX_Wake1_STS", BIT(1), 0},
{"LSX_Wake2_STS", BIT(2), 0},
@@ -337,7 +337,7 @@ const struct pmc_bit_map lnl_signal_status_map[] = {
{}
};
-const struct pmc_bit_map lnl_rsc_status_map[] = {
+static const struct pmc_bit_map lnl_rsc_status_map[] = {
{"Memory", 0, 1},
{"PSF0", 0, 1},
{"PSF4", 0, 1},
@@ -349,7 +349,7 @@ const struct pmc_bit_map lnl_rsc_status_map[] = {
{}
};
-const struct pmc_bit_map *lnl_lpm_maps[] = {
+static const struct pmc_bit_map *lnl_lpm_maps[] = {
lnl_clocksource_status_map,
lnl_power_gating_status_0_map,
lnl_power_gating_status_1_map,
@@ -367,7 +367,7 @@ const struct pmc_bit_map *lnl_lpm_maps[] = {
NULL
};
-const struct pmc_bit_map *lnl_blk_maps[] = {
+static const struct pmc_bit_map *lnl_blk_maps[] = {
lnl_power_gating_status_0_map,
lnl_power_gating_status_1_map,
lnl_power_gating_status_2_map,
@@ -386,7 +386,7 @@ const struct pmc_bit_map *lnl_blk_maps[] = {
NULL
};
-const struct pmc_bit_map lnl_pfear_map[] = {
+static const struct pmc_bit_map lnl_pfear_map[] = {
{"PMC_0", BIT(0)},
{"FUSE_OSSE", BIT(1)},
{"ESPISPI", BIT(2)},
@@ -498,12 +498,12 @@ const struct pmc_bit_map lnl_pfear_map[] = {
{}
};
-const struct pmc_bit_map *ext_lnl_pfear_map[] = {
+static const struct pmc_bit_map *ext_lnl_pfear_map[] = {
lnl_pfear_map,
NULL
};
-const struct pmc_reg_map lnl_socm_reg_map = {
+static const struct pmc_reg_map lnl_socm_reg_map = {
.pfear_sts = ext_lnl_pfear_map,
.slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET,
.slp_s0_res_counter_step = TGL_PMC_SLP_S0_RES_COUNTER_STEP,
@@ -550,22 +550,15 @@ static int lnl_resume(struct pmc_dev *pmcdev)
return cnl_resume(pmcdev);
}
-int lnl_core_init(struct pmc_dev *pmcdev)
+static int lnl_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info)
{
- int ret;
- struct pmc *pmc = pmcdev->pmcs[PMC_IDX_SOC];
-
lnl_d3_fixup();
-
- pmcdev->suspend = cnl_suspend;
- pmcdev->resume = lnl_resume;
-
- pmc->map = &lnl_socm_reg_map;
- ret = get_primary_reg_base(pmc);
- if (ret)
- return ret;
-
- pmc_core_get_low_power_modes(pmcdev);
-
- return 0;
+ return generic_core_init(pmcdev, pmc_dev_info);
}
+
+struct pmc_dev_info lnl_pmc_dev = {
+ .map = &lnl_socm_reg_map,
+ .suspend = cnl_suspend,
+ .resume = lnl_resume,
+ .init = lnl_core_init,
+};
diff --git a/drivers/platform/x86/intel/pmc/mtl.c b/drivers/platform/x86/intel/pmc/mtl.c
index 02949fed76e9..8862829694a7 100644
--- a/drivers/platform/x86/intel/pmc/mtl.c
+++ b/drivers/platform/x86/intel/pmc/mtl.c
@@ -102,12 +102,12 @@ const struct pmc_bit_map mtl_socm_pfear_map[] = {
{}
};
-const struct pmc_bit_map *ext_mtl_socm_pfear_map[] = {
+static const struct pmc_bit_map *ext_mtl_socm_pfear_map[] = {
mtl_socm_pfear_map,
NULL
};
-const struct pmc_bit_map mtl_socm_ltr_show_map[] = {
+static const struct pmc_bit_map mtl_socm_ltr_show_map[] = {
{"SOUTHPORT_A", CNP_PMC_LTR_SPA},
{"SOUTHPORT_B", CNP_PMC_LTR_SPB},
{"SATA", CNP_PMC_LTR_SATA},
@@ -141,7 +141,7 @@ const struct pmc_bit_map mtl_socm_ltr_show_map[] = {
{}
};
-const struct pmc_bit_map mtl_socm_clocksource_status_map[] = {
+static const struct pmc_bit_map mtl_socm_clocksource_status_map[] = {
{"AON2_OFF_STS", BIT(0)},
{"AON3_OFF_STS", BIT(1)},
{"AON4_OFF_STS", BIT(2)},
@@ -167,7 +167,7 @@ const struct pmc_bit_map mtl_socm_clocksource_status_map[] = {
{}
};
-const struct pmc_bit_map mtl_socm_power_gating_status_0_map[] = {
+static const struct pmc_bit_map mtl_socm_power_gating_status_0_map[] = {
{"PMC_PGD0_PG_STS", BIT(0)},
{"DMI_PGD0_PG_STS", BIT(1)},
{"ESPISPI_PGD0_PG_STS", BIT(2)},
@@ -203,7 +203,7 @@ const struct pmc_bit_map mtl_socm_power_gating_status_0_map[] = {
{}
};
-const struct pmc_bit_map mtl_socm_power_gating_status_1_map[] = {
+static const struct pmc_bit_map mtl_socm_power_gating_status_1_map[] = {
{"USBR0_PGD0_PG_STS", BIT(0)},
{"SUSRAM_PGD0_PG_STS", BIT(1)},
{"SMT1_PGD0_PG_STS", BIT(2)},
@@ -239,7 +239,7 @@ const struct pmc_bit_map mtl_socm_power_gating_status_1_map[] = {
{}
};
-const struct pmc_bit_map mtl_socm_power_gating_status_2_map[] = {
+static const struct pmc_bit_map mtl_socm_power_gating_status_2_map[] = {
{"PSF8_PGD0_PG_STS", BIT(0)},
{"FIA_PGD0_PG_STS", BIT(1)},
{"SOC_D2D_PGD1_PG_STS", BIT(2)},
@@ -291,7 +291,7 @@ const struct pmc_bit_map mtl_socm_d3_status_1_map[] = {
{}
};
-const struct pmc_bit_map mtl_socm_d3_status_2_map[] = {
+static const struct pmc_bit_map mtl_socm_d3_status_2_map[] = {
{"GNA_D3_STS", BIT(0)},
{"CSMERTC_D3_STS", BIT(1)},
{"SUSRAM_D3_STS", BIT(2)},
@@ -310,7 +310,7 @@ const struct pmc_bit_map mtl_socm_d3_status_2_map[] = {
{}
};
-const struct pmc_bit_map mtl_socm_d3_status_3_map[] = {
+static const struct pmc_bit_map mtl_socm_d3_status_3_map[] = {
{"ESE_D3_STS", BIT(2)},
{"GBETSN_D3_STS", BIT(13)},
{"THC0_D3_STS", BIT(14)},
@@ -353,7 +353,7 @@ const struct pmc_bit_map mtl_socm_vnn_req_status_2_map[] = {
{}
};
-const struct pmc_bit_map mtl_socm_vnn_req_status_3_map[] = {
+static const struct pmc_bit_map mtl_socm_vnn_req_status_3_map[] = {
{"ESE_VNN_REQ_STS", BIT(2)},
{"DTS0_VNN_REQ_STS", BIT(7)},
{"GPIOCOM5_VNN_REQ_STS", BIT(11)},
@@ -432,7 +432,7 @@ const struct pmc_bit_map mtl_socm_signal_status_map[] = {
{}
};
-const struct pmc_bit_map *mtl_socm_lpm_maps[] = {
+static const struct pmc_bit_map *mtl_socm_lpm_maps[] = {
mtl_socm_clocksource_status_map,
mtl_socm_power_gating_status_0_map,
mtl_socm_power_gating_status_1_map,
@@ -476,7 +476,7 @@ const struct pmc_reg_map mtl_socm_reg_map = {
.lpm_reg_index = MTL_LPM_REG_INDEX,
};
-const struct pmc_bit_map mtl_ioep_pfear_map[] = {
+static const struct pmc_bit_map mtl_ioep_pfear_map[] = {
{"PMC_0", BIT(0)},
{"OPI", BIT(1)},
{"TCSS", BIT(2)},
@@ -563,12 +563,12 @@ const struct pmc_bit_map mtl_ioep_pfear_map[] = {
{}
};
-const struct pmc_bit_map *ext_mtl_ioep_pfear_map[] = {
+static const struct pmc_bit_map *ext_mtl_ioep_pfear_map[] = {
mtl_ioep_pfear_map,
NULL
};
-const struct pmc_bit_map mtl_ioep_ltr_show_map[] = {
+static const struct pmc_bit_map mtl_ioep_ltr_show_map[] = {
{"SOUTHPORT_A", CNP_PMC_LTR_SPA},
{"SOUTHPORT_B", CNP_PMC_LTR_SPB},
{"SATA", CNP_PMC_LTR_SATA},
@@ -600,7 +600,7 @@ const struct pmc_bit_map mtl_ioep_ltr_show_map[] = {
{}
};
-const struct pmc_bit_map mtl_ioep_clocksource_status_map[] = {
+static const struct pmc_bit_map mtl_ioep_clocksource_status_map[] = {
{"AON2_OFF_STS", BIT(0)},
{"AON3_OFF_STS", BIT(1)},
{"AON4_OFF_STS", BIT(2)},
@@ -623,7 +623,7 @@ const struct pmc_bit_map mtl_ioep_clocksource_status_map[] = {
{}
};
-const struct pmc_bit_map mtl_ioep_power_gating_status_0_map[] = {
+static const struct pmc_bit_map mtl_ioep_power_gating_status_0_map[] = {
{"PMC_PGD0_PG_STS", BIT(0)},
{"DMI_PGD0_PG_STS", BIT(1)},
{"TCSS_PGD0_PG_STS", BIT(2)},
@@ -650,7 +650,7 @@ const struct pmc_bit_map mtl_ioep_power_gating_status_0_map[] = {
{}
};
-const struct pmc_bit_map mtl_ioep_power_gating_status_1_map[] = {
+static const struct pmc_bit_map mtl_ioep_power_gating_status_1_map[] = {
{"PSF9_PGD0_PG_STS", BIT(0)},
{"MPFPW4_PGD0_PG_STS", BIT(1)},
{"SBR0_PGD0_PG_STS", BIT(8)},
@@ -668,7 +668,7 @@ const struct pmc_bit_map mtl_ioep_power_gating_status_1_map[] = {
{}
};
-const struct pmc_bit_map mtl_ioep_power_gating_status_2_map[] = {
+static const struct pmc_bit_map mtl_ioep_power_gating_status_2_map[] = {
{"FIA_PGD0_PG_STS", BIT(1)},
{"FIA_P_PGD0_PG_STS", BIT(3)},
{"TAM_PGD0_PG_STS", BIT(4)},
@@ -680,7 +680,7 @@ const struct pmc_bit_map mtl_ioep_power_gating_status_2_map[] = {
{}
};
-const struct pmc_bit_map mtl_ioep_d3_status_0_map[] = {
+static const struct pmc_bit_map mtl_ioep_d3_status_0_map[] = {
{"SPF_D3_STS", BIT(0)},
{"SPA_D3_STS", BIT(12)},
{"SPB_D3_STS", BIT(13)},
@@ -691,43 +691,43 @@ const struct pmc_bit_map mtl_ioep_d3_status_0_map[] = {
{}
};
-const struct pmc_bit_map mtl_ioep_d3_status_1_map[] = {
+static const struct pmc_bit_map mtl_ioep_d3_status_1_map[] = {
{"GBETSN1_D3_STS", BIT(14)},
{"P2S_D3_STS", BIT(24)},
{}
};
-const struct pmc_bit_map mtl_ioep_d3_status_2_map[] = {
+static const struct pmc_bit_map mtl_ioep_d3_status_2_map[] = {
{}
};
-const struct pmc_bit_map mtl_ioep_d3_status_3_map[] = {
+static const struct pmc_bit_map mtl_ioep_d3_status_3_map[] = {
{"GBETSN_D3_STS", BIT(13)},
{"ACE_D3_STS", BIT(23)},
{}
};
-const struct pmc_bit_map mtl_ioep_vnn_req_status_0_map[] = {
+static const struct pmc_bit_map mtl_ioep_vnn_req_status_0_map[] = {
{"FIA_VNN_REQ_STS", BIT(17)},
{}
};
-const struct pmc_bit_map mtl_ioep_vnn_req_status_1_map[] = {
+static const struct pmc_bit_map mtl_ioep_vnn_req_status_1_map[] = {
{"DFXAGG_VNN_REQ_STS", BIT(8)},
{}
};
-const struct pmc_bit_map mtl_ioep_vnn_req_status_2_map[] = {
+static const struct pmc_bit_map mtl_ioep_vnn_req_status_2_map[] = {
{}
};
-const struct pmc_bit_map mtl_ioep_vnn_req_status_3_map[] = {
+static const struct pmc_bit_map mtl_ioep_vnn_req_status_3_map[] = {
{"DTS0_VNN_REQ_STS", BIT(7)},
{"DISP_VNN_REQ_STS", BIT(19)},
{}
};
-const struct pmc_bit_map mtl_ioep_vnn_misc_status_map[] = {
+static const struct pmc_bit_map mtl_ioep_vnn_misc_status_map[] = {
{"CPU_C10_REQ_STS", BIT(0)},
{"TS_OFF_REQ_STS", BIT(1)},
{"PNDE_MET_REQ_STS", BIT(2)},
@@ -762,7 +762,7 @@ const struct pmc_bit_map mtl_ioep_vnn_misc_status_map[] = {
{}
};
-const struct pmc_bit_map *mtl_ioep_lpm_maps[] = {
+static const struct pmc_bit_map *mtl_ioep_lpm_maps[] = {
mtl_ioep_clocksource_status_map,
mtl_ioep_power_gating_status_0_map,
mtl_ioep_power_gating_status_1_map,
@@ -800,7 +800,7 @@ const struct pmc_reg_map mtl_ioep_reg_map = {
.lpm_reg_index = MTL_LPM_REG_INDEX,
};
-const struct pmc_bit_map mtl_ioem_pfear_map[] = {
+static const struct pmc_bit_map mtl_ioem_pfear_map[] = {
{"PMC_0", BIT(0)},
{"OPI", BIT(1)},
{"TCSS", BIT(2)},
@@ -887,12 +887,12 @@ const struct pmc_bit_map mtl_ioem_pfear_map[] = {
{}
};
-const struct pmc_bit_map *ext_mtl_ioem_pfear_map[] = {
+static const struct pmc_bit_map *ext_mtl_ioem_pfear_map[] = {
mtl_ioem_pfear_map,
NULL
};
-const struct pmc_bit_map mtl_ioem_power_gating_status_1_map[] = {
+static const struct pmc_bit_map mtl_ioem_power_gating_status_1_map[] = {
{"PSF9_PGD0_PG_STS", BIT(0)},
{"MPFPW4_PGD0_PG_STS", BIT(1)},
{"SBR0_PGD0_PG_STS", BIT(8)},
@@ -909,7 +909,7 @@ const struct pmc_bit_map mtl_ioem_power_gating_status_1_map[] = {
{}
};
-const struct pmc_bit_map *mtl_ioem_lpm_maps[] = {
+static const struct pmc_bit_map *mtl_ioem_lpm_maps[] = {
mtl_ioep_clocksource_status_map,
mtl_ioep_power_gating_status_0_map,
mtl_ioem_power_gating_status_1_map,
@@ -927,7 +927,7 @@ const struct pmc_bit_map *mtl_ioem_lpm_maps[] = {
NULL
};
-const struct pmc_reg_map mtl_ioem_reg_map = {
+static const struct pmc_reg_map mtl_ioem_reg_map = {
.regmap_length = MTL_IOE_PMC_MMIO_REG_LEN,
.pfear_sts = ext_mtl_ioem_pfear_map,
.ppfear0_offset = CNP_PMC_HOST_PPFEAR0A,
@@ -990,39 +990,18 @@ static int mtl_resume(struct pmc_dev *pmcdev)
return cnl_resume(pmcdev);
}
-int mtl_core_init(struct pmc_dev *pmcdev)
+static int mtl_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info)
{
- struct pmc *pmc = pmcdev->pmcs[PMC_IDX_SOC];
- int ret;
- int func = 2;
- bool ssram_init = true;
-
mtl_d3_fixup();
-
- pmcdev->suspend = cnl_suspend;
- pmcdev->resume = mtl_resume;
- pmcdev->regmap_list = mtl_pmc_info_list;
-
- /*
- * If ssram init fails use legacy method to at least get the
- * primary PMC
- */
- ret = pmc_core_ssram_init(pmcdev, func);
- if (ret) {
- ssram_init = false;
- dev_warn(&pmcdev->pdev->dev,
- "ssram init failed, %d, using legacy init\n", ret);
- pmc->map = &mtl_socm_reg_map;
- ret = get_primary_reg_base(pmc);
- if (ret)
- return ret;
- }
-
- pmc_core_get_low_power_modes(pmcdev);
- pmc_core_punit_pmt_init(pmcdev, MTL_PMT_DMU_GUID);
-
- if (ssram_init)
- return pmc_core_ssram_get_lpm_reqs(pmcdev);
-
- return 0;
+ return generic_core_init(pmcdev, pmc_dev_info);
}
+
+struct pmc_dev_info mtl_pmc_dev = {
+ .pci_func = 2,
+ .dmu_guid = MTL_PMT_DMU_GUID,
+ .regmap_list = mtl_pmc_info_list,
+ .map = &mtl_socm_reg_map,
+ .suspend = cnl_suspend,
+ .resume = mtl_resume,
+ .init = mtl_core_init,
+};
diff --git a/drivers/platform/x86/intel/pmc/ptl.c b/drivers/platform/x86/intel/pmc/ptl.c
new file mode 100644
index 000000000000..394515af60d6
--- /dev/null
+++ b/drivers/platform/x86/intel/pmc/ptl.c
@@ -0,0 +1,550 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * This file contains platform specific structure definitions
+ * and init function used by Panther Lake PCH.
+ *
+ * Copyright (c) 2025, Intel Corporation.
+ */
+
+#include <linux/pci.h>
+
+#include "core.h"
+
+static const struct pmc_bit_map ptl_pcdp_pfear_map[] = {
+ {"PMC_0", BIT(0)},
+ {"FUSE_OSSE", BIT(1)},
+ {"ESPISPI", BIT(2)},
+ {"XHCI", BIT(3)},
+ {"SPA", BIT(4)},
+ {"SPB", BIT(5)},
+ {"MPFPW2", BIT(6)},
+ {"GBE", BIT(7)},
+
+ {"SBR16B20", BIT(0)},
+ {"SBR8B20", BIT(1)},
+ {"SBR16B21", BIT(2)},
+ {"DBG_SBR16B", BIT(3)},
+ {"OSSE_HOTHAM", BIT(4)},
+ {"D2D_DISP_1", BIT(5)},
+ {"LPSS", BIT(6)},
+ {"LPC", BIT(7)},
+
+ {"SMB", BIT(0)},
+ {"ISH", BIT(1)},
+ {"SBR16B2", BIT(2)},
+ {"NPK_0", BIT(3)},
+ {"D2D_NOC_1", BIT(4)},
+ {"SBR8B2", BIT(5)},
+ {"FUSE", BIT(6)},
+ {"SBR16B0", BIT(7)},
+
+ {"PSF0", BIT(0)},
+ {"XDCI", BIT(1)},
+ {"EXI", BIT(2)},
+ {"CSE", BIT(3)},
+ {"KVMCC", BIT(4)},
+ {"PMT", BIT(5)},
+ {"CLINK", BIT(6)},
+ {"PTIO", BIT(7)},
+
+ {"USBR0", BIT(0)},
+ {"SUSRAM", BIT(1)},
+ {"SMT1", BIT(2)},
+ {"MPFPW1", BIT(3)},
+ {"SMS2", BIT(4)},
+ {"SMS1", BIT(5)},
+ {"CSMERTC", BIT(6)},
+ {"CSMEPSF", BIT(7)},
+
+ {"D2D_NOC_0", BIT(0)},
+ {"ESE", BIT(1)},
+ {"P2SB8B", BIT(2)},
+ {"SBR16B7", BIT(3)},
+ {"SBR16B3", BIT(4)},
+ {"OSSE_SMT1", BIT(5)},
+ {"D2D_DISP", BIT(6)},
+ {"DBG_SBR", BIT(7)},
+
+ {"U3FPW1", BIT(0)},
+ {"FIA_X", BIT(1)},
+ {"PSF4", BIT(2)},
+ {"CNVI", BIT(3)},
+ {"UFSX2", BIT(4)},
+ {"ENDBG", BIT(5)},
+ {"DBC", BIT(6)},
+ {"FIA_PG", BIT(7)},
+
+ {"D2D_IPU", BIT(0)},
+ {"NPK1", BIT(1)},
+ {"FIACPCB_X", BIT(2)},
+ {"SBR8B4", BIT(3)},
+ {"DBG_PSF", BIT(4)},
+ {"PSF6", BIT(5)},
+ {"UFSPW1", BIT(6)},
+ {"FIA_U", BIT(7)},
+
+ {"PSF8", BIT(0)},
+ {"SBR16B4", BIT(1)},
+ {"SBR16B5", BIT(2)},
+ {"FIACPCB_U", BIT(3)},
+ {"TAM", BIT(4)},
+ {"D2D_NOC_2", BIT(5)},
+ {"TBTLSX", BIT(6)},
+ {"THC0", BIT(7)},
+
+ {"THC1", BIT(0)},
+ {"PMC_1", BIT(1)},
+ {"SBR8B1", BIT(2)},
+ {"TCSS", BIT(3)},
+ {"DISP_PGA", BIT(4)},
+ {"SBR16B1", BIT(5)},
+ {"SBRG", BIT(6)},
+ {"PSF5", BIT(7)},
+
+ {"P2SB16B", BIT(0)},
+ {"ACE_0", BIT(1)},
+ {"ACE_1", BIT(2)},
+ {"ACE_2", BIT(3)},
+ {"ACE_3", BIT(4)},
+ {"ACE_4", BIT(5)},
+ {"ACE_5", BIT(6)},
+ {"ACE_6", BIT(7)},
+
+ {"ACE_7", BIT(0)},
+ {"ACE_8", BIT(1)},
+ {"ACE_9", BIT(2)},
+ {"ACE_10", BIT(3)},
+ {"FIACPCB_PG", BIT(4)},
+ {"SBR16B6", BIT(5)},
+ {"OSSE", BIT(6)},
+ {"SBR8B0", BIT(7)},
+ {}
+};
+
+static const struct pmc_bit_map *ext_ptl_pcdp_pfear_map[] = {
+ ptl_pcdp_pfear_map,
+ NULL
+};
+
+static 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},
+ {"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},
+ {"ESE", MTL_PMC_LTR_ESE},
+ {"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 ptl_pcdp_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},
+ {"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},
+ {"SAF_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},
+ {"RTC_PLL_OFF_STS", BIT(31), 0},
+ {}
+};
+
+static const struct pmc_bit_map ptl_pcdp_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},
+ {"SBR8B20_PGD0_PG_STS", BIT(9), 0},
+ {"SBR16B21_PGD0_PG_STS", BIT(10), 0},
+ {"DBG_PGD0_PG_STS", BIT(11), 0},
+ {"OSSE_HOTHAM_PGD0_PG_STS", BIT(12), 1},
+ {"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},
+ {"SBR8B2_PGD0_PG_STS", BIT(21), 0},
+ {"FUSE_PGD0_PG_STS", BIT(22), 0},
+ {"SBR16B0_PGD0_PG_STS", BIT(23), 0},
+ {"PSF0_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 ptl_pcdp_power_gating_status_1_map[] = {
+ {"USBR0_PGD0_PG_STS", BIT(0), 1},
+ {"SUSRAM_PGD0_PG_STS", BIT(1), 1},
+ {"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},
+ {"P2SB8B_PGD0_PG_STS", BIT(10), 1},
+ {"SBR16B7_PGD0_PG_STS", BIT(11), 0},
+ {"SBR16B3_PGD0_PG_STS", BIT(12), 0},
+ {"OSSE_SMT1_PGD0_PG_STS", BIT(13), 1},
+ {"D2D_DISP_PGD0_PG_STS", BIT(14), 1},
+ {"DBG_SBR_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 ptl_pcdp_power_gating_status_2_map[] = {
+ {"PSF8_PGD0_PG_STS", BIT(0), 0},
+ {"SBR16B4_PGD0_PG_STS", BIT(1), 0},
+ {"SBR16B5_PGD0_PG_STS", BIT(2), 0},
+ {"FIACPCB_U_PGD0_PG_STS", BIT(3), 0},
+ {"TAM_PGD0_PG_STS", BIT(4), 1},
+ {"D2D_NOC_PGD0_PG_STS", BIT(5), 1},
+ {"TBTLSX_PGD0_PG_STS", BIT(6), 1},
+ {"THC0_PGD0_PG_STS", BIT(7), 1},
+ {"THC1_PGD0_PG_STS", BIT(8), 1},
+ {"PMC_PGD1_PG_STS", BIT(9), 0},
+ {"SBR8B1_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},
+ {"P2SB16B_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},
+ {"FIACPCB_PG_PGD0_PG_STS", BIT(28), 0},
+ {"SBR16B6_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 ptl_pcdp_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},
+ {"OSSE_SMT1_D3_STS", BIT(30), 0},
+ {}
+};
+
+static const struct pmc_bit_map ptl_pcdp_d3_status_1_map[] = {
+ {"GBE_D3_STS", BIT(19), 0},
+ {"ITSS_D3_STS", BIT(23), 0},
+ {"CNVI_D3_STS", BIT(27), 0},
+ {"UFSX2_D3_STS", BIT(28), 1},
+ {"OSSE_HOTHAM_D3_STS", BIT(29), 0},
+ {"ESE_D3_STS", BIT(30), 0},
+ {}
+};
+
+static const struct pmc_bit_map ptl_pcdp_d3_status_2_map[] = {
+ {"CSMERTC_D3_STS", BIT(1), 0},
+ {"SUSRAM_D3_STS", BIT(2), 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(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 ptl_pcdp_d3_status_3_map[] = {
+ {"THC0_D3_STS", BIT(14), 1},
+ {"THC1_D3_STS", BIT(15), 1},
+ {"OSSE_SMT3_D3_STS", BIT(18), 0},
+ {"ACE_D3_STS", BIT(23), 0},
+ {}
+};
+
+static const struct pmc_bit_map ptl_pcdp_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},
+ {"OSSE_SMT1_VNN_REQ_STS", BIT(30), 1},
+ {}
+};
+
+static const struct pmc_bit_map ptl_pcdp_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},
+ {"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(30), 1},
+ {}
+};
+
+static const struct pmc_bit_map ptl_pcdp_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},
+ {"GPIOCOM1_VNN_REQ_STS", BIT(23), 1},
+ {"GPIOCOM0_VNN_REQ_STS", BIT(24), 1},
+ {"DISP_SHIM_VNN_REQ_STS", BIT(26), 1},
+ {}
+};
+
+static const struct pmc_bit_map ptl_pcdp_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 ptl_pcdp_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), 0},
+ {"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), 0},
+ {"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},
+ {"D2D_DISP_EDP_QACTIVE_REQ_STS", BIT(31), 1},
+ {}
+};
+
+static const struct pmc_bit_map ptl_pcdp_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 ptl_pcdp_rsc_status_map[] = {
+ {"Memory", 0, 1},
+ {"PSF0", 0, 1},
+ {"PSF4", 0, 1},
+ {"PSF5", 0, 1},
+ {"PSF6", 0, 1},
+ {"PSF8", 0, 1},
+ {"SAF_CFI_LINK", 0, 1},
+ {"SB", 0, 1},
+ {}
+};
+
+static const struct pmc_bit_map *ptl_pcdp_lpm_maps[] = {
+ ptl_pcdp_clocksource_status_map,
+ ptl_pcdp_power_gating_status_0_map,
+ ptl_pcdp_power_gating_status_1_map,
+ ptl_pcdp_power_gating_status_2_map,
+ ptl_pcdp_d3_status_0_map,
+ ptl_pcdp_d3_status_1_map,
+ ptl_pcdp_d3_status_2_map,
+ ptl_pcdp_d3_status_3_map,
+ ptl_pcdp_vnn_req_status_0_map,
+ ptl_pcdp_vnn_req_status_1_map,
+ ptl_pcdp_vnn_req_status_2_map,
+ ptl_pcdp_vnn_req_status_3_map,
+ ptl_pcdp_vnn_misc_status_map,
+ ptl_pcdp_signal_status_map,
+ NULL
+};
+
+static const struct pmc_bit_map *ptl_pcdp_blk_maps[] = {
+ ptl_pcdp_power_gating_status_0_map,
+ ptl_pcdp_power_gating_status_1_map,
+ ptl_pcdp_power_gating_status_2_map,
+ ptl_pcdp_rsc_status_map,
+ ptl_pcdp_vnn_req_status_0_map,
+ ptl_pcdp_vnn_req_status_1_map,
+ ptl_pcdp_vnn_req_status_2_map,
+ ptl_pcdp_vnn_req_status_3_map,
+ ptl_pcdp_d3_status_0_map,
+ ptl_pcdp_d3_status_1_map,
+ ptl_pcdp_d3_status_2_map,
+ ptl_pcdp_d3_status_3_map,
+ ptl_pcdp_clocksource_status_map,
+ ptl_pcdp_vnn_misc_status_map,
+ ptl_pcdp_signal_status_map,
+ NULL
+};
+
+static const struct pmc_reg_map ptl_pcdp_reg_map = {
+ .pfear_sts = ext_ptl_pcdp_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 = PTL_PCD_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 = ptl_pcdp_lpm_maps,
+ .lpm_status_offset = MTL_LPM_STATUS_OFFSET,
+ .lpm_live_status_offset = MTL_LPM_LIVE_STATUS_OFFSET,
+ .s0ix_blocker_maps = ptl_pcdp_blk_maps,
+ .s0ix_blocker_offset = LNL_S0IX_BLOCKER_OFFSET,
+};
+
+#define PTL_NPU_PCI_DEV 0xb03e
+#define PTL_IPU_PCI_DEV 0xb05d
+
+/*
+ * Set power state of select devices that do not have drivers to D3
+ * so that they do not block Package C entry.
+ */
+static void ptl_d3_fixup(void)
+{
+ pmc_core_set_device_d3(PTL_IPU_PCI_DEV);
+ pmc_core_set_device_d3(PTL_NPU_PCI_DEV);
+}
+
+static int ptl_resume(struct pmc_dev *pmcdev)
+{
+ ptl_d3_fixup();
+ return cnl_resume(pmcdev);
+}
+
+static int ptl_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info)
+{
+ ptl_d3_fixup();
+ return generic_core_init(pmcdev, pmc_dev_info);
+}
+
+struct pmc_dev_info ptl_pmc_dev = {
+ .map = &ptl_pcdp_reg_map,
+ .suspend = cnl_suspend,
+ .resume = ptl_resume,
+ .init = ptl_core_init,
+};
diff --git a/drivers/platform/x86/intel/pmc/spt.c b/drivers/platform/x86/intel/pmc/spt.c
index ab993a69e33e..b50534aa2cba 100644
--- a/drivers/platform/x86/intel/pmc/spt.c
+++ b/drivers/platform/x86/intel/pmc/spt.c
@@ -8,9 +8,11 @@
*
*/
+#include <linux/pci.h>
+
#include "core.h"
-const struct pmc_bit_map spt_pll_map[] = {
+static const struct pmc_bit_map spt_pll_map[] = {
{"MIPI PLL", SPT_PMC_BIT_MPHY_CMN_LANE0},
{"GEN2 USB2PCIE2 PLL", SPT_PMC_BIT_MPHY_CMN_LANE1},
{"DMIPCIE3 PLL", SPT_PMC_BIT_MPHY_CMN_LANE2},
@@ -18,7 +20,7 @@ const struct pmc_bit_map spt_pll_map[] = {
{}
};
-const struct pmc_bit_map spt_mphy_map[] = {
+static const struct pmc_bit_map spt_mphy_map[] = {
{"MPHY CORE LANE 0", SPT_PMC_BIT_MPHY_LANE0},
{"MPHY CORE LANE 1", SPT_PMC_BIT_MPHY_LANE1},
{"MPHY CORE LANE 2", SPT_PMC_BIT_MPHY_LANE2},
@@ -38,7 +40,7 @@ const struct pmc_bit_map spt_mphy_map[] = {
{}
};
-const struct pmc_bit_map spt_pfear_map[] = {
+static const struct pmc_bit_map spt_pfear_map[] = {
{"PMC", SPT_PMC_BIT_PMC},
{"OPI-DMI", SPT_PMC_BIT_OPI},
{"SPI / eSPI", SPT_PMC_BIT_SPI},
@@ -82,7 +84,7 @@ const struct pmc_bit_map spt_pfear_map[] = {
{}
};
-const struct pmc_bit_map *ext_spt_pfear_map[] = {
+static const struct pmc_bit_map *ext_spt_pfear_map[] = {
/*
* Check intel_pmc_core_ids[] users of spt_reg_map for
* a list of core SoCs using this.
@@ -91,7 +93,7 @@ const struct pmc_bit_map *ext_spt_pfear_map[] = {
NULL
};
-const struct pmc_bit_map spt_ltr_show_map[] = {
+static const struct pmc_bit_map spt_ltr_show_map[] = {
{"SOUTHPORT_A", SPT_PMC_LTR_SPA},
{"SOUTHPORT_B", SPT_PMC_LTR_SPB},
{"SATA", SPT_PMC_LTR_SATA},
@@ -116,7 +118,7 @@ const struct pmc_bit_map spt_ltr_show_map[] = {
{}
};
-const struct pmc_reg_map spt_reg_map = {
+static const struct pmc_reg_map spt_reg_map = {
.pfear_sts = ext_spt_pfear_map,
.mphy_sts = spt_mphy_map,
.pll_sts = spt_pll_map,
@@ -134,18 +136,25 @@ const struct pmc_reg_map spt_reg_map = {
.pm_vric1_offset = SPT_PMC_VRIC1_OFFSET,
};
-int spt_core_init(struct pmc_dev *pmcdev)
-{
- struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN];
- int ret;
-
- pmc->map = &spt_reg_map;
-
- ret = get_primary_reg_base(pmc);
- if (ret)
- return ret;
+static const struct pci_device_id spt_pmc_pci_id[] = {
+ { PCI_VDEVICE(INTEL, SPT_PMC_PCI_DEVICE_ID) },
+ { }
+};
- pmc_core_get_low_power_modes(pmcdev);
+static int spt_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info)
+{
+ /*
+ * Coffee Lake has CPU ID of Kaby Lake and Cannon Lake PCH. So here
+ * Sunrisepoint PCH regmap can't be used. Use Cannon Lake PCH regmap
+ * in this case.
+ */
+ if (!pci_dev_present(spt_pmc_pci_id))
+ return generic_core_init(pmcdev, &cnp_pmc_dev);
- return ret;
+ return generic_core_init(pmcdev, pmc_dev_info);
}
+
+struct pmc_dev_info spt_pmc_dev = {
+ .map = &spt_reg_map,
+ .init = spt_core_init,
+};
diff --git a/drivers/platform/x86/intel/pmc/tgl.c b/drivers/platform/x86/intel/pmc/tgl.c
index e0580de18077..02e731ed3391 100644
--- a/drivers/platform/x86/intel/pmc/tgl.c
+++ b/drivers/platform/x86/intel/pmc/tgl.c
@@ -18,7 +18,7 @@ enum pch_type {
PCH_LP
};
-const struct pmc_bit_map tgl_pfear_map[] = {
+static const struct pmc_bit_map tgl_pfear_map[] = {
{"PSF9", BIT(0)},
{"RES_66", BIT(1)},
{"RES_67", BIT(2)},
@@ -29,7 +29,7 @@ const struct pmc_bit_map tgl_pfear_map[] = {
{}
};
-const struct pmc_bit_map *ext_tgl_pfear_map[] = {
+static const struct pmc_bit_map *ext_tgl_pfear_map[] = {
/*
* Check intel_pmc_core_ids[] users of tgl_reg_map for
* a list of core SoCs using this.
@@ -39,7 +39,7 @@ const struct pmc_bit_map *ext_tgl_pfear_map[] = {
NULL
};
-const struct pmc_bit_map tgl_clocksource_status_map[] = {
+static const struct pmc_bit_map tgl_clocksource_status_map[] = {
{"USB2PLL_OFF_STS", BIT(18)},
{"PCIe/USB3.1_Gen2PLL_OFF_STS", BIT(19)},
{"PCIe_Gen3PLL_OFF_STS", BIT(20)},
@@ -55,7 +55,7 @@ const struct pmc_bit_map tgl_clocksource_status_map[] = {
{}
};
-const struct pmc_bit_map tgl_power_gating_status_map[] = {
+static const struct pmc_bit_map tgl_power_gating_status_map[] = {
{"CSME_PG_STS", BIT(0)},
{"SATA_PG_STS", BIT(1)},
{"xHCI_PG_STS", BIT(2)},
@@ -83,7 +83,7 @@ const struct pmc_bit_map tgl_power_gating_status_map[] = {
{}
};
-const struct pmc_bit_map tgl_d3_status_map[] = {
+static const struct pmc_bit_map tgl_d3_status_map[] = {
{"ADSP_D3_STS", BIT(0)},
{"SATA_D3_STS", BIT(1)},
{"xHCI0_D3_STS", BIT(2)},
@@ -98,7 +98,7 @@ const struct pmc_bit_map tgl_d3_status_map[] = {
{}
};
-const struct pmc_bit_map tgl_vnn_req_status_map[] = {
+static const struct pmc_bit_map tgl_vnn_req_status_map[] = {
{"GPIO_COM0_VNN_REQ_STS", BIT(1)},
{"GPIO_COM1_VNN_REQ_STS", BIT(2)},
{"GPIO_COM2_VNN_REQ_STS", BIT(3)},
@@ -123,7 +123,7 @@ const struct pmc_bit_map tgl_vnn_req_status_map[] = {
{}
};
-const struct pmc_bit_map tgl_vnn_misc_status_map[] = {
+static const struct pmc_bit_map tgl_vnn_misc_status_map[] = {
{"CPU_C10_REQ_STS_0", BIT(0)},
{"PCIe_LPM_En_REQ_STS_3", BIT(3)},
{"ITH_REQ_STS_5", BIT(5)},
@@ -175,7 +175,7 @@ const struct pmc_bit_map tgl_signal_status_map[] = {
{}
};
-const struct pmc_bit_map *tgl_lpm_maps[] = {
+static const struct pmc_bit_map *tgl_lpm_maps[] = {
tgl_clocksource_status_map,
tgl_power_gating_status_map,
tgl_d3_status_map,
@@ -185,7 +185,7 @@ const struct pmc_bit_map *tgl_lpm_maps[] = {
NULL
};
-const struct pmc_reg_map tgl_reg_map = {
+static const struct pmc_reg_map tgl_reg_map = {
.pfear_sts = ext_tgl_pfear_map,
.slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET,
.slp_s0_res_counter_step = TGL_PMC_SLP_S0_RES_COUNTER_STEP,
@@ -210,7 +210,7 @@ const struct pmc_reg_map tgl_reg_map = {
.etr3_offset = ETR3_OFFSET,
};
-const struct pmc_reg_map tgl_h_reg_map = {
+static const struct pmc_reg_map tgl_h_reg_map = {
.pfear_sts = ext_tgl_pfear_map,
.slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET,
.slp_s0_res_counter_step = TGL_PMC_SLP_S0_RES_COUNTER_STEP,
@@ -285,35 +285,28 @@ free_acpi_obj:
ACPI_FREE(out_obj);
}
-int tgl_l_core_init(struct pmc_dev *pmcdev)
+static int tgl_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info)
{
- return tgl_core_generic_init(pmcdev, PCH_LP);
-}
-
-int tgl_core_init(struct pmc_dev *pmcdev)
-{
- return tgl_core_generic_init(pmcdev, PCH_H);
-}
-
-int tgl_core_generic_init(struct pmc_dev *pmcdev, int pch_tp)
-{
- struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN];
int ret;
- if (pch_tp == PCH_H)
- pmc->map = &tgl_h_reg_map;
- else
- pmc->map = &tgl_reg_map;
-
- pmcdev->suspend = cnl_suspend;
- pmcdev->resume = cnl_resume;
-
- ret = get_primary_reg_base(pmc);
+ ret = generic_core_init(pmcdev, pmc_dev_info);
if (ret)
return ret;
- pmc_core_get_low_power_modes(pmcdev);
pmc_core_get_tgl_lpm_reqs(pmcdev->pdev);
-
return 0;
}
+
+struct pmc_dev_info tgl_l_pmc_dev = {
+ .map = &tgl_reg_map,
+ .suspend = cnl_suspend,
+ .resume = cnl_resume,
+ .init = tgl_core_init,
+};
+
+struct pmc_dev_info tgl_pmc_dev = {
+ .map = &tgl_h_reg_map,
+ .suspend = cnl_suspend,
+ .resume = cnl_resume,
+ .init = tgl_core_init,
+};
diff --git a/drivers/platform/x86/lenovo-wmi-hotkey-utilities.c b/drivers/platform/x86/lenovo-wmi-hotkey-utilities.c
new file mode 100644
index 000000000000..89153afd7015
--- /dev/null
+++ b/drivers/platform/x86/lenovo-wmi-hotkey-utilities.c
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Lenovo Super Hotkey Utility WMI extras driver for Ideapad laptop
+ *
+ * Copyright (C) 2025 Lenovo
+ */
+
+#include <linux/cleanup.h>
+#include <linux/dev_printk.h>
+#include <linux/device.h>
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/wmi.h>
+
+/* Lenovo Super Hotkey WMI GUIDs */
+#define LUD_WMI_METHOD_GUID "CE6C0974-0407-4F50-88BA-4FC3B6559AD8"
+
+/* Lenovo Utility Data WMI method_id */
+#define WMI_LUD_GET_SUPPORT 1
+#define WMI_LUD_SET_FEATURE 2
+
+#define WMI_LUD_GET_MICMUTE_LED_VER 20
+#define WMI_LUD_GET_AUDIOMUTE_LED_VER 26
+
+#define WMI_LUD_SUPPORT_MICMUTE_LED_VER 25
+#define WMI_LUD_SUPPORT_AUDIOMUTE_LED_VER 27
+
+/* Input parameters to mute/unmute audio LED and Mic LED */
+struct wmi_led_args {
+ u8 id;
+ u8 subid;
+ u16 value;
+};
+
+/* Values of input parameters to SetFeature of audio LED and Mic LED */
+enum hotkey_set_feature {
+ MIC_MUTE_LED_ON = 1,
+ MIC_MUTE_LED_OFF = 2,
+ AUDIO_MUTE_LED_ON = 4,
+ AUDIO_MUTE_LED_OFF = 5,
+};
+
+#define LSH_ACPI_LED_MAX 2
+
+struct lenovo_super_hotkey_wmi_private {
+ struct led_classdev cdev[LSH_ACPI_LED_MAX];
+ struct wmi_device *led_wdev;
+};
+
+enum mute_led_type {
+ MIC_MUTE,
+ AUDIO_MUTE,
+};
+
+static int lsh_wmi_mute_led_set(enum mute_led_type led_type, struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+
+{
+ struct lenovo_super_hotkey_wmi_private *wpriv = container_of(led_cdev,
+ struct lenovo_super_hotkey_wmi_private, cdev[led_type]);
+ struct wmi_led_args led_arg = {0, 0, 0};
+ struct acpi_buffer input;
+ acpi_status status;
+
+ switch (led_type) {
+ case MIC_MUTE:
+ led_arg.id = brightness == LED_ON ? MIC_MUTE_LED_ON : MIC_MUTE_LED_OFF;
+ break;
+ case AUDIO_MUTE:
+ led_arg.id = brightness == LED_ON ? AUDIO_MUTE_LED_ON : AUDIO_MUTE_LED_OFF;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ input.length = sizeof(led_arg);
+ input.pointer = &led_arg;
+ status = wmidev_evaluate_method(wpriv->led_wdev, 0, WMI_LUD_SET_FEATURE, &input, NULL);
+ if (ACPI_FAILURE(status))
+ return -EIO;
+
+ return 0;
+}
+
+static int lsh_wmi_audiomute_led_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+
+{
+ return lsh_wmi_mute_led_set(AUDIO_MUTE, led_cdev, brightness);
+}
+
+static int lsh_wmi_micmute_led_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ return lsh_wmi_mute_led_set(MIC_MUTE, led_cdev, brightness);
+}
+
+static int lenovo_super_hotkey_wmi_led_init(enum mute_led_type led_type, struct device *dev)
+{
+ struct lenovo_super_hotkey_wmi_private *wpriv = dev_get_drvdata(dev);
+ struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+ struct acpi_buffer input;
+ int led_version, err = 0;
+ unsigned int wmiarg;
+ acpi_status status;
+
+ switch (led_type) {
+ case MIC_MUTE:
+ wmiarg = WMI_LUD_GET_MICMUTE_LED_VER;
+ break;
+ case AUDIO_MUTE:
+ wmiarg = WMI_LUD_GET_AUDIOMUTE_LED_VER;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ input.length = sizeof(wmiarg);
+ input.pointer = &wmiarg;
+ status = wmidev_evaluate_method(wpriv->led_wdev, 0, WMI_LUD_GET_SUPPORT, &input, &output);
+ if (ACPI_FAILURE(status))
+ return -EIO;
+
+ union acpi_object *obj __free(kfree) = output.pointer;
+ if (obj && obj->type == ACPI_TYPE_INTEGER)
+ led_version = obj->integer.value;
+ else
+ return -EIO;
+
+ wpriv->cdev[led_type].max_brightness = LED_ON;
+ wpriv->cdev[led_type].flags = LED_CORE_SUSPENDRESUME;
+
+ switch (led_type) {
+ case MIC_MUTE:
+ if (led_version != WMI_LUD_SUPPORT_MICMUTE_LED_VER)
+ return -EIO;
+
+ wpriv->cdev[led_type].name = "platform::micmute";
+ wpriv->cdev[led_type].brightness_set_blocking = &lsh_wmi_micmute_led_set;
+ wpriv->cdev[led_type].default_trigger = "audio-micmute";
+ break;
+ case AUDIO_MUTE:
+ if (led_version != WMI_LUD_SUPPORT_AUDIOMUTE_LED_VER)
+ return -EIO;
+
+ wpriv->cdev[led_type].name = "platform::mute";
+ wpriv->cdev[led_type].brightness_set_blocking = &lsh_wmi_audiomute_led_set;
+ wpriv->cdev[led_type].default_trigger = "audio-mute";
+ break;
+ default:
+ dev_err(dev, "Unknown LED type %d\n", led_type);
+ return -EINVAL;
+ }
+
+ err = devm_led_classdev_register(dev, &wpriv->cdev[led_type]);
+ if (err < 0) {
+ dev_err(dev, "Could not register mute LED %d : %d\n", led_type, err);
+ return err;
+ }
+ return 0;
+}
+
+static int lenovo_super_hotkey_wmi_leds_setup(struct device *dev)
+{
+ int err;
+
+ err = lenovo_super_hotkey_wmi_led_init(MIC_MUTE, dev);
+ if (err)
+ return err;
+
+ err = lenovo_super_hotkey_wmi_led_init(AUDIO_MUTE, dev);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+static int lenovo_super_hotkey_wmi_probe(struct wmi_device *wdev, const void *context)
+{
+ struct lenovo_super_hotkey_wmi_private *wpriv;
+
+ wpriv = devm_kzalloc(&wdev->dev, sizeof(*wpriv), GFP_KERNEL);
+ if (!wpriv)
+ return -ENOMEM;
+
+ dev_set_drvdata(&wdev->dev, wpriv);
+ wpriv->led_wdev = wdev;
+ return lenovo_super_hotkey_wmi_leds_setup(&wdev->dev);
+}
+
+static const struct wmi_device_id lenovo_super_hotkey_wmi_id_table[] = {
+ { LUD_WMI_METHOD_GUID, NULL }, /* Utility data */
+ { }
+};
+
+MODULE_DEVICE_TABLE(wmi, lenovo_super_hotkey_wmi_id_table);
+
+static struct wmi_driver lenovo_wmi_hotkey_utilities_driver = {
+ .driver = {
+ .name = "lenovo_wmi_hotkey_utilities",
+ .probe_type = PROBE_PREFER_ASYNCHRONOUS
+ },
+ .id_table = lenovo_super_hotkey_wmi_id_table,
+ .probe = lenovo_super_hotkey_wmi_probe,
+ .no_singleton = true,
+};
+
+module_wmi_driver(lenovo_wmi_hotkey_utilities_driver);
+
+MODULE_AUTHOR("Jackie Dong <dongeg1@lenovo.com>");
+MODULE_DESCRIPTION("Lenovo Super Hotkey Utility WMI extras driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/platform/x86/lenovo-yoga-tab2-pro-1380-fastcharger.c b/drivers/platform/x86/lenovo-yoga-tab2-pro-1380-fastcharger.c
index a96b215cd2c5..25933cd018d1 100644
--- a/drivers/platform/x86/lenovo-yoga-tab2-pro-1380-fastcharger.c
+++ b/drivers/platform/x86/lenovo-yoga-tab2-pro-1380-fastcharger.c
@@ -219,7 +219,7 @@ static int yt2_1380_fc_serdev_probe(struct serdev_device *serdev)
return 0;
}
-struct serdev_device_driver yt2_1380_fc_serdev_driver = {
+static struct serdev_device_driver yt2_1380_fc_serdev_driver = {
.probe = yt2_1380_fc_serdev_probe,
.driver = {
.name = KBUILD_MODNAME,
diff --git a/drivers/platform/x86/mlx-platform.c b/drivers/platform/x86/mlx-platform.c
deleted file mode 100644
index 9c7f30a47f1f..000000000000
--- a/drivers/platform/x86/mlx-platform.c
+++ /dev/null
@@ -1,6666 +0,0 @@
-// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
-/*
- * Mellanox platform driver
- *
- * Copyright (C) 2016-2018 Mellanox Technologies
- * Copyright (C) 2016-2018 Vadim Pasternak <vadimp@mellanox.com>
- */
-
-#include <linux/device.h>
-#include <linux/dmi.h>
-#include <linux/i2c.h>
-#include <linux/i2c-mux.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/platform_device.h>
-#include <linux/platform_data/i2c-mux-reg.h>
-#include <linux/platform_data/mlxreg.h>
-#include <linux/reboot.h>
-#include <linux/regmap.h>
-
-#define MLX_PLAT_DEVICE_NAME "mlxplat"
-
-/* LPC bus IO offsets */
-#define MLXPLAT_CPLD_LPC_I2C_BASE_ADRR 0x2000
-#define MLXPLAT_CPLD_LPC_REG_BASE_ADRR 0x2500
-#define MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET 0x00
-#define MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET 0x01
-#define MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET 0x02
-#define MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET 0x03
-#define MLXPLAT_CPLD_LPC_REG_CPLD1_PN_OFFSET 0x04
-#define MLXPLAT_CPLD_LPC_REG_CPLD1_PN1_OFFSET 0x05
-#define MLXPLAT_CPLD_LPC_REG_CPLD2_PN_OFFSET 0x06
-#define MLXPLAT_CPLD_LPC_REG_CPLD2_PN1_OFFSET 0x07
-#define MLXPLAT_CPLD_LPC_REG_CPLD3_PN_OFFSET 0x08
-#define MLXPLAT_CPLD_LPC_REG_CPLD3_PN1_OFFSET 0x09
-#define MLXPLAT_CPLD_LPC_REG_CPLD4_PN_OFFSET 0x0a
-#define MLXPLAT_CPLD_LPC_REG_CPLD4_PN1_OFFSET 0x0b
-#define MLXPLAT_CPLD_LPC_REG_RESET_GP1_OFFSET 0x17
-#define MLXPLAT_CPLD_LPC_REG_RESET_GP2_OFFSET 0x19
-#define MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET 0x1c
-#define MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET 0x1d
-#define MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET 0x1e
-#define MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET 0x1f
-#define MLXPLAT_CPLD_LPC_REG_LED1_OFFSET 0x20
-#define MLXPLAT_CPLD_LPC_REG_LED2_OFFSET 0x21
-#define MLXPLAT_CPLD_LPC_REG_LED3_OFFSET 0x22
-#define MLXPLAT_CPLD_LPC_REG_LED4_OFFSET 0x23
-#define MLXPLAT_CPLD_LPC_REG_LED5_OFFSET 0x24
-#define MLXPLAT_CPLD_LPC_REG_LED6_OFFSET 0x25
-#define MLXPLAT_CPLD_LPC_REG_LED7_OFFSET 0x26
-#define MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION 0x2a
-#define MLXPLAT_CPLD_LPC_REG_GP0_RO_OFFSET 0x2b
-#define MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET 0x2d
-#define MLXPLAT_CPLD_LPC_REG_GP0_OFFSET 0x2e
-#define MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET 0x2f
-#define MLXPLAT_CPLD_LPC_REG_GP1_OFFSET 0x30
-#define MLXPLAT_CPLD_LPC_REG_WP1_OFFSET 0x31
-#define MLXPLAT_CPLD_LPC_REG_GP2_OFFSET 0x32
-#define MLXPLAT_CPLD_LPC_REG_WP2_OFFSET 0x33
-#define MLXPLAT_CPLD_LPC_REG_FIELD_UPGRADE 0x34
-#define MLXPLAT_CPLD_LPC_SAFE_BIOS_OFFSET 0x35
-#define MLXPLAT_CPLD_LPC_SAFE_BIOS_WP_OFFSET 0x36
-#define MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET 0x37
-#define MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET 0x3a
-#define MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET 0x3b
-#define MLXPLAT_CPLD_LPC_REG_FU_CAP_OFFSET 0x3c
-#define MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET 0x40
-#define MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET 0x41
-#define MLXPLAT_CPLD_LPC_REG_AGGRCO_OFFSET 0x42
-#define MLXPLAT_CPLD_LPC_REG_AGGRCO_MASK_OFFSET 0x43
-#define MLXPLAT_CPLD_LPC_REG_AGGRCX_OFFSET 0x44
-#define MLXPLAT_CPLD_LPC_REG_AGGRCX_MASK_OFFSET 0x45
-#define MLXPLAT_CPLD_LPC_REG_BRD_OFFSET 0x47
-#define MLXPLAT_CPLD_LPC_REG_BRD_EVENT_OFFSET 0x48
-#define MLXPLAT_CPLD_LPC_REG_BRD_MASK_OFFSET 0x49
-#define MLXPLAT_CPLD_LPC_REG_GWP_OFFSET 0x4a
-#define MLXPLAT_CPLD_LPC_REG_GWP_EVENT_OFFSET 0x4b
-#define MLXPLAT_CPLD_LPC_REG_GWP_MASK_OFFSET 0x4c
-#define MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET 0x50
-#define MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET 0x51
-#define MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET 0x52
-#define MLXPLAT_CPLD_LPC_REG_ASIC2_HEALTH_OFFSET 0x53
-#define MLXPLAT_CPLD_LPC_REG_ASIC2_EVENT_OFFSET 0x54
-#define MLXPLAT_CPLD_LPC_REG_ASIC2_MASK_OFFSET 0x55
-#define MLXPLAT_CPLD_LPC_REG_AGGRLC_OFFSET 0x56
-#define MLXPLAT_CPLD_LPC_REG_AGGRLC_MASK_OFFSET 0x57
-#define MLXPLAT_CPLD_LPC_REG_PSU_OFFSET 0x58
-#define MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET 0x59
-#define MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET 0x5a
-#define MLXPLAT_CPLD_LPC_REG_PWR_OFFSET 0x64
-#define MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET 0x65
-#define MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET 0x66
-#define MLXPLAT_CPLD_LPC_REG_LC_IN_OFFSET 0x70
-#define MLXPLAT_CPLD_LPC_REG_LC_IN_EVENT_OFFSET 0x71
-#define MLXPLAT_CPLD_LPC_REG_LC_IN_MASK_OFFSET 0x72
-#define MLXPLAT_CPLD_LPC_REG_FAN_OFFSET 0x88
-#define MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET 0x89
-#define MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET 0x8a
-#define MLXPLAT_CPLD_LPC_REG_CPLD5_VER_OFFSET 0x8e
-#define MLXPLAT_CPLD_LPC_REG_CPLD5_PN_OFFSET 0x8f
-#define MLXPLAT_CPLD_LPC_REG_CPLD5_PN1_OFFSET 0x90
-#define MLXPLAT_CPLD_LPC_REG_EROT_OFFSET 0x91
-#define MLXPLAT_CPLD_LPC_REG_EROT_EVENT_OFFSET 0x92
-#define MLXPLAT_CPLD_LPC_REG_EROT_MASK_OFFSET 0x93
-#define MLXPLAT_CPLD_LPC_REG_EROTE_OFFSET 0x94
-#define MLXPLAT_CPLD_LPC_REG_EROTE_EVENT_OFFSET 0x95
-#define MLXPLAT_CPLD_LPC_REG_EROTE_MASK_OFFSET 0x96
-#define MLXPLAT_CPLD_LPC_REG_PWRB_OFFSET 0x97
-#define MLXPLAT_CPLD_LPC_REG_PWRB_EVENT_OFFSET 0x98
-#define MLXPLAT_CPLD_LPC_REG_PWRB_MASK_OFFSET 0x99
-#define MLXPLAT_CPLD_LPC_REG_LC_VR_OFFSET 0x9a
-#define MLXPLAT_CPLD_LPC_REG_LC_VR_EVENT_OFFSET 0x9b
-#define MLXPLAT_CPLD_LPC_REG_LC_VR_MASK_OFFSET 0x9c
-#define MLXPLAT_CPLD_LPC_REG_LC_PG_OFFSET 0x9d
-#define MLXPLAT_CPLD_LPC_REG_LC_PG_EVENT_OFFSET 0x9e
-#define MLXPLAT_CPLD_LPC_REG_LC_PG_MASK_OFFSET 0x9f
-#define MLXPLAT_CPLD_LPC_REG_LC_RD_OFFSET 0xa0
-#define MLXPLAT_CPLD_LPC_REG_LC_RD_EVENT_OFFSET 0xa1
-#define MLXPLAT_CPLD_LPC_REG_LC_RD_MASK_OFFSET 0xa2
-#define MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET 0xa3
-#define MLXPLAT_CPLD_LPC_REG_LC_SN_EVENT_OFFSET 0xa4
-#define MLXPLAT_CPLD_LPC_REG_LC_SN_MASK_OFFSET 0xa5
-#define MLXPLAT_CPLD_LPC_REG_LC_OK_OFFSET 0xa6
-#define MLXPLAT_CPLD_LPC_REG_LC_OK_EVENT_OFFSET 0xa7
-#define MLXPLAT_CPLD_LPC_REG_LC_OK_MASK_OFFSET 0xa8
-#define MLXPLAT_CPLD_LPC_REG_LC_SD_OFFSET 0xa9
-#define MLXPLAT_CPLD_LPC_REG_LC_SD_EVENT_OFFSET 0xaa
-#define MLXPLAT_CPLD_LPC_REG_LC_SD_MASK_OFFSET 0xab
-#define MLXPLAT_CPLD_LPC_REG_LC_PWR_ON 0xb2
-#define MLXPLAT_CPLD_LPC_REG_DBG1_OFFSET 0xb6
-#define MLXPLAT_CPLD_LPC_REG_DBG2_OFFSET 0xb7
-#define MLXPLAT_CPLD_LPC_REG_DBG3_OFFSET 0xb8
-#define MLXPLAT_CPLD_LPC_REG_DBG4_OFFSET 0xb9
-#define MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET 0xc2
-#define MLXPLAT_CPLD_LPC_REG_SPI_CHNL_SELECT 0xc3
-#define MLXPLAT_CPLD_LPC_REG_CPLD5_MVER_OFFSET 0xc4
-#define MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET 0xc7
-#define MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET 0xc8
-#define MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET 0xc9
-#define MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET 0xcb
-#define MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET 0xcd
-#define MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET 0xce
-#define MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET 0xcf
-#define MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET 0xd1
-#define MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET 0xd2
-#define MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET 0xd3
-#define MLXPLAT_CPLD_LPC_REG_DBG_CTRL_OFFSET 0xd9
-#define MLXPLAT_CPLD_LPC_REG_I2C_CH1_OFFSET 0xdb
-#define MLXPLAT_CPLD_LPC_REG_I2C_CH2_OFFSET 0xda
-#define MLXPLAT_CPLD_LPC_REG_I2C_CH3_OFFSET 0xdc
-#define MLXPLAT_CPLD_LPC_REG_I2C_CH4_OFFSET 0xdd
-#define MLXPLAT_CPLD_LPC_REG_CPLD1_MVER_OFFSET 0xde
-#define MLXPLAT_CPLD_LPC_REG_CPLD2_MVER_OFFSET 0xdf
-#define MLXPLAT_CPLD_LPC_REG_CPLD3_MVER_OFFSET 0xe0
-#define MLXPLAT_CPLD_LPC_REG_CPLD4_MVER_OFFSET 0xe1
-#define MLXPLAT_CPLD_LPC_REG_UFM_VERSION_OFFSET 0xe2
-#define MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET 0xe3
-#define MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET 0xe4
-#define MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET 0xe5
-#define MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET 0xe6
-#define MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET 0xe7
-#define MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET 0xe8
-#define MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET 0xe9
-#define MLXPLAT_CPLD_LPC_REG_PWM2_OFFSET 0xea
-#define MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET 0xeb
-#define MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET 0xec
-#define MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET 0xed
-#define MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET 0xee
-#define MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET 0xef
-#define MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET 0xf0
-#define MLXPLAT_CPLD_LPC_REG_TACHO13_OFFSET 0xf1
-#define MLXPLAT_CPLD_LPC_REG_TACHO14_OFFSET 0xf2
-#define MLXPLAT_CPLD_LPC_REG_PWM3_OFFSET 0xf3
-#define MLXPLAT_CPLD_LPC_REG_PWM4_OFFSET 0xf4
-#define MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET 0xf5
-#define MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET 0xf6
-#define MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET 0xf7
-#define MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET 0xf8
-#define MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET 0xf9
-#define MLXPLAT_CPLD_LPC_REG_SLOT_QTY_OFFSET 0xfa
-#define MLXPLAT_CPLD_LPC_REG_CONFIG1_OFFSET 0xfb
-#define MLXPLAT_CPLD_LPC_REG_CONFIG2_OFFSET 0xfc
-#define MLXPLAT_CPLD_LPC_REG_CONFIG3_OFFSET 0xfd
-#define MLXPLAT_CPLD_LPC_IO_RANGE 0x100
-
-#define MLXPLAT_CPLD_LPC_PIO_OFFSET 0x10000UL
-#define MLXPLAT_CPLD_LPC_REG1 ((MLXPLAT_CPLD_LPC_REG_BASE_ADRR + \
- MLXPLAT_CPLD_LPC_REG_I2C_CH1_OFFSET) | \
- MLXPLAT_CPLD_LPC_PIO_OFFSET)
-#define MLXPLAT_CPLD_LPC_REG2 ((MLXPLAT_CPLD_LPC_REG_BASE_ADRR + \
- MLXPLAT_CPLD_LPC_REG_I2C_CH2_OFFSET) | \
- MLXPLAT_CPLD_LPC_PIO_OFFSET)
-#define MLXPLAT_CPLD_LPC_REG3 ((MLXPLAT_CPLD_LPC_REG_BASE_ADRR + \
- MLXPLAT_CPLD_LPC_REG_I2C_CH3_OFFSET) | \
- MLXPLAT_CPLD_LPC_PIO_OFFSET)
-#define MLXPLAT_CPLD_LPC_REG4 ((MLXPLAT_CPLD_LPC_REG_BASE_ADRR + \
- MLXPLAT_CPLD_LPC_REG_I2C_CH4_OFFSET) | \
- MLXPLAT_CPLD_LPC_PIO_OFFSET)
-
-/* Masks for aggregation, psu, pwr and fan event in CPLD related registers. */
-#define MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF 0x04
-#define MLXPLAT_CPLD_AGGR_PSU_MASK_DEF 0x08
-#define MLXPLAT_CPLD_AGGR_PWR_MASK_DEF 0x08
-#define MLXPLAT_CPLD_AGGR_FAN_MASK_DEF 0x40
-#define MLXPLAT_CPLD_AGGR_MASK_DEF (MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF | \
- MLXPLAT_CPLD_AGGR_PSU_MASK_DEF | \
- MLXPLAT_CPLD_AGGR_FAN_MASK_DEF)
-#define MLXPLAT_CPLD_AGGR_ASIC_MASK_NG 0x01
-#define MLXPLAT_CPLD_AGGR_MASK_NG_DEF 0x04
-#define MLXPLAT_CPLD_AGGR_MASK_COMEX BIT(0)
-#define MLXPLAT_CPLD_AGGR_MASK_LC BIT(3)
-#define MLXPLAT_CPLD_AGGR_MASK_MODULAR (MLXPLAT_CPLD_AGGR_MASK_NG_DEF | \
- MLXPLAT_CPLD_AGGR_MASK_COMEX | \
- MLXPLAT_CPLD_AGGR_MASK_LC)
-#define MLXPLAT_CPLD_AGGR_MASK_LC_PRSNT BIT(0)
-#define MLXPLAT_CPLD_AGGR_MASK_LC_RDY BIT(1)
-#define MLXPLAT_CPLD_AGGR_MASK_LC_PG BIT(2)
-#define MLXPLAT_CPLD_AGGR_MASK_LC_SCRD BIT(3)
-#define MLXPLAT_CPLD_AGGR_MASK_LC_SYNC BIT(4)
-#define MLXPLAT_CPLD_AGGR_MASK_LC_ACT BIT(5)
-#define MLXPLAT_CPLD_AGGR_MASK_LC_SDWN BIT(6)
-#define MLXPLAT_CPLD_AGGR_MASK_LC_LOW (MLXPLAT_CPLD_AGGR_MASK_LC_PRSNT | \
- MLXPLAT_CPLD_AGGR_MASK_LC_RDY | \
- MLXPLAT_CPLD_AGGR_MASK_LC_PG | \
- MLXPLAT_CPLD_AGGR_MASK_LC_SCRD | \
- MLXPLAT_CPLD_AGGR_MASK_LC_SYNC | \
- MLXPLAT_CPLD_AGGR_MASK_LC_ACT | \
- MLXPLAT_CPLD_AGGR_MASK_LC_SDWN)
-#define MLXPLAT_CPLD_LOW_AGGR_MASK_LOW 0xc1
-#define MLXPLAT_CPLD_LOW_AGGR_MASK_ASIC2 BIT(2)
-#define MLXPLAT_CPLD_LOW_AGGR_MASK_PWR_BUT GENMASK(5, 4)
-#define MLXPLAT_CPLD_LOW_AGGR_MASK_I2C BIT(6)
-#define MLXPLAT_CPLD_PSU_MASK GENMASK(1, 0)
-#define MLXPLAT_CPLD_PWR_MASK GENMASK(1, 0)
-#define MLXPLAT_CPLD_PSU_EXT_MASK GENMASK(3, 0)
-#define MLXPLAT_CPLD_PWR_EXT_MASK GENMASK(3, 0)
-#define MLXPLAT_CPLD_FAN_MASK GENMASK(3, 0)
-#define MLXPLAT_CPLD_ASIC_MASK GENMASK(1, 0)
-#define MLXPLAT_CPLD_FAN_NG_MASK GENMASK(6, 0)
-#define MLXPLAT_CPLD_LED_LO_NIBBLE_MASK GENMASK(7, 4)
-#define MLXPLAT_CPLD_LED_HI_NIBBLE_MASK GENMASK(3, 0)
-#define MLXPLAT_CPLD_VOLTREG_UPD_MASK GENMASK(5, 4)
-#define MLXPLAT_CPLD_GWP_MASK GENMASK(0, 0)
-#define MLXPLAT_CPLD_EROT_MASK GENMASK(1, 0)
-#define MLXPLAT_CPLD_FU_CAP_MASK GENMASK(1, 0)
-#define MLXPLAT_CPLD_PWR_BUTTON_MASK BIT(0)
-#define MLXPLAT_CPLD_LATCH_RST_MASK BIT(6)
-#define MLXPLAT_CPLD_THERMAL1_PDB_MASK BIT(3)
-#define MLXPLAT_CPLD_THERMAL2_PDB_MASK BIT(4)
-#define MLXPLAT_CPLD_INTRUSION_MASK BIT(6)
-#define MLXPLAT_CPLD_PWM_PG_MASK BIT(7)
-#define MLXPLAT_CPLD_L1_CHA_HEALTH_MASK (MLXPLAT_CPLD_THERMAL1_PDB_MASK | \
- MLXPLAT_CPLD_THERMAL2_PDB_MASK | \
- MLXPLAT_CPLD_INTRUSION_MASK |\
- MLXPLAT_CPLD_PWM_PG_MASK)
-#define MLXPLAT_CPLD_I2C_CAP_BIT 0x04
-#define MLXPLAT_CPLD_I2C_CAP_MASK GENMASK(5, MLXPLAT_CPLD_I2C_CAP_BIT)
-#define MLXPLAT_CPLD_SYS_RESET_MASK BIT(0)
-
-/* Masks for aggregation for comex carriers */
-#define MLXPLAT_CPLD_AGGR_MASK_CARRIER BIT(1)
-#define MLXPLAT_CPLD_AGGR_MASK_CARR_DEF (MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF | \
- MLXPLAT_CPLD_AGGR_MASK_CARRIER)
-#define MLXPLAT_CPLD_LOW_AGGRCX_MASK 0xc1
-
-/* Masks for aggregation for modular systems */
-#define MLXPLAT_CPLD_LPC_LC_MASK GENMASK(7, 0)
-
-#define MLXPLAT_CPLD_HALT_MASK BIT(3)
-#define MLXPLAT_CPLD_RESET_MASK GENMASK(7, 1)
-
-/* Default I2C parent bus number */
-#define MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR 1
-
-/* Maximum number of possible physical buses equipped on system */
-#define MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM 16
-#define MLXPLAT_CPLD_MAX_PHYS_EXT_ADAPTER_NUM 24
-
-/* Number of channels in group */
-#define MLXPLAT_CPLD_GRP_CHNL_NUM 8
-
-/* Start channel numbers */
-#define MLXPLAT_CPLD_CH1 2
-#define MLXPLAT_CPLD_CH2 10
-#define MLXPLAT_CPLD_CH3 18
-#define MLXPLAT_CPLD_CH2_ETH_MODULAR 3
-#define MLXPLAT_CPLD_CH3_ETH_MODULAR 43
-#define MLXPLAT_CPLD_CH4_ETH_MODULAR 51
-#define MLXPLAT_CPLD_CH2_RACK_SWITCH 18
-#define MLXPLAT_CPLD_CH2_NG800 34
-
-/* Number of LPC attached MUX platform devices */
-#define MLXPLAT_CPLD_LPC_MUX_DEVS 4
-
-/* Hotplug devices adapter numbers */
-#define MLXPLAT_CPLD_NR_NONE -1
-#define MLXPLAT_CPLD_PSU_DEFAULT_NR 10
-#define MLXPLAT_CPLD_PSU_MSNXXXX_NR 4
-#define MLXPLAT_CPLD_FAN1_DEFAULT_NR 11
-#define MLXPLAT_CPLD_FAN2_DEFAULT_NR 12
-#define MLXPLAT_CPLD_FAN3_DEFAULT_NR 13
-#define MLXPLAT_CPLD_FAN4_DEFAULT_NR 14
-#define MLXPLAT_CPLD_NR_ASIC 3
-#define MLXPLAT_CPLD_NR_LC_BASE 34
-
-#define MLXPLAT_CPLD_NR_LC_SET(nr) (MLXPLAT_CPLD_NR_LC_BASE + (nr))
-#define MLXPLAT_CPLD_LC_ADDR 0x32
-
-/* Masks and default values for watchdogs */
-#define MLXPLAT_CPLD_WD1_CLEAR_MASK GENMASK(7, 1)
-#define MLXPLAT_CPLD_WD2_CLEAR_MASK (GENMASK(7, 0) & ~BIT(1))
-
-#define MLXPLAT_CPLD_WD_TYPE1_TO_MASK GENMASK(7, 4)
-#define MLXPLAT_CPLD_WD_TYPE2_TO_MASK 0
-#define MLXPLAT_CPLD_WD_RESET_ACT_MASK GENMASK(7, 1)
-#define MLXPLAT_CPLD_WD_FAN_ACT_MASK (GENMASK(7, 0) & ~BIT(4))
-#define MLXPLAT_CPLD_WD_COUNT_ACT_MASK (GENMASK(7, 0) & ~BIT(7))
-#define MLXPLAT_CPLD_WD_CPBLTY_MASK (GENMASK(7, 0) & ~BIT(6))
-#define MLXPLAT_CPLD_WD_DFLT_TIMEOUT 30
-#define MLXPLAT_CPLD_WD3_DFLT_TIMEOUT 600
-#define MLXPLAT_CPLD_WD_MAX_DEVS 2
-
-#define MLXPLAT_CPLD_LPC_SYSIRQ 17
-
-/* Minimum power required for turning on Ethernet modular system (WATT) */
-#define MLXPLAT_CPLD_ETH_MODULAR_PWR_MIN 50
-
-/* Default value for PWM control register for rack switch system */
-#define MLXPLAT_REGMAP_NVSWITCH_PWM_DEFAULT 0xf4
-
-#define MLXPLAT_I2C_MAIN_BUS_NOTIFIED 0x01
-#define MLXPLAT_I2C_MAIN_BUS_HANDLE_CREATED 0x02
-
-/* Lattice FPGA PCI configuration */
-#define PCI_VENDOR_ID_LATTICE 0x1204
-#define PCI_DEVICE_ID_LATTICE_I2C_BRIDGE 0x9c2f
-#define PCI_DEVICE_ID_LATTICE_JTAG_BRIDGE 0x9c30
-#define PCI_DEVICE_ID_LATTICE_LPC_BRIDGE 0x9c32
-
-/* mlxplat_priv - platform private data
- * @pdev_i2c - i2c controller platform device
- * @pdev_mux - array of mux platform devices
- * @pdev_hotplug - hotplug platform devices
- * @pdev_led - led platform devices
- * @pdev_io_regs - register access platform devices
- * @pdev_fan - FAN platform devices
- * @pdev_wd - array of watchdog platform devices
- * @regmap: device register map
- * @hotplug_resources: system hotplug resources
- * @hotplug_resources_size: size of system hotplug resources
- * @hi2c_main_init_status: init status of I2C main bus
- * @irq_fpga: FPGA IRQ number
- */
-struct mlxplat_priv {
- struct platform_device *pdev_i2c;
- struct platform_device *pdev_mux[MLXPLAT_CPLD_LPC_MUX_DEVS];
- struct platform_device *pdev_hotplug;
- struct platform_device *pdev_led;
- struct platform_device *pdev_io_regs;
- struct platform_device *pdev_fan;
- struct platform_device *pdev_wd[MLXPLAT_CPLD_WD_MAX_DEVS];
- void *regmap;
- struct resource *hotplug_resources;
- unsigned int hotplug_resources_size;
- u8 i2c_main_init_status;
- int irq_fpga;
-};
-
-static struct platform_device *mlxplat_dev;
-static int mlxplat_i2c_main_completion_notify(void *handle, int id);
-static void __iomem *i2c_bridge_addr, *jtag_bridge_addr;
-
-/* Regions for LPC I2C controller and LPC base register space */
-static const struct resource mlxplat_lpc_resources[] = {
- [0] = DEFINE_RES_NAMED(MLXPLAT_CPLD_LPC_I2C_BASE_ADRR,
- MLXPLAT_CPLD_LPC_IO_RANGE,
- "mlxplat_cpld_lpc_i2c_ctrl", IORESOURCE_IO),
- [1] = DEFINE_RES_NAMED(MLXPLAT_CPLD_LPC_REG_BASE_ADRR,
- MLXPLAT_CPLD_LPC_IO_RANGE,
- "mlxplat_cpld_lpc_regs",
- IORESOURCE_IO),
-};
-
-/* Platform systems default i2c data */
-static struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_i2c_default_data = {
- .completion_notify = mlxplat_i2c_main_completion_notify,
-};
-
-/* Platform i2c next generation systems data */
-static struct mlxreg_core_data mlxplat_mlxcpld_i2c_ng_items_data[] = {
- {
- .reg = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
- .mask = MLXPLAT_CPLD_I2C_CAP_MASK,
- .bit = MLXPLAT_CPLD_I2C_CAP_BIT,
- },
-};
-
-static struct mlxreg_core_item mlxplat_mlxcpld_i2c_ng_items[] = {
- {
- .data = mlxplat_mlxcpld_i2c_ng_items_data,
- },
-};
-
-/* Platform next generation systems i2c data */
-static struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_i2c_ng_data = {
- .items = mlxplat_mlxcpld_i2c_ng_items,
- .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
- .mask = MLXPLAT_CPLD_AGGR_MASK_COMEX,
- .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRCO_OFFSET,
- .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_I2C,
- .completion_notify = mlxplat_i2c_main_completion_notify,
-};
-
-/* Platform default channels */
-static const int mlxplat_default_channels[][MLXPLAT_CPLD_GRP_CHNL_NUM] = {
- {
- MLXPLAT_CPLD_CH1, MLXPLAT_CPLD_CH1 + 1, MLXPLAT_CPLD_CH1 + 2,
- MLXPLAT_CPLD_CH1 + 3, MLXPLAT_CPLD_CH1 + 4, MLXPLAT_CPLD_CH1 +
- 5, MLXPLAT_CPLD_CH1 + 6, MLXPLAT_CPLD_CH1 + 7
- },
- {
- MLXPLAT_CPLD_CH2, MLXPLAT_CPLD_CH2 + 1, MLXPLAT_CPLD_CH2 + 2,
- MLXPLAT_CPLD_CH2 + 3, MLXPLAT_CPLD_CH2 + 4, MLXPLAT_CPLD_CH2 +
- 5, MLXPLAT_CPLD_CH2 + 6, MLXPLAT_CPLD_CH2 + 7
- },
-};
-
-/* Platform channels for MSN21xx system family */
-static const int mlxplat_msn21xx_channels[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
-
-/* Platform mux data */
-static struct i2c_mux_reg_platform_data mlxplat_default_mux_data[] = {
- {
- .parent = 1,
- .base_nr = MLXPLAT_CPLD_CH1,
- .write_only = 1,
- .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG1,
- .reg_size = 1,
- .idle_in_use = 1,
- },
- {
- .parent = 1,
- .base_nr = MLXPLAT_CPLD_CH2,
- .write_only = 1,
- .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG2,
- .reg_size = 1,
- .idle_in_use = 1,
- },
-
-};
-
-/* Platform mux configuration variables */
-static int mlxplat_max_adap_num;
-static int mlxplat_mux_num;
-static struct i2c_mux_reg_platform_data *mlxplat_mux_data;
-static struct notifier_block *mlxplat_reboot_nb;
-
-/* Platform extended mux data */
-static struct i2c_mux_reg_platform_data mlxplat_extended_mux_data[] = {
- {
- .parent = 1,
- .base_nr = MLXPLAT_CPLD_CH1,
- .write_only = 1,
- .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG1,
- .reg_size = 1,
- .idle_in_use = 1,
- },
- {
- .parent = 1,
- .base_nr = MLXPLAT_CPLD_CH2,
- .write_only = 1,
- .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG3,
- .reg_size = 1,
- .idle_in_use = 1,
- },
- {
- .parent = 1,
- .base_nr = MLXPLAT_CPLD_CH3,
- .write_only = 1,
- .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG2,
- .reg_size = 1,
- .idle_in_use = 1,
- },
-
-};
-
-/* Platform channels for modular system family */
-static const int mlxplat_modular_upper_channel[] = { 1 };
-static const int mlxplat_modular_channels[] = {
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
- 38, 39, 40
-};
-
-/* Platform modular mux data */
-static struct i2c_mux_reg_platform_data mlxplat_modular_mux_data[] = {
- {
- .parent = 1,
- .base_nr = MLXPLAT_CPLD_CH1,
- .write_only = 1,
- .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG4,
- .reg_size = 1,
- .idle_in_use = 1,
- .values = mlxplat_modular_upper_channel,
- .n_values = ARRAY_SIZE(mlxplat_modular_upper_channel),
- },
- {
- .parent = 1,
- .base_nr = MLXPLAT_CPLD_CH2_ETH_MODULAR,
- .write_only = 1,
- .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG1,
- .reg_size = 1,
- .idle_in_use = 1,
- .values = mlxplat_modular_channels,
- .n_values = ARRAY_SIZE(mlxplat_modular_channels),
- },
- {
- .parent = MLXPLAT_CPLD_CH1,
- .base_nr = MLXPLAT_CPLD_CH3_ETH_MODULAR,
- .write_only = 1,
- .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG3,
- .reg_size = 1,
- .idle_in_use = 1,
- .values = mlxplat_msn21xx_channels,
- .n_values = ARRAY_SIZE(mlxplat_msn21xx_channels),
- },
- {
- .parent = 1,
- .base_nr = MLXPLAT_CPLD_CH4_ETH_MODULAR,
- .write_only = 1,
- .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG2,
- .reg_size = 1,
- .idle_in_use = 1,
- .values = mlxplat_msn21xx_channels,
- .n_values = ARRAY_SIZE(mlxplat_msn21xx_channels),
- },
-};
-
-/* Platform channels for rack switch system family */
-static const int mlxplat_rack_switch_channels[] = {
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
-};
-
-/* Platform rack switch mux data */
-static struct i2c_mux_reg_platform_data mlxplat_rack_switch_mux_data[] = {
- {
- .parent = 1,
- .base_nr = MLXPLAT_CPLD_CH1,
- .write_only = 1,
- .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG1,
- .reg_size = 1,
- .idle_in_use = 1,
- .values = mlxplat_rack_switch_channels,
- .n_values = ARRAY_SIZE(mlxplat_rack_switch_channels),
- },
- {
- .parent = 1,
- .base_nr = MLXPLAT_CPLD_CH2_RACK_SWITCH,
- .write_only = 1,
- .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG2,
- .reg_size = 1,
- .idle_in_use = 1,
- .values = mlxplat_msn21xx_channels,
- .n_values = ARRAY_SIZE(mlxplat_msn21xx_channels),
- },
-
-};
-
-/* Platform channels for ng800 system family */
-static const int mlxplat_ng800_channels[] = {
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
- 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32
-};
-
-/* Platform ng800 mux data */
-static struct i2c_mux_reg_platform_data mlxplat_ng800_mux_data[] = {
- {
- .parent = 1,
- .base_nr = MLXPLAT_CPLD_CH1,
- .write_only = 1,
- .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG1,
- .reg_size = 1,
- .idle_in_use = 1,
- .values = mlxplat_ng800_channels,
- .n_values = ARRAY_SIZE(mlxplat_ng800_channels),
- },
- {
- .parent = 1,
- .base_nr = MLXPLAT_CPLD_CH2_NG800,
- .write_only = 1,
- .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG2,
- .reg_size = 1,
- .idle_in_use = 1,
- .values = mlxplat_msn21xx_channels,
- .n_values = ARRAY_SIZE(mlxplat_msn21xx_channels),
- },
-
-};
-
-/* Platform hotplug devices */
-static struct i2c_board_info mlxplat_mlxcpld_pwr[] = {
- {
- I2C_BOARD_INFO("dps460", 0x59),
- },
- {
- I2C_BOARD_INFO("dps460", 0x58),
- },
-};
-
-static struct i2c_board_info mlxplat_mlxcpld_ext_pwr[] = {
- {
- I2C_BOARD_INFO("dps460", 0x5b),
- },
- {
- I2C_BOARD_INFO("dps460", 0x5a),
- },
-};
-
-static struct i2c_board_info mlxplat_mlxcpld_pwr_ng800[] = {
- {
- I2C_BOARD_INFO("dps460", 0x59),
- },
- {
- I2C_BOARD_INFO("dps460", 0x5a),
- },
-};
-
-static struct i2c_board_info mlxplat_mlxcpld_fan[] = {
- {
- I2C_BOARD_INFO("24c32", 0x50),
- },
- {
- I2C_BOARD_INFO("24c32", 0x50),
- },
- {
- I2C_BOARD_INFO("24c32", 0x50),
- },
- {
- I2C_BOARD_INFO("24c32", 0x50),
- },
-};
-
-/* Platform hotplug comex carrier system family data */
-static struct mlxreg_core_data mlxplat_mlxcpld_comex_psu_items_data[] = {
- {
- .label = "psu1",
- .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
- .mask = BIT(0),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
- {
- .label = "psu2",
- .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
- .mask = BIT(1),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
-};
-
-/* Platform hotplug default data */
-static struct mlxreg_core_data mlxplat_mlxcpld_default_psu_items_data[] = {
- {
- .label = "psu1",
- .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
- .mask = BIT(0),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
- {
- .label = "psu2",
- .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
- .mask = BIT(1),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
-};
-
-static struct mlxreg_core_data mlxplat_mlxcpld_default_pwr_items_data[] = {
- {
- .label = "pwr1",
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = BIT(0),
- .hpdev.brdinfo = &mlxplat_mlxcpld_pwr[0],
- .hpdev.nr = MLXPLAT_CPLD_PSU_DEFAULT_NR,
- },
- {
- .label = "pwr2",
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = BIT(1),
- .hpdev.brdinfo = &mlxplat_mlxcpld_pwr[1],
- .hpdev.nr = MLXPLAT_CPLD_PSU_DEFAULT_NR,
- },
-};
-
-static struct mlxreg_core_data mlxplat_mlxcpld_default_pwr_wc_items_data[] = {
- {
- .label = "pwr1",
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = BIT(0),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
- {
- .label = "pwr2",
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = BIT(1),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
-};
-
-static struct mlxreg_core_data mlxplat_mlxcpld_default_pwr_ng800_items_data[] = {
- {
- .label = "pwr1",
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = BIT(0),
- .hpdev.brdinfo = &mlxplat_mlxcpld_pwr_ng800[0],
- .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
- },
- {
- .label = "pwr2",
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = BIT(1),
- .hpdev.brdinfo = &mlxplat_mlxcpld_pwr_ng800[1],
- .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
- },
-};
-
-static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_items_data[] = {
- {
- .label = "fan1",
- .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- .mask = BIT(0),
- .hpdev.brdinfo = &mlxplat_mlxcpld_fan[0],
- .hpdev.nr = MLXPLAT_CPLD_FAN1_DEFAULT_NR,
- },
- {
- .label = "fan2",
- .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- .mask = BIT(1),
- .hpdev.brdinfo = &mlxplat_mlxcpld_fan[1],
- .hpdev.nr = MLXPLAT_CPLD_FAN2_DEFAULT_NR,
- },
- {
- .label = "fan3",
- .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- .mask = BIT(2),
- .hpdev.brdinfo = &mlxplat_mlxcpld_fan[2],
- .hpdev.nr = MLXPLAT_CPLD_FAN3_DEFAULT_NR,
- },
- {
- .label = "fan4",
- .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- .mask = BIT(3),
- .hpdev.brdinfo = &mlxplat_mlxcpld_fan[3],
- .hpdev.nr = MLXPLAT_CPLD_FAN4_DEFAULT_NR,
- },
-};
-
-static struct mlxreg_core_data mlxplat_mlxcpld_default_asic_items_data[] = {
- {
- .label = "asic1",
- .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
- .mask = MLXPLAT_CPLD_ASIC_MASK,
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
-};
-
-static struct mlxreg_core_data mlxplat_mlxcpld_default_asic2_items_data[] = {
- {
- .label = "asic2",
- .reg = MLXPLAT_CPLD_LPC_REG_ASIC2_HEALTH_OFFSET,
- .mask = MLXPLAT_CPLD_ASIC_MASK,
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
-};
-
-static struct mlxreg_core_item mlxplat_mlxcpld_default_items[] = {
- {
- .data = mlxplat_mlxcpld_default_psu_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_PSU_MASK_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
- .mask = MLXPLAT_CPLD_PSU_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_psu_items_data),
- .inversed = 1,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_default_pwr_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = MLXPLAT_CPLD_PWR_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_pwr_items_data),
- .inversed = 0,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_default_fan_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_FAN_MASK_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- .mask = MLXPLAT_CPLD_FAN_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_fan_items_data),
- .inversed = 1,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_default_asic_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
- .mask = MLXPLAT_CPLD_ASIC_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
- .inversed = 0,
- .health = true,
- },
-};
-
-static struct mlxreg_core_item mlxplat_mlxcpld_comex_items[] = {
- {
- .data = mlxplat_mlxcpld_comex_psu_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_CARRIER,
- .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
- .mask = MLXPLAT_CPLD_PSU_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_psu_items_data),
- .inversed = 1,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_default_pwr_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_CARRIER,
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = MLXPLAT_CPLD_PWR_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_pwr_items_data),
- .inversed = 0,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_default_fan_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_CARRIER,
- .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- .mask = MLXPLAT_CPLD_FAN_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_fan_items_data),
- .inversed = 1,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_default_asic_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
- .mask = MLXPLAT_CPLD_ASIC_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
- .inversed = 0,
- .health = true,
- },
-};
-
-static
-struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_data = {
- .items = mlxplat_mlxcpld_default_items,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_items),
- .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
- .mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
- .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
- .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
-};
-
-static struct mlxreg_core_item mlxplat_mlxcpld_default_wc_items[] = {
- {
- .data = mlxplat_mlxcpld_comex_psu_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_CARRIER,
- .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
- .mask = MLXPLAT_CPLD_PSU_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_psu_items_data),
- .inversed = 1,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_default_pwr_wc_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_CARRIER,
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = MLXPLAT_CPLD_PWR_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_pwr_items_data),
- .inversed = 0,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_default_asic_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
- .mask = MLXPLAT_CPLD_ASIC_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
- .inversed = 0,
- .health = true,
- },
-};
-
-static
-struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_wc_data = {
- .items = mlxplat_mlxcpld_default_wc_items,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_wc_items),
- .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
- .mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
- .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
- .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
-};
-
-static
-struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_comex_data = {
- .items = mlxplat_mlxcpld_comex_items,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_comex_items),
- .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
- .mask = MLXPLAT_CPLD_AGGR_MASK_CARR_DEF,
- .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRCX_OFFSET,
- .mask_low = MLXPLAT_CPLD_LOW_AGGRCX_MASK,
-};
-
-static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_pwr_items_data[] = {
- {
- .label = "pwr1",
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = BIT(0),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
- {
- .label = "pwr2",
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = BIT(1),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
-};
-
-/* Platform hotplug MSN21xx system family data */
-static struct mlxreg_core_item mlxplat_mlxcpld_msn21xx_items[] = {
- {
- .data = mlxplat_mlxcpld_msn21xx_pwr_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = MLXPLAT_CPLD_PWR_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_pwr_items_data),
- .inversed = 0,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_default_asic_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
- .mask = MLXPLAT_CPLD_ASIC_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
- .inversed = 0,
- .health = true,
- },
-};
-
-static
-struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn21xx_data = {
- .items = mlxplat_mlxcpld_msn21xx_items,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_items),
- .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
- .mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
- .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
- .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
-};
-
-/* Platform hotplug msn274x system family data */
-static struct mlxreg_core_data mlxplat_mlxcpld_msn274x_psu_items_data[] = {
- {
- .label = "psu1",
- .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
- .mask = BIT(0),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
- {
- .label = "psu2",
- .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
- .mask = BIT(1),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
-};
-
-static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_pwr_items_data[] = {
- {
- .label = "pwr1",
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = BIT(0),
- .hpdev.brdinfo = &mlxplat_mlxcpld_pwr[0],
- .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
- },
- {
- .label = "pwr2",
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = BIT(1),
- .hpdev.brdinfo = &mlxplat_mlxcpld_pwr[1],
- .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
- },
-};
-
-static struct mlxreg_core_data mlxplat_mlxcpld_msn274x_fan_items_data[] = {
- {
- .label = "fan1",
- .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- .mask = BIT(0),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
- {
- .label = "fan2",
- .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- .mask = BIT(1),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
- {
- .label = "fan3",
- .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- .mask = BIT(2),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
- {
- .label = "fan4",
- .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- .mask = BIT(3),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
-};
-
-static struct mlxreg_core_item mlxplat_mlxcpld_msn274x_items[] = {
- {
- .data = mlxplat_mlxcpld_msn274x_psu_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
- .mask = MLXPLAT_CPLD_PSU_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_msn274x_psu_items_data),
- .inversed = 1,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_default_ng_pwr_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = MLXPLAT_CPLD_PWR_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_pwr_items_data),
- .inversed = 0,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_msn274x_fan_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- .mask = MLXPLAT_CPLD_FAN_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_msn274x_fan_items_data),
- .inversed = 1,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_default_asic_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
- .mask = MLXPLAT_CPLD_ASIC_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
- .inversed = 0,
- .health = true,
- },
-};
-
-static
-struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn274x_data = {
- .items = mlxplat_mlxcpld_msn274x_items,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_msn274x_items),
- .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
- .mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
- .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
-};
-
-/* Platform hotplug MSN201x system family data */
-static struct mlxreg_core_data mlxplat_mlxcpld_msn201x_pwr_items_data[] = {
- {
- .label = "pwr1",
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = BIT(0),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
- {
- .label = "pwr2",
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = BIT(1),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
-};
-
-static struct mlxreg_core_item mlxplat_mlxcpld_msn201x_items[] = {
- {
- .data = mlxplat_mlxcpld_msn201x_pwr_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = MLXPLAT_CPLD_PWR_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_msn201x_pwr_items_data),
- .inversed = 0,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_default_asic_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_ASIC_MASK_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
- .mask = MLXPLAT_CPLD_ASIC_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
- .inversed = 0,
- .health = true,
- },
-};
-
-static
-struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn201x_data = {
- .items = mlxplat_mlxcpld_msn201x_items,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_msn201x_items),
- .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
- .mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
- .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
- .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
-};
-
-/* Platform hotplug next generation system family data */
-static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_psu_items_data[] = {
- {
- .label = "psu1",
- .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
- .mask = BIT(0),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
- {
- .label = "psu2",
- .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
- .mask = BIT(1),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
-};
-
-static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_fan_items_data[] = {
- {
- .label = "fan1",
- .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- .mask = BIT(0),
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(0),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
- {
- .label = "fan2",
- .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- .mask = BIT(1),
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(1),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
- {
- .label = "fan3",
- .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- .mask = BIT(2),
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(2),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
- {
- .label = "fan4",
- .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- .mask = BIT(3),
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(3),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
- {
- .label = "fan5",
- .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- .mask = BIT(4),
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(4),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
- {
- .label = "fan6",
- .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- .mask = BIT(5),
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(5),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
- {
- .label = "fan7",
- .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- .mask = BIT(6),
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(6),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
-};
-
-static struct mlxreg_core_item mlxplat_mlxcpld_default_ng_items[] = {
- {
- .data = mlxplat_mlxcpld_default_ng_psu_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
- .mask = MLXPLAT_CPLD_PSU_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_psu_items_data),
- .inversed = 1,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_default_ng_pwr_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = MLXPLAT_CPLD_PWR_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_pwr_items_data),
- .inversed = 0,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_default_ng_fan_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- .mask = MLXPLAT_CPLD_FAN_NG_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_fan_items_data),
- .inversed = 1,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_default_asic_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
- .mask = MLXPLAT_CPLD_ASIC_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
- .inversed = 0,
- .health = true,
- },
-};
-
-static
-struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_ng_data = {
- .items = mlxplat_mlxcpld_default_ng_items,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_items),
- .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
- .mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF | MLXPLAT_CPLD_AGGR_MASK_COMEX,
- .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
- .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
-};
-
-/* Platform hotplug extended system family data */
-static struct mlxreg_core_data mlxplat_mlxcpld_ext_psu_items_data[] = {
- {
- .label = "psu1",
- .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
- .mask = BIT(0),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
- {
- .label = "psu2",
- .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
- .mask = BIT(1),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
- {
- .label = "psu3",
- .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
- .mask = BIT(2),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
- {
- .label = "psu4",
- .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
- .mask = BIT(3),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
-};
-
-static struct mlxreg_core_data mlxplat_mlxcpld_ext_pwr_items_data[] = {
- {
- .label = "pwr1",
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = BIT(0),
- .hpdev.brdinfo = &mlxplat_mlxcpld_pwr[0],
- .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
- },
- {
- .label = "pwr2",
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = BIT(1),
- .hpdev.brdinfo = &mlxplat_mlxcpld_pwr[1],
- .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
- },
- {
- .label = "pwr3",
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = BIT(2),
- .hpdev.brdinfo = &mlxplat_mlxcpld_ext_pwr[0],
- .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
- },
- {
- .label = "pwr4",
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = BIT(3),
- .hpdev.brdinfo = &mlxplat_mlxcpld_ext_pwr[1],
- .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
- },
-};
-
-static struct mlxreg_core_item mlxplat_mlxcpld_ext_items[] = {
- {
- .data = mlxplat_mlxcpld_ext_psu_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
- .mask = MLXPLAT_CPLD_PSU_EXT_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_ext_psu_items_data),
- .inversed = 1,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_ext_pwr_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = MLXPLAT_CPLD_PWR_EXT_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_ext_pwr_items_data),
- .inversed = 0,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_default_ng_fan_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- .mask = MLXPLAT_CPLD_FAN_NG_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_fan_items_data),
- .inversed = 1,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_default_asic_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
- .mask = MLXPLAT_CPLD_ASIC_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
- .inversed = 0,
- .health = true,
- },
- {
- .data = mlxplat_mlxcpld_default_asic2_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_ASIC2_HEALTH_OFFSET,
- .mask = MLXPLAT_CPLD_ASIC_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic2_items_data),
- .inversed = 0,
- .health = true,
- }
-};
-
-static struct mlxreg_core_item mlxplat_mlxcpld_ng800_items[] = {
- {
- .data = mlxplat_mlxcpld_default_ng_psu_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
- .mask = MLXPLAT_CPLD_PSU_EXT_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_psu_items_data),
- .inversed = 1,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_default_pwr_ng800_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = MLXPLAT_CPLD_PWR_EXT_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_pwr_ng800_items_data),
- .inversed = 0,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_default_ng_fan_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- .mask = MLXPLAT_CPLD_FAN_NG_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_fan_items_data),
- .inversed = 1,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_default_asic_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
- .mask = MLXPLAT_CPLD_ASIC_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
- .inversed = 0,
- .health = true,
- },
-};
-
-static
-struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_ext_data = {
- .items = mlxplat_mlxcpld_ext_items,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_ext_items),
- .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
- .mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF | MLXPLAT_CPLD_AGGR_MASK_COMEX,
- .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
- .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW | MLXPLAT_CPLD_LOW_AGGR_MASK_ASIC2,
-};
-
-static
-struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_ng800_data = {
- .items = mlxplat_mlxcpld_ng800_items,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_ng800_items),
- .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
- .mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF | MLXPLAT_CPLD_AGGR_MASK_COMEX,
- .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
- .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW | MLXPLAT_CPLD_LOW_AGGR_MASK_ASIC2,
-};
-
-static struct mlxreg_core_data mlxplat_mlxcpld_modular_pwr_items_data[] = {
- {
- .label = "pwr1",
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = BIT(0),
- .hpdev.brdinfo = &mlxplat_mlxcpld_pwr[0],
- .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
- },
- {
- .label = "pwr2",
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = BIT(1),
- .hpdev.brdinfo = &mlxplat_mlxcpld_pwr[1],
- .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
- },
- {
- .label = "pwr3",
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = BIT(2),
- .hpdev.brdinfo = &mlxplat_mlxcpld_ext_pwr[0],
- .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
- },
- {
- .label = "pwr4",
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = BIT(3),
- .hpdev.brdinfo = &mlxplat_mlxcpld_ext_pwr[1],
- .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
- },
-};
-
-static
-struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_lc_act = {
- .irq = MLXPLAT_CPLD_LPC_SYSIRQ,
-};
-
-static struct mlxreg_core_data mlxplat_mlxcpld_modular_asic_items_data[] = {
- {
- .label = "asic1",
- .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
- .mask = MLXPLAT_CPLD_ASIC_MASK,
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
-};
-
-static struct i2c_board_info mlxplat_mlxcpld_lc_i2c_dev[] = {
- {
- I2C_BOARD_INFO("mlxreg-lc", MLXPLAT_CPLD_LC_ADDR),
- .platform_data = &mlxplat_mlxcpld_lc_act,
- },
- {
- I2C_BOARD_INFO("mlxreg-lc", MLXPLAT_CPLD_LC_ADDR),
- .platform_data = &mlxplat_mlxcpld_lc_act,
- },
- {
- I2C_BOARD_INFO("mlxreg-lc", MLXPLAT_CPLD_LC_ADDR),
- .platform_data = &mlxplat_mlxcpld_lc_act,
- },
- {
- I2C_BOARD_INFO("mlxreg-lc", MLXPLAT_CPLD_LC_ADDR),
- .platform_data = &mlxplat_mlxcpld_lc_act,
- },
- {
- I2C_BOARD_INFO("mlxreg-lc", MLXPLAT_CPLD_LC_ADDR),
- .platform_data = &mlxplat_mlxcpld_lc_act,
- },
- {
- I2C_BOARD_INFO("mlxreg-lc", MLXPLAT_CPLD_LC_ADDR),
- .platform_data = &mlxplat_mlxcpld_lc_act,
- },
- {
- I2C_BOARD_INFO("mlxreg-lc", MLXPLAT_CPLD_LC_ADDR),
- .platform_data = &mlxplat_mlxcpld_lc_act,
- },
- {
- I2C_BOARD_INFO("mlxreg-lc", MLXPLAT_CPLD_LC_ADDR),
- .platform_data = &mlxplat_mlxcpld_lc_act,
- },
-};
-
-static struct mlxreg_core_hotplug_notifier mlxplat_mlxcpld_modular_lc_notifier[] = {
- {
- .identity = "lc1",
- },
- {
- .identity = "lc2",
- },
- {
- .identity = "lc3",
- },
- {
- .identity = "lc4",
- },
- {
- .identity = "lc5",
- },
- {
- .identity = "lc6",
- },
- {
- .identity = "lc7",
- },
- {
- .identity = "lc8",
- },
-};
-
-static struct mlxreg_core_data mlxplat_mlxcpld_modular_lc_pr_items_data[] = {
- {
- .label = "lc1_present",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_IN_OFFSET,
- .mask = BIT(0),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[0],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(0),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[0],
- .slot = 1,
- },
- {
- .label = "lc2_present",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_IN_OFFSET,
- .mask = BIT(1),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[1],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(1),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[1],
- .slot = 2,
- },
- {
- .label = "lc3_present",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_IN_OFFSET,
- .mask = BIT(2),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[2],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(2),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[2],
- .slot = 3,
- },
- {
- .label = "lc4_present",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_IN_OFFSET,
- .mask = BIT(3),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[3],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(3),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[3],
- .slot = 4,
- },
- {
- .label = "lc5_present",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_IN_OFFSET,
- .mask = BIT(4),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[4],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(4),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[4],
- .slot = 5,
- },
- {
- .label = "lc6_present",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_IN_OFFSET,
- .mask = BIT(5),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[5],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(5),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[5],
- .slot = 6,
- },
- {
- .label = "lc7_present",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_IN_OFFSET,
- .mask = BIT(6),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[6],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(6),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[6],
- .slot = 7,
- },
- {
- .label = "lc8_present",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_IN_OFFSET,
- .mask = BIT(7),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[7],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(7),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[7],
- .slot = 8,
- },
-};
-
-static struct mlxreg_core_data mlxplat_mlxcpld_modular_lc_ver_items_data[] = {
- {
- .label = "lc1_verified",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_VR_OFFSET,
- .mask = BIT(0),
- .reg_prsnt = MLXPLAT_CPLD_LPC_REG_LC_PG_OFFSET,
- .reg_sync = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
- .reg_pwr = MLXPLAT_CPLD_LPC_REG_LC_PWR_ON,
- .reg_ena = MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET,
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[0],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(0),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_PLATFORM_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[0],
- .slot = 1,
- },
- {
- .label = "lc2_verified",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_VR_OFFSET,
- .mask = BIT(1),
- .reg_prsnt = MLXPLAT_CPLD_LPC_REG_LC_PG_OFFSET,
- .reg_sync = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
- .reg_pwr = MLXPLAT_CPLD_LPC_REG_LC_PWR_ON,
- .reg_ena = MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET,
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[1],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(1),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_PLATFORM_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[1],
- .slot = 2,
- },
- {
- .label = "lc3_verified",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_VR_OFFSET,
- .mask = BIT(2),
- .reg_prsnt = MLXPLAT_CPLD_LPC_REG_LC_PG_OFFSET,
- .reg_sync = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
- .reg_pwr = MLXPLAT_CPLD_LPC_REG_LC_PWR_ON,
- .reg_ena = MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET,
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[2],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(2),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_PLATFORM_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[2],
- .slot = 3,
- },
- {
- .label = "lc4_verified",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_VR_OFFSET,
- .mask = BIT(3),
- .reg_prsnt = MLXPLAT_CPLD_LPC_REG_LC_PG_OFFSET,
- .reg_sync = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
- .reg_pwr = MLXPLAT_CPLD_LPC_REG_LC_PWR_ON,
- .reg_ena = MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET,
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[3],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(3),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_PLATFORM_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[3],
- .slot = 4,
- },
- {
- .label = "lc5_verified",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_VR_OFFSET,
- .mask = BIT(4),
- .reg_prsnt = MLXPLAT_CPLD_LPC_REG_LC_PG_OFFSET,
- .reg_sync = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
- .reg_pwr = MLXPLAT_CPLD_LPC_REG_LC_PWR_ON,
- .reg_ena = MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET,
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[4],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(4),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_PLATFORM_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[4],
- .slot = 5,
- },
- {
- .label = "lc6_verified",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_VR_OFFSET,
- .mask = BIT(5),
- .reg_prsnt = MLXPLAT_CPLD_LPC_REG_LC_PG_OFFSET,
- .reg_sync = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
- .reg_pwr = MLXPLAT_CPLD_LPC_REG_LC_PWR_ON,
- .reg_ena = MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET,
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[5],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(5),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_PLATFORM_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[5],
- .slot = 6,
- },
- {
- .label = "lc7_verified",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_VR_OFFSET,
- .mask = BIT(6),
- .reg_prsnt = MLXPLAT_CPLD_LPC_REG_LC_PG_OFFSET,
- .reg_sync = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
- .reg_pwr = MLXPLAT_CPLD_LPC_REG_LC_PWR_ON,
- .reg_ena = MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET,
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[6],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(6),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_PLATFORM_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[6],
- .slot = 7,
- },
- {
- .label = "lc8_verified",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_VR_OFFSET,
- .mask = BIT(7),
- .reg_prsnt = MLXPLAT_CPLD_LPC_REG_LC_PG_OFFSET,
- .reg_sync = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
- .reg_pwr = MLXPLAT_CPLD_LPC_REG_LC_PWR_ON,
- .reg_ena = MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET,
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[7],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(7),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_PLATFORM_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[7],
- .slot = 8,
- },
-};
-
-static struct mlxreg_core_data mlxplat_mlxcpld_modular_lc_pg_data[] = {
- {
- .label = "lc1_powered",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_PG_OFFSET,
- .mask = BIT(0),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[0],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(0),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[0],
- .slot = 1,
- },
- {
- .label = "lc2_powered",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_PG_OFFSET,
- .mask = BIT(1),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[1],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(1),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[1],
- .slot = 2,
- },
- {
- .label = "lc3_powered",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_PG_OFFSET,
- .mask = BIT(2),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[2],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(2),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[2],
- .slot = 3,
- },
- {
- .label = "lc4_powered",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_PG_OFFSET,
- .mask = BIT(3),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[3],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(3),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[3],
- .slot = 4,
- },
- {
- .label = "lc5_powered",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_PG_OFFSET,
- .mask = BIT(4),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[4],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(4),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[4],
- .slot = 5,
- },
- {
- .label = "lc6_powered",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_PG_OFFSET,
- .mask = BIT(5),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[5],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(5),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[5],
- .slot = 6,
- },
- {
- .label = "lc7_powered",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_PG_OFFSET,
- .mask = BIT(6),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[6],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(6),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[6],
- .slot = 7,
- },
- {
- .label = "lc8_powered",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_PG_OFFSET,
- .mask = BIT(7),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[7],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(7),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[7],
- .slot = 8,
- },
-};
-
-static struct mlxreg_core_data mlxplat_mlxcpld_modular_lc_ready_data[] = {
- {
- .label = "lc1_ready",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_RD_OFFSET,
- .mask = BIT(0),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[0],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(0),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[0],
- .slot = 1,
- },
- {
- .label = "lc2_ready",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_RD_OFFSET,
- .mask = BIT(1),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[1],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(1),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[1],
- .slot = 2,
- },
- {
- .label = "lc3_ready",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_RD_OFFSET,
- .mask = BIT(2),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[2],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(2),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[2],
- .slot = 3,
- },
- {
- .label = "lc4_ready",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_RD_OFFSET,
- .mask = BIT(3),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[3],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(3),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[3],
- .slot = 4,
- },
- {
- .label = "lc5_ready",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_RD_OFFSET,
- .mask = BIT(4),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[4],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(4),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[4],
- .slot = 5,
- },
- {
- .label = "lc6_ready",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_RD_OFFSET,
- .mask = BIT(5),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[5],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(5),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[5],
- .slot = 6,
- },
- {
- .label = "lc7_ready",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_RD_OFFSET,
- .mask = BIT(6),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[6],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(6),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[6],
- .slot = 7,
- },
- {
- .label = "lc8_ready",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_RD_OFFSET,
- .mask = BIT(7),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[7],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(7),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[7],
- .slot = 8,
- },
-};
-
-static struct mlxreg_core_data mlxplat_mlxcpld_modular_lc_synced_data[] = {
- {
- .label = "lc1_synced",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
- .mask = BIT(0),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[0],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(0),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[0],
- .slot = 1,
- },
- {
- .label = "lc2_synced",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
- .mask = BIT(1),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[1],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(1),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[1],
- .slot = 2,
- },
- {
- .label = "lc3_synced",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
- .mask = BIT(2),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[2],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(2),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[2],
- .slot = 3,
- },
- {
- .label = "lc4_synced",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
- .mask = BIT(3),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[3],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(3),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[3],
- .slot = 4,
- },
- {
- .label = "lc5_synced",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
- .mask = BIT(4),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[4],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(4),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[4],
- .slot = 5,
- },
- {
- .label = "lc6_synced",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
- .mask = BIT(5),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[5],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(5),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[5],
- .slot = 6,
- },
- {
- .label = "lc7_synced",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
- .mask = BIT(6),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[6],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(6),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[6],
- .slot = 7,
- },
- {
- .label = "lc8_synced",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
- .mask = BIT(7),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[7],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(7),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[7],
- .slot = 8,
- },
-};
-
-static struct mlxreg_core_data mlxplat_mlxcpld_modular_lc_act_data[] = {
- {
- .label = "lc1_active",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_OK_OFFSET,
- .mask = BIT(0),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[0],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(0),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[0],
- .slot = 1,
- },
- {
- .label = "lc2_active",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_OK_OFFSET,
- .mask = BIT(1),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[1],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(1),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[1],
- .slot = 2,
- },
- {
- .label = "lc3_active",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_OK_OFFSET,
- .mask = BIT(2),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[2],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(2),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[2],
- .slot = 3,
- },
- {
- .label = "lc4_active",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_OK_OFFSET,
- .mask = BIT(3),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[3],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(3),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[3],
- .slot = 4,
- },
- {
- .label = "lc5_active",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_OK_OFFSET,
- .mask = BIT(4),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[4],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(4),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[4],
- .slot = 5,
- },
- {
- .label = "lc6_active",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_OK_OFFSET,
- .mask = BIT(5),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[5],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(5),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[5],
- .slot = 6,
- },
- {
- .label = "lc7_active",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_OK_OFFSET,
- .mask = BIT(6),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[6],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(6),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[6],
- .slot = 7,
- },
- {
- .label = "lc8_active",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_OK_OFFSET,
- .mask = BIT(7),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[7],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(7),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[7],
- .slot = 8,
- },
-};
-
-static struct mlxreg_core_data mlxplat_mlxcpld_modular_lc_sd_data[] = {
- {
- .label = "lc1_shutdown",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_SD_OFFSET,
- .mask = BIT(0),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[0],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(0),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[0],
- .slot = 1,
- },
- {
- .label = "lc2_shutdown",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_SD_OFFSET,
- .mask = BIT(1),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[1],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(1),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[1],
- .slot = 2,
- },
- {
- .label = "lc3_shutdown",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_SD_OFFSET,
- .mask = BIT(2),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[2],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(2),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[2],
- .slot = 3,
- },
- {
- .label = "lc4_shutdown",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_SD_OFFSET,
- .mask = BIT(3),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[3],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(3),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[3],
- .slot = 4,
- },
- {
- .label = "lc5_shutdown",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_SD_OFFSET,
- .mask = BIT(4),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[4],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(4),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[4],
- .slot = 5,
- },
- {
- .label = "lc6_shutdown",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_SD_OFFSET,
- .mask = BIT(5),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[5],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(5),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[5],
- .slot = 6,
- },
- {
- .label = "lc7_shutdown",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_SD_OFFSET,
- .mask = BIT(6),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[6],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(6),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[6],
- .slot = 7,
- },
- {
- .label = "lc8_shutdown",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_SD_OFFSET,
- .mask = BIT(7),
- .hpdev.brdinfo = &mlxplat_mlxcpld_lc_i2c_dev[7],
- .hpdev.nr = MLXPLAT_CPLD_NR_LC_SET(7),
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_modular_lc_notifier[7],
- .slot = 8,
- },
-};
-
-static struct mlxreg_core_item mlxplat_mlxcpld_modular_items[] = {
- {
- .data = mlxplat_mlxcpld_ext_psu_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
- .mask = MLXPLAT_CPLD_PSU_EXT_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_ext_psu_items_data),
- .inversed = 1,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_modular_pwr_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = MLXPLAT_CPLD_PWR_EXT_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_ext_pwr_items_data),
- .inversed = 0,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_default_ng_fan_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- .mask = MLXPLAT_CPLD_FAN_NG_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_fan_items_data),
- .inversed = 1,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_modular_asic_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
- .mask = MLXPLAT_CPLD_ASIC_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_modular_asic_items_data),
- .inversed = 0,
- .health = true,
- },
- {
- .data = mlxplat_mlxcpld_modular_lc_pr_items_data,
- .kind = MLXREG_HOTPLUG_LC_PRESENT,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_LC,
- .reg = MLXPLAT_CPLD_LPC_REG_LC_IN_OFFSET,
- .mask = MLXPLAT_CPLD_LPC_LC_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_modular_lc_pr_items_data),
- .inversed = 1,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_modular_lc_ver_items_data,
- .kind = MLXREG_HOTPLUG_LC_VERIFIED,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_LC,
- .reg = MLXPLAT_CPLD_LPC_REG_LC_VR_OFFSET,
- .mask = MLXPLAT_CPLD_LPC_LC_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_modular_lc_ver_items_data),
- .inversed = 0,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_modular_lc_pg_data,
- .kind = MLXREG_HOTPLUG_LC_POWERED,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_LC,
- .reg = MLXPLAT_CPLD_LPC_REG_LC_PG_OFFSET,
- .mask = MLXPLAT_CPLD_LPC_LC_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_modular_lc_pg_data),
- .inversed = 0,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_modular_lc_ready_data,
- .kind = MLXREG_HOTPLUG_LC_READY,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_LC,
- .reg = MLXPLAT_CPLD_LPC_REG_LC_RD_OFFSET,
- .mask = MLXPLAT_CPLD_LPC_LC_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_modular_lc_ready_data),
- .inversed = 0,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_modular_lc_synced_data,
- .kind = MLXREG_HOTPLUG_LC_SYNCED,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_LC,
- .reg = MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET,
- .mask = MLXPLAT_CPLD_LPC_LC_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_modular_lc_synced_data),
- .inversed = 0,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_modular_lc_act_data,
- .kind = MLXREG_HOTPLUG_LC_ACTIVE,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_LC,
- .reg = MLXPLAT_CPLD_LPC_REG_LC_OK_OFFSET,
- .mask = MLXPLAT_CPLD_LPC_LC_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_modular_lc_act_data),
- .inversed = 0,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_modular_lc_sd_data,
- .kind = MLXREG_HOTPLUG_LC_THERMAL,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_LC,
- .reg = MLXPLAT_CPLD_LPC_REG_LC_SD_OFFSET,
- .mask = MLXPLAT_CPLD_LPC_LC_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_modular_lc_sd_data),
- .inversed = 0,
- .health = false,
- },
-};
-
-static
-struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_modular_data = {
- .items = mlxplat_mlxcpld_modular_items,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_modular_items),
- .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
- .mask = MLXPLAT_CPLD_AGGR_MASK_MODULAR,
- .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
- .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
-};
-
-/* Platform hotplug for NVLink blade systems family data */
-static struct mlxreg_core_data mlxplat_mlxcpld_global_wp_items_data[] = {
- {
- .label = "global_wp_grant",
- .reg = MLXPLAT_CPLD_LPC_REG_GWP_OFFSET,
- .mask = MLXPLAT_CPLD_GWP_MASK,
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
-};
-
-static struct mlxreg_core_item mlxplat_mlxcpld_chassis_blade_items[] = {
- {
- .data = mlxplat_mlxcpld_global_wp_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_GWP_OFFSET,
- .mask = MLXPLAT_CPLD_GWP_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_global_wp_items_data),
- .inversed = 0,
- .health = false,
- },
-};
-
-static
-struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_chassis_blade_data = {
- .items = mlxplat_mlxcpld_chassis_blade_items,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_chassis_blade_items),
- .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
- .mask = MLXPLAT_CPLD_AGGR_MASK_COMEX,
- .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
- .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
-};
-
-/* Platform hotplug for switch systems family data */
-static struct mlxreg_core_data mlxplat_mlxcpld_erot_ap_items_data[] = {
- {
- .label = "erot1_ap",
- .reg = MLXPLAT_CPLD_LPC_REG_EROT_OFFSET,
- .mask = BIT(0),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
- {
- .label = "erot2_ap",
- .reg = MLXPLAT_CPLD_LPC_REG_EROT_OFFSET,
- .mask = BIT(1),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
-};
-
-static struct mlxreg_core_data mlxplat_mlxcpld_erot_error_items_data[] = {
- {
- .label = "erot1_error",
- .reg = MLXPLAT_CPLD_LPC_REG_EROTE_OFFSET,
- .mask = BIT(0),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
- {
- .label = "erot2_error",
- .reg = MLXPLAT_CPLD_LPC_REG_EROTE_OFFSET,
- .mask = BIT(1),
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
-};
-
-static struct mlxreg_core_item mlxplat_mlxcpld_rack_switch_items[] = {
- {
- .data = mlxplat_mlxcpld_ext_psu_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
- .mask = MLXPLAT_CPLD_PSU_EXT_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_ext_psu_items_data),
- .inversed = 1,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_ext_pwr_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
- .mask = MLXPLAT_CPLD_PWR_EXT_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_ext_pwr_items_data),
- .inversed = 0,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_default_ng_fan_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- .mask = MLXPLAT_CPLD_FAN_NG_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_fan_items_data),
- .inversed = 1,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_erot_ap_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_EROT_OFFSET,
- .mask = MLXPLAT_CPLD_EROT_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_erot_ap_items_data),
- .inversed = 1,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_erot_error_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_EROTE_OFFSET,
- .mask = MLXPLAT_CPLD_EROT_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_erot_error_items_data),
- .inversed = 1,
- .health = false,
- },
-};
-
-static
-struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_rack_switch_data = {
- .items = mlxplat_mlxcpld_rack_switch_items,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_rack_switch_items),
- .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
- .mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF | MLXPLAT_CPLD_AGGR_MASK_COMEX,
- .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
- .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
-};
-
-/* Callback performs graceful shutdown after notification about power button event */
-static int
-mlxplat_mlxcpld_l1_switch_pwr_events_handler(void *handle, enum mlxreg_hotplug_kind kind,
- u8 action)
-{
- if (action) {
- dev_info(&mlxplat_dev->dev, "System shutdown due to short press of power button");
- kernel_power_off();
- }
-
- return 0;
-}
-
-static struct mlxreg_core_hotplug_notifier mlxplat_mlxcpld_l1_switch_pwr_events_notifier = {
- .user_handler = mlxplat_mlxcpld_l1_switch_pwr_events_handler,
-};
-
-/* Platform hotplug for l1 switch systems family data */
-static struct mlxreg_core_data mlxplat_mlxcpld_l1_switch_pwr_events_items_data[] = {
- {
- .label = "power_button",
- .reg = MLXPLAT_CPLD_LPC_REG_PWRB_OFFSET,
- .mask = MLXPLAT_CPLD_PWR_BUTTON_MASK,
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_l1_switch_pwr_events_notifier,
- },
-};
-
-/* Callback activates latch reset flow after notification about intrusion event */
-static int
-mlxplat_mlxcpld_l1_switch_intrusion_events_handler(void *handle, enum mlxreg_hotplug_kind kind,
- u8 action)
-{
- struct mlxplat_priv *priv = platform_get_drvdata(mlxplat_dev);
- u32 regval;
- int err;
-
- err = regmap_read(priv->regmap, MLXPLAT_CPLD_LPC_REG_GP1_OFFSET, &regval);
- if (err)
- goto fail_regmap_read;
-
- if (action) {
- dev_info(&mlxplat_dev->dev, "Detected intrusion - system latch is opened");
- err = regmap_write(priv->regmap, MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
- regval | MLXPLAT_CPLD_LATCH_RST_MASK);
- } else {
- dev_info(&mlxplat_dev->dev, "System latch is properly closed");
- err = regmap_write(priv->regmap, MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
- regval & ~MLXPLAT_CPLD_LATCH_RST_MASK);
- }
-
- if (err)
- goto fail_regmap_write;
-
- return 0;
-
-fail_regmap_read:
-fail_regmap_write:
- dev_err(&mlxplat_dev->dev, "Register access failed");
- return err;
-}
-
-static struct mlxreg_core_hotplug_notifier mlxplat_mlxcpld_l1_switch_intrusion_events_notifier = {
- .user_handler = mlxplat_mlxcpld_l1_switch_intrusion_events_handler,
-};
-
-static struct mlxreg_core_data mlxplat_mlxcpld_l1_switch_health_events_items_data[] = {
- {
- .label = "thermal1_pdb",
- .reg = MLXPLAT_CPLD_LPC_REG_BRD_OFFSET,
- .mask = MLXPLAT_CPLD_THERMAL1_PDB_MASK,
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
- {
- .label = "thermal2_pdb",
- .reg = MLXPLAT_CPLD_LPC_REG_BRD_OFFSET,
- .mask = MLXPLAT_CPLD_THERMAL2_PDB_MASK,
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
- {
- .label = "intrusion",
- .reg = MLXPLAT_CPLD_LPC_REG_BRD_OFFSET,
- .mask = MLXPLAT_CPLD_INTRUSION_MASK,
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- .hpdev.action = MLXREG_HOTPLUG_DEVICE_NO_ACTION,
- .hpdev.notifier = &mlxplat_mlxcpld_l1_switch_intrusion_events_notifier,
- },
- {
- .label = "pwm_pg",
- .reg = MLXPLAT_CPLD_LPC_REG_BRD_OFFSET,
- .mask = MLXPLAT_CPLD_PWM_PG_MASK,
- .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
- },
-};
-
-static struct mlxreg_core_item mlxplat_mlxcpld_l1_switch_events_items[] = {
- {
- .data = mlxplat_mlxcpld_default_ng_fan_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- .mask = MLXPLAT_CPLD_FAN_NG_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_fan_items_data),
- .inversed = 1,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_erot_ap_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_EROT_OFFSET,
- .mask = MLXPLAT_CPLD_EROT_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_erot_ap_items_data),
- .inversed = 1,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_erot_error_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_EROTE_OFFSET,
- .mask = MLXPLAT_CPLD_EROT_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_erot_error_items_data),
- .inversed = 1,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_l1_switch_pwr_events_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_PWRB_OFFSET,
- .mask = MLXPLAT_CPLD_PWR_BUTTON_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_l1_switch_pwr_events_items_data),
- .inversed = 1,
- .health = false,
- },
- {
- .data = mlxplat_mlxcpld_l1_switch_health_events_items_data,
- .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
- .reg = MLXPLAT_CPLD_LPC_REG_BRD_OFFSET,
- .mask = MLXPLAT_CPLD_L1_CHA_HEALTH_MASK,
- .count = ARRAY_SIZE(mlxplat_mlxcpld_l1_switch_health_events_items_data),
- .inversed = 1,
- .health = false,
- .ind = 8,
- },
-};
-
-static
-struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_l1_switch_data = {
- .items = mlxplat_mlxcpld_l1_switch_events_items,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_l1_switch_events_items),
- .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
- .mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF | MLXPLAT_CPLD_AGGR_MASK_COMEX,
- .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
- .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW | MLXPLAT_CPLD_LOW_AGGR_MASK_PWR_BUT,
-};
-
-/* Platform led default data */
-static struct mlxreg_core_data mlxplat_mlxcpld_default_led_data[] = {
- {
- .label = "status:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
- {
- .label = "status:red",
- .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
- },
- {
- .label = "psu:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- },
- {
- .label = "psu:red",
- .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- },
- {
- .label = "fan1:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
- {
- .label = "fan1:red",
- .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
- {
- .label = "fan2:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- },
- {
- .label = "fan2:red",
- .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- },
- {
- .label = "fan3:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
- {
- .label = "fan3:red",
- .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
- {
- .label = "fan4:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- },
- {
- .label = "fan4:red",
- .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- },
-};
-
-static struct mlxreg_core_platform_data mlxplat_default_led_data = {
- .data = mlxplat_mlxcpld_default_led_data,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_led_data),
-};
-
-/* Platform led default data for water cooling */
-static struct mlxreg_core_data mlxplat_mlxcpld_default_led_wc_data[] = {
- {
- .label = "status:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
- {
- .label = "status:red",
- .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
- },
- {
- .label = "psu:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- },
- {
- .label = "psu:red",
- .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- },
-};
-
-static struct mlxreg_core_platform_data mlxplat_default_led_wc_data = {
- .data = mlxplat_mlxcpld_default_led_wc_data,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_led_wc_data),
-};
-
-/* Platform led default data for water cooling Ethernet switch blade */
-static struct mlxreg_core_data mlxplat_mlxcpld_default_led_eth_wc_blade_data[] = {
- {
- .label = "status:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
- {
- .label = "status:red",
- .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
- },
-};
-
-static struct mlxreg_core_platform_data mlxplat_default_led_eth_wc_blade_data = {
- .data = mlxplat_mlxcpld_default_led_eth_wc_blade_data,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_led_eth_wc_blade_data),
-};
-
-/* Platform led MSN21xx system family data */
-static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_led_data[] = {
- {
- .label = "status:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
- {
- .label = "status:red",
- .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
- },
- {
- .label = "fan:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
- {
- .label = "fan:red",
- .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
- {
- .label = "psu1:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
- {
- .label = "psu1:red",
- .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
- {
- .label = "psu2:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- },
- {
- .label = "psu2:red",
- .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- },
- {
- .label = "uid:blue",
- .reg = MLXPLAT_CPLD_LPC_REG_LED5_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
-};
-
-static struct mlxreg_core_platform_data mlxplat_msn21xx_led_data = {
- .data = mlxplat_mlxcpld_msn21xx_led_data,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_led_data),
-};
-
-/* Platform led for default data for 200GbE systems */
-static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_led_data[] = {
- {
- .label = "status:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
- {
- .label = "status:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
- },
- {
- .label = "psu:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- },
- {
- .label = "psu:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- },
- {
- .label = "fan1:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(0),
- },
- {
- .label = "fan1:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(0),
- },
- {
- .label = "fan2:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(1),
- },
- {
- .label = "fan2:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(1),
- },
- {
- .label = "fan3:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(2),
- },
- {
- .label = "fan3:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(2),
- },
- {
- .label = "fan4:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(3),
- },
- {
- .label = "fan4:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(3),
- },
- {
- .label = "fan5:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(4),
- },
- {
- .label = "fan5:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(4),
- },
- {
- .label = "fan6:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(5),
- },
- {
- .label = "fan6:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(5),
- },
- {
- .label = "fan7:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED6_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(6),
- },
- {
- .label = "fan7:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED6_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(6),
- },
- {
- .label = "uid:blue",
- .reg = MLXPLAT_CPLD_LPC_REG_LED5_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
-};
-
-static struct mlxreg_core_platform_data mlxplat_default_ng_led_data = {
- .data = mlxplat_mlxcpld_default_ng_led_data,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_led_data),
-};
-
-/* Platform led for Comex based 100GbE systems */
-static struct mlxreg_core_data mlxplat_mlxcpld_comex_100G_led_data[] = {
- {
- .label = "status:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
- {
- .label = "status:red",
- .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
- },
- {
- .label = "psu:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- },
- {
- .label = "psu:red",
- .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- },
- {
- .label = "fan1:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
- {
- .label = "fan1:red",
- .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
- {
- .label = "fan2:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- },
- {
- .label = "fan2:red",
- .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- },
- {
- .label = "fan3:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
- {
- .label = "fan3:red",
- .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
- {
- .label = "fan4:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- },
- {
- .label = "fan4:red",
- .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- },
- {
- .label = "uid:blue",
- .reg = MLXPLAT_CPLD_LPC_REG_LED5_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
-};
-
-static struct mlxreg_core_platform_data mlxplat_comex_100G_led_data = {
- .data = mlxplat_mlxcpld_comex_100G_led_data,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_comex_100G_led_data),
-};
-
-/* Platform led for data for modular systems */
-static struct mlxreg_core_data mlxplat_mlxcpld_modular_led_data[] = {
- {
- .label = "status:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
- {
- .label = "status:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
- },
- {
- .label = "psu:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- },
- {
- .label = "psu:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- },
- {
- .label = "fan1:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(0),
- },
- {
- .label = "fan1:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(0),
- },
- {
- .label = "fan2:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(1),
- },
- {
- .label = "fan2:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(1),
- },
- {
- .label = "fan3:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(2),
- },
- {
- .label = "fan3:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(2),
- },
- {
- .label = "fan4:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(3),
- },
- {
- .label = "fan4:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(3),
- },
- {
- .label = "fan5:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(4),
- },
- {
- .label = "fan5:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(4),
- },
- {
- .label = "fan6:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(5),
- },
- {
- .label = "fan6:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(5),
- },
- {
- .label = "fan7:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED6_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(6),
- },
- {
- .label = "fan7:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED6_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(6),
- },
- {
- .label = "uid:blue",
- .reg = MLXPLAT_CPLD_LPC_REG_LED5_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
- {
- .label = "fan_front:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED6_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
- {
- .label = "fan_front:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED6_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
- {
- .label = "mgmt:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED7_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
- {
- .label = "mgmt:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED7_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
-};
-
-static struct mlxreg_core_platform_data mlxplat_modular_led_data = {
- .data = mlxplat_mlxcpld_modular_led_data,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_modular_led_data),
-};
-
-/* Platform led data for chassis system */
-static struct mlxreg_core_data mlxplat_mlxcpld_l1_switch_led_data[] = {
- {
- .label = "status:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
- {
- .label = "status:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED1_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK
- },
- {
- .label = "fan1:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(0),
- },
- {
- .label = "fan1:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(0),
- },
- {
- .label = "fan2:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(1),
- },
- {
- .label = "fan2:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED2_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(1),
- },
- {
- .label = "fan3:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(2),
- },
- {
- .label = "fan3:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(2),
- },
- {
- .label = "fan4:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(3),
- },
- {
- .label = "fan4:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED3_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(3),
- },
- {
- .label = "fan5:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(4),
- },
- {
- .label = "fan5:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(4),
- },
- {
- .label = "fan6:green",
- .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(5),
- },
- {
- .label = "fan6:orange",
- .reg = MLXPLAT_CPLD_LPC_REG_LED4_OFFSET,
- .mask = MLXPLAT_CPLD_LED_HI_NIBBLE_MASK,
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
- .bit = BIT(5),
- },
- {
- .label = "uid:blue",
- .reg = MLXPLAT_CPLD_LPC_REG_LED5_OFFSET,
- .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
- },
-};
-
-static struct mlxreg_core_platform_data mlxplat_l1_switch_led_data = {
- .data = mlxplat_mlxcpld_l1_switch_led_data,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_l1_switch_led_data),
-};
-
-/* Platform register access default */
-static struct mlxreg_core_data mlxplat_mlxcpld_default_regs_io_data[] = {
- {
- .label = "cpld1_version",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "cpld2_version",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "cpld1_pn",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD1_PN_OFFSET,
- .bit = GENMASK(15, 0),
- .mode = 0444,
- .regnum = 2,
- },
- {
- .label = "cpld2_pn",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD2_PN_OFFSET,
- .bit = GENMASK(15, 0),
- .mode = 0444,
- .regnum = 2,
- },
- {
- .label = "cpld1_version_min",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD1_MVER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "cpld2_version_min",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD2_MVER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "reset_long_pb",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(0),
- .mode = 0444,
- },
- {
- .label = "reset_short_pb",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(1),
- .mode = 0444,
- },
- {
- .label = "reset_aux_pwr_or_ref",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(2),
- .mode = 0444,
- },
- {
- .label = "reset_main_pwr_fail",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(3),
- .mode = 0444,
- },
- {
- .label = "reset_sw_reset",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(4),
- .mode = 0444,
- },
- {
- .label = "reset_fw_reset",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(5),
- .mode = 0444,
- },
- {
- .label = "reset_hotswap_or_wd",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(6),
- .mode = 0444,
- },
- {
- .label = "reset_asic_thermal",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(7),
- .mode = 0444,
- },
- {
- .label = "psu1_on",
- .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(0),
- .mode = 0200,
- },
- {
- .label = "psu2_on",
- .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(1),
- .mode = 0200,
- },
- {
- .label = "pwr_cycle",
- .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(2),
- .mode = 0200,
- },
- {
- .label = "pwr_down",
- .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(3),
- .mode = 0200,
- },
- {
- .label = "select_iio",
- .reg = MLXPLAT_CPLD_LPC_REG_GP2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(6),
- .mode = 0644,
- },
- {
- .label = "asic_health",
- .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
- .mask = MLXPLAT_CPLD_ASIC_MASK,
- .bit = 1,
- .mode = 0444,
- },
-};
-
-static struct mlxreg_core_platform_data mlxplat_default_regs_io_data = {
- .data = mlxplat_mlxcpld_default_regs_io_data,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_regs_io_data),
-};
-
-/* Platform register access MSN21xx, MSN201x, MSN274x systems families data */
-static struct mlxreg_core_data mlxplat_mlxcpld_msn21xx_regs_io_data[] = {
- {
- .label = "cpld1_version",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "cpld2_version",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "cpld1_pn",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD1_PN_OFFSET,
- .bit = GENMASK(15, 0),
- .mode = 0444,
- .regnum = 2,
- },
- {
- .label = "cpld2_pn",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD2_PN_OFFSET,
- .bit = GENMASK(15, 0),
- .mode = 0444,
- .regnum = 2,
- },
- {
- .label = "cpld1_version_min",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD1_MVER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "cpld2_version_min",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD2_MVER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "reset_long_pb",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(0),
- .mode = 0444,
- },
- {
- .label = "reset_short_pb",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(1),
- .mode = 0444,
- },
- {
- .label = "reset_aux_pwr_or_ref",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(2),
- .mode = 0444,
- },
- {
- .label = "reset_sw_reset",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(3),
- .mode = 0444,
- },
- {
- .label = "reset_main_pwr_fail",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(4),
- .mode = 0444,
- },
- {
- .label = "reset_asic_thermal",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(5),
- .mode = 0444,
- },
- {
- .label = "reset_hotswap_or_halt",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(6),
- .mode = 0444,
- },
- {
- .label = "reset_sff_wd",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(6),
- .mode = 0444,
- },
- {
- .label = "psu1_on",
- .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(0),
- .mode = 0200,
- },
- {
- .label = "psu2_on",
- .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(1),
- .mode = 0200,
- },
- {
- .label = "pwr_cycle",
- .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(2),
- .mode = 0200,
- },
- {
- .label = "pwr_down",
- .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(3),
- .mode = 0200,
- },
- {
- .label = "select_iio",
- .reg = MLXPLAT_CPLD_LPC_REG_GP2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(6),
- .mode = 0644,
- },
- {
- .label = "asic_health",
- .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
- .mask = MLXPLAT_CPLD_ASIC_MASK,
- .bit = 1,
- .mode = 0444,
- },
-};
-
-static struct mlxreg_core_platform_data mlxplat_msn21xx_regs_io_data = {
- .data = mlxplat_mlxcpld_msn21xx_regs_io_data,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_regs_io_data),
-};
-
-/* Platform register access for next generation systems families data */
-static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = {
- {
- .label = "cpld1_version",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "cpld2_version",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "cpld3_version",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "cpld4_version",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "cpld5_version",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD5_VER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "cpld1_pn",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD1_PN_OFFSET,
- .bit = GENMASK(15, 0),
- .mode = 0444,
- .regnum = 2,
- },
- {
- .label = "cpld2_pn",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD2_PN_OFFSET,
- .bit = GENMASK(15, 0),
- .mode = 0444,
- .regnum = 2,
- },
- {
- .label = "cpld3_pn",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD3_PN_OFFSET,
- .bit = GENMASK(15, 0),
- .mode = 0444,
- .regnum = 2,
- },
- {
- .label = "cpld4_pn",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD4_PN_OFFSET,
- .bit = GENMASK(15, 0),
- .mode = 0444,
- .regnum = 2,
- },
- {
- .label = "cpld5_pn",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD5_PN_OFFSET,
- .bit = GENMASK(15, 0),
- .mode = 0444,
- .regnum = 2,
- },
- {
- .label = "cpld1_version_min",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD1_MVER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "cpld2_version_min",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD2_MVER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "cpld3_version_min",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD3_MVER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "cpld4_version_min",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD4_MVER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "cpld5_version_min",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD5_MVER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "asic_reset",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_GP2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(3),
- .mode = 0200,
- },
- {
- .label = "asic2_reset",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_GP2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(2),
- .mode = 0200,
- },
- {
- .label = "erot1_reset",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_GP2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(6),
- .mode = 0644,
- },
- {
- .label = "erot2_reset",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_GP2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(7),
- .mode = 0644,
- },
- {
- .label = "clk_brd_prog_en",
- .reg = MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(1),
- .mode = 0644,
- .secured = 1,
- },
- {
- .label = "erot1_recovery",
- .reg = MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(6),
- .mode = 0644,
- },
- {
- .label = "erot2_recovery",
- .reg = MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(7),
- .mode = 0644,
- },
- {
- .label = "erot1_wp",
- .reg = MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(4),
- .mode = 0644,
- .secured = 1,
- },
- {
- .label = "erot2_wp",
- .reg = MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(5),
- .mode = 0644,
- .secured = 1,
- },
- {
- .label = "reset_long_pb",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(0),
- .mode = 0444,
- },
- {
- .label = "reset_short_pb",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(1),
- .mode = 0444,
- },
- {
- .label = "reset_aux_pwr_or_ref",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(2),
- .mode = 0444,
- },
- {
- .label = "reset_swb_dc_dc_pwr_fail",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(3),
- .mode = 0444,
- },
- {
- .label = "reset_from_asic",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(5),
- .mode = 0444,
- },
- {
- .label = "reset_swb_wd",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(6),
- .mode = 0444,
- },
- {
- .label = "reset_asic_thermal",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(7),
- .mode = 0444,
- },
- {
- .label = "reset_sw_reset",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(0),
- .mode = 0444,
- },
- {
- .label = "reset_comex_pwr_fail",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(3),
- .mode = 0444,
- },
- {
- .label = "reset_platform",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(4),
- .mode = 0444,
- },
- {
- .label = "reset_soc",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(5),
- .mode = 0444,
- },
- {
- .label = "reset_comex_wd",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(6),
- .mode = 0444,
- },
- {
- .label = "reset_pwr_converter_fail",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(0),
- .mode = 0444,
- },
- {
- .label = "reset_system",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(1),
- .mode = 0444,
- },
- {
- .label = "reset_sw_pwr_off",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(2),
- .mode = 0444,
- },
- {
- .label = "reset_comex_thermal",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(3),
- .mode = 0444,
- },
- {
- .label = "reset_reload_bios",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(5),
- .mode = 0444,
- },
- {
- .label = "reset_ac_pwr_fail",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(6),
- .mode = 0444,
- },
- {
- .label = "reset_ac_ok_fail",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(7),
- .mode = 0444,
- },
- {
- .label = "psu1_on",
- .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(0),
- .mode = 0200,
- },
- {
- .label = "psu2_on",
- .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(1),
- .mode = 0200,
- },
- {
- .label = "pwr_cycle",
- .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(2),
- .mode = 0200,
- },
- {
- .label = "pwr_down",
- .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(3),
- .mode = 0200,
- },
- {
- .label = "deep_pwr_cycle",
- .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(5),
- .mode = 0200,
- },
- {
- .label = "latch_reset",
- .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(6),
- .mode = 0200,
- },
- {
- .label = "jtag_cap",
- .reg = MLXPLAT_CPLD_LPC_REG_FU_CAP_OFFSET,
- .mask = MLXPLAT_CPLD_FU_CAP_MASK,
- .bit = 1,
- .mode = 0444,
- },
- {
- .label = "jtag_enable",
- .reg = MLXPLAT_CPLD_LPC_REG_GP2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(4),
- .mode = 0644,
- },
- {
- .label = "dbg1",
- .reg = MLXPLAT_CPLD_LPC_REG_DBG1_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0644,
- },
- {
- .label = "dbg2",
- .reg = MLXPLAT_CPLD_LPC_REG_DBG2_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0644,
- },
- {
- .label = "dbg3",
- .reg = MLXPLAT_CPLD_LPC_REG_DBG3_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0644,
- },
- {
- .label = "dbg4",
- .reg = MLXPLAT_CPLD_LPC_REG_DBG4_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0644,
- },
- {
- .label = "asic_health",
- .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
- .mask = MLXPLAT_CPLD_ASIC_MASK,
- .bit = 1,
- .mode = 0444,
- },
- {
- .label = "asic2_health",
- .reg = MLXPLAT_CPLD_LPC_REG_ASIC2_HEALTH_OFFSET,
- .mask = MLXPLAT_CPLD_ASIC_MASK,
- .bit = 1,
- .mode = 0444,
- },
- {
- .label = "fan_dir",
- .reg = MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "bios_safe_mode",
- .reg = MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(4),
- .mode = 0444,
- },
- {
- .label = "bios_active_image",
- .reg = MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(5),
- .mode = 0444,
- },
- {
- .label = "bios_auth_fail",
- .reg = MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(6),
- .mode = 0444,
- },
- {
- .label = "bios_upgrade_fail",
- .reg = MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(7),
- .mode = 0444,
- },
- {
- .label = "voltreg_update_status",
- .reg = MLXPLAT_CPLD_LPC_REG_GP0_RO_OFFSET,
- .mask = MLXPLAT_CPLD_VOLTREG_UPD_MASK,
- .bit = 5,
- .mode = 0444,
- },
- {
- .label = "pwr_converter_prog_en",
- .reg = MLXPLAT_CPLD_LPC_REG_GP0_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(0),
- .mode = 0644,
- .secured = 1,
- },
- {
- .label = "vpd_wp",
- .reg = MLXPLAT_CPLD_LPC_REG_GP0_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(3),
- .mode = 0644,
- },
- {
- .label = "pcie_asic_reset_dis",
- .reg = MLXPLAT_CPLD_LPC_REG_GP0_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(4),
- .mode = 0644,
- },
- {
- .label = "erot1_ap_reset",
- .reg = MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(0),
- .mode = 0444,
- },
- {
- .label = "erot2_ap_reset",
- .reg = MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(1),
- .mode = 0444,
- },
- {
- .label = "lid_open",
- .reg = MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(2),
- .mode = 0444,
- },
- {
- .label = "clk_brd1_boot_fail",
- .reg = MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(4),
- .mode = 0444,
- },
- {
- .label = "clk_brd2_boot_fail",
- .reg = MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(5),
- .mode = 0444,
- },
- {
- .label = "clk_brd_fail",
- .reg = MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(6),
- .mode = 0444,
- },
- {
- .label = "asic_pg_fail",
- .reg = MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(7),
- .mode = 0444,
- },
- {
- .label = "spi_chnl_select",
- .reg = MLXPLAT_CPLD_LPC_REG_SPI_CHNL_SELECT,
- .mask = GENMASK(7, 0),
- .bit = 1,
- .mode = 0644,
- },
- {
- .label = "config1",
- .reg = MLXPLAT_CPLD_LPC_REG_CONFIG1_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "config2",
- .reg = MLXPLAT_CPLD_LPC_REG_CONFIG2_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "config3",
- .reg = MLXPLAT_CPLD_LPC_REG_CONFIG3_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "ufm_version",
- .reg = MLXPLAT_CPLD_LPC_REG_UFM_VERSION_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
-};
-
-static struct mlxreg_core_platform_data mlxplat_default_ng_regs_io_data = {
- .data = mlxplat_mlxcpld_default_ng_regs_io_data,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_regs_io_data),
-};
-
-/* Platform register access for modular systems families data */
-static struct mlxreg_core_data mlxplat_mlxcpld_modular_regs_io_data[] = {
- {
- .label = "cpld1_version",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "cpld2_version",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "cpld3_version",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "cpld4_version",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "cpld1_pn",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD1_PN_OFFSET,
- .bit = GENMASK(15, 0),
- .mode = 0444,
- .regnum = 2,
- },
- {
- .label = "cpld2_pn",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD2_PN_OFFSET,
- .bit = GENMASK(15, 0),
- .mode = 0444,
- .regnum = 2,
- },
- {
- .label = "cpld3_pn",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD3_PN_OFFSET,
- .bit = GENMASK(15, 0),
- .mode = 0444,
- .regnum = 2,
- },
- {
- .label = "cpld4_pn",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD4_PN_OFFSET,
- .bit = GENMASK(15, 0),
- .mode = 0444,
- .regnum = 2,
- },
- {
- .label = "cpld1_version_min",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD1_MVER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "cpld2_version_min",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD2_MVER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "cpld3_version_min",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD3_MVER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "cpld4_version_min",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD4_MVER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "lc1_enable",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(0),
- .mode = 0644,
- },
- {
- .label = "lc2_enable",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(1),
- .mode = 0644,
- },
- {
- .label = "lc3_enable",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(2),
- .mode = 0644,
- },
- {
- .label = "lc4_enable",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(3),
- .mode = 0644,
- },
- {
- .label = "lc5_enable",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(4),
- .mode = 0644,
- },
- {
- .label = "lc6_enable",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(5),
- .mode = 0644,
- },
- {
- .label = "lc7_enable",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(6),
- .mode = 0644,
- },
- {
- .label = "lc8_enable",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(7),
- .mode = 0644,
- },
- {
- .label = "reset_long_pb",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(0),
- .mode = 0444,
- },
- {
- .label = "reset_short_pb",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(1),
- .mode = 0444,
- },
- {
- .label = "reset_aux_pwr_or_fu",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(2),
- .mode = 0444,
- },
- {
- .label = "reset_mgmt_dc_dc_pwr_fail",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(3),
- .mode = 0444,
- },
- {
- .label = "reset_sys_comex_bios",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(5),
- .mode = 0444,
- },
- {
- .label = "reset_sw_reset",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(0),
- .mode = 0444,
- },
- {
- .label = "reset_aux_pwr_or_reload",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(2),
- .mode = 0444,
- },
- {
- .label = "reset_comex_pwr_fail",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(3),
- .mode = 0444,
- },
- {
- .label = "reset_platform",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(4),
- .mode = 0444,
- },
- {
- .label = "reset_soc",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(5),
- .mode = 0444,
- },
- {
- .label = "reset_pwr_off_from_carrier",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(7),
- .mode = 0444,
- },
- {
- .label = "reset_swb_wd",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(0),
- .mode = 0444,
- },
- {
- .label = "reset_swb_aux_pwr_or_fu",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(2),
- .mode = 0444,
- },
- {
- .label = "reset_swb_dc_dc_pwr_fail",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(3),
- .mode = 0444,
- },
- {
- .label = "reset_swb_12v_fail",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(4),
- .mode = 0444,
- },
- {
- .label = "reset_system",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(5),
- .mode = 0444,
- },
- {
- .label = "reset_thermal_spc_or_pciesw",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(7),
- .mode = 0444,
- },
- {
- .label = "bios_safe_mode",
- .reg = MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(4),
- .mode = 0444,
- },
- {
- .label = "bios_active_image",
- .reg = MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(5),
- .mode = 0444,
- },
- {
- .label = "bios_auth_fail",
- .reg = MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(6),
- .mode = 0444,
- },
- {
- .label = "bios_upgrade_fail",
- .reg = MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(7),
- .mode = 0444,
- },
- {
- .label = "voltreg_update_status",
- .reg = MLXPLAT_CPLD_LPC_REG_GP0_RO_OFFSET,
- .mask = MLXPLAT_CPLD_VOLTREG_UPD_MASK,
- .bit = 5,
- .mode = 0444,
- },
- {
- .label = "vpd_wp",
- .reg = MLXPLAT_CPLD_LPC_REG_GP0_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(3),
- .mode = 0644,
- },
- {
- .label = "pcie_asic_reset_dis",
- .reg = MLXPLAT_CPLD_LPC_REG_GP0_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(4),
- .mode = 0644,
- },
- {
- .label = "shutdown_unlock",
- .reg = MLXPLAT_CPLD_LPC_REG_GP0_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(5),
- .mode = 0644,
- },
- {
- .label = "lc1_rst_mask",
- .reg = MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(0),
- .mode = 0200,
- },
- {
- .label = "lc2_rst_mask",
- .reg = MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(1),
- .mode = 0200,
- },
- {
- .label = "lc3_rst_mask",
- .reg = MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(2),
- .mode = 0200,
- },
- {
- .label = "lc4_rst_mask",
- .reg = MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(3),
- .mode = 0200,
- },
- {
- .label = "lc5_rst_mask",
- .reg = MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(4),
- .mode = 0200,
- },
- {
- .label = "lc6_rst_mask",
- .reg = MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(5),
- .mode = 0200,
- },
- {
- .label = "lc7_rst_mask",
- .reg = MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(6),
- .mode = 0200,
- },
- {
- .label = "lc8_rst_mask",
- .reg = MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(7),
- .mode = 0200,
- },
- {
- .label = "psu1_on",
- .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(0),
- .mode = 0200,
- },
- {
- .label = "psu2_on",
- .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(1),
- .mode = 0200,
- },
- {
- .label = "pwr_cycle",
- .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(2),
- .mode = 0200,
- },
- {
- .label = "pwr_down",
- .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(3),
- .mode = 0200,
- },
- {
- .label = "psu3_on",
- .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(4),
- .mode = 0200,
- },
- {
- .label = "psu4_on",
- .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(5),
- .mode = 0200,
- },
- {
- .label = "auto_power_mode",
- .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(6),
- .mode = 0644,
- },
- {
- .label = "pm_mgmt_en",
- .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(7),
- .mode = 0644,
- },
- {
- .label = "jtag_enable",
- .reg = MLXPLAT_CPLD_LPC_REG_FIELD_UPGRADE,
- .mask = GENMASK(3, 0),
- .bit = 1,
- .mode = 0644,
- },
- {
- .label = "safe_bios_dis",
- .reg = MLXPLAT_CPLD_LPC_SAFE_BIOS_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(5),
- .mode = 0644,
- },
- {
- .label = "safe_bios_dis_wp",
- .reg = MLXPLAT_CPLD_LPC_SAFE_BIOS_WP_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(5),
- .mode = 0644,
- },
- {
- .label = "asic_health",
- .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
- .mask = MLXPLAT_CPLD_ASIC_MASK,
- .bit = 1,
- .mode = 0444,
- },
- {
- .label = "fan_dir",
- .reg = MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "lc1_pwr",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_PWR_ON,
- .mask = GENMASK(7, 0) & ~BIT(0),
- .mode = 0644,
- },
- {
- .label = "lc2_pwr",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_PWR_ON,
- .mask = GENMASK(7, 0) & ~BIT(1),
- .mode = 0644,
- },
- {
- .label = "lc3_pwr",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_PWR_ON,
- .mask = GENMASK(7, 0) & ~BIT(2),
- .mode = 0644,
- },
- {
- .label = "lc4_pwr",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_PWR_ON,
- .mask = GENMASK(7, 0) & ~BIT(3),
- .mode = 0644,
- },
- {
- .label = "lc5_pwr",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_PWR_ON,
- .mask = GENMASK(7, 0) & ~BIT(4),
- .mode = 0644,
- },
- {
- .label = "lc6_pwr",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_PWR_ON,
- .mask = GENMASK(7, 0) & ~BIT(5),
- .mode = 0644,
- },
- {
- .label = "lc7_pwr",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_PWR_ON,
- .mask = GENMASK(7, 0) & ~BIT(6),
- .mode = 0644,
- },
- {
- .label = "lc8_pwr",
- .reg = MLXPLAT_CPLD_LPC_REG_LC_PWR_ON,
- .mask = GENMASK(7, 0) & ~BIT(7),
- .mode = 0644,
- },
- {
- .label = "config1",
- .reg = MLXPLAT_CPLD_LPC_REG_CONFIG1_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "config2",
- .reg = MLXPLAT_CPLD_LPC_REG_CONFIG2_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "config3",
- .reg = MLXPLAT_CPLD_LPC_REG_CONFIG3_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "ufm_version",
- .reg = MLXPLAT_CPLD_LPC_REG_UFM_VERSION_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
-};
-
-static struct mlxreg_core_platform_data mlxplat_modular_regs_io_data = {
- .data = mlxplat_mlxcpld_modular_regs_io_data,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_modular_regs_io_data),
-};
-
-/* Platform register access for chassis blade systems family data */
-static struct mlxreg_core_data mlxplat_mlxcpld_chassis_blade_regs_io_data[] = {
- {
- .label = "cpld1_version",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "cpld1_pn",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD1_PN_OFFSET,
- .bit = GENMASK(15, 0),
- .mode = 0444,
- .regnum = 2,
- },
- {
- .label = "cpld1_version_min",
- .reg = MLXPLAT_CPLD_LPC_REG_CPLD1_MVER_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "reset_aux_pwr_or_ref",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(2),
- .mode = 0444,
- },
- {
- .label = "reset_from_comex",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(4),
- .mode = 0444,
- },
- {
- .label = "reset_comex_pwr_fail",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(3),
- .mode = 0444,
- },
- {
- .label = "reset_platform",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(4),
- .mode = 0444,
- },
- {
- .label = "reset_soc",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(5),
- .mode = 0444,
- },
- {
- .label = "reset_comex_wd",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(6),
- .mode = 0444,
- },
- {
- .label = "reset_voltmon_upgrade_fail",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(0),
- .mode = 0444,
- },
- {
- .label = "reset_system",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(1),
- .mode = 0444,
- },
- {
- .label = "reset_sw_pwr_off",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(2),
- .mode = 0444,
- },
- {
- .label = "reset_comex_thermal",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(3),
- .mode = 0444,
- },
- {
- .label = "reset_reload_bios",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(5),
- .mode = 0444,
- },
- {
- .label = "reset_ac_pwr_fail",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(6),
- .mode = 0444,
- },
- {
- .label = "reset_long_pwr_pb",
- .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(7),
- .mode = 0444,
- },
- {
- .label = "pwr_cycle",
- .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(2),
- .mode = 0200,
- },
- {
- .label = "pwr_down",
- .reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(3),
- .mode = 0200,
- },
- {
- .label = "global_wp_request",
- .reg = MLXPLAT_CPLD_LPC_REG_GP2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(0),
- .mode = 0644,
- },
- {
- .label = "jtag_enable",
- .reg = MLXPLAT_CPLD_LPC_REG_GP2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(4),
- .mode = 0644,
- },
- {
- .label = "comm_chnl_ready",
- .reg = MLXPLAT_CPLD_LPC_REG_GP2_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(6),
- .mode = 0200,
- },
- {
- .label = "bios_safe_mode",
- .reg = MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(4),
- .mode = 0444,
- },
- {
- .label = "bios_active_image",
- .reg = MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(5),
- .mode = 0444,
- },
- {
- .label = "bios_auth_fail",
- .reg = MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(6),
- .mode = 0444,
- },
- {
- .label = "bios_upgrade_fail",
- .reg = MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(7),
- .mode = 0444,
- },
- {
- .label = "voltreg_update_status",
- .reg = MLXPLAT_CPLD_LPC_REG_GP0_RO_OFFSET,
- .mask = MLXPLAT_CPLD_VOLTREG_UPD_MASK,
- .bit = 5,
- .mode = 0444,
- },
- {
- .label = "vpd_wp",
- .reg = MLXPLAT_CPLD_LPC_REG_GP0_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(3),
- .mode = 0644,
- },
- {
- .label = "pcie_asic_reset_dis",
- .reg = MLXPLAT_CPLD_LPC_REG_GP0_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(4),
- .mode = 0644,
- },
- {
- .label = "global_wp_response",
- .reg = MLXPLAT_CPLD_LPC_REG_GWP_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(0),
- .mode = 0444,
- },
- {
- .label = "config1",
- .reg = MLXPLAT_CPLD_LPC_REG_CONFIG1_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "config2",
- .reg = MLXPLAT_CPLD_LPC_REG_CONFIG2_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "config3",
- .reg = MLXPLAT_CPLD_LPC_REG_CONFIG3_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
- {
- .label = "ufm_version",
- .reg = MLXPLAT_CPLD_LPC_REG_UFM_VERSION_OFFSET,
- .bit = GENMASK(7, 0),
- .mode = 0444,
- },
-};
-
-static struct mlxreg_core_platform_data mlxplat_chassis_blade_regs_io_data = {
- .data = mlxplat_mlxcpld_chassis_blade_regs_io_data,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_chassis_blade_regs_io_data),
-};
-
-/* Platform FAN default */
-static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_data[] = {
- {
- .label = "pwm1",
- .reg = MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET,
- },
- {
- .label = "pwm2",
- .reg = MLXPLAT_CPLD_LPC_REG_PWM2_OFFSET,
- },
- {
- .label = "pwm3",
- .reg = MLXPLAT_CPLD_LPC_REG_PWM3_OFFSET,
- },
- {
- .label = "pwm4",
- .reg = MLXPLAT_CPLD_LPC_REG_PWM4_OFFSET,
- },
- {
- .label = "tacho1",
- .reg = MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET,
- .mask = GENMASK(7, 0),
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
- .bit = BIT(0),
- .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
-
- },
- {
- .label = "tacho2",
- .reg = MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET,
- .mask = GENMASK(7, 0),
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
- .bit = BIT(1),
- .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- },
- {
- .label = "tacho3",
- .reg = MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET,
- .mask = GENMASK(7, 0),
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
- .bit = BIT(2),
- .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- },
- {
- .label = "tacho4",
- .reg = MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET,
- .mask = GENMASK(7, 0),
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
- .bit = BIT(3),
- .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- },
- {
- .label = "tacho5",
- .reg = MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET,
- .mask = GENMASK(7, 0),
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
- .bit = BIT(4),
- .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- },
- {
- .label = "tacho6",
- .reg = MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET,
- .mask = GENMASK(7, 0),
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
- .bit = BIT(5),
- .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- },
- {
- .label = "tacho7",
- .reg = MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET,
- .mask = GENMASK(7, 0),
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
- .bit = BIT(6),
- .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- },
- {
- .label = "tacho8",
- .reg = MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET,
- .mask = GENMASK(7, 0),
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET,
- .bit = BIT(7),
- .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- },
- {
- .label = "tacho9",
- .reg = MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET,
- .mask = GENMASK(7, 0),
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET,
- .bit = BIT(0),
- .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- },
- {
- .label = "tacho10",
- .reg = MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET,
- .mask = GENMASK(7, 0),
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET,
- .bit = BIT(1),
- .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- },
- {
- .label = "tacho11",
- .reg = MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET,
- .mask = GENMASK(7, 0),
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET,
- .bit = BIT(2),
- .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- },
- {
- .label = "tacho12",
- .reg = MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET,
- .mask = GENMASK(7, 0),
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET,
- .bit = BIT(3),
- .reg_prsnt = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
- },
- {
- .label = "tacho13",
- .reg = MLXPLAT_CPLD_LPC_REG_TACHO13_OFFSET,
- .mask = GENMASK(7, 0),
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET,
- .bit = BIT(4),
- },
- {
- .label = "tacho14",
- .reg = MLXPLAT_CPLD_LPC_REG_TACHO14_OFFSET,
- .mask = GENMASK(7, 0),
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET,
- .bit = BIT(5),
- },
- {
- .label = "conf",
- .capability = MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET,
- },
-};
-
-static struct mlxreg_core_platform_data mlxplat_default_fan_data = {
- .data = mlxplat_mlxcpld_default_fan_data,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_fan_data),
- .capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
-};
-
-/* Watchdog type1: hardware implementation version1
- * (MSN2700, MSN2410, MSN2740, MSN2100 and MSN2140 systems).
- */
-static struct mlxreg_core_data mlxplat_mlxcpld_wd_main_regs_type1[] = {
- {
- .label = "action",
- .reg = MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET,
- .mask = MLXPLAT_CPLD_WD_RESET_ACT_MASK,
- .bit = 0,
- },
- {
- .label = "timeout",
- .reg = MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET,
- .mask = MLXPLAT_CPLD_WD_TYPE1_TO_MASK,
- .health_cntr = MLXPLAT_CPLD_WD_DFLT_TIMEOUT,
- },
- {
- .label = "ping",
- .reg = MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET,
- .mask = MLXPLAT_CPLD_WD1_CLEAR_MASK,
- .bit = 0,
- },
- {
- .label = "reset",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(6),
- .bit = 6,
- },
-};
-
-static struct mlxreg_core_data mlxplat_mlxcpld_wd_aux_regs_type1[] = {
- {
- .label = "action",
- .reg = MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET,
- .mask = MLXPLAT_CPLD_WD_FAN_ACT_MASK,
- .bit = 4,
- },
- {
- .label = "timeout",
- .reg = MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET,
- .mask = MLXPLAT_CPLD_WD_TYPE1_TO_MASK,
- .health_cntr = MLXPLAT_CPLD_WD_DFLT_TIMEOUT,
- },
- {
- .label = "ping",
- .reg = MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET,
- .mask = MLXPLAT_CPLD_WD1_CLEAR_MASK,
- .bit = 1,
- },
-};
-
-static struct mlxreg_core_platform_data mlxplat_mlxcpld_wd_set_type1[] = {
- {
- .data = mlxplat_mlxcpld_wd_main_regs_type1,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_wd_main_regs_type1),
- .version = MLX_WDT_TYPE1,
- .identity = "mlx-wdt-main",
- },
- {
- .data = mlxplat_mlxcpld_wd_aux_regs_type1,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_wd_aux_regs_type1),
- .version = MLX_WDT_TYPE1,
- .identity = "mlx-wdt-aux",
- },
-};
-
-/* Watchdog type2: hardware implementation version 2
- * (all systems except (MSN2700, MSN2410, MSN2740, MSN2100 and MSN2140).
- */
-static struct mlxreg_core_data mlxplat_mlxcpld_wd_main_regs_type2[] = {
- {
- .label = "action",
- .reg = MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET,
- .mask = MLXPLAT_CPLD_WD_RESET_ACT_MASK,
- .bit = 0,
- },
- {
- .label = "timeout",
- .reg = MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET,
- .mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK,
- .health_cntr = MLXPLAT_CPLD_WD_DFLT_TIMEOUT,
- },
- {
- .label = "timeleft",
- .reg = MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET,
- .mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK,
- },
- {
- .label = "ping",
- .reg = MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET,
- .mask = MLXPLAT_CPLD_WD_RESET_ACT_MASK,
- .bit = 0,
- },
- {
- .label = "reset",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(6),
- .bit = 6,
- },
-};
-
-static struct mlxreg_core_data mlxplat_mlxcpld_wd_aux_regs_type2[] = {
- {
- .label = "action",
- .reg = MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET,
- .mask = MLXPLAT_CPLD_WD_FAN_ACT_MASK,
- .bit = 4,
- },
- {
- .label = "timeout",
- .reg = MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET,
- .mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK,
- .health_cntr = MLXPLAT_CPLD_WD_DFLT_TIMEOUT,
- },
- {
- .label = "timeleft",
- .reg = MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET,
- .mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK,
- },
- {
- .label = "ping",
- .reg = MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET,
- .mask = MLXPLAT_CPLD_WD_FAN_ACT_MASK,
- .bit = 4,
- },
-};
-
-static struct mlxreg_core_platform_data mlxplat_mlxcpld_wd_set_type2[] = {
- {
- .data = mlxplat_mlxcpld_wd_main_regs_type2,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_wd_main_regs_type2),
- .version = MLX_WDT_TYPE2,
- .identity = "mlx-wdt-main",
- },
- {
- .data = mlxplat_mlxcpld_wd_aux_regs_type2,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_wd_aux_regs_type2),
- .version = MLX_WDT_TYPE2,
- .identity = "mlx-wdt-aux",
- },
-};
-
-/* Watchdog type3: hardware implementation version 3
- * Can be on all systems. It's differentiated by WD capability bit.
- * Old systems (MSN2700, MSN2410, MSN2740, MSN2100 and MSN2140)
- * still have only one main watchdog.
- */
-static struct mlxreg_core_data mlxplat_mlxcpld_wd_main_regs_type3[] = {
- {
- .label = "action",
- .reg = MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET,
- .mask = MLXPLAT_CPLD_WD_RESET_ACT_MASK,
- .bit = 0,
- },
- {
- .label = "timeout",
- .reg = MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET,
- .mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK,
- .health_cntr = MLXPLAT_CPLD_WD3_DFLT_TIMEOUT,
- },
- {
- .label = "timeleft",
- .reg = MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET,
- .mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK,
- },
- {
- .label = "ping",
- .reg = MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET,
- .mask = MLXPLAT_CPLD_WD_RESET_ACT_MASK,
- .bit = 0,
- },
- {
- .label = "reset",
- .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
- .mask = GENMASK(7, 0) & ~BIT(6),
- .bit = 6,
- },
-};
-
-static struct mlxreg_core_data mlxplat_mlxcpld_wd_aux_regs_type3[] = {
- {
- .label = "action",
- .reg = MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET,
- .mask = MLXPLAT_CPLD_WD_FAN_ACT_MASK,
- .bit = 4,
- },
- {
- .label = "timeout",
- .reg = MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET,
- .mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK,
- .health_cntr = MLXPLAT_CPLD_WD3_DFLT_TIMEOUT,
- },
- {
- .label = "timeleft",
- .reg = MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET,
- .mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK,
- },
- {
- .label = "ping",
- .reg = MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET,
- .mask = MLXPLAT_CPLD_WD_FAN_ACT_MASK,
- .bit = 4,
- },
-};
-
-static struct mlxreg_core_platform_data mlxplat_mlxcpld_wd_set_type3[] = {
- {
- .data = mlxplat_mlxcpld_wd_main_regs_type3,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_wd_main_regs_type3),
- .version = MLX_WDT_TYPE3,
- .identity = "mlx-wdt-main",
- },
- {
- .data = mlxplat_mlxcpld_wd_aux_regs_type3,
- .counter = ARRAY_SIZE(mlxplat_mlxcpld_wd_aux_regs_type3),
- .version = MLX_WDT_TYPE3,
- .identity = "mlx-wdt-aux",
- },
-};
-
-static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case MLXPLAT_CPLD_LPC_REG_RESET_GP1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LED6_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LED7_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_GP0_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_WP1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_WP2_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_FIELD_UPGRADE:
- case MLXPLAT_CPLD_LPC_SAFE_BIOS_OFFSET:
- case MLXPLAT_CPLD_LPC_SAFE_BIOS_WP_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_FU_CAP_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_DBG1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_DBG2_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_DBG3_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_DBG4_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_AGGRCO_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_AGGRCX_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_GWP_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_GWP_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_BRD_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_BRD_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_BRD_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_ASIC2_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_ASIC2_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_EROT_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_EROT_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_EROTE_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_EROTE_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWRB_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWRB_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_AGGRLC_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_IN_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_IN_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_VR_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_VR_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_PG_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_PG_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_PG_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_RD_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_RD_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_OK_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_OK_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_SN_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_SN_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_SD_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_SD_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_PWR_ON:
- case MLXPLAT_CPLD_LPC_REG_SPI_CHNL_SELECT:
- case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_DBG_CTRL_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_I2C_CH1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_I2C_CH2_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_I2C_CH3_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_I2C_CH4_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWM2_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWM3_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWM4_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
- return true;
- }
- return false;
-}
-
-static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD5_VER_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD1_PN_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD1_PN1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD2_PN_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD2_PN1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD3_PN_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD3_PN1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD4_PN_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD4_PN1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD5_PN_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD5_PN1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_RESET_GP1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LED6_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LED7_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION:
- case MLXPLAT_CPLD_LPC_REG_GP0_RO_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_GP0_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_WP1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_WP2_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_FIELD_UPGRADE:
- case MLXPLAT_CPLD_LPC_SAFE_BIOS_OFFSET:
- case MLXPLAT_CPLD_LPC_SAFE_BIOS_WP_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_FU_CAP_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_DBG1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_DBG2_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_DBG3_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_DBG4_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_AGGRCO_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_AGGRCO_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_AGGRCX_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_AGGRCX_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_GWP_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_GWP_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_GWP_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_BRD_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_BRD_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_BRD_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_ASIC2_HEALTH_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_ASIC2_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_ASIC2_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PSU_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWR_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_EROT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_EROT_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_EROT_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_EROTE_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_EROTE_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_EROTE_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWRB_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWRB_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWRB_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_AGGRLC_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_AGGRLC_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_IN_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_IN_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_IN_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_VR_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_VR_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_VR_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_PG_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_PG_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_PG_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_RD_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_RD_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_RD_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_OK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_OK_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_OK_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_SN_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_SN_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_SD_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_SD_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_SD_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_PWR_ON:
- case MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_SPI_CHNL_SELECT:
- case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_DBG_CTRL_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_I2C_CH1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_I2C_CH2_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_I2C_CH3_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_I2C_CH4_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD1_MVER_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD2_MVER_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD3_MVER_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD4_MVER_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD5_MVER_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWM2_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWM3_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWM4_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO13_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO14_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_SLOT_QTY_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CONFIG1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CONFIG2_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CONFIG3_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_UFM_VERSION_OFFSET:
- return true;
- }
- return false;
-}
-
-static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg)
-{
- switch (reg) {
- case MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD5_VER_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD1_PN_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD1_PN1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD2_PN_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD2_PN1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD3_PN_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD3_PN1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD4_PN_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD4_PN1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD5_PN_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD5_PN1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_RESET_GP1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_RESET_GP4_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LED1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LED2_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LED3_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LED4_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LED5_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LED6_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LED7_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION:
- case MLXPLAT_CPLD_LPC_REG_GP0_RO_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_GPCOM0_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_GP0_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_GP_RST_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_GP1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_GP2_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_FIELD_UPGRADE:
- case MLXPLAT_CPLD_LPC_SAFE_BIOS_OFFSET:
- case MLXPLAT_CPLD_LPC_SAFE_BIOS_WP_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_FU_CAP_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_DBG1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_DBG2_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_DBG3_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_DBG4_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_AGGRCO_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_AGGRCO_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_AGGRCX_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_AGGRCX_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_GWP_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_GWP_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_GWP_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_BRD_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_BRD_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_BRD_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_ASIC_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_ASIC_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_ASIC2_HEALTH_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_ASIC2_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_ASIC2_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PSU_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWR_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_EROT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_EROT_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_EROT_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_EROTE_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_EROTE_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_EROTE_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWRB_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWRB_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWRB_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_AGGRLC_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_AGGRLC_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_IN_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_IN_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_IN_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_VR_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_VR_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_VR_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_PG_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_PG_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_PG_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_RD_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_RD_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_RD_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_OK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_OK_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_OK_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_SN_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_SN_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_SN_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_SD_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_SD_EVENT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_SD_MASK_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_LC_PWR_ON:
- case MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_SPI_CHNL_SELECT:
- case MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_DBG_CTRL_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_I2C_CH1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_I2C_CH2_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_I2C_CH3_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_I2C_CH4_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD1_MVER_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD2_MVER_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD3_MVER_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD4_MVER_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CPLD5_MVER_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWM2_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWM3_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWM4_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO3_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO4_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO5_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO6_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO7_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO8_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO9_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO10_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO11_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO13_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO14_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_FAN_CAP1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_FAN_CAP2_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_SLOT_QTY_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CONFIG1_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CONFIG2_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_CONFIG3_OFFSET:
- case MLXPLAT_CPLD_LPC_REG_UFM_VERSION_OFFSET:
- return true;
- }
- return false;
-}
-
-static const struct reg_default mlxplat_mlxcpld_regmap_default[] = {
- { MLXPLAT_CPLD_LPC_REG_WP1_OFFSET, 0x00 },
- { MLXPLAT_CPLD_LPC_REG_WP2_OFFSET, 0x00 },
- { MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET, 0x00 },
- { MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET, 0x00 },
-};
-
-static const struct reg_default mlxplat_mlxcpld_regmap_ng[] = {
- { MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET, 0x00 },
- { MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET, 0x00 },
-};
-
-static const struct reg_default mlxplat_mlxcpld_regmap_comex_default[] = {
- { MLXPLAT_CPLD_LPC_REG_AGGRCX_MASK_OFFSET,
- MLXPLAT_CPLD_LOW_AGGRCX_MASK },
- { MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET, 0x00 },
-};
-
-static const struct reg_default mlxplat_mlxcpld_regmap_ng400[] = {
- { MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET, 0x00 },
- { MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET, 0x00 },
- { MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET, 0x00 },
- { MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET, 0x00 },
-};
-
-static const struct reg_default mlxplat_mlxcpld_regmap_rack_switch[] = {
- { MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET, MLXPLAT_REGMAP_NVSWITCH_PWM_DEFAULT },
- { MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET, 0x00 },
- { MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET, 0x00 },
- { MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET, 0x00 },
-};
-
-static const struct reg_default mlxplat_mlxcpld_regmap_eth_modular[] = {
- { MLXPLAT_CPLD_LPC_REG_GP2_OFFSET, 0x61 },
- { MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET, 0x00 },
- { MLXPLAT_CPLD_LPC_REG_PWM2_OFFSET, 0x00 },
- { MLXPLAT_CPLD_LPC_REG_PWM3_OFFSET, 0x00 },
- { MLXPLAT_CPLD_LPC_REG_PWM4_OFFSET, 0x00 },
- { MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET, 0x00 },
- { MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET, 0x00 },
- { MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET, 0x00 },
- { MLXPLAT_CPLD_LPC_REG_AGGRLC_MASK_OFFSET,
- MLXPLAT_CPLD_AGGR_MASK_LC_LOW },
-};
-
-struct mlxplat_mlxcpld_regmap_context {
- void __iomem *base;
-};
-
-static struct mlxplat_mlxcpld_regmap_context mlxplat_mlxcpld_regmap_ctx;
-
-static int
-mlxplat_mlxcpld_reg_read(void *context, unsigned int reg, unsigned int *val)
-{
- struct mlxplat_mlxcpld_regmap_context *ctx = context;
-
- *val = ioread8(ctx->base + reg);
- return 0;
-}
-
-static int
-mlxplat_mlxcpld_reg_write(void *context, unsigned int reg, unsigned int val)
-{
- struct mlxplat_mlxcpld_regmap_context *ctx = context;
-
- iowrite8(val, ctx->base + reg);
- return 0;
-}
-
-static const struct regmap_config mlxplat_mlxcpld_regmap_config = {
- .reg_bits = 8,
- .val_bits = 8,
- .max_register = 255,
- .cache_type = REGCACHE_FLAT,
- .writeable_reg = mlxplat_mlxcpld_writeable_reg,
- .readable_reg = mlxplat_mlxcpld_readable_reg,
- .volatile_reg = mlxplat_mlxcpld_volatile_reg,
- .reg_defaults = mlxplat_mlxcpld_regmap_default,
- .num_reg_defaults = ARRAY_SIZE(mlxplat_mlxcpld_regmap_default),
- .reg_read = mlxplat_mlxcpld_reg_read,
- .reg_write = mlxplat_mlxcpld_reg_write,
-};
-
-static const struct regmap_config mlxplat_mlxcpld_regmap_config_ng = {
- .reg_bits = 8,
- .val_bits = 8,
- .max_register = 255,
- .cache_type = REGCACHE_FLAT,
- .writeable_reg = mlxplat_mlxcpld_writeable_reg,
- .readable_reg = mlxplat_mlxcpld_readable_reg,
- .volatile_reg = mlxplat_mlxcpld_volatile_reg,
- .reg_defaults = mlxplat_mlxcpld_regmap_ng,
- .num_reg_defaults = ARRAY_SIZE(mlxplat_mlxcpld_regmap_ng),
- .reg_read = mlxplat_mlxcpld_reg_read,
- .reg_write = mlxplat_mlxcpld_reg_write,
-};
-
-static const struct regmap_config mlxplat_mlxcpld_regmap_config_comex = {
- .reg_bits = 8,
- .val_bits = 8,
- .max_register = 255,
- .cache_type = REGCACHE_FLAT,
- .writeable_reg = mlxplat_mlxcpld_writeable_reg,
- .readable_reg = mlxplat_mlxcpld_readable_reg,
- .volatile_reg = mlxplat_mlxcpld_volatile_reg,
- .reg_defaults = mlxplat_mlxcpld_regmap_comex_default,
- .num_reg_defaults = ARRAY_SIZE(mlxplat_mlxcpld_regmap_comex_default),
- .reg_read = mlxplat_mlxcpld_reg_read,
- .reg_write = mlxplat_mlxcpld_reg_write,
-};
-
-static const struct regmap_config mlxplat_mlxcpld_regmap_config_ng400 = {
- .reg_bits = 8,
- .val_bits = 8,
- .max_register = 255,
- .cache_type = REGCACHE_FLAT,
- .writeable_reg = mlxplat_mlxcpld_writeable_reg,
- .readable_reg = mlxplat_mlxcpld_readable_reg,
- .volatile_reg = mlxplat_mlxcpld_volatile_reg,
- .reg_defaults = mlxplat_mlxcpld_regmap_ng400,
- .num_reg_defaults = ARRAY_SIZE(mlxplat_mlxcpld_regmap_ng400),
- .reg_read = mlxplat_mlxcpld_reg_read,
- .reg_write = mlxplat_mlxcpld_reg_write,
-};
-
-static const struct regmap_config mlxplat_mlxcpld_regmap_config_rack_switch = {
- .reg_bits = 8,
- .val_bits = 8,
- .max_register = 255,
- .cache_type = REGCACHE_FLAT,
- .writeable_reg = mlxplat_mlxcpld_writeable_reg,
- .readable_reg = mlxplat_mlxcpld_readable_reg,
- .volatile_reg = mlxplat_mlxcpld_volatile_reg,
- .reg_defaults = mlxplat_mlxcpld_regmap_rack_switch,
- .num_reg_defaults = ARRAY_SIZE(mlxplat_mlxcpld_regmap_rack_switch),
- .reg_read = mlxplat_mlxcpld_reg_read,
- .reg_write = mlxplat_mlxcpld_reg_write,
-};
-
-static const struct regmap_config mlxplat_mlxcpld_regmap_config_eth_modular = {
- .reg_bits = 8,
- .val_bits = 8,
- .max_register = 255,
- .cache_type = REGCACHE_FLAT,
- .writeable_reg = mlxplat_mlxcpld_writeable_reg,
- .readable_reg = mlxplat_mlxcpld_readable_reg,
- .volatile_reg = mlxplat_mlxcpld_volatile_reg,
- .reg_defaults = mlxplat_mlxcpld_regmap_eth_modular,
- .num_reg_defaults = ARRAY_SIZE(mlxplat_mlxcpld_regmap_eth_modular),
- .reg_read = mlxplat_mlxcpld_reg_read,
- .reg_write = mlxplat_mlxcpld_reg_write,
-};
-
-static struct resource mlxplat_mlxcpld_resources[] = {
- [0] = DEFINE_RES_IRQ_NAMED(MLXPLAT_CPLD_LPC_SYSIRQ, "mlxreg-hotplug"),
-};
-
-static struct mlxreg_core_hotplug_platform_data *mlxplat_i2c;
-static struct mlxreg_core_hotplug_platform_data *mlxplat_hotplug;
-static struct mlxreg_core_platform_data *mlxplat_led;
-static struct mlxreg_core_platform_data *mlxplat_regs_io;
-static struct mlxreg_core_platform_data *mlxplat_fan;
-static struct mlxreg_core_platform_data
- *mlxplat_wd_data[MLXPLAT_CPLD_WD_MAX_DEVS];
-static const struct regmap_config *mlxplat_regmap_config;
-static struct pci_dev *lpc_bridge;
-static struct pci_dev *i2c_bridge;
-static struct pci_dev *jtag_bridge;
-
-/* Platform default reset function */
-static int mlxplat_reboot_notifier(struct notifier_block *nb, unsigned long action, void *unused)
-{
- struct mlxplat_priv *priv = platform_get_drvdata(mlxplat_dev);
- u32 regval;
- int ret;
-
- ret = regmap_read(priv->regmap, MLXPLAT_CPLD_LPC_REG_RESET_GP1_OFFSET, &regval);
-
- if (action == SYS_RESTART && !ret && regval & MLXPLAT_CPLD_SYS_RESET_MASK)
- regmap_write(priv->regmap, MLXPLAT_CPLD_LPC_REG_RESET_GP1_OFFSET,
- MLXPLAT_CPLD_RESET_MASK);
-
- return NOTIFY_DONE;
-}
-
-static struct notifier_block mlxplat_reboot_default_nb = {
- .notifier_call = mlxplat_reboot_notifier,
-};
-
-/* Platform default poweroff function */
-static void mlxplat_poweroff(void)
-{
- struct mlxplat_priv *priv = platform_get_drvdata(mlxplat_dev);
-
- if (mlxplat_reboot_nb)
- unregister_reboot_notifier(mlxplat_reboot_nb);
- regmap_write(priv->regmap, MLXPLAT_CPLD_LPC_REG_GP1_OFFSET, MLXPLAT_CPLD_HALT_MASK);
- kernel_halt();
-}
-
-static int __init mlxplat_register_platform_device(void)
-{
- mlxplat_dev = platform_device_register_simple(MLX_PLAT_DEVICE_NAME, -1,
- mlxplat_lpc_resources,
- ARRAY_SIZE(mlxplat_lpc_resources));
- if (IS_ERR(mlxplat_dev))
- return PTR_ERR(mlxplat_dev);
- else
- return 1;
-}
-
-static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi)
-{
- int i;
-
- mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
- mlxplat_mux_num = ARRAY_SIZE(mlxplat_default_mux_data);
- mlxplat_mux_data = mlxplat_default_mux_data;
- for (i = 0; i < mlxplat_mux_num; i++) {
- mlxplat_mux_data[i].values = mlxplat_default_channels[i];
- mlxplat_mux_data[i].n_values =
- ARRAY_SIZE(mlxplat_default_channels[i]);
- }
- mlxplat_hotplug = &mlxplat_mlxcpld_default_data;
- mlxplat_hotplug->deferred_nr =
- mlxplat_default_channels[i - 1][MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
- mlxplat_led = &mlxplat_default_led_data;
- mlxplat_regs_io = &mlxplat_default_regs_io_data;
- mlxplat_wd_data[0] = &mlxplat_mlxcpld_wd_set_type1[0];
- mlxplat_i2c = &mlxplat_mlxcpld_i2c_default_data;
-
- return mlxplat_register_platform_device();
-}
-
-static int __init mlxplat_dmi_default_wc_matched(const struct dmi_system_id *dmi)
-{
- int i;
-
- mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
- mlxplat_mux_num = ARRAY_SIZE(mlxplat_default_mux_data);
- mlxplat_mux_data = mlxplat_default_mux_data;
- for (i = 0; i < mlxplat_mux_num; i++) {
- mlxplat_mux_data[i].values = mlxplat_default_channels[i];
- mlxplat_mux_data[i].n_values =
- ARRAY_SIZE(mlxplat_default_channels[i]);
- }
- mlxplat_hotplug = &mlxplat_mlxcpld_default_wc_data;
- mlxplat_hotplug->deferred_nr =
- mlxplat_default_channels[i - 1][MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
- mlxplat_led = &mlxplat_default_led_wc_data;
- mlxplat_regs_io = &mlxplat_default_regs_io_data;
- mlxplat_wd_data[0] = &mlxplat_mlxcpld_wd_set_type1[0];
- mlxplat_i2c = &mlxplat_mlxcpld_i2c_default_data;
-
- return mlxplat_register_platform_device();
-}
-
-static int __init mlxplat_dmi_default_eth_wc_blade_matched(const struct dmi_system_id *dmi)
-{
- int i;
-
- mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
- mlxplat_mux_num = ARRAY_SIZE(mlxplat_default_mux_data);
- mlxplat_mux_data = mlxplat_default_mux_data;
- for (i = 0; i < mlxplat_mux_num; i++) {
- mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
- mlxplat_mux_data[i].n_values =
- ARRAY_SIZE(mlxplat_msn21xx_channels);
- }
- mlxplat_hotplug = &mlxplat_mlxcpld_default_wc_data;
- mlxplat_hotplug->deferred_nr =
- mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
- mlxplat_led = &mlxplat_default_led_eth_wc_blade_data;
- mlxplat_regs_io = &mlxplat_default_ng_regs_io_data;
- for (i = 0; i < ARRAY_SIZE(mlxplat_mlxcpld_wd_set_type2); i++)
- mlxplat_wd_data[i] = &mlxplat_mlxcpld_wd_set_type2[i];
- mlxplat_i2c = &mlxplat_mlxcpld_i2c_ng_data;
- mlxplat_regmap_config = &mlxplat_mlxcpld_regmap_config_ng;
-
- return mlxplat_register_platform_device();
-}
-
-static int __init mlxplat_dmi_msn21xx_matched(const struct dmi_system_id *dmi)
-{
- int i;
-
- mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
- mlxplat_mux_num = ARRAY_SIZE(mlxplat_default_mux_data);
- mlxplat_mux_data = mlxplat_default_mux_data;
- for (i = 0; i < mlxplat_mux_num; i++) {
- mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
- mlxplat_mux_data[i].n_values =
- ARRAY_SIZE(mlxplat_msn21xx_channels);
- }
- mlxplat_hotplug = &mlxplat_mlxcpld_msn21xx_data;
- mlxplat_hotplug->deferred_nr =
- mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
- mlxplat_led = &mlxplat_msn21xx_led_data;
- mlxplat_regs_io = &mlxplat_msn21xx_regs_io_data;
- mlxplat_wd_data[0] = &mlxplat_mlxcpld_wd_set_type1[0];
- mlxplat_i2c = &mlxplat_mlxcpld_i2c_default_data;
-
- return mlxplat_register_platform_device();
-}
-
-static int __init mlxplat_dmi_msn274x_matched(const struct dmi_system_id *dmi)
-{
- int i;
-
- mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
- mlxplat_mux_num = ARRAY_SIZE(mlxplat_default_mux_data);
- mlxplat_mux_data = mlxplat_default_mux_data;
- for (i = 0; i < mlxplat_mux_num; i++) {
- mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
- mlxplat_mux_data[i].n_values =
- ARRAY_SIZE(mlxplat_msn21xx_channels);
- }
- mlxplat_hotplug = &mlxplat_mlxcpld_msn274x_data;
- mlxplat_hotplug->deferred_nr =
- mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
- mlxplat_led = &mlxplat_default_led_data;
- mlxplat_regs_io = &mlxplat_msn21xx_regs_io_data;
- mlxplat_wd_data[0] = &mlxplat_mlxcpld_wd_set_type1[0];
- mlxplat_i2c = &mlxplat_mlxcpld_i2c_default_data;
-
- return mlxplat_register_platform_device();
-}
-
-static int __init mlxplat_dmi_msn201x_matched(const struct dmi_system_id *dmi)
-{
- int i;
-
- mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
- mlxplat_mux_num = ARRAY_SIZE(mlxplat_default_mux_data);
- mlxplat_mux_data = mlxplat_default_mux_data;
- for (i = 0; i < mlxplat_mux_num; i++) {
- mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
- mlxplat_mux_data[i].n_values =
- ARRAY_SIZE(mlxplat_msn21xx_channels);
- }
- mlxplat_hotplug = &mlxplat_mlxcpld_msn201x_data;
- mlxplat_hotplug->deferred_nr =
- mlxplat_default_channels[i - 1][MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
- mlxplat_led = &mlxplat_msn21xx_led_data;
- mlxplat_regs_io = &mlxplat_msn21xx_regs_io_data;
- mlxplat_wd_data[0] = &mlxplat_mlxcpld_wd_set_type1[0];
- mlxplat_i2c = &mlxplat_mlxcpld_i2c_default_data;
-
- return mlxplat_register_platform_device();
-}
-
-static int __init mlxplat_dmi_qmb7xx_matched(const struct dmi_system_id *dmi)
-{
- int i;
-
- mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
- mlxplat_mux_num = ARRAY_SIZE(mlxplat_default_mux_data);
- mlxplat_mux_data = mlxplat_default_mux_data;
- for (i = 0; i < mlxplat_mux_num; i++) {
- mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
- mlxplat_mux_data[i].n_values =
- ARRAY_SIZE(mlxplat_msn21xx_channels);
- }
- mlxplat_hotplug = &mlxplat_mlxcpld_default_ng_data;
- mlxplat_hotplug->deferred_nr =
- mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
- mlxplat_led = &mlxplat_default_ng_led_data;
- mlxplat_regs_io = &mlxplat_default_ng_regs_io_data;
- mlxplat_fan = &mlxplat_default_fan_data;
- for (i = 0; i < ARRAY_SIZE(mlxplat_mlxcpld_wd_set_type2); i++)
- mlxplat_wd_data[i] = &mlxplat_mlxcpld_wd_set_type2[i];
- mlxplat_i2c = &mlxplat_mlxcpld_i2c_ng_data;
- mlxplat_regmap_config = &mlxplat_mlxcpld_regmap_config_ng;
-
- return mlxplat_register_platform_device();
-}
-
-static int __init mlxplat_dmi_comex_matched(const struct dmi_system_id *dmi)
-{
- int i;
-
- mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_EXT_ADAPTER_NUM;
- mlxplat_mux_num = ARRAY_SIZE(mlxplat_extended_mux_data);
- mlxplat_mux_data = mlxplat_extended_mux_data;
- for (i = 0; i < mlxplat_mux_num; i++) {
- mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
- mlxplat_mux_data[i].n_values =
- ARRAY_SIZE(mlxplat_msn21xx_channels);
- }
- mlxplat_hotplug = &mlxplat_mlxcpld_comex_data;
- mlxplat_hotplug->deferred_nr = MLXPLAT_CPLD_MAX_PHYS_EXT_ADAPTER_NUM;
- mlxplat_led = &mlxplat_comex_100G_led_data;
- mlxplat_regs_io = &mlxplat_default_ng_regs_io_data;
- mlxplat_fan = &mlxplat_default_fan_data;
- for (i = 0; i < ARRAY_SIZE(mlxplat_mlxcpld_wd_set_type2); i++)
- mlxplat_wd_data[i] = &mlxplat_mlxcpld_wd_set_type2[i];
- mlxplat_i2c = &mlxplat_mlxcpld_i2c_default_data;
- mlxplat_regmap_config = &mlxplat_mlxcpld_regmap_config_comex;
-
- return mlxplat_register_platform_device();
-}
-
-static int __init mlxplat_dmi_ng400_matched(const struct dmi_system_id *dmi)
-{
- int i;
-
- mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
- mlxplat_mux_num = ARRAY_SIZE(mlxplat_default_mux_data);
- mlxplat_mux_data = mlxplat_default_mux_data;
- for (i = 0; i < mlxplat_mux_num; i++) {
- mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
- mlxplat_mux_data[i].n_values =
- ARRAY_SIZE(mlxplat_msn21xx_channels);
- }
- mlxplat_hotplug = &mlxplat_mlxcpld_ext_data;
- mlxplat_hotplug->deferred_nr =
- mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
- mlxplat_led = &mlxplat_default_ng_led_data;
- mlxplat_regs_io = &mlxplat_default_ng_regs_io_data;
- mlxplat_fan = &mlxplat_default_fan_data;
- for (i = 0; i < ARRAY_SIZE(mlxplat_mlxcpld_wd_set_type2); i++)
- mlxplat_wd_data[i] = &mlxplat_mlxcpld_wd_set_type2[i];
- mlxplat_i2c = &mlxplat_mlxcpld_i2c_ng_data;
- mlxplat_regmap_config = &mlxplat_mlxcpld_regmap_config_ng400;
-
- return mlxplat_register_platform_device();
-}
-
-static int __init mlxplat_dmi_modular_matched(const struct dmi_system_id *dmi)
-{
- int i;
-
- mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
- mlxplat_mux_num = ARRAY_SIZE(mlxplat_modular_mux_data);
- mlxplat_mux_data = mlxplat_modular_mux_data;
- mlxplat_hotplug = &mlxplat_mlxcpld_modular_data;
- mlxplat_hotplug->deferred_nr = MLXPLAT_CPLD_CH4_ETH_MODULAR;
- mlxplat_led = &mlxplat_modular_led_data;
- mlxplat_regs_io = &mlxplat_modular_regs_io_data;
- mlxplat_fan = &mlxplat_default_fan_data;
- for (i = 0; i < ARRAY_SIZE(mlxplat_mlxcpld_wd_set_type2); i++)
- mlxplat_wd_data[i] = &mlxplat_mlxcpld_wd_set_type2[i];
- mlxplat_i2c = &mlxplat_mlxcpld_i2c_ng_data;
- mlxplat_regmap_config = &mlxplat_mlxcpld_regmap_config_eth_modular;
-
- return mlxplat_register_platform_device();
-}
-
-static int __init mlxplat_dmi_chassis_blade_matched(const struct dmi_system_id *dmi)
-{
- int i;
-
- mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
- mlxplat_mux_num = ARRAY_SIZE(mlxplat_default_mux_data);
- mlxplat_mux_data = mlxplat_default_mux_data;
- mlxplat_hotplug = &mlxplat_mlxcpld_chassis_blade_data;
- mlxplat_hotplug->deferred_nr =
- mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
- for (i = 0; i < mlxplat_mux_num; i++) {
- mlxplat_mux_data[i].values = mlxplat_msn21xx_channels;
- mlxplat_mux_data[i].n_values =
- ARRAY_SIZE(mlxplat_msn21xx_channels);
- }
- mlxplat_regs_io = &mlxplat_chassis_blade_regs_io_data;
- mlxplat_i2c = &mlxplat_mlxcpld_i2c_ng_data;
- mlxplat_regmap_config = &mlxplat_mlxcpld_regmap_config_ng400;
-
- return mlxplat_register_platform_device();
-}
-
-static int __init mlxplat_dmi_rack_switch_matched(const struct dmi_system_id *dmi)
-{
- int i;
-
- mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
- mlxplat_mux_num = ARRAY_SIZE(mlxplat_rack_switch_mux_data);
- mlxplat_mux_data = mlxplat_rack_switch_mux_data;
- mlxplat_hotplug = &mlxplat_mlxcpld_rack_switch_data;
- mlxplat_hotplug->deferred_nr =
- mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
- mlxplat_led = &mlxplat_default_ng_led_data;
- mlxplat_regs_io = &mlxplat_default_ng_regs_io_data;
- mlxplat_fan = &mlxplat_default_fan_data;
- for (i = 0; i < ARRAY_SIZE(mlxplat_mlxcpld_wd_set_type2); i++)
- mlxplat_wd_data[i] = &mlxplat_mlxcpld_wd_set_type2[i];
- mlxplat_i2c = &mlxplat_mlxcpld_i2c_ng_data;
- mlxplat_regmap_config = &mlxplat_mlxcpld_regmap_config_rack_switch;
-
- return mlxplat_register_platform_device();
-}
-
-static int __init mlxplat_dmi_ng800_matched(const struct dmi_system_id *dmi)
-{
- int i;
-
- mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
- mlxplat_mux_num = ARRAY_SIZE(mlxplat_ng800_mux_data);
- mlxplat_mux_data = mlxplat_ng800_mux_data;
- mlxplat_hotplug = &mlxplat_mlxcpld_ng800_data;
- mlxplat_hotplug->deferred_nr =
- mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
- mlxplat_led = &mlxplat_default_ng_led_data;
- mlxplat_regs_io = &mlxplat_default_ng_regs_io_data;
- mlxplat_fan = &mlxplat_default_fan_data;
- for (i = 0; i < ARRAY_SIZE(mlxplat_mlxcpld_wd_set_type2); i++)
- mlxplat_wd_data[i] = &mlxplat_mlxcpld_wd_set_type2[i];
- mlxplat_i2c = &mlxplat_mlxcpld_i2c_ng_data;
- mlxplat_regmap_config = &mlxplat_mlxcpld_regmap_config_ng400;
-
- return mlxplat_register_platform_device();
-}
-
-static int __init mlxplat_dmi_l1_switch_matched(const struct dmi_system_id *dmi)
-{
- int i;
-
- mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
- mlxplat_mux_num = ARRAY_SIZE(mlxplat_rack_switch_mux_data);
- mlxplat_mux_data = mlxplat_rack_switch_mux_data;
- mlxplat_hotplug = &mlxplat_mlxcpld_l1_switch_data;
- mlxplat_hotplug->deferred_nr =
- mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
- mlxplat_led = &mlxplat_l1_switch_led_data;
- mlxplat_regs_io = &mlxplat_default_ng_regs_io_data;
- mlxplat_fan = &mlxplat_default_fan_data;
- for (i = 0; i < ARRAY_SIZE(mlxplat_mlxcpld_wd_set_type2); i++)
- mlxplat_wd_data[i] = &mlxplat_mlxcpld_wd_set_type2[i];
- mlxplat_i2c = &mlxplat_mlxcpld_i2c_ng_data;
- mlxplat_regmap_config = &mlxplat_mlxcpld_regmap_config_rack_switch;
- pm_power_off = mlxplat_poweroff;
- mlxplat_reboot_nb = &mlxplat_reboot_default_nb;
-
- return mlxplat_register_platform_device();
-}
-
-static const struct dmi_system_id mlxplat_dmi_table[] __initconst = {
- {
- .callback = mlxplat_dmi_default_wc_matched,
- .matches = {
- DMI_MATCH(DMI_BOARD_NAME, "VMOD0001"),
- DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "HI138"),
- },
- },
- {
- .callback = mlxplat_dmi_default_matched,
- .matches = {
- DMI_MATCH(DMI_BOARD_NAME, "VMOD0001"),
- },
- },
- {
- .callback = mlxplat_dmi_msn21xx_matched,
- .matches = {
- DMI_MATCH(DMI_BOARD_NAME, "VMOD0002"),
- },
- },
- {
- .callback = mlxplat_dmi_msn274x_matched,
- .matches = {
- DMI_MATCH(DMI_BOARD_NAME, "VMOD0003"),
- },
- },
- {
- .callback = mlxplat_dmi_msn201x_matched,
- .matches = {
- DMI_MATCH(DMI_BOARD_NAME, "VMOD0004"),
- },
- },
- {
- .callback = mlxplat_dmi_default_eth_wc_blade_matched,
- .matches = {
- DMI_MATCH(DMI_BOARD_NAME, "VMOD0005"),
- DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "HI139"),
- },
- },
- {
- .callback = mlxplat_dmi_qmb7xx_matched,
- .matches = {
- DMI_MATCH(DMI_BOARD_NAME, "VMOD0005"),
- },
- },
- {
- .callback = mlxplat_dmi_qmb7xx_matched,
- .matches = {
- DMI_MATCH(DMI_BOARD_NAME, "VMOD0007"),
- },
- },
- {
- .callback = mlxplat_dmi_comex_matched,
- .matches = {
- DMI_MATCH(DMI_BOARD_NAME, "VMOD0009"),
- },
- },
- {
- .callback = mlxplat_dmi_rack_switch_matched,
- .matches = {
- DMI_MATCH(DMI_BOARD_NAME, "VMOD0010"),
- DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "HI142"),
- },
- },
- {
- .callback = mlxplat_dmi_ng400_matched,
- .matches = {
- DMI_MATCH(DMI_BOARD_NAME, "VMOD0010"),
- },
- },
- {
- .callback = mlxplat_dmi_modular_matched,
- .matches = {
- DMI_MATCH(DMI_BOARD_NAME, "VMOD0011"),
- },
- },
- {
- .callback = mlxplat_dmi_ng800_matched,
- .matches = {
- DMI_MATCH(DMI_BOARD_NAME, "VMOD0013"),
- },
- },
- {
- .callback = mlxplat_dmi_chassis_blade_matched,
- .matches = {
- DMI_MATCH(DMI_BOARD_NAME, "VMOD0015"),
- },
- },
- {
- .callback = mlxplat_dmi_l1_switch_matched,
- .matches = {
- DMI_MATCH(DMI_BOARD_NAME, "VMOD0017"),
- },
- },
- {
- .callback = mlxplat_dmi_msn274x_matched,
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
- DMI_MATCH(DMI_PRODUCT_NAME, "MSN274"),
- },
- },
- {
- .callback = mlxplat_dmi_default_matched,
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
- DMI_MATCH(DMI_PRODUCT_NAME, "MSN24"),
- },
- },
- {
- .callback = mlxplat_dmi_default_matched,
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
- DMI_MATCH(DMI_PRODUCT_NAME, "MSN27"),
- },
- },
- {
- .callback = mlxplat_dmi_default_matched,
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
- DMI_MATCH(DMI_PRODUCT_NAME, "MSB"),
- },
- },
- {
- .callback = mlxplat_dmi_default_matched,
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
- DMI_MATCH(DMI_PRODUCT_NAME, "MSX"),
- },
- },
- {
- .callback = mlxplat_dmi_msn21xx_matched,
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
- DMI_MATCH(DMI_PRODUCT_NAME, "MSN21"),
- },
- },
- {
- .callback = mlxplat_dmi_msn201x_matched,
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
- DMI_MATCH(DMI_PRODUCT_NAME, "MSN201"),
- },
- },
- {
- .callback = mlxplat_dmi_qmb7xx_matched,
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
- DMI_MATCH(DMI_PRODUCT_NAME, "MQM87"),
- },
- },
- {
- .callback = mlxplat_dmi_qmb7xx_matched,
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
- DMI_MATCH(DMI_PRODUCT_NAME, "MSN37"),
- },
- },
- {
- .callback = mlxplat_dmi_qmb7xx_matched,
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
- DMI_MATCH(DMI_PRODUCT_NAME, "MSN34"),
- },
- },
- {
- .callback = mlxplat_dmi_qmb7xx_matched,
- .matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
- DMI_MATCH(DMI_PRODUCT_NAME, "MSN38"),
- },
- },
- { }
-};
-
-MODULE_DEVICE_TABLE(dmi, mlxplat_dmi_table);
-
-static int mlxplat_mlxcpld_verify_bus_topology(int *nr)
-{
- struct i2c_adapter *search_adap;
- int i, shift = 0;
-
- /* Scan adapters from expected id to verify it is free. */
- *nr = MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR;
- for (i = MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR; i <
- mlxplat_max_adap_num; i++) {
- search_adap = i2c_get_adapter(i);
- if (search_adap) {
- i2c_put_adapter(search_adap);
- continue;
- }
-
- /* Return if expected parent adapter is free. */
- if (i == MLXPLAT_CPLD_PHYS_ADAPTER_DEF_NR)
- return 0;
- break;
- }
-
- /* Return with error if free id for adapter is not found. */
- if (i == mlxplat_max_adap_num)
- return -ENODEV;
-
- /* Shift adapter ids, since expected parent adapter is not free. */
- *nr = i;
- for (i = 0; i < mlxplat_mux_num; i++) {
- shift = *nr - mlxplat_mux_data[i].parent;
- mlxplat_mux_data[i].parent = *nr;
- mlxplat_mux_data[i].base_nr += shift;
- }
-
- if (shift > 0)
- mlxplat_hotplug->shift_nr = shift;
-
- return 0;
-}
-
-static int mlxplat_mlxcpld_check_wd_capability(void *regmap)
-{
- u32 regval;
- int i, rc;
-
- rc = regmap_read(regmap, MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
- &regval);
- if (rc)
- return rc;
-
- if (!(regval & ~MLXPLAT_CPLD_WD_CPBLTY_MASK)) {
- for (i = 0; i < ARRAY_SIZE(mlxplat_mlxcpld_wd_set_type3); i++) {
- if (mlxplat_wd_data[i])
- mlxplat_wd_data[i] =
- &mlxplat_mlxcpld_wd_set_type3[i];
- }
- }
-
- return 0;
-}
-
-static int mlxplat_lpc_cpld_device_init(struct resource **hotplug_resources,
- unsigned int *hotplug_resources_size)
-{
- int err;
-
- mlxplat_mlxcpld_regmap_ctx.base = devm_ioport_map(&mlxplat_dev->dev,
- mlxplat_lpc_resources[1].start, 1);
- if (!mlxplat_mlxcpld_regmap_ctx.base) {
- err = -ENOMEM;
- goto fail_devm_ioport_map;
- }
-
- *hotplug_resources = mlxplat_mlxcpld_resources;
- *hotplug_resources_size = ARRAY_SIZE(mlxplat_mlxcpld_resources);
-
- return 0;
-
-fail_devm_ioport_map:
- return err;
-}
-
-static void mlxplat_lpc_cpld_device_exit(void)
-{
-}
-
-static int
-mlxplat_pci_fpga_device_init(unsigned int device, const char *res_name, struct pci_dev **pci_bridge,
- void __iomem **pci_bridge_addr)
-{
- void __iomem *pci_mem_addr;
- struct pci_dev *pci_dev;
- int err;
-
- pci_dev = pci_get_device(PCI_VENDOR_ID_LATTICE, device, NULL);
- if (!pci_dev)
- return -ENODEV;
-
- err = pci_enable_device(pci_dev);
- if (err) {
- dev_err(&pci_dev->dev, "pci_enable_device failed with error %d\n", err);
- goto fail_pci_enable_device;
- }
-
- err = pci_request_region(pci_dev, 0, res_name);
- if (err) {
- dev_err(&pci_dev->dev, "pci_request_regions failed with error %d\n", err);
- goto fail_pci_request_regions;
- }
-
- err = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(64));
- if (err) {
- err = dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32));
- if (err) {
- dev_err(&pci_dev->dev, "dma_set_mask failed with error %d\n", err);
- goto fail_pci_set_dma_mask;
- }
- }
-
- pci_set_master(pci_dev);
-
- pci_mem_addr = devm_ioremap(&pci_dev->dev, pci_resource_start(pci_dev, 0),
- pci_resource_len(pci_dev, 0));
- if (!pci_mem_addr) {
- dev_err(&mlxplat_dev->dev, "ioremap failed\n");
- err = -EIO;
- goto fail_ioremap;
- }
-
- *pci_bridge = pci_dev;
- *pci_bridge_addr = pci_mem_addr;
-
- return 0;
-
-fail_ioremap:
-fail_pci_set_dma_mask:
- pci_release_regions(pci_dev);
-fail_pci_request_regions:
- pci_disable_device(pci_dev);
-fail_pci_enable_device:
- pci_dev_put(pci_dev);
- return err;
-}
-
-static void
-mlxplat_pci_fpga_device_exit(struct pci_dev *pci_bridge,
- void __iomem *pci_bridge_addr)
-{
- iounmap(pci_bridge_addr);
- pci_release_regions(pci_bridge);
- pci_disable_device(pci_bridge);
- pci_dev_put(pci_bridge);
-}
-
-static int
-mlxplat_pci_fpga_devices_init(struct resource **hotplug_resources,
- unsigned int *hotplug_resources_size)
-{
- int err;
-
- err = mlxplat_pci_fpga_device_init(PCI_DEVICE_ID_LATTICE_LPC_BRIDGE,
- "mlxplat_lpc_bridge", &lpc_bridge,
- &mlxplat_mlxcpld_regmap_ctx.base);
- if (err)
- goto mlxplat_pci_fpga_device_init_lpc_fail;
-
- err = mlxplat_pci_fpga_device_init(PCI_DEVICE_ID_LATTICE_I2C_BRIDGE,
- "mlxplat_i2c_bridge", &i2c_bridge,
- &i2c_bridge_addr);
- if (err)
- goto mlxplat_pci_fpga_device_init_i2c_fail;
-
- err = mlxplat_pci_fpga_device_init(PCI_DEVICE_ID_LATTICE_JTAG_BRIDGE,
- "mlxplat_jtag_bridge", &jtag_bridge,
- &jtag_bridge_addr);
- if (err)
- goto mlxplat_pci_fpga_device_init_jtag_fail;
-
- return 0;
-
-mlxplat_pci_fpga_device_init_jtag_fail:
- mlxplat_pci_fpga_device_exit(i2c_bridge, i2c_bridge_addr);
-mlxplat_pci_fpga_device_init_i2c_fail:
- mlxplat_pci_fpga_device_exit(lpc_bridge, mlxplat_mlxcpld_regmap_ctx.base);
-mlxplat_pci_fpga_device_init_lpc_fail:
- return err;
-}
-
-static void mlxplat_pci_fpga_devices_exit(void)
-{
- mlxplat_pci_fpga_device_exit(jtag_bridge, jtag_bridge_addr);
- mlxplat_pci_fpga_device_exit(i2c_bridge, i2c_bridge_addr);
- mlxplat_pci_fpga_device_exit(lpc_bridge, mlxplat_mlxcpld_regmap_ctx.base);
-}
-
-static int
-mlxplat_logicdev_init(struct resource **hotplug_resources, unsigned int *hotplug_resources_size)
-{
- int err;
-
- err = mlxplat_pci_fpga_devices_init(hotplug_resources, hotplug_resources_size);
- if (err == -ENODEV)
- return mlxplat_lpc_cpld_device_init(hotplug_resources, hotplug_resources_size);
-
- return err;
-}
-
-static void mlxplat_logicdev_exit(void)
-{
- if (lpc_bridge)
- mlxplat_pci_fpga_devices_exit();
- else
- mlxplat_lpc_cpld_device_exit();
-}
-
-static int mlxplat_platdevs_init(struct mlxplat_priv *priv)
-{
- int i = 0, err;
-
- /* Add hotplug driver */
- if (mlxplat_hotplug) {
- mlxplat_hotplug->regmap = priv->regmap;
- if (priv->irq_fpga)
- mlxplat_hotplug->irq = priv->irq_fpga;
- priv->pdev_hotplug =
- platform_device_register_resndata(&mlxplat_dev->dev,
- "mlxreg-hotplug", PLATFORM_DEVID_NONE,
- priv->hotplug_resources,
- priv->hotplug_resources_size,
- mlxplat_hotplug, sizeof(*mlxplat_hotplug));
- if (IS_ERR(priv->pdev_hotplug)) {
- err = PTR_ERR(priv->pdev_hotplug);
- goto fail_platform_hotplug_register;
- }
- }
-
- /* Add LED driver. */
- if (mlxplat_led) {
- mlxplat_led->regmap = priv->regmap;
- priv->pdev_led =
- platform_device_register_resndata(&mlxplat_dev->dev, "leds-mlxreg",
- PLATFORM_DEVID_NONE, NULL, 0, mlxplat_led,
- sizeof(*mlxplat_led));
- if (IS_ERR(priv->pdev_led)) {
- err = PTR_ERR(priv->pdev_led);
- goto fail_platform_leds_register;
- }
- }
-
- /* Add registers io access driver. */
- if (mlxplat_regs_io) {
- mlxplat_regs_io->regmap = priv->regmap;
- priv->pdev_io_regs = platform_device_register_resndata(&mlxplat_dev->dev,
- "mlxreg-io",
- PLATFORM_DEVID_NONE, NULL,
- 0, mlxplat_regs_io,
- sizeof(*mlxplat_regs_io));
- if (IS_ERR(priv->pdev_io_regs)) {
- err = PTR_ERR(priv->pdev_io_regs);
- goto fail_platform_io_register;
- }
- }
-
- /* Add FAN driver. */
- if (mlxplat_fan) {
- mlxplat_fan->regmap = priv->regmap;
- priv->pdev_fan = platform_device_register_resndata(&mlxplat_dev->dev, "mlxreg-fan",
- PLATFORM_DEVID_NONE, NULL, 0,
- mlxplat_fan,
- sizeof(*mlxplat_fan));
- if (IS_ERR(priv->pdev_fan)) {
- err = PTR_ERR(priv->pdev_fan);
- goto fail_platform_fan_register;
- }
- }
-
- /* Add WD drivers. */
- err = mlxplat_mlxcpld_check_wd_capability(priv->regmap);
- if (err)
- goto fail_platform_wd_register;
- for (i = 0; i < MLXPLAT_CPLD_WD_MAX_DEVS; i++) {
- if (mlxplat_wd_data[i]) {
- mlxplat_wd_data[i]->regmap = priv->regmap;
- priv->pdev_wd[i] =
- platform_device_register_resndata(&mlxplat_dev->dev, "mlx-wdt", i,
- NULL, 0, mlxplat_wd_data[i],
- sizeof(*mlxplat_wd_data[i]));
- if (IS_ERR(priv->pdev_wd[i])) {
- err = PTR_ERR(priv->pdev_wd[i]);
- goto fail_platform_wd_register;
- }
- }
- }
-
- return 0;
-
-fail_platform_wd_register:
- while (--i >= 0)
- platform_device_unregister(priv->pdev_wd[i]);
-fail_platform_fan_register:
- if (mlxplat_regs_io)
- platform_device_unregister(priv->pdev_io_regs);
-fail_platform_io_register:
- if (mlxplat_led)
- platform_device_unregister(priv->pdev_led);
-fail_platform_leds_register:
- if (mlxplat_hotplug)
- platform_device_unregister(priv->pdev_hotplug);
-fail_platform_hotplug_register:
- return err;
-}
-
-static void mlxplat_platdevs_exit(struct mlxplat_priv *priv)
-{
- int i;
-
- for (i = MLXPLAT_CPLD_WD_MAX_DEVS - 1; i >= 0 ; i--)
- platform_device_unregister(priv->pdev_wd[i]);
- if (priv->pdev_fan)
- platform_device_unregister(priv->pdev_fan);
- if (priv->pdev_io_regs)
- platform_device_unregister(priv->pdev_io_regs);
- if (priv->pdev_led)
- platform_device_unregister(priv->pdev_led);
- if (priv->pdev_hotplug)
- platform_device_unregister(priv->pdev_hotplug);
-}
-
-static int
-mlxplat_i2c_mux_complition_notify(void *handle, struct i2c_adapter *parent,
- struct i2c_adapter *adapters[])
-{
- struct mlxplat_priv *priv = handle;
-
- return mlxplat_platdevs_init(priv);
-}
-
-static int mlxplat_i2c_mux_topology_init(struct mlxplat_priv *priv)
-{
- int i, err;
-
- if (!priv->pdev_i2c) {
- priv->i2c_main_init_status = MLXPLAT_I2C_MAIN_BUS_NOTIFIED;
- return 0;
- }
-
- priv->i2c_main_init_status = MLXPLAT_I2C_MAIN_BUS_HANDLE_CREATED;
- for (i = 0; i < mlxplat_mux_num; i++) {
- priv->pdev_mux[i] = platform_device_register_resndata(&priv->pdev_i2c->dev,
- "i2c-mux-reg", i, NULL, 0,
- &mlxplat_mux_data[i],
- sizeof(mlxplat_mux_data[i]));
- if (IS_ERR(priv->pdev_mux[i])) {
- err = PTR_ERR(priv->pdev_mux[i]);
- goto fail_platform_mux_register;
- }
- }
-
- return mlxplat_i2c_mux_complition_notify(priv, NULL, NULL);
-
-fail_platform_mux_register:
- while (--i >= 0)
- platform_device_unregister(priv->pdev_mux[i]);
- return err;
-}
-
-static void mlxplat_i2c_mux_topology_exit(struct mlxplat_priv *priv)
-{
- int i;
-
- for (i = mlxplat_mux_num - 1; i >= 0 ; i--) {
- if (priv->pdev_mux[i])
- platform_device_unregister(priv->pdev_mux[i]);
- }
-}
-
-static int mlxplat_i2c_main_completion_notify(void *handle, int id)
-{
- struct mlxplat_priv *priv = handle;
-
- return mlxplat_i2c_mux_topology_init(priv);
-}
-
-static int mlxplat_i2c_main_init(struct mlxplat_priv *priv)
-{
- int nr, err;
-
- if (!mlxplat_i2c)
- return 0;
-
- err = mlxplat_mlxcpld_verify_bus_topology(&nr);
- if (nr < 0)
- goto fail_mlxplat_mlxcpld_verify_bus_topology;
-
- nr = (nr == mlxplat_max_adap_num) ? -1 : nr;
- mlxplat_i2c->regmap = priv->regmap;
- mlxplat_i2c->handle = priv;
-
- /* Set mapped base address of I2C-LPC bridge over PCIe */
- if (lpc_bridge)
- mlxplat_i2c->addr = i2c_bridge_addr;
- priv->pdev_i2c = platform_device_register_resndata(&mlxplat_dev->dev, "i2c_mlxcpld",
- nr, priv->hotplug_resources,
- priv->hotplug_resources_size,
- mlxplat_i2c, sizeof(*mlxplat_i2c));
- if (IS_ERR(priv->pdev_i2c)) {
- err = PTR_ERR(priv->pdev_i2c);
- goto fail_platform_i2c_register;
- }
-
- if (priv->i2c_main_init_status == MLXPLAT_I2C_MAIN_BUS_NOTIFIED) {
- err = mlxplat_i2c_mux_topology_init(priv);
- if (err)
- goto fail_mlxplat_i2c_mux_topology_init;
- }
-
- return 0;
-
-fail_mlxplat_i2c_mux_topology_init:
- platform_device_unregister(priv->pdev_i2c);
-fail_platform_i2c_register:
-fail_mlxplat_mlxcpld_verify_bus_topology:
- return err;
-}
-
-static void mlxplat_i2c_main_exit(struct mlxplat_priv *priv)
-{
- mlxplat_platdevs_exit(priv);
- mlxplat_i2c_mux_topology_exit(priv);
- if (priv->pdev_i2c)
- platform_device_unregister(priv->pdev_i2c);
-}
-
-static int mlxplat_probe(struct platform_device *pdev)
-{
- unsigned int hotplug_resources_size = 0;
- struct resource *hotplug_resources = NULL;
- struct acpi_device *acpi_dev;
- struct mlxplat_priv *priv;
- int irq_fpga = 0, i, err;
-
- acpi_dev = ACPI_COMPANION(&pdev->dev);
- if (acpi_dev) {
- irq_fpga = acpi_dev_gpio_irq_get(acpi_dev, 0);
- if (irq_fpga < 0)
- return -ENODEV;
- mlxplat_dev = pdev;
- }
-
- err = mlxplat_logicdev_init(&hotplug_resources, &hotplug_resources_size);
- if (err)
- return err;
-
- priv = devm_kzalloc(&mlxplat_dev->dev, sizeof(struct mlxplat_priv),
- GFP_KERNEL);
- if (!priv) {
- err = -ENOMEM;
- goto fail_alloc;
- }
- platform_set_drvdata(mlxplat_dev, priv);
- priv->hotplug_resources = hotplug_resources;
- priv->hotplug_resources_size = hotplug_resources_size;
- priv->irq_fpga = irq_fpga;
-
- if (!mlxplat_regmap_config)
- mlxplat_regmap_config = &mlxplat_mlxcpld_regmap_config;
-
- priv->regmap = devm_regmap_init(&mlxplat_dev->dev, NULL,
- &mlxplat_mlxcpld_regmap_ctx,
- mlxplat_regmap_config);
- if (IS_ERR(priv->regmap)) {
- err = PTR_ERR(priv->regmap);
- goto fail_alloc;
- }
-
- /* Set default registers. */
- for (i = 0; i < mlxplat_regmap_config->num_reg_defaults; i++) {
- err = regmap_write(priv->regmap,
- mlxplat_regmap_config->reg_defaults[i].reg,
- mlxplat_regmap_config->reg_defaults[i].def);
- if (err)
- goto fail_regmap_write;
- }
-
- err = mlxplat_i2c_main_init(priv);
- if (err)
- goto fail_mlxplat_i2c_main_init;
-
- /* Sync registers with hardware. */
- regcache_mark_dirty(priv->regmap);
- err = regcache_sync(priv->regmap);
- if (err)
- goto fail_regcache_sync;
-
- if (mlxplat_reboot_nb) {
- err = register_reboot_notifier(mlxplat_reboot_nb);
- if (err)
- goto fail_register_reboot_notifier;
- }
-
- return 0;
-
-fail_register_reboot_notifier:
-fail_regcache_sync:
- mlxplat_i2c_main_exit(priv);
-fail_mlxplat_i2c_main_init:
-fail_regmap_write:
-fail_alloc:
- mlxplat_logicdev_exit();
-
- return err;
-}
-
-static void mlxplat_remove(struct platform_device *pdev)
-{
- struct mlxplat_priv *priv = platform_get_drvdata(mlxplat_dev);
-
- if (pm_power_off)
- pm_power_off = NULL;
- if (mlxplat_reboot_nb)
- unregister_reboot_notifier(mlxplat_reboot_nb);
- mlxplat_i2c_main_exit(priv);
- mlxplat_logicdev_exit();
-}
-
-static const struct acpi_device_id mlxplat_acpi_table[] = {
- { "MLNXBF49", 0 },
- {}
-};
-MODULE_DEVICE_TABLE(acpi, mlxplat_acpi_table);
-
-static struct platform_driver mlxplat_driver = {
- .driver = {
- .name = "mlxplat",
- .acpi_match_table = mlxplat_acpi_table,
- .probe_type = PROBE_FORCE_SYNCHRONOUS,
- },
- .probe = mlxplat_probe,
- .remove = mlxplat_remove,
-};
-
-static int __init mlxplat_init(void)
-{
- int err;
-
- if (!dmi_check_system(mlxplat_dmi_table))
- return -ENODEV;
-
- err = platform_driver_register(&mlxplat_driver);
- if (err)
- return err;
- return 0;
-}
-module_init(mlxplat_init);
-
-static void __exit mlxplat_exit(void)
-{
- if (mlxplat_dev)
- platform_device_unregister(mlxplat_dev);
-
- platform_driver_unregister(&mlxplat_driver);
-}
-module_exit(mlxplat_exit);
-
-MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
-MODULE_DESCRIPTION("Mellanox platform driver");
-MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/platform/x86/samsung-galaxybook.c b/drivers/platform/x86/samsung-galaxybook.c
new file mode 100644
index 000000000000..5878a351993e
--- /dev/null
+++ b/drivers/platform/x86/samsung-galaxybook.c
@@ -0,0 +1,1425 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Samsung Galaxy Book driver
+ *
+ * Copyright (c) 2025 Joshua Grisham <josh@joshuagrisham.com>
+ *
+ * With contributions to the SCAI ACPI device interface:
+ * Copyright (c) 2024 Giulio Girardi <giulio.girardi@protechgroup.it>
+ *
+ * Implementation inspired by existing x86 platform drivers.
+ * Thank you to the authors!
+ */
+
+#include <linux/acpi.h>
+#include <linux/bits.h>
+#include <linux/err.h>
+#include <linux/i8042.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/platform_profile.h>
+#include <linux/serio.h>
+#include <linux/sysfs.h>
+#include <linux/uuid.h>
+#include <linux/workqueue.h>
+#include <acpi/battery.h>
+#include "firmware_attributes_class.h"
+
+#define DRIVER_NAME "samsung-galaxybook"
+
+struct samsung_galaxybook {
+ struct platform_device *platform;
+ struct acpi_device *acpi;
+
+ struct device *fw_attrs_dev;
+ struct kset *fw_attrs_kset;
+ /* block in case firmware attributes are updated in multiple threads */
+ struct mutex fw_attr_lock;
+
+ bool has_kbd_backlight;
+ bool has_block_recording;
+ bool has_performance_mode;
+
+ struct led_classdev kbd_backlight;
+ struct work_struct kbd_backlight_hotkey_work;
+ /* block in case brightness updated using hotkey and another thread */
+ struct mutex kbd_backlight_lock;
+
+ void *i8042_filter_ptr;
+
+ struct work_struct block_recording_hotkey_work;
+ struct input_dev *camera_lens_cover_switch;
+
+ struct acpi_battery_hook battery_hook;
+
+ u8 profile_performance_modes[PLATFORM_PROFILE_LAST];
+};
+
+enum galaxybook_fw_attr_id {
+ GB_ATTR_POWER_ON_LID_OPEN,
+ GB_ATTR_USB_CHARGING,
+ GB_ATTR_BLOCK_RECORDING,
+};
+
+static const char * const galaxybook_fw_attr_name[] = {
+ [GB_ATTR_POWER_ON_LID_OPEN] = "power_on_lid_open",
+ [GB_ATTR_USB_CHARGING] = "usb_charging",
+ [GB_ATTR_BLOCK_RECORDING] = "block_recording",
+};
+
+static const char * const galaxybook_fw_attr_desc[] = {
+ [GB_ATTR_POWER_ON_LID_OPEN] = "Power On Lid Open",
+ [GB_ATTR_USB_CHARGING] = "USB Charging",
+ [GB_ATTR_BLOCK_RECORDING] = "Block Recording",
+};
+
+#define GB_ATTR_LANGUAGE_CODE "en_US.UTF-8"
+
+struct galaxybook_fw_attr {
+ struct samsung_galaxybook *galaxybook;
+ enum galaxybook_fw_attr_id fw_attr_id;
+ struct attribute_group attr_group;
+ struct kobj_attribute display_name;
+ struct kobj_attribute current_value;
+ int (*get_value)(struct samsung_galaxybook *galaxybook, bool *value);
+ int (*set_value)(struct samsung_galaxybook *galaxybook, const bool value);
+};
+
+struct sawb {
+ u16 safn;
+ u16 sasb;
+ u8 rflg;
+ union {
+ struct {
+ u8 gunm;
+ u8 guds[250];
+ } __packed;
+ struct {
+ u8 caid[16];
+ u8 fncn;
+ u8 subn;
+ u8 iob0;
+ u8 iob1;
+ u8 iob2;
+ u8 iob3;
+ u8 iob4;
+ u8 iob5;
+ u8 iob6;
+ u8 iob7;
+ u8 iob8;
+ u8 iob9;
+ } __packed;
+ struct {
+ u8 iob_prefix[18];
+ u8 iobs[10];
+ } __packed;
+ } __packed;
+} __packed;
+
+#define GB_SAWB_LEN_SETTINGS 0x15
+#define GB_SAWB_LEN_PERFORMANCE_MODE 0x100
+
+#define GB_SAFN 0x5843
+
+#define GB_SASB_KBD_BACKLIGHT 0x78
+#define GB_SASB_POWER_MANAGEMENT 0x7a
+#define GB_SASB_USB_CHARGING_GET 0x67
+#define GB_SASB_USB_CHARGING_SET 0x68
+#define GB_SASB_NOTIFICATIONS 0x86
+#define GB_SASB_BLOCK_RECORDING 0x8a
+#define GB_SASB_PERFORMANCE_MODE 0x91
+
+#define GB_SAWB_RFLG_POS 4
+#define GB_SAWB_GB_GUNM_POS 5
+
+#define GB_RFLG_SUCCESS 0xaa
+#define GB_GUNM_FAIL 0xff
+
+#define GB_GUNM_FEATURE_ENABLE 0xbb
+#define GB_GUNM_FEATURE_ENABLE_SUCCESS 0xdd
+#define GB_GUDS_FEATURE_ENABLE 0xaa
+#define GB_GUDS_FEATURE_ENABLE_SUCCESS 0xcc
+
+#define GB_GUNM_GET 0x81
+#define GB_GUNM_SET 0x82
+
+#define GB_GUNM_POWER_MANAGEMENT 0x82
+
+#define GB_GUNM_USB_CHARGING_GET 0x80
+#define GB_GUNM_USB_CHARGING_ON 0x81
+#define GB_GUNM_USB_CHARGING_OFF 0x80
+#define GB_GUDS_POWER_ON_LID_OPEN 0xa3
+#define GB_GUDS_POWER_ON_LID_OPEN_GET 0x81
+#define GB_GUDS_POWER_ON_LID_OPEN_SET 0x80
+#define GB_GUDS_BATTERY_CHARGE_CONTROL 0xe9
+#define GB_GUDS_BATTERY_CHARGE_CONTROL_GET 0x91
+#define GB_GUDS_BATTERY_CHARGE_CONTROL_SET 0x90
+#define GB_GUNM_ACPI_NOTIFY_ENABLE 0x80
+#define GB_GUDS_ACPI_NOTIFY_ENABLE 0x02
+
+#define GB_BLOCK_RECORDING_ON 0x0
+#define GB_BLOCK_RECORDING_OFF 0x1
+
+#define GB_FNCN_PERFORMANCE_MODE 0x51
+#define GB_SUBN_PERFORMANCE_MODE_LIST 0x01
+#define GB_SUBN_PERFORMANCE_MODE_GET 0x02
+#define GB_SUBN_PERFORMANCE_MODE_SET 0x03
+
+/* guid 8246028d-8bca-4a55-ba0f-6f1e6b921b8f */
+static const guid_t performance_mode_guid =
+ GUID_INIT(0x8246028d, 0x8bca, 0x4a55, 0xba, 0x0f, 0x6f, 0x1e, 0x6b, 0x92, 0x1b, 0x8f);
+#define GB_PERFORMANCE_MODE_GUID performance_mode_guid
+
+#define GB_PERFORMANCE_MODE_FANOFF 0xb
+#define GB_PERFORMANCE_MODE_LOWNOISE 0xa
+#define GB_PERFORMANCE_MODE_OPTIMIZED 0x0
+#define GB_PERFORMANCE_MODE_OPTIMIZED_V2 0x2
+#define GB_PERFORMANCE_MODE_PERFORMANCE 0x1
+#define GB_PERFORMANCE_MODE_PERFORMANCE_V2 0x15
+#define GB_PERFORMANCE_MODE_ULTRA 0x16
+#define GB_PERFORMANCE_MODE_IGNORE1 0x14
+#define GB_PERFORMANCE_MODE_IGNORE2 0xc
+
+#define GB_ACPI_METHOD_ENABLE "SDLS"
+#define GB_ACPI_METHOD_ENABLE_ON 1
+#define GB_ACPI_METHOD_ENABLE_OFF 0
+#define GB_ACPI_METHOD_SETTINGS "CSFI"
+#define GB_ACPI_METHOD_PERFORMANCE_MODE "CSXI"
+
+#define GB_KBD_BACKLIGHT_MAX_BRIGHTNESS 3
+
+#define GB_ACPI_NOTIFY_BATTERY_STATE_CHANGED 0x61
+#define GB_ACPI_NOTIFY_DEVICE_ON_TABLE 0x6c
+#define GB_ACPI_NOTIFY_DEVICE_OFF_TABLE 0x6d
+#define GB_ACPI_NOTIFY_HOTKEY_PERFORMANCE_MODE 0x70
+
+#define GB_KEY_KBD_BACKLIGHT_KEYDOWN 0x2c
+#define GB_KEY_KBD_BACKLIGHT_KEYUP 0xac
+#define GB_KEY_BLOCK_RECORDING_KEYDOWN 0x1f
+#define GB_KEY_BLOCK_RECORDING_KEYUP 0x9f
+#define GB_KEY_BATTERY_NOTIFY_KEYUP 0xf
+#define GB_KEY_BATTERY_NOTIFY_KEYDOWN 0x8f
+
+/*
+ * Optional features which have been determined as not supported on a particular
+ * device will return GB_NOT_SUPPORTED from their init function. Positive
+ * EOPNOTSUPP is used as the underlying value instead of negative to
+ * differentiate this return code from valid upstream failures.
+ */
+#define GB_NOT_SUPPORTED EOPNOTSUPP /* Galaxy Book feature not supported */
+
+/*
+ * ACPI method handling
+ */
+
+static int galaxybook_acpi_method(struct samsung_galaxybook *galaxybook, acpi_string method,
+ struct sawb *buf, size_t len)
+{
+ struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
+ union acpi_object in_obj, *out_obj;
+ struct acpi_object_list input;
+ acpi_status status;
+ int err;
+
+ in_obj.type = ACPI_TYPE_BUFFER;
+ in_obj.buffer.length = len;
+ in_obj.buffer.pointer = (u8 *)buf;
+
+ input.count = 1;
+ input.pointer = &in_obj;
+
+ status = acpi_evaluate_object_typed(galaxybook->acpi->handle, method, &input, &output,
+ ACPI_TYPE_BUFFER);
+
+ if (ACPI_FAILURE(status)) {
+ dev_err(&galaxybook->acpi->dev, "failed to execute method %s; got %s\n",
+ method, acpi_format_exception(status));
+ return -EIO;
+ }
+
+ out_obj = output.pointer;
+
+ if (out_obj->buffer.length != len || out_obj->buffer.length < GB_SAWB_GB_GUNM_POS + 1) {
+ dev_err(&galaxybook->acpi->dev,
+ "failed to execute %s; response length mismatch\n",
+ method);
+ err = -EPROTO;
+ goto out_free;
+ }
+ if (out_obj->buffer.pointer[GB_SAWB_RFLG_POS] != GB_RFLG_SUCCESS) {
+ dev_err(&galaxybook->acpi->dev,
+ "failed to execute %s; device did not respond with success code 0x%x\n",
+ method, GB_RFLG_SUCCESS);
+ err = -ENXIO;
+ goto out_free;
+ }
+ if (out_obj->buffer.pointer[GB_SAWB_GB_GUNM_POS] == GB_GUNM_FAIL) {
+ dev_err(&galaxybook->acpi->dev,
+ "failed to execute %s; device responded with failure code 0x%x\n",
+ method, GB_GUNM_FAIL);
+ err = -ENXIO;
+ goto out_free;
+ }
+
+ memcpy(buf, out_obj->buffer.pointer, len);
+ err = 0;
+
+out_free:
+ kfree(out_obj);
+ return err;
+}
+
+static int galaxybook_enable_acpi_feature(struct samsung_galaxybook *galaxybook, const u16 sasb)
+{
+ struct sawb buf = {};
+ int err;
+
+ buf.safn = GB_SAFN;
+ buf.sasb = sasb;
+ buf.gunm = GB_GUNM_FEATURE_ENABLE;
+ buf.guds[0] = GB_GUDS_FEATURE_ENABLE;
+
+ err = galaxybook_acpi_method(galaxybook, GB_ACPI_METHOD_SETTINGS,
+ &buf, GB_SAWB_LEN_SETTINGS);
+ if (err)
+ return err;
+
+ if (buf.gunm != GB_GUNM_FEATURE_ENABLE_SUCCESS &&
+ buf.guds[0] != GB_GUDS_FEATURE_ENABLE_SUCCESS)
+ return -ENODEV;
+
+ return 0;
+}
+
+/*
+ * Keyboard Backlight
+ */
+
+static int kbd_backlight_acpi_get(struct samsung_galaxybook *galaxybook,
+ enum led_brightness *brightness)
+{
+ struct sawb buf = {};
+ int err;
+
+ buf.safn = GB_SAFN;
+ buf.sasb = GB_SASB_KBD_BACKLIGHT;
+ buf.gunm = GB_GUNM_GET;
+
+ err = galaxybook_acpi_method(galaxybook, GB_ACPI_METHOD_SETTINGS,
+ &buf, GB_SAWB_LEN_SETTINGS);
+ if (err)
+ return err;
+
+ *brightness = buf.gunm;
+
+ return 0;
+}
+
+static int kbd_backlight_acpi_set(struct samsung_galaxybook *galaxybook,
+ const enum led_brightness brightness)
+{
+ struct sawb buf = {};
+
+ buf.safn = GB_SAFN;
+ buf.sasb = GB_SASB_KBD_BACKLIGHT;
+ buf.gunm = GB_GUNM_SET;
+
+ buf.guds[0] = brightness;
+
+ return galaxybook_acpi_method(galaxybook, GB_ACPI_METHOD_SETTINGS,
+ &buf, GB_SAWB_LEN_SETTINGS);
+}
+
+static enum led_brightness kbd_backlight_show(struct led_classdev *led)
+{
+ struct samsung_galaxybook *galaxybook =
+ container_of(led, struct samsung_galaxybook, kbd_backlight);
+ enum led_brightness brightness;
+ int err;
+
+ err = kbd_backlight_acpi_get(galaxybook, &brightness);
+ if (err)
+ return err;
+
+ return brightness;
+}
+
+static int kbd_backlight_store(struct led_classdev *led,
+ const enum led_brightness brightness)
+{
+ struct samsung_galaxybook *galaxybook =
+ container_of_const(led, struct samsung_galaxybook, kbd_backlight);
+
+ return kbd_backlight_acpi_set(galaxybook, brightness);
+}
+
+static int galaxybook_kbd_backlight_init(struct samsung_galaxybook *galaxybook)
+{
+ struct led_init_data init_data = {};
+ enum led_brightness brightness;
+ int err;
+
+ err = devm_mutex_init(&galaxybook->platform->dev, &galaxybook->kbd_backlight_lock);
+ if (err)
+ return err;
+
+ err = galaxybook_enable_acpi_feature(galaxybook, GB_SASB_KBD_BACKLIGHT);
+ if (err) {
+ dev_dbg(&galaxybook->platform->dev,
+ "failed to enable kbd_backlight feature, error %d\n", err);
+ return GB_NOT_SUPPORTED;
+ }
+
+ err = kbd_backlight_acpi_get(galaxybook, &brightness);
+ if (err) {
+ dev_dbg(&galaxybook->platform->dev,
+ "failed to get initial kbd_backlight brightness, error %d\n", err);
+ return GB_NOT_SUPPORTED;
+ }
+
+ init_data.devicename = DRIVER_NAME;
+ init_data.default_label = ":" LED_FUNCTION_KBD_BACKLIGHT;
+ init_data.devname_mandatory = true;
+
+ galaxybook->kbd_backlight.brightness_get = kbd_backlight_show;
+ galaxybook->kbd_backlight.brightness_set_blocking = kbd_backlight_store;
+ galaxybook->kbd_backlight.flags = LED_BRIGHT_HW_CHANGED;
+ galaxybook->kbd_backlight.max_brightness = GB_KBD_BACKLIGHT_MAX_BRIGHTNESS;
+
+ return devm_led_classdev_register_ext(&galaxybook->platform->dev,
+ &galaxybook->kbd_backlight, &init_data);
+}
+
+/*
+ * Battery Extension (adds charge_control_end_threshold to the battery device)
+ */
+
+static int charge_control_end_threshold_acpi_get(struct samsung_galaxybook *galaxybook, u8 *value)
+{
+ struct sawb buf = {};
+ int err;
+
+ buf.safn = GB_SAFN;
+ buf.sasb = GB_SASB_POWER_MANAGEMENT;
+ buf.gunm = GB_GUNM_POWER_MANAGEMENT;
+ buf.guds[0] = GB_GUDS_BATTERY_CHARGE_CONTROL;
+ buf.guds[1] = GB_GUDS_BATTERY_CHARGE_CONTROL_GET;
+
+ err = galaxybook_acpi_method(galaxybook, GB_ACPI_METHOD_SETTINGS,
+ &buf, GB_SAWB_LEN_SETTINGS);
+ if (err)
+ return err;
+
+ *value = buf.guds[1];
+
+ return 0;
+}
+
+static int charge_control_end_threshold_acpi_set(struct samsung_galaxybook *galaxybook, u8 value)
+{
+ struct sawb buf = {};
+
+ buf.safn = GB_SAFN;
+ buf.sasb = GB_SASB_POWER_MANAGEMENT;
+ buf.gunm = GB_GUNM_POWER_MANAGEMENT;
+ buf.guds[0] = GB_GUDS_BATTERY_CHARGE_CONTROL;
+ buf.guds[1] = GB_GUDS_BATTERY_CHARGE_CONTROL_SET;
+ buf.guds[2] = value;
+
+ return galaxybook_acpi_method(galaxybook, GB_ACPI_METHOD_SETTINGS,
+ &buf, GB_SAWB_LEN_SETTINGS);
+}
+
+static int galaxybook_battery_ext_property_get(struct power_supply *psy,
+ const struct power_supply_ext *ext,
+ void *ext_data,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct samsung_galaxybook *galaxybook = ext_data;
+ int err;
+
+ if (psp != POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD)
+ return -EINVAL;
+
+ err = charge_control_end_threshold_acpi_get(galaxybook, (u8 *)&val->intval);
+ if (err)
+ return err;
+
+ /*
+ * device stores "no end threshold" as 0 instead of 100;
+ * if device has 0, report 100
+ */
+ if (val->intval == 0)
+ val->intval = 100;
+
+ return 0;
+}
+
+static int galaxybook_battery_ext_property_set(struct power_supply *psy,
+ const struct power_supply_ext *ext,
+ void *ext_data,
+ enum power_supply_property psp,
+ const union power_supply_propval *val)
+{
+ struct samsung_galaxybook *galaxybook = ext_data;
+ u8 value;
+
+ if (psp != POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD)
+ return -EINVAL;
+
+ value = val->intval;
+
+ if (value < 1 || value > 100)
+ return -EINVAL;
+
+ /*
+ * device stores "no end threshold" as 0 instead of 100;
+ * if setting to 100, send 0
+ */
+ if (value == 100)
+ value = 0;
+
+ return charge_control_end_threshold_acpi_set(galaxybook, value);
+}
+
+static int galaxybook_battery_ext_property_is_writeable(struct power_supply *psy,
+ const struct power_supply_ext *ext,
+ void *ext_data,
+ enum power_supply_property psp)
+{
+ if (psp == POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD)
+ return true;
+
+ return false;
+}
+
+static const enum power_supply_property galaxybook_battery_properties[] = {
+ POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD,
+};
+
+static const struct power_supply_ext galaxybook_battery_ext = {
+ .name = DRIVER_NAME,
+ .properties = galaxybook_battery_properties,
+ .num_properties = ARRAY_SIZE(galaxybook_battery_properties),
+ .get_property = galaxybook_battery_ext_property_get,
+ .set_property = galaxybook_battery_ext_property_set,
+ .property_is_writeable = galaxybook_battery_ext_property_is_writeable,
+};
+
+static int galaxybook_battery_add(struct power_supply *battery, struct acpi_battery_hook *hook)
+{
+ struct samsung_galaxybook *galaxybook =
+ container_of(hook, struct samsung_galaxybook, battery_hook);
+
+ return power_supply_register_extension(battery, &galaxybook_battery_ext,
+ &battery->dev, galaxybook);
+}
+
+static int galaxybook_battery_remove(struct power_supply *battery, struct acpi_battery_hook *hook)
+{
+ power_supply_unregister_extension(battery, &galaxybook_battery_ext);
+ return 0;
+}
+
+static int galaxybook_battery_threshold_init(struct samsung_galaxybook *galaxybook)
+{
+ u8 value;
+ int err;
+
+ err = charge_control_end_threshold_acpi_get(galaxybook, &value);
+ if (err) {
+ dev_dbg(&galaxybook->platform->dev,
+ "failed to get initial battery charge end threshold, error %d\n", err);
+ return 0;
+ }
+
+ galaxybook->battery_hook.add_battery = galaxybook_battery_add;
+ galaxybook->battery_hook.remove_battery = galaxybook_battery_remove;
+ galaxybook->battery_hook.name = "Samsung Galaxy Book Battery Extension";
+
+ return devm_battery_hook_register(&galaxybook->platform->dev, &galaxybook->battery_hook);
+}
+
+/*
+ * Platform Profile / Performance mode
+ */
+
+static int performance_mode_acpi_get(struct samsung_galaxybook *galaxybook, u8 *performance_mode)
+{
+ struct sawb buf = {};
+ int err;
+
+ buf.safn = GB_SAFN;
+ buf.sasb = GB_SASB_PERFORMANCE_MODE;
+ export_guid(buf.caid, &GB_PERFORMANCE_MODE_GUID);
+ buf.fncn = GB_FNCN_PERFORMANCE_MODE;
+ buf.subn = GB_SUBN_PERFORMANCE_MODE_GET;
+
+ err = galaxybook_acpi_method(galaxybook, GB_ACPI_METHOD_PERFORMANCE_MODE,
+ &buf, GB_SAWB_LEN_PERFORMANCE_MODE);
+ if (err)
+ return err;
+
+ *performance_mode = buf.iob0;
+
+ return 0;
+}
+
+static int performance_mode_acpi_set(struct samsung_galaxybook *galaxybook,
+ const u8 performance_mode)
+{
+ struct sawb buf = {};
+
+ buf.safn = GB_SAFN;
+ buf.sasb = GB_SASB_PERFORMANCE_MODE;
+ export_guid(buf.caid, &GB_PERFORMANCE_MODE_GUID);
+ buf.fncn = GB_FNCN_PERFORMANCE_MODE;
+ buf.subn = GB_SUBN_PERFORMANCE_MODE_SET;
+ buf.iob0 = performance_mode;
+
+ return galaxybook_acpi_method(galaxybook, GB_ACPI_METHOD_PERFORMANCE_MODE,
+ &buf, GB_SAWB_LEN_PERFORMANCE_MODE);
+}
+
+static int get_performance_mode_profile(struct samsung_galaxybook *galaxybook,
+ const u8 performance_mode,
+ enum platform_profile_option *profile)
+{
+ switch (performance_mode) {
+ case GB_PERFORMANCE_MODE_FANOFF:
+ *profile = PLATFORM_PROFILE_LOW_POWER;
+ break;
+ case GB_PERFORMANCE_MODE_LOWNOISE:
+ *profile = PLATFORM_PROFILE_QUIET;
+ break;
+ case GB_PERFORMANCE_MODE_OPTIMIZED:
+ case GB_PERFORMANCE_MODE_OPTIMIZED_V2:
+ *profile = PLATFORM_PROFILE_BALANCED;
+ break;
+ case GB_PERFORMANCE_MODE_PERFORMANCE:
+ case GB_PERFORMANCE_MODE_PERFORMANCE_V2:
+ case GB_PERFORMANCE_MODE_ULTRA:
+ *profile = PLATFORM_PROFILE_PERFORMANCE;
+ break;
+ case GB_PERFORMANCE_MODE_IGNORE1:
+ case GB_PERFORMANCE_MODE_IGNORE2:
+ return -EOPNOTSUPP;
+ default:
+ dev_warn(&galaxybook->platform->dev,
+ "unrecognized performance mode 0x%x\n", performance_mode);
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static int galaxybook_platform_profile_get(struct device *dev,
+ enum platform_profile_option *profile)
+{
+ struct samsung_galaxybook *galaxybook = dev_get_drvdata(dev);
+ u8 performance_mode;
+ int err;
+
+ err = performance_mode_acpi_get(galaxybook, &performance_mode);
+ if (err)
+ return err;
+
+ return get_performance_mode_profile(galaxybook, performance_mode, profile);
+}
+
+static int galaxybook_platform_profile_set(struct device *dev,
+ enum platform_profile_option profile)
+{
+ struct samsung_galaxybook *galaxybook = dev_get_drvdata(dev);
+
+ return performance_mode_acpi_set(galaxybook,
+ galaxybook->profile_performance_modes[profile]);
+}
+
+static int galaxybook_platform_profile_probe(void *drvdata, unsigned long *choices)
+{
+ struct samsung_galaxybook *galaxybook = drvdata;
+ u8 *perfmodes = galaxybook->profile_performance_modes;
+ enum platform_profile_option profile;
+ struct sawb buf = {};
+ unsigned int i;
+ int err;
+
+ buf.safn = GB_SAFN;
+ buf.sasb = GB_SASB_PERFORMANCE_MODE;
+ export_guid(buf.caid, &GB_PERFORMANCE_MODE_GUID);
+ buf.fncn = GB_FNCN_PERFORMANCE_MODE;
+ buf.subn = GB_SUBN_PERFORMANCE_MODE_LIST;
+
+ err = galaxybook_acpi_method(galaxybook, GB_ACPI_METHOD_PERFORMANCE_MODE,
+ &buf, GB_SAWB_LEN_PERFORMANCE_MODE);
+ if (err) {
+ dev_dbg(&galaxybook->platform->dev,
+ "failed to get supported performance modes, error %d\n", err);
+ return err;
+ }
+
+ /* set initial default profile performance mode values */
+ perfmodes[PLATFORM_PROFILE_LOW_POWER] = GB_PERFORMANCE_MODE_FANOFF;
+ perfmodes[PLATFORM_PROFILE_QUIET] = GB_PERFORMANCE_MODE_LOWNOISE;
+ perfmodes[PLATFORM_PROFILE_BALANCED] = GB_PERFORMANCE_MODE_OPTIMIZED;
+ perfmodes[PLATFORM_PROFILE_PERFORMANCE] = GB_PERFORMANCE_MODE_PERFORMANCE;
+
+ /*
+ * Value returned in iob0 will have the number of supported performance
+ * modes per device. The performance mode values will then be given as a
+ * list after this (iob1-iobX). Loop through the supported values and
+ * enable their mapped platform_profile choice, overriding "legacy"
+ * values along the way if a non-legacy value exists.
+ */
+ for (i = 1; i <= buf.iob0; i++) {
+ err = get_performance_mode_profile(galaxybook, buf.iobs[i], &profile);
+ if (err) {
+ dev_dbg(&galaxybook->platform->dev,
+ "ignoring unmapped performance mode 0x%x\n", buf.iobs[i]);
+ continue;
+ }
+ switch (buf.iobs[i]) {
+ case GB_PERFORMANCE_MODE_OPTIMIZED_V2:
+ perfmodes[profile] = GB_PERFORMANCE_MODE_OPTIMIZED_V2;
+ break;
+ case GB_PERFORMANCE_MODE_PERFORMANCE_V2:
+ /* only update if not already overwritten by Ultra */
+ if (perfmodes[profile] != GB_PERFORMANCE_MODE_ULTRA)
+ perfmodes[profile] = GB_PERFORMANCE_MODE_PERFORMANCE_V2;
+ break;
+ case GB_PERFORMANCE_MODE_ULTRA:
+ perfmodes[profile] = GB_PERFORMANCE_MODE_ULTRA;
+ break;
+ default:
+ break;
+ }
+ set_bit(profile, choices);
+ dev_dbg(&galaxybook->platform->dev,
+ "setting platform profile %d to use performance mode 0x%x\n",
+ profile, perfmodes[profile]);
+ }
+
+ /* initialize performance_mode using balanced's mapped value */
+ if (test_bit(PLATFORM_PROFILE_BALANCED, choices))
+ return performance_mode_acpi_set(galaxybook, perfmodes[PLATFORM_PROFILE_BALANCED]);
+
+ return 0;
+}
+
+static const struct platform_profile_ops galaxybook_platform_profile_ops = {
+ .probe = galaxybook_platform_profile_probe,
+ .profile_get = galaxybook_platform_profile_get,
+ .profile_set = galaxybook_platform_profile_set,
+};
+
+static int galaxybook_platform_profile_init(struct samsung_galaxybook *galaxybook)
+{
+ struct device *platform_profile_dev;
+ u8 performance_mode;
+ int err;
+
+ err = performance_mode_acpi_get(galaxybook, &performance_mode);
+ if (err) {
+ dev_dbg(&galaxybook->platform->dev,
+ "failed to get initial performance mode, error %d\n", err);
+ return GB_NOT_SUPPORTED;
+ }
+
+ platform_profile_dev = devm_platform_profile_register(&galaxybook->platform->dev,
+ DRIVER_NAME, galaxybook,
+ &galaxybook_platform_profile_ops);
+
+ return PTR_ERR_OR_ZERO(platform_profile_dev);
+}
+
+/*
+ * Firmware Attributes
+ */
+
+/* Power on lid open (device should power on when lid is opened) */
+
+static int power_on_lid_open_acpi_get(struct samsung_galaxybook *galaxybook, bool *value)
+{
+ struct sawb buf = {};
+ int err;
+
+ buf.safn = GB_SAFN;
+ buf.sasb = GB_SASB_POWER_MANAGEMENT;
+ buf.gunm = GB_GUNM_POWER_MANAGEMENT;
+ buf.guds[0] = GB_GUDS_POWER_ON_LID_OPEN;
+ buf.guds[1] = GB_GUDS_POWER_ON_LID_OPEN_GET;
+
+ err = galaxybook_acpi_method(galaxybook, GB_ACPI_METHOD_SETTINGS,
+ &buf, GB_SAWB_LEN_SETTINGS);
+ if (err)
+ return err;
+
+ *value = buf.guds[1];
+
+ return 0;
+}
+
+static int power_on_lid_open_acpi_set(struct samsung_galaxybook *galaxybook, const bool value)
+{
+ struct sawb buf = {};
+
+ lockdep_assert_held(&galaxybook->fw_attr_lock);
+
+ buf.safn = GB_SAFN;
+ buf.sasb = GB_SASB_POWER_MANAGEMENT;
+ buf.gunm = GB_GUNM_POWER_MANAGEMENT;
+ buf.guds[0] = GB_GUDS_POWER_ON_LID_OPEN;
+ buf.guds[1] = GB_GUDS_POWER_ON_LID_OPEN_SET;
+ buf.guds[2] = value ? 1 : 0;
+
+ return galaxybook_acpi_method(galaxybook, GB_ACPI_METHOD_SETTINGS,
+ &buf, GB_SAWB_LEN_SETTINGS);
+}
+
+/* USB Charging (USB ports can provide power when device is powered off) */
+
+static int usb_charging_acpi_get(struct samsung_galaxybook *galaxybook, bool *value)
+{
+ struct sawb buf = {};
+ int err;
+
+ buf.safn = GB_SAFN;
+ buf.sasb = GB_SASB_USB_CHARGING_GET;
+ buf.gunm = GB_GUNM_USB_CHARGING_GET;
+
+ err = galaxybook_acpi_method(galaxybook, GB_ACPI_METHOD_SETTINGS,
+ &buf, GB_SAWB_LEN_SETTINGS);
+ if (err)
+ return err;
+
+ *value = buf.gunm == 1;
+
+ return 0;
+}
+
+static int usb_charging_acpi_set(struct samsung_galaxybook *galaxybook, const bool value)
+{
+ struct sawb buf = {};
+
+ lockdep_assert_held(&galaxybook->fw_attr_lock);
+
+ buf.safn = GB_SAFN;
+ buf.sasb = GB_SASB_USB_CHARGING_SET;
+ buf.gunm = value ? GB_GUNM_USB_CHARGING_ON : GB_GUNM_USB_CHARGING_OFF;
+
+ return galaxybook_acpi_method(galaxybook, GB_ACPI_METHOD_SETTINGS,
+ &buf, GB_SAWB_LEN_SETTINGS);
+}
+
+/* Block recording (blocks access to camera and microphone) */
+
+static int block_recording_acpi_get(struct samsung_galaxybook *galaxybook, bool *value)
+{
+ struct sawb buf = {};
+ int err;
+
+ buf.safn = GB_SAFN;
+ buf.sasb = GB_SASB_BLOCK_RECORDING;
+ buf.gunm = GB_GUNM_GET;
+
+ err = galaxybook_acpi_method(galaxybook, GB_ACPI_METHOD_SETTINGS,
+ &buf, GB_SAWB_LEN_SETTINGS);
+ if (err)
+ return err;
+
+ *value = buf.gunm == GB_BLOCK_RECORDING_ON;
+
+ return 0;
+}
+
+static int block_recording_acpi_set(struct samsung_galaxybook *galaxybook, const bool value)
+{
+ struct sawb buf = {};
+ int err;
+
+ lockdep_assert_held(&galaxybook->fw_attr_lock);
+
+ buf.safn = GB_SAFN;
+ buf.sasb = GB_SASB_BLOCK_RECORDING;
+ buf.gunm = GB_GUNM_SET;
+ buf.guds[0] = value ? GB_BLOCK_RECORDING_ON : GB_BLOCK_RECORDING_OFF;
+
+ err = galaxybook_acpi_method(galaxybook, GB_ACPI_METHOD_SETTINGS,
+ &buf, GB_SAWB_LEN_SETTINGS);
+ if (err)
+ return err;
+
+ input_report_switch(galaxybook->camera_lens_cover_switch,
+ SW_CAMERA_LENS_COVER, value ? 1 : 0);
+ input_sync(galaxybook->camera_lens_cover_switch);
+
+ return 0;
+}
+
+static int galaxybook_block_recording_init(struct samsung_galaxybook *galaxybook)
+{
+ bool value;
+ int err;
+
+ err = galaxybook_enable_acpi_feature(galaxybook, GB_SASB_BLOCK_RECORDING);
+ if (err) {
+ dev_dbg(&galaxybook->platform->dev,
+ "failed to initialize block_recording, error %d\n", err);
+ return GB_NOT_SUPPORTED;
+ }
+
+ guard(mutex)(&galaxybook->fw_attr_lock);
+
+ err = block_recording_acpi_get(galaxybook, &value);
+ if (err) {
+ dev_dbg(&galaxybook->platform->dev,
+ "failed to get initial block_recording state, error %d\n", err);
+ return GB_NOT_SUPPORTED;
+ }
+
+ galaxybook->camera_lens_cover_switch =
+ devm_input_allocate_device(&galaxybook->platform->dev);
+ if (!galaxybook->camera_lens_cover_switch)
+ return -ENOMEM;
+
+ galaxybook->camera_lens_cover_switch->name = "Samsung Galaxy Book Camera Lens Cover";
+ galaxybook->camera_lens_cover_switch->phys = DRIVER_NAME "/input0";
+ galaxybook->camera_lens_cover_switch->id.bustype = BUS_HOST;
+
+ input_set_capability(galaxybook->camera_lens_cover_switch, EV_SW, SW_CAMERA_LENS_COVER);
+
+ err = input_register_device(galaxybook->camera_lens_cover_switch);
+ if (err)
+ return err;
+
+ input_report_switch(galaxybook->camera_lens_cover_switch,
+ SW_CAMERA_LENS_COVER, value ? 1 : 0);
+ input_sync(galaxybook->camera_lens_cover_switch);
+
+ return 0;
+}
+
+/* Firmware Attributes setup */
+
+static ssize_t type_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+ return sysfs_emit(buf, "enumeration\n");
+}
+
+static struct kobj_attribute fw_attr_type = __ATTR_RO(type);
+
+static ssize_t default_value_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+ return sysfs_emit(buf, "0\n");
+}
+
+static struct kobj_attribute fw_attr_default_value = __ATTR_RO(default_value);
+
+static ssize_t possible_values_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+ return sysfs_emit(buf, "0;1\n");
+}
+
+static struct kobj_attribute fw_attr_possible_values = __ATTR_RO(possible_values);
+
+static ssize_t display_name_language_code_show(struct kobject *kobj, struct kobj_attribute *attr,
+ char *buf)
+{
+ return sysfs_emit(buf, "%s\n", GB_ATTR_LANGUAGE_CODE);
+}
+
+static struct kobj_attribute fw_attr_display_name_language_code =
+ __ATTR_RO(display_name_language_code);
+
+static ssize_t display_name_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+ struct galaxybook_fw_attr *fw_attr =
+ container_of(attr, struct galaxybook_fw_attr, display_name);
+
+ return sysfs_emit(buf, "%s\n", galaxybook_fw_attr_desc[fw_attr->fw_attr_id]);
+}
+
+static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+ struct galaxybook_fw_attr *fw_attr =
+ container_of(attr, struct galaxybook_fw_attr, current_value);
+ bool value;
+ int err;
+
+ err = fw_attr->get_value(fw_attr->galaxybook, &value);
+ if (err)
+ return err;
+
+ return sysfs_emit(buf, "%u\n", value);
+}
+
+static ssize_t current_value_store(struct kobject *kobj, struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct galaxybook_fw_attr *fw_attr =
+ container_of(attr, struct galaxybook_fw_attr, current_value);
+ struct samsung_galaxybook *galaxybook = fw_attr->galaxybook;
+ bool value;
+ int err;
+
+ if (!count)
+ return -EINVAL;
+
+ err = kstrtobool(buf, &value);
+ if (err)
+ return err;
+
+ guard(mutex)(&galaxybook->fw_attr_lock);
+
+ err = fw_attr->set_value(galaxybook, value);
+ if (err)
+ return err;
+
+ return count;
+}
+
+#define NUM_FW_ATTR_ENUM_ATTRS 6
+
+static int galaxybook_fw_attr_init(struct samsung_galaxybook *galaxybook,
+ const enum galaxybook_fw_attr_id fw_attr_id,
+ int (*get_value)(struct samsung_galaxybook *galaxybook,
+ bool *value),
+ int (*set_value)(struct samsung_galaxybook *galaxybook,
+ const bool value))
+{
+ struct galaxybook_fw_attr *fw_attr;
+ struct attribute **attrs;
+
+ fw_attr = devm_kzalloc(&galaxybook->platform->dev, sizeof(*fw_attr), GFP_KERNEL);
+ if (!fw_attr)
+ return -ENOMEM;
+
+ attrs = devm_kcalloc(&galaxybook->platform->dev, NUM_FW_ATTR_ENUM_ATTRS + 1,
+ sizeof(*attrs), GFP_KERNEL);
+ if (!attrs)
+ return -ENOMEM;
+
+ attrs[0] = &fw_attr_type.attr;
+ attrs[1] = &fw_attr_default_value.attr;
+ attrs[2] = &fw_attr_possible_values.attr;
+ attrs[3] = &fw_attr_display_name_language_code.attr;
+
+ sysfs_attr_init(&fw_attr->display_name.attr);
+ fw_attr->display_name.attr.name = "display_name";
+ fw_attr->display_name.attr.mode = 0444;
+ fw_attr->display_name.show = display_name_show;
+ attrs[4] = &fw_attr->display_name.attr;
+
+ sysfs_attr_init(&fw_attr->current_value.attr);
+ fw_attr->current_value.attr.name = "current_value";
+ fw_attr->current_value.attr.mode = 0644;
+ fw_attr->current_value.show = current_value_show;
+ fw_attr->current_value.store = current_value_store;
+ attrs[5] = &fw_attr->current_value.attr;
+
+ attrs[6] = NULL;
+
+ fw_attr->galaxybook = galaxybook;
+ fw_attr->fw_attr_id = fw_attr_id;
+ fw_attr->attr_group.name = galaxybook_fw_attr_name[fw_attr_id];
+ fw_attr->attr_group.attrs = attrs;
+ fw_attr->get_value = get_value;
+ fw_attr->set_value = set_value;
+
+ return sysfs_create_group(&galaxybook->fw_attrs_kset->kobj, &fw_attr->attr_group);
+}
+
+static void galaxybook_kset_unregister(void *data)
+{
+ struct kset *kset = data;
+
+ kset_unregister(kset);
+}
+
+static void galaxybook_fw_attrs_dev_unregister(void *data)
+{
+ struct device *fw_attrs_dev = data;
+
+ device_unregister(fw_attrs_dev);
+}
+
+static int galaxybook_fw_attrs_init(struct samsung_galaxybook *galaxybook)
+{
+ bool value;
+ int err;
+
+ err = devm_mutex_init(&galaxybook->platform->dev, &galaxybook->fw_attr_lock);
+ if (err)
+ return err;
+
+ galaxybook->fw_attrs_dev = device_create(&firmware_attributes_class, NULL, MKDEV(0, 0),
+ NULL, "%s", DRIVER_NAME);
+ if (IS_ERR(galaxybook->fw_attrs_dev))
+ return PTR_ERR(galaxybook->fw_attrs_dev);
+
+ err = devm_add_action_or_reset(&galaxybook->platform->dev,
+ galaxybook_fw_attrs_dev_unregister,
+ galaxybook->fw_attrs_dev);
+ if (err)
+ return err;
+
+ galaxybook->fw_attrs_kset = kset_create_and_add("attributes", NULL,
+ &galaxybook->fw_attrs_dev->kobj);
+ if (!galaxybook->fw_attrs_kset)
+ return -ENOMEM;
+ err = devm_add_action_or_reset(&galaxybook->platform->dev,
+ galaxybook_kset_unregister, galaxybook->fw_attrs_kset);
+ if (err)
+ return err;
+
+ err = power_on_lid_open_acpi_get(galaxybook, &value);
+ if (!err) {
+ err = galaxybook_fw_attr_init(galaxybook,
+ GB_ATTR_POWER_ON_LID_OPEN,
+ &power_on_lid_open_acpi_get,
+ &power_on_lid_open_acpi_set);
+ if (err)
+ return err;
+ }
+
+ err = usb_charging_acpi_get(galaxybook, &value);
+ if (!err) {
+ err = galaxybook_fw_attr_init(galaxybook,
+ GB_ATTR_USB_CHARGING,
+ &usb_charging_acpi_get,
+ &usb_charging_acpi_set);
+ if (err)
+ return err;
+ }
+
+ err = galaxybook_block_recording_init(galaxybook);
+ if (err == GB_NOT_SUPPORTED)
+ return 0;
+ else if (err)
+ return err;
+
+ galaxybook->has_block_recording = true;
+
+ return galaxybook_fw_attr_init(galaxybook,
+ GB_ATTR_BLOCK_RECORDING,
+ &block_recording_acpi_get,
+ &block_recording_acpi_set);
+}
+
+/*
+ * Hotkeys and notifications
+ */
+
+static void galaxybook_kbd_backlight_hotkey_work(struct work_struct *work)
+{
+ struct samsung_galaxybook *galaxybook =
+ from_work(galaxybook, work, kbd_backlight_hotkey_work);
+ int brightness;
+ int err;
+
+ guard(mutex)(&galaxybook->kbd_backlight_lock);
+
+ brightness = galaxybook->kbd_backlight.brightness;
+ if (brightness < galaxybook->kbd_backlight.max_brightness)
+ brightness++;
+ else
+ brightness = 0;
+
+ err = led_set_brightness_sync(&galaxybook->kbd_backlight, brightness);
+ if (err) {
+ dev_err(&galaxybook->platform->dev,
+ "failed to set kbd_backlight brightness, error %d\n", err);
+ return;
+ }
+
+ led_classdev_notify_brightness_hw_changed(&galaxybook->kbd_backlight, brightness);
+}
+
+static void galaxybook_block_recording_hotkey_work(struct work_struct *work)
+{
+ struct samsung_galaxybook *galaxybook =
+ from_work(galaxybook, work, block_recording_hotkey_work);
+ bool value;
+ int err;
+
+ guard(mutex)(&galaxybook->fw_attr_lock);
+
+ err = block_recording_acpi_get(galaxybook, &value);
+ if (err) {
+ dev_err(&galaxybook->platform->dev,
+ "failed to get block_recording, error %d\n", err);
+ return;
+ }
+
+ err = block_recording_acpi_set(galaxybook, !value);
+ if (err)
+ dev_err(&galaxybook->platform->dev,
+ "failed to set block_recording, error %d\n", err);
+}
+
+static bool galaxybook_i8042_filter(unsigned char data, unsigned char str, struct serio *port,
+ void *context)
+{
+ struct samsung_galaxybook *galaxybook = context;
+ static bool extended;
+
+ if (str & I8042_STR_AUXDATA)
+ return false;
+
+ if (data == 0xe0) {
+ extended = true;
+ return true;
+ } else if (extended) {
+ extended = false;
+ switch (data) {
+ case GB_KEY_KBD_BACKLIGHT_KEYDOWN:
+ return true;
+ case GB_KEY_KBD_BACKLIGHT_KEYUP:
+ if (galaxybook->has_kbd_backlight)
+ schedule_work(&galaxybook->kbd_backlight_hotkey_work);
+ return true;
+
+ case GB_KEY_BLOCK_RECORDING_KEYDOWN:
+ return true;
+ case GB_KEY_BLOCK_RECORDING_KEYUP:
+ if (galaxybook->has_block_recording)
+ schedule_work(&galaxybook->block_recording_hotkey_work);
+ return true;
+
+ /* battery notification already sent to battery + SCAI device */
+ case GB_KEY_BATTERY_NOTIFY_KEYUP:
+ case GB_KEY_BATTERY_NOTIFY_KEYDOWN:
+ return true;
+
+ default:
+ /*
+ * Report the previously filtered e0 before continuing
+ * with the next non-filtered byte.
+ */
+ serio_interrupt(port, 0xe0, 0);
+ return false;
+ }
+ }
+
+ return false;
+}
+
+static void galaxybook_i8042_filter_remove(void *data)
+{
+ struct samsung_galaxybook *galaxybook = data;
+
+ i8042_remove_filter(galaxybook_i8042_filter);
+ cancel_work_sync(&galaxybook->kbd_backlight_hotkey_work);
+ cancel_work_sync(&galaxybook->block_recording_hotkey_work);
+}
+
+static int galaxybook_i8042_filter_install(struct samsung_galaxybook *galaxybook)
+{
+ int err;
+
+ if (!galaxybook->has_kbd_backlight && !galaxybook->has_block_recording)
+ return 0;
+
+ INIT_WORK(&galaxybook->kbd_backlight_hotkey_work,
+ galaxybook_kbd_backlight_hotkey_work);
+ INIT_WORK(&galaxybook->block_recording_hotkey_work,
+ galaxybook_block_recording_hotkey_work);
+
+ err = i8042_install_filter(galaxybook_i8042_filter, galaxybook);
+ if (err)
+ return err;
+
+ return devm_add_action_or_reset(&galaxybook->platform->dev,
+ galaxybook_i8042_filter_remove, galaxybook);
+}
+
+/*
+ * ACPI device setup
+ */
+
+static void galaxybook_acpi_notify(acpi_handle handle, u32 event, void *data)
+{
+ struct samsung_galaxybook *galaxybook = data;
+
+ switch (event) {
+ case GB_ACPI_NOTIFY_BATTERY_STATE_CHANGED:
+ case GB_ACPI_NOTIFY_DEVICE_ON_TABLE:
+ case GB_ACPI_NOTIFY_DEVICE_OFF_TABLE:
+ break;
+ case GB_ACPI_NOTIFY_HOTKEY_PERFORMANCE_MODE:
+ if (galaxybook->has_performance_mode)
+ platform_profile_cycle();
+ break;
+ default:
+ dev_warn(&galaxybook->platform->dev,
+ "unknown ACPI notification event: 0x%x\n", event);
+ }
+
+ acpi_bus_generate_netlink_event(DRIVER_NAME, dev_name(&galaxybook->platform->dev),
+ event, 1);
+}
+
+static int galaxybook_enable_acpi_notify(struct samsung_galaxybook *galaxybook)
+{
+ struct sawb buf = {};
+ int err;
+
+ err = galaxybook_enable_acpi_feature(galaxybook, GB_SASB_NOTIFICATIONS);
+ if (err)
+ return err;
+
+ buf.safn = GB_SAFN;
+ buf.sasb = GB_SASB_NOTIFICATIONS;
+ buf.gunm = GB_GUNM_ACPI_NOTIFY_ENABLE;
+ buf.guds[0] = GB_GUDS_ACPI_NOTIFY_ENABLE;
+
+ return galaxybook_acpi_method(galaxybook, GB_ACPI_METHOD_SETTINGS,
+ &buf, GB_SAWB_LEN_SETTINGS);
+}
+
+static void galaxybook_acpi_remove_notify_handler(void *data)
+{
+ struct samsung_galaxybook *galaxybook = data;
+
+ acpi_remove_notify_handler(galaxybook->acpi->handle, ACPI_ALL_NOTIFY,
+ galaxybook_acpi_notify);
+}
+
+static void galaxybook_acpi_disable(void *data)
+{
+ struct samsung_galaxybook *galaxybook = data;
+
+ acpi_execute_simple_method(galaxybook->acpi->handle,
+ GB_ACPI_METHOD_ENABLE, GB_ACPI_METHOD_ENABLE_OFF);
+}
+
+static int galaxybook_acpi_init(struct samsung_galaxybook *galaxybook)
+{
+ acpi_status status;
+ int err;
+
+ status = acpi_execute_simple_method(galaxybook->acpi->handle, GB_ACPI_METHOD_ENABLE,
+ GB_ACPI_METHOD_ENABLE_ON);
+ if (ACPI_FAILURE(status))
+ return -EIO;
+ err = devm_add_action_or_reset(&galaxybook->platform->dev,
+ galaxybook_acpi_disable, galaxybook);
+ if (err)
+ return err;
+
+ status = acpi_install_notify_handler(galaxybook->acpi->handle, ACPI_ALL_NOTIFY,
+ galaxybook_acpi_notify, galaxybook);
+ if (ACPI_FAILURE(status))
+ return -EIO;
+ err = devm_add_action_or_reset(&galaxybook->platform->dev,
+ galaxybook_acpi_remove_notify_handler, galaxybook);
+ if (err)
+ return err;
+
+ err = galaxybook_enable_acpi_notify(galaxybook);
+ if (err)
+ dev_dbg(&galaxybook->platform->dev, "failed to enable ACPI notifications; "
+ "some hotkeys will not be supported\n");
+
+ err = galaxybook_enable_acpi_feature(galaxybook, GB_SASB_POWER_MANAGEMENT);
+ if (err)
+ dev_dbg(&galaxybook->platform->dev,
+ "failed to initialize ACPI power management features; "
+ "many features of this driver will not be available\n");
+
+ return 0;
+}
+
+/*
+ * Platform driver
+ */
+
+static int galaxybook_probe(struct platform_device *pdev)
+{
+ struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
+ struct samsung_galaxybook *galaxybook;
+ int err;
+
+ if (!adev)
+ return -ENODEV;
+
+ galaxybook = devm_kzalloc(&pdev->dev, sizeof(*galaxybook), GFP_KERNEL);
+ if (!galaxybook)
+ return -ENOMEM;
+
+ galaxybook->platform = pdev;
+ galaxybook->acpi = adev;
+
+ /*
+ * Features must be enabled and initialized in the following order to
+ * avoid failures seen on certain devices:
+ * - GB_SASB_POWER_MANAGEMENT (including performance mode)
+ * - GB_SASB_KBD_BACKLIGHT
+ * - GB_SASB_BLOCK_RECORDING (as part of fw_attrs init)
+ */
+
+ err = galaxybook_acpi_init(galaxybook);
+ if (err)
+ return dev_err_probe(&galaxybook->platform->dev, err,
+ "failed to initialize ACPI device\n");
+
+ err = galaxybook_platform_profile_init(galaxybook);
+ if (!err)
+ galaxybook->has_performance_mode = true;
+ else if (err != GB_NOT_SUPPORTED)
+ return dev_err_probe(&galaxybook->platform->dev, err,
+ "failed to initialize platform profile\n");
+
+ err = galaxybook_battery_threshold_init(galaxybook);
+ if (err)
+ return dev_err_probe(&galaxybook->platform->dev, err,
+ "failed to initialize battery threshold\n");
+
+ err = galaxybook_kbd_backlight_init(galaxybook);
+ if (!err)
+ galaxybook->has_kbd_backlight = true;
+ else if (err != GB_NOT_SUPPORTED)
+ return dev_err_probe(&galaxybook->platform->dev, err,
+ "failed to initialize kbd_backlight\n");
+
+ err = galaxybook_fw_attrs_init(galaxybook);
+ if (err)
+ return dev_err_probe(&galaxybook->platform->dev, err,
+ "failed to initialize firmware-attributes\n");
+
+ err = galaxybook_i8042_filter_install(galaxybook);
+ if (err)
+ return dev_err_probe(&galaxybook->platform->dev, err,
+ "failed to initialize i8042_filter\n");
+
+ return 0;
+}
+
+static const struct acpi_device_id galaxybook_device_ids[] = {
+ { "SAM0427" },
+ { "SAM0428" },
+ { "SAM0429" },
+ { "SAM0430" },
+ {}
+};
+MODULE_DEVICE_TABLE(acpi, galaxybook_device_ids);
+
+static struct platform_driver galaxybook_platform_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .acpi_match_table = galaxybook_device_ids,
+ },
+ .probe = galaxybook_probe,
+};
+module_platform_driver(galaxybook_platform_driver);
+
+MODULE_AUTHOR("Joshua Grisham <josh@joshuagrisham.com>");
+MODULE_DESCRIPTION("Samsung Galaxy Book driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c
index 323316ac6783..0fc275e461be 100644
--- a/drivers/platform/x86/think-lmi.c
+++ b/drivers/platform/x86/think-lmi.c
@@ -262,16 +262,11 @@ static int tlmi_simple_call(const char *guid, const char *arg)
return 0;
}
-/* Extract output string from WMI return buffer */
-static int tlmi_extract_output_string(const struct acpi_buffer *output,
- char **string)
+/* Extract output string from WMI return value */
+static int tlmi_extract_output_string(union acpi_object *obj, char **string)
{
- const union acpi_object *obj;
char *s;
- obj = output->pointer;
- if (!obj)
- return -ENOMEM;
if (obj->type != ACPI_TYPE_STRING || !obj->string.pointer)
return -EIO;
@@ -349,20 +344,18 @@ static int tlmi_opcode_setting(char *setting, const char *value)
return ret;
}
-static int tlmi_setting(int item, char **value, const char *guid_string)
+static int tlmi_setting(struct wmi_device *wdev, int item, char **value)
{
- struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
- acpi_status status;
+ union acpi_object *obj;
int ret;
- status = wmi_query_block(guid_string, item, &output);
- if (ACPI_FAILURE(status)) {
- kfree(output.pointer);
+ obj = wmidev_block_query(wdev, item);
+ if (!obj)
return -EIO;
- }
- ret = tlmi_extract_output_string(&output, value);
- kfree(output.pointer);
+ ret = tlmi_extract_output_string(obj, value);
+ kfree(obj);
+
return ret;
}
@@ -370,19 +363,22 @@ static int tlmi_get_bios_selections(const char *item, char **value)
{
const struct acpi_buffer input = { strlen(item), (char *)item };
struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *obj;
acpi_status status;
int ret;
status = wmi_evaluate_method(LENOVO_GET_BIOS_SELECTIONS_GUID,
0, 0, &input, &output);
-
- if (ACPI_FAILURE(status)) {
- kfree(output.pointer);
+ if (ACPI_FAILURE(status))
return -EIO;
- }
- ret = tlmi_extract_output_string(&output, value);
- kfree(output.pointer);
+ obj = output.pointer;
+ if (!obj)
+ return -ENODATA;
+
+ ret = tlmi_extract_output_string(obj, value);
+ kfree(obj);
+
return ret;
}
@@ -993,7 +989,7 @@ static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *a
char *item, *value;
int ret;
- ret = tlmi_setting(setting->index, &item, LENOVO_BIOS_SETTING_GUID);
+ ret = tlmi_setting(setting->wdev, setting->index, &item);
if (ret)
return ret;
@@ -1586,7 +1582,7 @@ static struct tlmi_pwd_setting *tlmi_create_auth(const char *pwd_type,
return new_pwd;
}
-static int tlmi_analyze(void)
+static int tlmi_analyze(struct wmi_device *wdev)
{
int i, ret;
@@ -1623,7 +1619,7 @@ static int tlmi_analyze(void)
char *item = NULL;
tlmi_priv.setting[i] = NULL;
- ret = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID);
+ ret = tlmi_setting(wdev, i, &item);
if (ret)
break;
if (!item)
@@ -1646,6 +1642,7 @@ static int tlmi_analyze(void)
kfree(item);
goto fail_clear_attr;
}
+ setting->wdev = wdev;
setting->index = i;
strscpy(setting->display_name, item);
/* If BIOS selections supported, load those */
@@ -1664,7 +1661,7 @@ static int tlmi_analyze(void)
*/
char *optitem, *optstart, *optend;
- if (!tlmi_setting(setting->index, &optitem, LENOVO_BIOS_SETTING_GUID)) {
+ if (!tlmi_setting(setting->wdev, setting->index, &optitem)) {
optstart = strstr(optitem, "[Optional:");
if (optstart) {
optstart += strlen("[Optional:");
@@ -1789,7 +1786,7 @@ static int tlmi_probe(struct wmi_device *wdev, const void *context)
{
int ret;
- ret = tlmi_analyze();
+ ret = tlmi_analyze(wdev);
if (ret)
return ret;
diff --git a/drivers/platform/x86/think-lmi.h b/drivers/platform/x86/think-lmi.h
index f267d8b46957..a80452482227 100644
--- a/drivers/platform/x86/think-lmi.h
+++ b/drivers/platform/x86/think-lmi.h
@@ -4,6 +4,7 @@
#define _THINK_LMI_H_
#include <linux/types.h>
+#include <linux/wmi.h>
#define TLMI_SETTINGS_COUNT 256
#define TLMI_SETTINGS_MAXLEN 512
@@ -87,6 +88,7 @@ struct tlmi_pwd_setting {
/* Attribute setting details */
struct tlmi_attr_setting {
struct kobject kobj;
+ struct wmi_device *wdev;
int index;
char display_name[TLMI_SETTINGS_MAXLEN];
char *possible_values;
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index 1cc91173e012..0384cf311878 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -39,7 +39,6 @@
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/dmi.h>
-#include <linux/fb.h>
#include <linux/freezer.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
@@ -368,9 +367,6 @@ static struct {
u32 beep_needs_two_args:1;
u32 mixer_no_level_control:1;
u32 battery_force_primary:1;
- u32 input_device_registered:1;
- u32 platform_drv_registered:1;
- u32 sensors_pdrv_registered:1;
u32 hotkey_poll_active:1;
u32 has_adaptive_kbd:1;
u32 kbd_lang:1;
@@ -8513,7 +8509,7 @@ static void fan_watchdog_reset(void)
if (fan_watchdog_maxinterval > 0 &&
tpacpi_lifecycle != TPACPI_LIFE_EXITING)
mod_delayed_work(tpacpi_wq, &fan_watchdog_task,
- msecs_to_jiffies(fan_watchdog_maxinterval * 1000));
+ secs_to_jiffies(fan_watchdog_maxinterval));
else
cancel_delayed_work(&fan_watchdog_task);
}
@@ -11817,36 +11813,18 @@ MODULE_PARM_DESC(profile_force, "Force profile mode. -1=off, 1=MMC, 2=PSC");
static void thinkpad_acpi_module_exit(void)
{
- struct ibm_struct *ibm, *itmp;
-
tpacpi_lifecycle = TPACPI_LIFE_EXITING;
- if (tpacpi_hwmon)
- hwmon_device_unregister(tpacpi_hwmon);
- if (tp_features.sensors_pdrv_registered)
+ if (tpacpi_sensors_pdev) {
platform_driver_unregister(&tpacpi_hwmon_pdriver);
- if (tp_features.platform_drv_registered)
- platform_driver_unregister(&tpacpi_pdriver);
-
- list_for_each_entry_safe_reverse(ibm, itmp,
- &tpacpi_all_drivers,
- all_drivers) {
- ibm_exit(ibm);
+ platform_device_unregister(tpacpi_sensors_pdev);
}
- dbg_printk(TPACPI_DBG_INIT, "finished subdriver exit path...\n");
-
- if (tpacpi_inputdev) {
- if (tp_features.input_device_registered)
- input_unregister_device(tpacpi_inputdev);
- else
- input_free_device(tpacpi_inputdev);
+ if (tpacpi_pdev) {
+ platform_driver_unregister(&tpacpi_pdriver);
+ platform_device_unregister(tpacpi_pdev);
}
- if (tpacpi_sensors_pdev)
- platform_device_unregister(tpacpi_sensors_pdev);
- if (tpacpi_pdev)
- platform_device_unregister(tpacpi_pdev);
if (proc_dir)
remove_proc_entry(TPACPI_PROC_DIR, acpi_root_dir);
if (tpacpi_wq)
@@ -11858,11 +11836,76 @@ static void thinkpad_acpi_module_exit(void)
kfree(thinkpad_id.nummodel_str);
}
+static void tpacpi_subdrivers_release(void *data)
+{
+ struct ibm_struct *ibm, *itmp;
+
+ list_for_each_entry_safe_reverse(ibm, itmp, &tpacpi_all_drivers, all_drivers)
+ ibm_exit(ibm);
+
+ dbg_printk(TPACPI_DBG_INIT, "finished subdriver exit path...\n");
+}
+
+static int __init tpacpi_pdriver_probe(struct platform_device *pdev)
+{
+ int ret;
+
+ ret = devm_mutex_init(&pdev->dev, &tpacpi_inputdev_send_mutex);
+ if (ret)
+ return ret;
+
+ tpacpi_inputdev = devm_input_allocate_device(&pdev->dev);
+ if (!tpacpi_inputdev)
+ return -ENOMEM;
+
+ tpacpi_inputdev->name = "ThinkPad Extra Buttons";
+ tpacpi_inputdev->phys = TPACPI_DRVR_NAME "/input0";
+ tpacpi_inputdev->id.bustype = BUS_HOST;
+ tpacpi_inputdev->id.vendor = thinkpad_id.vendor;
+ tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT;
+ tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION;
+ tpacpi_inputdev->dev.parent = &tpacpi_pdev->dev;
+
+ /* Init subdriver dependencies */
+ tpacpi_detect_brightness_capabilities();
+
+ /* Init subdrivers */
+ for (unsigned int i = 0; i < ARRAY_SIZE(ibms_init); i++) {
+ ret = ibm_init(&ibms_init[i]);
+ if (ret >= 0 && *ibms_init[i].param)
+ ret = ibms_init[i].data->write(ibms_init[i].param);
+ if (ret < 0) {
+ tpacpi_subdrivers_release(NULL);
+ return ret;
+ }
+ }
+
+ ret = devm_add_action_or_reset(&pdev->dev, tpacpi_subdrivers_release, NULL);
+ if (ret)
+ return ret;
+
+ ret = input_register_device(tpacpi_inputdev);
+ if (ret < 0)
+ pr_err("unable to register input device\n");
+
+ return ret;
+}
+
+static int __init tpacpi_hwmon_pdriver_probe(struct platform_device *pdev)
+{
+ tpacpi_hwmon = devm_hwmon_device_register_with_groups(
+ &tpacpi_sensors_pdev->dev, TPACPI_NAME, NULL, tpacpi_hwmon_groups);
+
+ if (IS_ERR(tpacpi_hwmon))
+ pr_err("unable to register hwmon device\n");
+
+ return PTR_ERR_OR_ZERO(tpacpi_hwmon);
+}
static int __init thinkpad_acpi_module_init(void)
{
const struct dmi_system_id *dmi_id;
- int ret, i;
+ int ret;
acpi_object_type obj_type;
tpacpi_lifecycle = TPACPI_LIFE_INIT;
@@ -11922,93 +11965,29 @@ static int __init thinkpad_acpi_module_init(void)
tp_features.quirks = dmi_id->driver_data;
/* Device initialization */
- tpacpi_pdev = platform_device_register_simple(TPACPI_DRVR_NAME, PLATFORM_DEVID_NONE,
- NULL, 0);
+ tpacpi_pdev = platform_create_bundle(&tpacpi_pdriver, tpacpi_pdriver_probe,
+ NULL, 0, NULL, 0);
if (IS_ERR(tpacpi_pdev)) {
ret = PTR_ERR(tpacpi_pdev);
tpacpi_pdev = NULL;
- pr_err("unable to register platform device\n");
+ pr_err("unable to register platform device/driver bundle\n");
thinkpad_acpi_module_exit();
return ret;
}
- tpacpi_sensors_pdev = platform_device_register_simple(
- TPACPI_HWMON_DRVR_NAME,
- PLATFORM_DEVID_NONE, NULL, 0);
+
+ tpacpi_sensors_pdev = platform_create_bundle(&tpacpi_hwmon_pdriver,
+ tpacpi_hwmon_pdriver_probe,
+ NULL, 0, NULL, 0);
if (IS_ERR(tpacpi_sensors_pdev)) {
ret = PTR_ERR(tpacpi_sensors_pdev);
tpacpi_sensors_pdev = NULL;
- pr_err("unable to register hwmon platform device\n");
+ pr_err("unable to register hwmon platform device/driver bundle\n");
thinkpad_acpi_module_exit();
return ret;
}
- mutex_init(&tpacpi_inputdev_send_mutex);
- tpacpi_inputdev = input_allocate_device();
- if (!tpacpi_inputdev) {
- thinkpad_acpi_module_exit();
- return -ENOMEM;
- } else {
- /* Prepare input device, but don't register */
- tpacpi_inputdev->name = "ThinkPad Extra Buttons";
- tpacpi_inputdev->phys = TPACPI_DRVR_NAME "/input0";
- tpacpi_inputdev->id.bustype = BUS_HOST;
- tpacpi_inputdev->id.vendor = thinkpad_id.vendor;
- tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT;
- tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION;
- tpacpi_inputdev->dev.parent = &tpacpi_pdev->dev;
- }
-
- /* Init subdriver dependencies */
- tpacpi_detect_brightness_capabilities();
-
- /* Init subdrivers */
- for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
- ret = ibm_init(&ibms_init[i]);
- if (ret >= 0 && *ibms_init[i].param)
- ret = ibms_init[i].data->write(ibms_init[i].param);
- if (ret < 0) {
- thinkpad_acpi_module_exit();
- return ret;
- }
- }
-
tpacpi_lifecycle = TPACPI_LIFE_RUNNING;
- ret = platform_driver_register(&tpacpi_pdriver);
- if (ret) {
- pr_err("unable to register main platform driver\n");
- thinkpad_acpi_module_exit();
- return ret;
- }
- tp_features.platform_drv_registered = 1;
-
- ret = platform_driver_register(&tpacpi_hwmon_pdriver);
- if (ret) {
- pr_err("unable to register hwmon platform driver\n");
- thinkpad_acpi_module_exit();
- return ret;
- }
- tp_features.sensors_pdrv_registered = 1;
-
- tpacpi_hwmon = hwmon_device_register_with_groups(
- &tpacpi_sensors_pdev->dev, TPACPI_NAME, NULL, tpacpi_hwmon_groups);
- if (IS_ERR(tpacpi_hwmon)) {
- ret = PTR_ERR(tpacpi_hwmon);
- tpacpi_hwmon = NULL;
- pr_err("unable to register hwmon device\n");
- thinkpad_acpi_module_exit();
- return ret;
- }
-
- ret = input_register_device(tpacpi_inputdev);
- if (ret < 0) {
- pr_err("unable to register input device\n");
- thinkpad_acpi_module_exit();
- return ret;
- } else {
- tp_features.input_device_registered = 1;
- }
-
return 0;
}
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
index 646370bd6b03..e46453750d5f 100644
--- a/drivers/platform/x86/wmi.c
+++ b/drivers/platform/x86/wmi.c
@@ -123,24 +123,6 @@ static const void *find_guid_context(struct wmi_block *wblock,
return NULL;
}
-static acpi_status wmi_method_enable(struct wmi_block *wblock, bool enable)
-{
- struct guid_block *block;
- char method[5];
- acpi_status status;
- acpi_handle handle;
-
- block = &wblock->gblock;
- handle = wblock->acpi_device->handle;
-
- snprintf(method, 5, "WE%02X", block->notify_id);
- status = acpi_execute_simple_method(handle, method, enable);
- if (status == AE_NOT_FOUND)
- return AE_OK;
-
- return status;
-}
-
#define WMI_ACPI_METHOD_NAME_SIZE 5
static inline void get_acpi_method_name(const struct wmi_block *wblock,
@@ -184,6 +166,44 @@ static int wmidev_match_guid(struct device *dev, const void *data)
static const struct bus_type wmi_bus_type;
+static const struct device_type wmi_type_event;
+
+static const struct device_type wmi_type_method;
+
+static int wmi_device_enable(struct wmi_device *wdev, bool enable)
+{
+ struct wmi_block *wblock = container_of(wdev, struct wmi_block, dev);
+ char method[WMI_ACPI_METHOD_NAME_SIZE];
+ acpi_handle handle;
+ acpi_status status;
+
+ if (!(wblock->gblock.flags & ACPI_WMI_EXPENSIVE))
+ return 0;
+
+ if (wblock->dev.dev.type == &wmi_type_method)
+ return 0;
+
+ if (wblock->dev.dev.type == &wmi_type_event)
+ snprintf(method, sizeof(method), "WE%02X", wblock->gblock.notify_id);
+ else
+ get_acpi_method_name(wblock, 'C', method);
+
+ /*
+ * Not all WMI devices marked as expensive actually implement the
+ * necessary ACPI method. Ignore this missing ACPI method to match
+ * the behaviour of the Windows driver.
+ */
+ status = acpi_get_handle(wblock->acpi_device->handle, method, &handle);
+ if (ACPI_FAILURE(status))
+ return 0;
+
+ status = acpi_execute_simple_method(handle, NULL, enable);
+ if (ACPI_FAILURE(status))
+ return -EIO;
+
+ return 0;
+}
+
static struct wmi_device *wmi_find_device_by_guid(const char *guid_string)
{
struct device *dev;
@@ -337,10 +357,8 @@ static acpi_status __query_block(struct wmi_block *wblock, u8 instance,
{
struct guid_block *block;
acpi_handle handle;
- acpi_status status, wc_status = AE_ERROR;
struct acpi_object_list input;
union acpi_object wq_params[1];
- char wc_method[WMI_ACPI_METHOD_NAME_SIZE];
char method[WMI_ACPI_METHOD_NAME_SIZE];
if (!out)
@@ -364,40 +382,9 @@ static acpi_status __query_block(struct wmi_block *wblock, u8 instance,
if (instance == 0 && test_bit(WMI_READ_TAKES_NO_ARGS, &wblock->flags))
input.count = 0;
- /*
- * If ACPI_WMI_EXPENSIVE, call the relevant WCxx method first to
- * enable collection.
- */
- if (block->flags & ACPI_WMI_EXPENSIVE) {
- get_acpi_method_name(wblock, 'C', wc_method);
-
- /*
- * Some GUIDs break the specification by declaring themselves
- * expensive, but have no corresponding WCxx method. So we
- * should not fail if this happens.
- */
- wc_status = acpi_execute_simple_method(handle, wc_method, 1);
- }
-
get_acpi_method_name(wblock, 'Q', method);
- status = acpi_evaluate_object(handle, method, &input, out);
-
- /*
- * If ACPI_WMI_EXPENSIVE, call the relevant WCxx method, even if
- * the WQxx method failed - we should disable collection anyway.
- */
- if ((block->flags & ACPI_WMI_EXPENSIVE) && ACPI_SUCCESS(wc_status)) {
- /*
- * Ignore whether this WCxx call succeeds or not since
- * the previously executed WQxx method call might have
- * succeeded, and returning the failing status code
- * of this call would throw away the result of the WQxx
- * call, potentially leaking memory.
- */
- acpi_execute_simple_method(handle, wc_method, 0);
- }
- return status;
+ return acpi_evaluate_object(handle, method, &input, out);
}
/**
@@ -421,9 +408,15 @@ acpi_status wmi_query_block(const char *guid_string, u8 instance,
if (IS_ERR(wdev))
return AE_ERROR;
+ if (wmi_device_enable(wdev, true) < 0)
+ dev_warn(&wdev->dev, "Failed to enable device\n");
+
wblock = container_of(wdev, struct wmi_block, dev);
status = __query_block(wblock, instance, out);
+ if (wmi_device_enable(wdev, false) < 0)
+ dev_warn(&wdev->dev, "Failed to disable device\n");
+
wmi_device_put(wdev);
return status;
@@ -470,7 +463,14 @@ acpi_status wmi_set_block(const char *guid_string, u8 instance, const struct acp
if (IS_ERR(wdev))
return AE_ERROR;
+ if (wmi_device_enable(wdev, true) < 0)
+ dev_warn(&wdev->dev, "Failed to enable device\n");
+
status = wmidev_block_set(wdev, instance, in);
+
+ if (wmi_device_enable(wdev, false) < 0)
+ dev_warn(&wdev->dev, "Failed to disable device\n");
+
wmi_device_put(wdev);
return status;
@@ -551,7 +551,7 @@ acpi_status wmi_install_notify_handler(const char *guid,
wblock->handler = handler;
wblock->handler_data = data;
- if (ACPI_FAILURE(wmi_method_enable(wblock, true)))
+ if (wmi_device_enable(wdev, true) < 0)
dev_warn(&wblock->dev.dev, "Failed to enable device\n");
status = AE_OK;
@@ -588,7 +588,7 @@ acpi_status wmi_remove_notify_handler(const char *guid)
if (!wblock->handler) {
status = AE_NULL_ENTRY;
} else {
- if (ACPI_FAILURE(wmi_method_enable(wblock, false)))
+ if (wmi_device_enable(wdev, false) < 0)
dev_warn(&wblock->dev.dev, "Failed to disable device\n");
wblock->handler = NULL;
@@ -821,11 +821,19 @@ static int wmi_dev_match(struct device *dev, const struct device_driver *driver)
return 0;
}
+static void wmi_dev_disable(void *data)
+{
+ struct device *dev = data;
+
+ if (wmi_device_enable(to_wmi_device(dev), false) < 0)
+ dev_warn(dev, "Failed to disable device\n");
+}
+
static int wmi_dev_probe(struct device *dev)
{
struct wmi_block *wblock = dev_to_wblock(dev);
struct wmi_driver *wdriver = to_wmi_driver(dev->driver);
- int ret = 0;
+ int ret;
/* Some older WMI drivers will break if instantiated multiple times,
* so they are blocked from probing WMI devices with a duplicated GUID.
@@ -844,18 +852,22 @@ static int wmi_dev_probe(struct device *dev)
return -ENODEV;
}
- if (ACPI_FAILURE(wmi_method_enable(wblock, true)))
+ if (wmi_device_enable(to_wmi_device(dev), true) < 0)
dev_warn(dev, "failed to enable device -- probing anyway\n");
+ /*
+ * We have to make sure that all devres-managed resources are released first because
+ * some might still want to access the underlying WMI device.
+ */
+ ret = devm_add_action_or_reset(dev, wmi_dev_disable, dev);
+ if (ret < 0)
+ return ret;
+
if (wdriver->probe) {
ret = wdriver->probe(to_wmi_device(dev),
find_guid_context(wblock, wdriver));
- if (ret) {
- if (ACPI_FAILURE(wmi_method_enable(wblock, false)))
- dev_warn(dev, "Failed to disable device\n");
-
+ if (ret)
return ret;
- }
}
down_write(&wblock->notify_lock);
@@ -876,9 +888,6 @@ static void wmi_dev_remove(struct device *dev)
if (wdriver->remove)
wdriver->remove(to_wmi_device(dev));
-
- if (ACPI_FAILURE(wmi_method_enable(wblock, false)))
- dev_warn(dev, "failed to disable device\n");
}
static void wmi_dev_shutdown(struct device *dev)
@@ -902,7 +911,11 @@ static void wmi_dev_shutdown(struct device *dev)
if (wdriver->shutdown)
wdriver->shutdown(to_wmi_device(dev));
- if (ACPI_FAILURE(wmi_method_enable(wblock, false)))
+ /*
+ * We still need to disable the WMI device here since devres-managed resources
+ * like wmi_dev_disable() will not be release during shutdown.
+ */
+ if (wmi_device_enable(to_wmi_device(dev), false) < 0)
dev_warn(dev, "Failed to disable device\n");
}
}
diff --git a/drivers/platform/x86/x86-android-tablets/Kconfig b/drivers/platform/x86/x86-android-tablets/Kconfig
index a67bddc43007..193da15ee01c 100644
--- a/drivers/platform/x86/x86-android-tablets/Kconfig
+++ b/drivers/platform/x86/x86-android-tablets/Kconfig
@@ -10,6 +10,7 @@ config X86_ANDROID_TABLETS
depends on ACPI && EFI && PCI
select NEW_LEDS
select LEDS_CLASS
+ select POWER_SUPPLY
help
X86 tablets which ship with Android as (part of) the factory image
typically have various problems with their DSDTs. The factory kernels