Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'platform-drivers-x86-v6.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86

Pull x86 platform driver updates from Hans de Goede:

- Intel:
- PMC: Add support for Meteor Lake
- Intel On Demand: various updates

- Ideapad-laptop:
- Add support for various Fn keys on new models
- Fix touchpad on/off handling in a generic way to avoid having to
add more and more quirks

- Android x86 tablets:
- Add support for two more X86 Android tablet models

- New Dell WMI DDV driver

- Miscellaneous cleanups and small bugfixes

* tag 'platform-drivers-x86-v6.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86: (52 commits)
platform/mellanox: mlxbf-pmc: Fix event typo
platform/x86: intel_scu_ipc: fix possible name leak in __intel_scu_ipc_register()
platform/x86: sony-laptop: Convert to use sysfs_emit_at() API
platform/x86/dell: alienware-wmi: Use sysfs_emit() instead of scnprintf()
platform/x86: uv_sysfs: Use sysfs_emit() instead of scnprintf()
platform/x86: mxm-wmi: fix memleak in mxm_wmi_call_mx[ds|mx]()
platform/x86: x86-android-tablets: Add Advantech MICA-071 extra button
platform/x86: x86-android-tablets: Add Lenovo Yoga Tab 3 (YT3-X90F) charger + fuel-gauge data
platform/x86: x86-android-tablets: Add Medion Lifetab S10346 data
platform/x86: wireless-hotkey: use ACPI HID as phys
platform/x86/intel/hid: Add module-params for 5 button array + SW_TABLET_MODE reporting
platform/x86: ideapad-laptop: Make touchpad_ctrl_via_ec a module option
platform/x86: ideapad-laptop: Stop writing VPCCMD_W_TOUCHPAD at probe time
platform/x86: ideapad-laptop: Send KEY_TOUCHPAD_TOGGLE on some models
platform/x86: ideapad-laptop: Only toggle ps2 aux port on/off on select models
platform/x86: ideapad-laptop: Do not send KEY_TOUCHPAD* events on probe / resume
platform/x86: ideapad-laptop: Refactor ideapad_sync_touchpad_state()
tools/arch/x86: intel_sdsi: Add support for reading meter certificates
tools/arch/x86: intel_sdsi: Add support for new GUID
tools/arch/x86: intel_sdsi: Read more On Demand registers
...

+3079 -1457
+21
Documentation/ABI/testing/debugfs-dell-wmi-ddv
··· 1 + What: /sys/kernel/debug/dell-wmi-ddv-<wmi_device_name>/fan_sensor_information 2 + Date: September 2022 3 + KernelVersion: 6.1 4 + Contact: Armin Wolf <W_Armin@gmx.de> 5 + Description: 6 + This file contains the contents of the fan sensor information buffer, 7 + which contains fan sensor entries and a terminating character (0xFF). 8 + 9 + Each fan sensor entry consists of three bytes with an unknown meaning, 10 + interested people may use this file for reverse-engineering. 11 + 12 + What: /sys/kernel/debug/dell-wmi-ddv-<wmi_device_name>/thermal_sensor_information 13 + Date: September 2022 14 + KernelVersion: 6.1 15 + Contact: Armin Wolf <W_Armin@gmx.de> 16 + Description: 17 + This file contains the contents of the thermal sensor information buffer, 18 + which contains thermal sensor entries and a terminating character (0xFF). 19 + 20 + Each thermal sensor entry consists of five bytes with an unknown meaning, 21 + interested people may use this file for reverse-engineering.
+29 -18
Documentation/ABI/testing/sysfs-driver-intel_sdsi
··· 4 4 Contact: "David E. Box" <david.e.box@linux.intel.com> 5 5 Description: 6 6 This directory contains interface files for accessing Intel 7 - Software Defined Silicon (SDSi) features on a CPU. X 8 - represents the socket instance (though not the socket ID). 9 - The socket ID is determined by reading the registers file 10 - and decoding it per the specification. 7 + On Demand (formerly Software Defined Silicon or SDSi) features 8 + on a CPU. X represents the socket instance (though not the 9 + socket ID). The socket ID is determined by reading the 10 + registers file and decoding it per the specification. 11 11 12 - Some files communicate with SDSi hardware through a mailbox. 13 - Should the operation fail, one of the following error codes 14 - may be returned: 12 + Some files communicate with On Demand hardware through a 13 + mailbox. Should the operation fail, one of the following error 14 + codes may be returned: 15 15 16 16 ========== ===== 17 17 Error Code Cause 18 18 ========== ===== 19 19 EIO General mailbox failure. Log may indicate cause. 20 20 EBUSY Mailbox is owned by another agent. 21 - EPERM SDSI capability is not enabled in hardware. 21 + EPERM On Demand capability is not enabled in hardware. 22 22 EPROTO Failure in mailbox protocol detected by driver. 23 23 See log for details. 24 24 EOVERFLOW For provision commands, the size of the data ··· 54 54 Contact: "David E. Box" <david.e.box@linux.intel.com> 55 55 Description: 56 56 (WO) Used to write an Authentication Key Certificate (AKC) to 57 - the SDSi NVRAM for the CPU. The AKC is used to authenticate a 58 - Capability Activation Payload. Mailbox command. 57 + the On Demand NVRAM for the CPU. The AKC is used to authenticate 58 + a Capability Activation Payload. Mailbox command. 59 59 60 60 What: /sys/bus/auxiliary/devices/intel_vsec.sdsi.X/provision_cap 61 61 Date: Feb 2022 ··· 63 63 Contact: "David E. Box" <david.e.box@linux.intel.com> 64 64 Description: 65 65 (WO) Used to write a Capability Activation Payload (CAP) to the 66 - SDSi NVRAM for the CPU. CAPs are used to activate a given CPU 67 - feature. A CAP is validated by SDSi hardware using a previously 68 - provisioned AKC file. Upon successful authentication, the CPU 69 - configuration is updated. A cold reboot is required to fully 70 - activate the feature. Mailbox command. 66 + On Demand NVRAM for the CPU. CAPs are used to activate a given 67 + CPU feature. A CAP is validated by On Demand hardware using a 68 + previously provisioned AKC file. Upon successful authentication, 69 + the CPU configuration is updated. A cold reboot is required to 70 + fully activate the feature. Mailbox command. 71 + 72 + What: /sys/bus/auxiliary/devices/intel_vsec.sdsi.X/meter_certificate 73 + Date: Nov 2022 74 + KernelVersion: 6.2 75 + Contact: "David E. Box" <david.e.box@linux.intel.com> 76 + Description: 77 + (RO) Used to read back the current meter certificate for the CPU 78 + from Intel On Demand hardware. The meter certificate contains 79 + utilization metrics of On Demand enabled features. Mailbox 80 + command. 71 81 72 82 What: /sys/bus/auxiliary/devices/intel_vsec.sdsi.X/state_certificate 73 83 Date: Feb 2022 74 84 KernelVersion: 5.18 75 85 Contact: "David E. Box" <david.e.box@linux.intel.com> 76 86 Description: 77 - (RO) Used to read back the current State Certificate for the CPU 78 - from SDSi hardware. The State Certificate contains information 79 - about the current licenses on the CPU. Mailbox command. 87 + (RO) Used to read back the current state certificate for the CPU 88 + from On Demand hardware. The state certificate contains 89 + information about the current licenses on the CPU. Mailbox 90 + command.
+7
Documentation/ABI/testing/sysfs-platform-dell-wmi-ddv
··· 1 + What: /sys/class/power_supply/<battery_name>/eppid 2 + Date: September 2022 3 + KernelVersion: 6.1 4 + Contact: Armin Wolf <W_Armin@gmx.de> 5 + Description: 6 + Reports the Dell ePPID (electronic Dell Piece Part Identification) 7 + of the ACPI battery.
+9 -2
MAINTAINERS
··· 5867 5867 S: Maintained 5868 5868 F: drivers/platform/x86/dell/dell-wmi-descriptor.c 5869 5869 5870 + DELL WMI DDV DRIVER 5871 + M: Armin Wolf <W_Armin@gmx.de> 5872 + S: Maintained 5873 + F: Documentation/ABI/testing/debugfs-dell-wmi-ddv 5874 + F: Documentation/ABI/testing/sysfs-platform-dell-wmi-ddv 5875 + F: drivers/platform/x86/dell/dell-wmi-ddv.c 5876 + 5870 5877 DELL WMI SYSMAN DRIVER 5871 5878 M: Divya Bharathi <divya.bharathi@dell.com> 5872 5879 M: Prasanth Ksr <prasanth.ksr@dell.com> ··· 9383 9376 HP COMPAQ TC1100 TABLET WMI EXTRAS DRIVER 9384 9377 L: platform-driver-x86@vger.kernel.org 9385 9378 S: Orphan 9386 - F: drivers/platform/x86/tc1100-wmi.c 9379 + F: drivers/platform/x86/hp/tc1100-wmi.c 9387 9380 9388 9381 HPET: High Precision Event Timers driver 9389 9382 M: Clemens Ladisch <clemens@ladisch.de> ··· 11877 11870 S: Maintained 11878 11871 F: Documentation/misc-devices/lis3lv02d.rst 11879 11872 F: drivers/misc/lis3lv02d/ 11880 - F: drivers/platform/x86/hp_accel.c 11873 + F: drivers/platform/x86/hp/hp_accel.c 11881 11874 11882 11875 LIST KUNIT TEST 11883 11876 M: David Gow <davidgow@google.com>
+4 -4
drivers/acpi/battery.c
··· 696 696 if (lock) 697 697 mutex_lock(&hook_mutex); 698 698 list_for_each_entry(battery, &acpi_battery_list, list) { 699 - hook->remove_battery(battery->bat); 699 + hook->remove_battery(battery->bat, hook); 700 700 } 701 701 list_del(&hook->list); 702 702 if (lock) ··· 724 724 * its attributes. 725 725 */ 726 726 list_for_each_entry(battery, &acpi_battery_list, list) { 727 - if (hook->add_battery(battery->bat)) { 727 + if (hook->add_battery(battery->bat, hook)) { 728 728 /* 729 729 * If a add-battery returns non-zero, 730 730 * the registration of the extension has failed, ··· 762 762 * during the battery module initialization. 763 763 */ 764 764 list_for_each_entry_safe(hook_node, tmp, &battery_hook_list, list) { 765 - if (hook_node->add_battery(battery->bat)) { 765 + if (hook_node->add_battery(battery->bat, hook_node)) { 766 766 /* 767 767 * The notification of the extensions has failed, to 768 768 * prevent further errors we will unload the extension. ··· 785 785 * custom attributes from the battery. 786 786 */ 787 787 list_for_each_entry(hook, &battery_hook_list, list) { 788 - hook->remove_battery(battery->bat); 788 + hook->remove_battery(battery->bat, hook); 789 789 } 790 790 /* Then, just remove the battery from the list */ 791 791 list_del(&battery->list);
+1 -1
drivers/platform/mellanox/mlxbf-pmc.c
··· 358 358 { 0x32, "DDN_DIAG_W_INGRESS" }, 359 359 { 0x33, "DDN_DIAG_C_INGRESS" }, 360 360 { 0x34, "DDN_DIAG_CORE_SENT" }, 361 - { 0x35, "NDN_DIAG_S_OUT_OF_CRED" }, 361 + { 0x35, "NDN_DIAG_N_OUT_OF_CRED" }, 362 362 { 0x36, "NDN_DIAG_S_OUT_OF_CRED" }, 363 363 { 0x37, "NDN_DIAG_E_OUT_OF_CRED" }, 364 364 { 0x38, "NDN_DIAG_W_OUT_OF_CRED" },
+10
drivers/platform/mellanox/mlxbf-tmfifo-regs.h
··· 60 60 #define MLXBF_TMFIFO_RX_CTL__MAX_ENTRIES_RMASK GENMASK_ULL(8, 0) 61 61 #define MLXBF_TMFIFO_RX_CTL__MAX_ENTRIES_MASK GENMASK_ULL(40, 32) 62 62 63 + /* BF3 register offsets within resource 0. */ 64 + #define MLXBF_TMFIFO_RX_DATA_BF3 0x0000 65 + #define MLXBF_TMFIFO_TX_DATA_BF3 0x1000 66 + 67 + /* BF3 register offsets within resource 1. */ 68 + #define MLXBF_TMFIFO_RX_STS_BF3 0x0000 69 + #define MLXBF_TMFIFO_RX_CTL_BF3 0x0008 70 + #define MLXBF_TMFIFO_TX_STS_BF3 0x0100 71 + #define MLXBF_TMFIFO_TX_CTL_BF3 0x0108 72 + 63 73 #endif /* !defined(__MLXBF_TMFIFO_REGS_H__) */
+64 -22
drivers/platform/mellanox/mlxbf-tmfifo.c
··· 47 47 /* Message with data needs at least two words (for header & data). */ 48 48 #define MLXBF_TMFIFO_DATA_MIN_WORDS 2 49 49 50 + /* ACPI UID for BlueField-3. */ 51 + #define TMFIFO_BF3_UID 1 52 + 50 53 struct mlxbf_tmfifo; 51 54 52 55 /** ··· 140 137 }; 141 138 142 139 /** 140 + * mlxbf_tmfifo_io - Structure of the TmFifo IO resource (for both rx & tx) 141 + * @ctl: control register offset (TMFIFO_RX_CTL / TMFIFO_TX_CTL) 142 + * @sts: status register offset (TMFIFO_RX_STS / TMFIFO_TX_STS) 143 + * @data: data register offset (TMFIFO_RX_DATA / TMFIFO_TX_DATA) 144 + */ 145 + struct mlxbf_tmfifo_io { 146 + void __iomem *ctl; 147 + void __iomem *sts; 148 + void __iomem *data; 149 + }; 150 + 151 + /** 143 152 * mlxbf_tmfifo - Structure of the TmFifo 144 153 * @vdev: array of the virtual devices running over the TmFifo 145 154 * @lock: lock to protect the TmFifo access 146 - * @rx_base: mapped register base address for the Rx FIFO 147 - * @tx_base: mapped register base address for the Tx FIFO 155 + * @res0: mapped resource block 0 156 + * @res1: mapped resource block 1 157 + * @rx: rx io resource 158 + * @tx: tx io resource 148 159 * @rx_fifo_size: number of entries of the Rx FIFO 149 160 * @tx_fifo_size: number of entries of the Tx FIFO 150 161 * @pend_events: pending bits for deferred events ··· 172 155 struct mlxbf_tmfifo { 173 156 struct mlxbf_tmfifo_vdev *vdev[MLXBF_TMFIFO_VDEV_MAX]; 174 157 struct mutex lock; /* TmFifo lock */ 175 - void __iomem *rx_base; 176 - void __iomem *tx_base; 158 + void __iomem *res0; 159 + void __iomem *res1; 160 + struct mlxbf_tmfifo_io rx; 161 + struct mlxbf_tmfifo_io tx; 177 162 int rx_fifo_size; 178 163 int tx_fifo_size; 179 164 unsigned long pend_events; ··· 491 472 { 492 473 u64 sts; 493 474 494 - sts = readq(fifo->rx_base + MLXBF_TMFIFO_RX_STS); 475 + sts = readq(fifo->rx.sts); 495 476 return FIELD_GET(MLXBF_TMFIFO_RX_STS__COUNT_MASK, sts); 496 477 } 497 478 ··· 508 489 else 509 490 tx_reserve = 1; 510 491 511 - sts = readq(fifo->tx_base + MLXBF_TMFIFO_TX_STS); 492 + sts = readq(fifo->tx.sts); 512 493 count = FIELD_GET(MLXBF_TMFIFO_TX_STS__COUNT_MASK, sts); 513 494 return fifo->tx_fifo_size - tx_reserve - count; 514 495 } ··· 544 525 /* Write header. */ 545 526 hdr.type = VIRTIO_ID_CONSOLE; 546 527 hdr.len = htons(size); 547 - writeq(*(u64 *)&hdr, fifo->tx_base + MLXBF_TMFIFO_TX_DATA); 528 + writeq(*(u64 *)&hdr, fifo->tx.data); 548 529 549 530 /* Use spin-lock to protect the 'cons->tx_buf'. */ 550 531 spin_lock_irqsave(&fifo->spin_lock[0], flags); ··· 561 542 memcpy((u8 *)&data + seg, cons->tx_buf.buf, 562 543 sizeof(u64) - seg); 563 544 } 564 - writeq(data, fifo->tx_base + MLXBF_TMFIFO_TX_DATA); 545 + writeq(data, fifo->tx.data); 565 546 566 547 if (size >= sizeof(u64)) { 567 548 cons->tx_buf.tail = (cons->tx_buf.tail + sizeof(u64)) % ··· 592 573 593 574 /* Read a word from FIFO for Rx. */ 594 575 if (is_rx) 595 - data = readq(fifo->rx_base + MLXBF_TMFIFO_RX_DATA); 576 + data = readq(fifo->rx.data); 596 577 597 578 if (vring->cur_len + sizeof(u64) <= len) { 598 579 /* The whole word. */ ··· 614 595 615 596 /* Write the word into FIFO for Tx. */ 616 597 if (!is_rx) 617 - writeq(data, fifo->tx_base + MLXBF_TMFIFO_TX_DATA); 598 + writeq(data, fifo->tx.data); 618 599 } 619 600 620 601 /* ··· 636 617 /* Read/Write packet header. */ 637 618 if (is_rx) { 638 619 /* Drain one word from the FIFO. */ 639 - *(u64 *)&hdr = readq(fifo->rx_base + MLXBF_TMFIFO_RX_DATA); 620 + *(u64 *)&hdr = readq(fifo->rx.data); 640 621 641 622 /* Skip the length 0 packets (keepalive). */ 642 623 if (hdr.len == 0) ··· 680 661 hdr.type = (vring->vdev_id == VIRTIO_ID_NET) ? 681 662 VIRTIO_ID_NET : VIRTIO_ID_CONSOLE; 682 663 hdr.len = htons(vring->pkt_len - hdr_len); 683 - writeq(*(u64 *)&hdr, fifo->tx_base + MLXBF_TMFIFO_TX_DATA); 664 + writeq(*(u64 *)&hdr, fifo->tx.data); 684 665 } 685 666 686 667 vring->cur_len = hdr_len; ··· 1176 1157 u64 ctl; 1177 1158 1178 1159 /* Get Tx FIFO size and set the low/high watermark. */ 1179 - ctl = readq(fifo->tx_base + MLXBF_TMFIFO_TX_CTL); 1160 + ctl = readq(fifo->tx.ctl); 1180 1161 fifo->tx_fifo_size = 1181 1162 FIELD_GET(MLXBF_TMFIFO_TX_CTL__MAX_ENTRIES_MASK, ctl); 1182 1163 ctl = (ctl & ~MLXBF_TMFIFO_TX_CTL__LWM_MASK) | ··· 1185 1166 ctl = (ctl & ~MLXBF_TMFIFO_TX_CTL__HWM_MASK) | 1186 1167 FIELD_PREP(MLXBF_TMFIFO_TX_CTL__HWM_MASK, 1187 1168 fifo->tx_fifo_size - 1); 1188 - writeq(ctl, fifo->tx_base + MLXBF_TMFIFO_TX_CTL); 1169 + writeq(ctl, fifo->tx.ctl); 1189 1170 1190 1171 /* Get Rx FIFO size and set the low/high watermark. */ 1191 - ctl = readq(fifo->rx_base + MLXBF_TMFIFO_RX_CTL); 1172 + ctl = readq(fifo->rx.ctl); 1192 1173 fifo->rx_fifo_size = 1193 1174 FIELD_GET(MLXBF_TMFIFO_RX_CTL__MAX_ENTRIES_MASK, ctl); 1194 1175 ctl = (ctl & ~MLXBF_TMFIFO_RX_CTL__LWM_MASK) | 1195 1176 FIELD_PREP(MLXBF_TMFIFO_RX_CTL__LWM_MASK, 0); 1196 1177 ctl = (ctl & ~MLXBF_TMFIFO_RX_CTL__HWM_MASK) | 1197 1178 FIELD_PREP(MLXBF_TMFIFO_RX_CTL__HWM_MASK, 1); 1198 - writeq(ctl, fifo->rx_base + MLXBF_TMFIFO_RX_CTL); 1179 + writeq(ctl, fifo->rx.ctl); 1199 1180 } 1200 1181 1201 1182 static void mlxbf_tmfifo_cleanup(struct mlxbf_tmfifo *fifo) ··· 1216 1197 struct virtio_net_config net_config; 1217 1198 struct device *dev = &pdev->dev; 1218 1199 struct mlxbf_tmfifo *fifo; 1200 + u64 dev_id; 1219 1201 int i, rc; 1202 + 1203 + rc = acpi_dev_uid_to_integer(ACPI_COMPANION(dev), &dev_id); 1204 + if (rc) { 1205 + dev_err(dev, "Cannot retrieve UID\n"); 1206 + return rc; 1207 + } 1220 1208 1221 1209 fifo = devm_kzalloc(dev, sizeof(*fifo), GFP_KERNEL); 1222 1210 if (!fifo) ··· 1235 1209 mutex_init(&fifo->lock); 1236 1210 1237 1211 /* Get the resource of the Rx FIFO. */ 1238 - fifo->rx_base = devm_platform_ioremap_resource(pdev, 0); 1239 - if (IS_ERR(fifo->rx_base)) 1240 - return PTR_ERR(fifo->rx_base); 1212 + fifo->res0 = devm_platform_ioremap_resource(pdev, 0); 1213 + if (IS_ERR(fifo->res0)) 1214 + return PTR_ERR(fifo->res0); 1241 1215 1242 1216 /* Get the resource of the Tx FIFO. */ 1243 - fifo->tx_base = devm_platform_ioremap_resource(pdev, 1); 1244 - if (IS_ERR(fifo->tx_base)) 1245 - return PTR_ERR(fifo->tx_base); 1217 + fifo->res1 = devm_platform_ioremap_resource(pdev, 1); 1218 + if (IS_ERR(fifo->res1)) 1219 + return PTR_ERR(fifo->res1); 1220 + 1221 + if (dev_id == TMFIFO_BF3_UID) { 1222 + fifo->rx.ctl = fifo->res1 + MLXBF_TMFIFO_RX_CTL_BF3; 1223 + fifo->rx.sts = fifo->res1 + MLXBF_TMFIFO_RX_STS_BF3; 1224 + fifo->rx.data = fifo->res0 + MLXBF_TMFIFO_RX_DATA_BF3; 1225 + fifo->tx.ctl = fifo->res1 + MLXBF_TMFIFO_TX_CTL_BF3; 1226 + fifo->tx.sts = fifo->res1 + MLXBF_TMFIFO_TX_STS_BF3; 1227 + fifo->tx.data = fifo->res0 + MLXBF_TMFIFO_TX_DATA_BF3; 1228 + } else { 1229 + fifo->rx.ctl = fifo->res0 + MLXBF_TMFIFO_RX_CTL; 1230 + fifo->rx.sts = fifo->res0 + MLXBF_TMFIFO_RX_STS; 1231 + fifo->rx.data = fifo->res0 + MLXBF_TMFIFO_RX_DATA; 1232 + fifo->tx.ctl = fifo->res1 + MLXBF_TMFIFO_TX_CTL; 1233 + fifo->tx.sts = fifo->res1 + MLXBF_TMFIFO_TX_STS; 1234 + fifo->tx.data = fifo->res1 + MLXBF_TMFIFO_TX_DATA; 1235 + } 1246 1236 1247 1237 platform_set_drvdata(pdev, fifo); 1248 1238
+1 -42
drivers/platform/x86/Kconfig
··· 424 424 of the CPU temperature. Say Y or M if the kernel may be used on a 425 425 GPD pocket. 426 426 427 - config HP_ACCEL 428 - tristate "HP laptop accelerometer" 429 - depends on INPUT && ACPI 430 - depends on SERIO_I8042 431 - select SENSORS_LIS3LV02D 432 - select NEW_LEDS 433 - select LEDS_CLASS 434 - help 435 - This driver provides support for the "Mobile Data Protection System 3D" 436 - or "3D DriveGuard" feature of HP laptops. On such systems the driver 437 - should load automatically (via ACPI alias). 438 - 439 - Support for a led indicating disk protection will be provided as 440 - hp::hddprotect. For more information on the feature, refer to 441 - Documentation/misc-devices/lis3lv02d.rst. 442 - 443 - To compile this driver as a module, choose M here: the module will 444 - be called hp_accel. 427 + source "drivers/platform/x86/hp/Kconfig" 445 428 446 429 config WIRELESS_HOTKEY 447 430 tristate "Wireless hotkey button" ··· 437 454 438 455 To compile this driver as a module, choose M here: the module will 439 456 be called wireless-hotkey. 440 - 441 - config HP_WMI 442 - tristate "HP WMI extras" 443 - depends on ACPI_WMI 444 - depends on INPUT 445 - depends on RFKILL || RFKILL = n 446 - select INPUT_SPARSEKMAP 447 - select ACPI_PLATFORM_PROFILE 448 - select HWMON 449 - help 450 - Say Y here if you want to support WMI-based hotkeys on HP laptops and 451 - to read data from WMI such as docking or ambient light sensor state. 452 - 453 - To compile this driver as a module, choose M here: the module will 454 - be called hp-wmi. 455 - 456 - config TC1100_WMI 457 - tristate "HP Compaq TC1100 Tablet WMI Extras" 458 - depends on !X86_64 459 - depends on ACPI 460 - depends on ACPI_WMI 461 - help 462 - This is a driver for the WMI extensions (wireless and bluetooth power 463 - control) of the HP Compaq TC1100 tablet. 464 457 465 458 config IBM_RTL 466 459 tristate "Device driver to enable PRTL support"
+1 -3
drivers/platform/x86/Makefile
··· 55 55 obj-$(CONFIG_GPD_POCKET_FAN) += gpd-pocket-fan.o 56 56 57 57 # Hewlett Packard 58 - obj-$(CONFIG_HP_ACCEL) += hp_accel.o 59 - obj-$(CONFIG_HP_WMI) += hp-wmi.o 60 - obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o 58 + obj-$(CONFIG_X86_PLATFORM_DRIVERS_HP) += hp/ 61 59 62 60 # Hewlett Packard Enterprise 63 61 obj-$(CONFIG_UV_SYSFS) += uv_sysfs.o
+46 -46
drivers/platform/x86/amd/pmf/cnqf.c
··· 158 158 return 0; 159 159 } 160 160 161 - static void amd_pmf_update_trans_data(int idx, struct apmf_dyn_slider_output out) 161 + static void amd_pmf_update_trans_data(int idx, struct apmf_dyn_slider_output *out) 162 162 { 163 163 struct cnqf_tran_params *tp; 164 164 165 165 tp = &config_store.trans_param[idx][CNQF_TRANSITION_TO_QUIET]; 166 - tp->time_constant = out.t_balanced_to_quiet; 166 + tp->time_constant = out->t_balanced_to_quiet; 167 167 tp->target_mode = CNQF_MODE_QUIET; 168 168 tp->shifting_up = false; 169 169 170 170 tp = &config_store.trans_param[idx][CNQF_TRANSITION_FROM_BALANCE_TO_PERFORMANCE]; 171 - tp->time_constant = out.t_balanced_to_perf; 171 + tp->time_constant = out->t_balanced_to_perf; 172 172 tp->target_mode = CNQF_MODE_PERFORMANCE; 173 173 tp->shifting_up = true; 174 174 175 175 tp = &config_store.trans_param[idx][CNQF_TRANSITION_FROM_QUIET_TO_BALANCE]; 176 - tp->time_constant = out.t_quiet_to_balanced; 176 + tp->time_constant = out->t_quiet_to_balanced; 177 177 tp->target_mode = CNQF_MODE_BALANCE; 178 178 tp->shifting_up = true; 179 179 180 180 tp = &config_store.trans_param[idx][CNQF_TRANSITION_FROM_PERFORMANCE_TO_BALANCE]; 181 - tp->time_constant = out.t_perf_to_balanced; 181 + tp->time_constant = out->t_perf_to_balanced; 182 182 tp->target_mode = CNQF_MODE_BALANCE; 183 183 tp->shifting_up = false; 184 184 185 185 tp = &config_store.trans_param[idx][CNQF_TRANSITION_FROM_TURBO_TO_PERFORMANCE]; 186 - tp->time_constant = out.t_turbo_to_perf; 186 + tp->time_constant = out->t_turbo_to_perf; 187 187 tp->target_mode = CNQF_MODE_PERFORMANCE; 188 188 tp->shifting_up = false; 189 189 190 190 tp = &config_store.trans_param[idx][CNQF_TRANSITION_TO_TURBO]; 191 - tp->time_constant = out.t_perf_to_turbo; 191 + tp->time_constant = out->t_perf_to_turbo; 192 192 tp->target_mode = CNQF_MODE_TURBO; 193 193 tp->shifting_up = true; 194 194 } 195 195 196 - static void amd_pmf_update_mode_set(int idx, struct apmf_dyn_slider_output out) 196 + static void amd_pmf_update_mode_set(int idx, struct apmf_dyn_slider_output *out) 197 197 { 198 198 struct cnqf_mode_settings *ms; 199 199 200 200 /* Quiet Mode */ 201 201 ms = &config_store.mode_set[idx][CNQF_MODE_QUIET]; 202 - ms->power_floor = out.ps[APMF_CNQF_QUIET].pfloor; 203 - ms->power_control.fppt = out.ps[APMF_CNQF_QUIET].fppt; 204 - ms->power_control.sppt = out.ps[APMF_CNQF_QUIET].sppt; 205 - ms->power_control.sppt_apu_only = out.ps[APMF_CNQF_QUIET].sppt_apu_only; 206 - ms->power_control.spl = out.ps[APMF_CNQF_QUIET].spl; 207 - ms->power_control.stt_min = out.ps[APMF_CNQF_QUIET].stt_min_limit; 202 + ms->power_floor = out->ps[APMF_CNQF_QUIET].pfloor; 203 + ms->power_control.fppt = out->ps[APMF_CNQF_QUIET].fppt; 204 + ms->power_control.sppt = out->ps[APMF_CNQF_QUIET].sppt; 205 + ms->power_control.sppt_apu_only = out->ps[APMF_CNQF_QUIET].sppt_apu_only; 206 + ms->power_control.spl = out->ps[APMF_CNQF_QUIET].spl; 207 + ms->power_control.stt_min = out->ps[APMF_CNQF_QUIET].stt_min_limit; 208 208 ms->power_control.stt_skin_temp[STT_TEMP_APU] = 209 - out.ps[APMF_CNQF_QUIET].stt_skintemp[STT_TEMP_APU]; 209 + out->ps[APMF_CNQF_QUIET].stt_skintemp[STT_TEMP_APU]; 210 210 ms->power_control.stt_skin_temp[STT_TEMP_HS2] = 211 - out.ps[APMF_CNQF_QUIET].stt_skintemp[STT_TEMP_HS2]; 212 - ms->fan_control.fan_id = out.ps[APMF_CNQF_QUIET].fan_id; 211 + out->ps[APMF_CNQF_QUIET].stt_skintemp[STT_TEMP_HS2]; 212 + ms->fan_control.fan_id = out->ps[APMF_CNQF_QUIET].fan_id; 213 213 214 214 /* Balance Mode */ 215 215 ms = &config_store.mode_set[idx][CNQF_MODE_BALANCE]; 216 - ms->power_floor = out.ps[APMF_CNQF_BALANCE].pfloor; 217 - ms->power_control.fppt = out.ps[APMF_CNQF_BALANCE].fppt; 218 - ms->power_control.sppt = out.ps[APMF_CNQF_BALANCE].sppt; 219 - ms->power_control.sppt_apu_only = out.ps[APMF_CNQF_BALANCE].sppt_apu_only; 220 - ms->power_control.spl = out.ps[APMF_CNQF_BALANCE].spl; 221 - ms->power_control.stt_min = out.ps[APMF_CNQF_BALANCE].stt_min_limit; 216 + ms->power_floor = out->ps[APMF_CNQF_BALANCE].pfloor; 217 + ms->power_control.fppt = out->ps[APMF_CNQF_BALANCE].fppt; 218 + ms->power_control.sppt = out->ps[APMF_CNQF_BALANCE].sppt; 219 + ms->power_control.sppt_apu_only = out->ps[APMF_CNQF_BALANCE].sppt_apu_only; 220 + ms->power_control.spl = out->ps[APMF_CNQF_BALANCE].spl; 221 + ms->power_control.stt_min = out->ps[APMF_CNQF_BALANCE].stt_min_limit; 222 222 ms->power_control.stt_skin_temp[STT_TEMP_APU] = 223 - out.ps[APMF_CNQF_BALANCE].stt_skintemp[STT_TEMP_APU]; 223 + out->ps[APMF_CNQF_BALANCE].stt_skintemp[STT_TEMP_APU]; 224 224 ms->power_control.stt_skin_temp[STT_TEMP_HS2] = 225 - out.ps[APMF_CNQF_BALANCE].stt_skintemp[STT_TEMP_HS2]; 226 - ms->fan_control.fan_id = out.ps[APMF_CNQF_BALANCE].fan_id; 225 + out->ps[APMF_CNQF_BALANCE].stt_skintemp[STT_TEMP_HS2]; 226 + ms->fan_control.fan_id = out->ps[APMF_CNQF_BALANCE].fan_id; 227 227 228 228 /* Performance Mode */ 229 229 ms = &config_store.mode_set[idx][CNQF_MODE_PERFORMANCE]; 230 - ms->power_floor = out.ps[APMF_CNQF_PERFORMANCE].pfloor; 231 - ms->power_control.fppt = out.ps[APMF_CNQF_PERFORMANCE].fppt; 232 - ms->power_control.sppt = out.ps[APMF_CNQF_PERFORMANCE].sppt; 233 - ms->power_control.sppt_apu_only = out.ps[APMF_CNQF_PERFORMANCE].sppt_apu_only; 234 - ms->power_control.spl = out.ps[APMF_CNQF_PERFORMANCE].spl; 235 - ms->power_control.stt_min = out.ps[APMF_CNQF_PERFORMANCE].stt_min_limit; 230 + ms->power_floor = out->ps[APMF_CNQF_PERFORMANCE].pfloor; 231 + ms->power_control.fppt = out->ps[APMF_CNQF_PERFORMANCE].fppt; 232 + ms->power_control.sppt = out->ps[APMF_CNQF_PERFORMANCE].sppt; 233 + ms->power_control.sppt_apu_only = out->ps[APMF_CNQF_PERFORMANCE].sppt_apu_only; 234 + ms->power_control.spl = out->ps[APMF_CNQF_PERFORMANCE].spl; 235 + ms->power_control.stt_min = out->ps[APMF_CNQF_PERFORMANCE].stt_min_limit; 236 236 ms->power_control.stt_skin_temp[STT_TEMP_APU] = 237 - out.ps[APMF_CNQF_PERFORMANCE].stt_skintemp[STT_TEMP_APU]; 237 + out->ps[APMF_CNQF_PERFORMANCE].stt_skintemp[STT_TEMP_APU]; 238 238 ms->power_control.stt_skin_temp[STT_TEMP_HS2] = 239 - out.ps[APMF_CNQF_PERFORMANCE].stt_skintemp[STT_TEMP_HS2]; 240 - ms->fan_control.fan_id = out.ps[APMF_CNQF_PERFORMANCE].fan_id; 239 + out->ps[APMF_CNQF_PERFORMANCE].stt_skintemp[STT_TEMP_HS2]; 240 + ms->fan_control.fan_id = out->ps[APMF_CNQF_PERFORMANCE].fan_id; 241 241 242 242 /* Turbo Mode */ 243 243 ms = &config_store.mode_set[idx][CNQF_MODE_TURBO]; 244 - ms->power_floor = out.ps[APMF_CNQF_TURBO].pfloor; 245 - ms->power_control.fppt = out.ps[APMF_CNQF_TURBO].fppt; 246 - ms->power_control.sppt = out.ps[APMF_CNQF_TURBO].sppt; 247 - ms->power_control.sppt_apu_only = out.ps[APMF_CNQF_TURBO].sppt_apu_only; 248 - ms->power_control.spl = out.ps[APMF_CNQF_TURBO].spl; 249 - ms->power_control.stt_min = out.ps[APMF_CNQF_TURBO].stt_min_limit; 244 + ms->power_floor = out->ps[APMF_CNQF_TURBO].pfloor; 245 + ms->power_control.fppt = out->ps[APMF_CNQF_TURBO].fppt; 246 + ms->power_control.sppt = out->ps[APMF_CNQF_TURBO].sppt; 247 + ms->power_control.sppt_apu_only = out->ps[APMF_CNQF_TURBO].sppt_apu_only; 248 + ms->power_control.spl = out->ps[APMF_CNQF_TURBO].spl; 249 + ms->power_control.stt_min = out->ps[APMF_CNQF_TURBO].stt_min_limit; 250 250 ms->power_control.stt_skin_temp[STT_TEMP_APU] = 251 - out.ps[APMF_CNQF_TURBO].stt_skintemp[STT_TEMP_APU]; 251 + out->ps[APMF_CNQF_TURBO].stt_skintemp[STT_TEMP_APU]; 252 252 ms->power_control.stt_skin_temp[STT_TEMP_HS2] = 253 - out.ps[APMF_CNQF_TURBO].stt_skintemp[STT_TEMP_HS2]; 254 - ms->fan_control.fan_id = out.ps[APMF_CNQF_TURBO].fan_id; 253 + out->ps[APMF_CNQF_TURBO].stt_skintemp[STT_TEMP_HS2]; 254 + ms->fan_control.fan_id = out->ps[APMF_CNQF_TURBO].fan_id; 255 255 } 256 256 257 257 static int amd_pmf_check_flags(struct amd_pmf_dev *dev) ··· 284 284 return ret; 285 285 } 286 286 287 - amd_pmf_update_mode_set(i, out); 288 - amd_pmf_update_trans_data(i, out); 287 + amd_pmf_update_mode_set(i, &out); 288 + amd_pmf_update_trans_data(i, &out); 289 289 amd_pmf_update_power_threshold(i); 290 290 291 291 for (j = 0; j < CNQF_MODE_MAX; j++) {
+2 -2
drivers/platform/x86/asus-wmi.c
··· 883 883 884 884 static DEVICE_ATTR_RW(charge_control_end_threshold); 885 885 886 - static int asus_wmi_battery_add(struct power_supply *battery) 886 + static int asus_wmi_battery_add(struct power_supply *battery, struct acpi_battery_hook *hook) 887 887 { 888 888 /* The WMI method does not provide a way to specific a battery, so we 889 889 * just assume it is the first battery. ··· 910 910 return 0; 911 911 } 912 912 913 - static int asus_wmi_battery_remove(struct power_supply *battery) 913 + static int asus_wmi_battery_remove(struct power_supply *battery, struct acpi_battery_hook *hook) 914 914 { 915 915 device_remove_file(&battery->dev, 916 916 &dev_attr_charge_control_end_threshold);
+13
drivers/platform/x86/dell/Kconfig
··· 189 189 default n 190 190 depends on ACPI_WMI 191 191 192 + config DELL_WMI_DDV 193 + tristate "Dell WMI sensors Support" 194 + default m 195 + depends on ACPI_BATTERY 196 + depends on ACPI_WMI 197 + help 198 + This option adds support for WMI-based sensors like 199 + battery temperature sensors found on some Dell notebooks. 200 + It also supports reading of the battery ePPID. 201 + 202 + To compile this drivers as a module, choose M here: the module will 203 + be called dell-wmi-ddv. 204 + 192 205 config DELL_WMI_LED 193 206 tristate "External LED on Dell Business Netbooks" 194 207 default m
+1
drivers/platform/x86/dell/Makefile
··· 19 19 dell-wmi-$(CONFIG_DELL_WMI_PRIVACY) += dell-wmi-privacy.o 20 20 obj-$(CONFIG_DELL_WMI_AIO) += dell-wmi-aio.o 21 21 obj-$(CONFIG_DELL_WMI_DESCRIPTOR) += dell-wmi-descriptor.o 22 + obj-$(CONFIG_DELL_WMI_DDV) += dell-wmi-ddv.o 22 23 obj-$(CONFIG_DELL_WMI_LED) += dell-wmi-led.o 23 24 obj-$(CONFIG_DELL_WMI_SYSMAN) += dell-wmi-sysman/
+16 -25
drivers/platform/x86/dell/alienware-wmi.c
··· 398 398 struct device_attribute *attr, char *buf) 399 399 { 400 400 if (lighting_control_state == LEGACY_BOOTING) 401 - return scnprintf(buf, PAGE_SIZE, "[booting] running suspend\n"); 401 + return sysfs_emit(buf, "[booting] running suspend\n"); 402 402 else if (lighting_control_state == LEGACY_SUSPEND) 403 - return scnprintf(buf, PAGE_SIZE, "booting running [suspend]\n"); 404 - return scnprintf(buf, PAGE_SIZE, "booting [running] suspend\n"); 403 + return sysfs_emit(buf, "booting running [suspend]\n"); 404 + return sysfs_emit(buf, "booting [running] suspend\n"); 405 405 } 406 406 407 407 static ssize_t store_control_state(struct device *dev, ··· 547 547 (u32 *) &out_data); 548 548 if (ACPI_SUCCESS(status)) { 549 549 if (out_data == 0) 550 - return scnprintf(buf, PAGE_SIZE, 551 - "[unconnected] connected unknown\n"); 550 + return sysfs_emit(buf, "[unconnected] connected unknown\n"); 552 551 else if (out_data == 1) 553 - return scnprintf(buf, PAGE_SIZE, 554 - "unconnected [connected] unknown\n"); 552 + return sysfs_emit(buf, "unconnected [connected] unknown\n"); 555 553 } 556 554 pr_err("alienware-wmi: unknown HDMI cable status: %d\n", status); 557 - return scnprintf(buf, PAGE_SIZE, "unconnected connected [unknown]\n"); 555 + return sysfs_emit(buf, "unconnected connected [unknown]\n"); 558 556 } 559 557 560 558 static ssize_t show_hdmi_source(struct device *dev, ··· 569 571 570 572 if (ACPI_SUCCESS(status)) { 571 573 if (out_data == 1) 572 - return scnprintf(buf, PAGE_SIZE, 573 - "[input] gpu unknown\n"); 574 + return sysfs_emit(buf, "[input] gpu unknown\n"); 574 575 else if (out_data == 2) 575 - return scnprintf(buf, PAGE_SIZE, 576 - "input [gpu] unknown\n"); 576 + return sysfs_emit(buf, "input [gpu] unknown\n"); 577 577 } 578 578 pr_err("alienware-wmi: unknown HDMI source status: %u\n", status); 579 - return scnprintf(buf, PAGE_SIZE, "input gpu [unknown]\n"); 579 + return sysfs_emit(buf, "input gpu [unknown]\n"); 580 580 } 581 581 582 582 static ssize_t toggle_hdmi_source(struct device *dev, ··· 648 652 (u32 *) &out_data); 649 653 if (ACPI_SUCCESS(status)) { 650 654 if (out_data == 0) 651 - return scnprintf(buf, PAGE_SIZE, 652 - "[unconnected] connected unknown\n"); 655 + return sysfs_emit(buf, "[unconnected] connected unknown\n"); 653 656 else if (out_data == 1) 654 - return scnprintf(buf, PAGE_SIZE, 655 - "unconnected [connected] unknown\n"); 657 + return sysfs_emit(buf, "unconnected [connected] unknown\n"); 656 658 } 657 659 pr_err("alienware-wmi: unknown amplifier cable status: %d\n", status); 658 - return scnprintf(buf, PAGE_SIZE, "unconnected connected [unknown]\n"); 660 + return sysfs_emit(buf, "unconnected connected [unknown]\n"); 659 661 } 660 662 661 663 static DEVICE_ATTR(status, S_IRUGO, show_amplifier_status, NULL); ··· 700 706 (u32 *) &out_data); 701 707 if (ACPI_SUCCESS(status)) { 702 708 if (out_data == 0) 703 - return scnprintf(buf, PAGE_SIZE, 704 - "[disabled] s5 s5_s4\n"); 709 + return sysfs_emit(buf, "[disabled] s5 s5_s4\n"); 705 710 else if (out_data == 1) 706 - return scnprintf(buf, PAGE_SIZE, 707 - "disabled [s5] s5_s4\n"); 711 + return sysfs_emit(buf, "disabled [s5] s5_s4\n"); 708 712 else if (out_data == 2) 709 - return scnprintf(buf, PAGE_SIZE, 710 - "disabled s5 [s5_s4]\n"); 713 + return sysfs_emit(buf, "disabled s5 [s5_s4]\n"); 711 714 } 712 715 pr_err("alienware-wmi: unknown deep sleep status: %d\n", status); 713 - return scnprintf(buf, PAGE_SIZE, "disabled s5 s5_s4 [unknown]\n"); 716 + return sysfs_emit(buf, "disabled s5 s5_s4 [unknown]\n"); 714 717 } 715 718 716 719 static ssize_t toggle_deepsleep(struct device *dev,
+375
drivers/platform/x86/dell/dell-wmi-ddv.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Linux driver for WMI sensor information on Dell notebooks. 4 + * 5 + * Copyright (C) 2022 Armin Wolf <W_Armin@gmx.de> 6 + */ 7 + 8 + #define pr_format(fmt) KBUILD_MODNAME ": " fmt 9 + 10 + #include <linux/acpi.h> 11 + #include <linux/debugfs.h> 12 + #include <linux/device.h> 13 + #include <linux/dev_printk.h> 14 + #include <linux/kernel.h> 15 + #include <linux/kstrtox.h> 16 + #include <linux/math.h> 17 + #include <linux/module.h> 18 + #include <linux/limits.h> 19 + #include <linux/power_supply.h> 20 + #include <linux/printk.h> 21 + #include <linux/seq_file.h> 22 + #include <linux/sysfs.h> 23 + #include <linux/wmi.h> 24 + 25 + #include <acpi/battery.h> 26 + 27 + #define DRIVER_NAME "dell-wmi-ddv" 28 + 29 + #define DELL_DDV_SUPPORTED_INTERFACE 2 30 + #define DELL_DDV_GUID "8A42EA14-4F2A-FD45-6422-0087F7A7E608" 31 + 32 + #define DELL_EPPID_LENGTH 20 33 + #define DELL_EPPID_EXT_LENGTH 23 34 + 35 + enum dell_ddv_method { 36 + DELL_DDV_BATTERY_DESIGN_CAPACITY = 0x01, 37 + DELL_DDV_BATTERY_FULL_CHARGE_CAPACITY = 0x02, 38 + DELL_DDV_BATTERY_MANUFACTURE_NAME = 0x03, 39 + DELL_DDV_BATTERY_MANUFACTURE_DATE = 0x04, 40 + DELL_DDV_BATTERY_SERIAL_NUMBER = 0x05, 41 + DELL_DDV_BATTERY_CHEMISTRY_VALUE = 0x06, 42 + DELL_DDV_BATTERY_TEMPERATURE = 0x07, 43 + DELL_DDV_BATTERY_CURRENT = 0x08, 44 + DELL_DDV_BATTERY_VOLTAGE = 0x09, 45 + DELL_DDV_BATTERY_MANUFACTURER_ACCESS = 0x0A, 46 + DELL_DDV_BATTERY_RELATIVE_CHARGE_STATE = 0x0B, 47 + DELL_DDV_BATTERY_CYCLE_COUNT = 0x0C, 48 + DELL_DDV_BATTERY_EPPID = 0x0D, 49 + DELL_DDV_BATTERY_RAW_ANALYTICS_START = 0x0E, 50 + DELL_DDV_BATTERY_RAW_ANALYTICS = 0x0F, 51 + DELL_DDV_BATTERY_DESIGN_VOLTAGE = 0x10, 52 + 53 + DELL_DDV_INTERFACE_VERSION = 0x12, 54 + 55 + DELL_DDV_FAN_SENSOR_INFORMATION = 0x20, 56 + DELL_DDV_THERMAL_SENSOR_INFORMATION = 0x22, 57 + }; 58 + 59 + struct dell_wmi_ddv_data { 60 + struct acpi_battery_hook hook; 61 + struct device_attribute temp_attr; 62 + struct device_attribute eppid_attr; 63 + struct wmi_device *wdev; 64 + }; 65 + 66 + static int dell_wmi_ddv_query_type(struct wmi_device *wdev, enum dell_ddv_method method, u32 arg, 67 + union acpi_object **result, acpi_object_type type) 68 + { 69 + struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL }; 70 + const struct acpi_buffer in = { 71 + .length = sizeof(arg), 72 + .pointer = &arg, 73 + }; 74 + union acpi_object *obj; 75 + acpi_status ret; 76 + 77 + ret = wmidev_evaluate_method(wdev, 0x0, method, &in, &out); 78 + if (ACPI_FAILURE(ret)) 79 + return -EIO; 80 + 81 + obj = out.pointer; 82 + if (!obj) 83 + return -ENODATA; 84 + 85 + if (obj->type != type) { 86 + kfree(obj); 87 + return -EIO; 88 + } 89 + 90 + *result = obj; 91 + 92 + return 0; 93 + } 94 + 95 + static int dell_wmi_ddv_query_integer(struct wmi_device *wdev, enum dell_ddv_method method, 96 + u32 arg, u32 *res) 97 + { 98 + union acpi_object *obj; 99 + int ret; 100 + 101 + ret = dell_wmi_ddv_query_type(wdev, method, arg, &obj, ACPI_TYPE_INTEGER); 102 + if (ret < 0) 103 + return ret; 104 + 105 + if (obj->integer.value <= U32_MAX) 106 + *res = (u32)obj->integer.value; 107 + else 108 + ret = -ERANGE; 109 + 110 + kfree(obj); 111 + 112 + return ret; 113 + } 114 + 115 + static int dell_wmi_ddv_query_buffer(struct wmi_device *wdev, enum dell_ddv_method method, 116 + u32 arg, union acpi_object **result) 117 + { 118 + union acpi_object *obj; 119 + u64 buffer_size; 120 + int ret; 121 + 122 + ret = dell_wmi_ddv_query_type(wdev, method, arg, &obj, ACPI_TYPE_PACKAGE); 123 + if (ret < 0) 124 + return ret; 125 + 126 + if (obj->package.count != 2) 127 + goto err_free; 128 + 129 + if (obj->package.elements[0].type != ACPI_TYPE_INTEGER) 130 + goto err_free; 131 + 132 + buffer_size = obj->package.elements[0].integer.value; 133 + 134 + if (obj->package.elements[1].type != ACPI_TYPE_BUFFER) 135 + goto err_free; 136 + 137 + if (buffer_size > obj->package.elements[1].buffer.length) { 138 + dev_warn(&wdev->dev, 139 + FW_WARN "WMI buffer size (%llu) exceeds ACPI buffer size (%d)\n", 140 + buffer_size, obj->package.elements[1].buffer.length); 141 + 142 + goto err_free; 143 + } 144 + 145 + *result = obj; 146 + 147 + return 0; 148 + 149 + err_free: 150 + kfree(obj); 151 + 152 + return -EIO; 153 + } 154 + 155 + static int dell_wmi_ddv_query_string(struct wmi_device *wdev, enum dell_ddv_method method, 156 + u32 arg, union acpi_object **result) 157 + { 158 + return dell_wmi_ddv_query_type(wdev, method, arg, result, ACPI_TYPE_STRING); 159 + } 160 + 161 + static int dell_wmi_ddv_battery_index(struct acpi_device *acpi_dev, u32 *index) 162 + { 163 + const char *uid_str; 164 + 165 + uid_str = acpi_device_uid(acpi_dev); 166 + if (!uid_str) 167 + return -ENODEV; 168 + 169 + return kstrtou32(uid_str, 10, index); 170 + } 171 + 172 + static ssize_t temp_show(struct device *dev, struct device_attribute *attr, char *buf) 173 + { 174 + struct dell_wmi_ddv_data *data = container_of(attr, struct dell_wmi_ddv_data, temp_attr); 175 + u32 index, value; 176 + int ret; 177 + 178 + ret = dell_wmi_ddv_battery_index(to_acpi_device(dev->parent), &index); 179 + if (ret < 0) 180 + return ret; 181 + 182 + ret = dell_wmi_ddv_query_integer(data->wdev, DELL_DDV_BATTERY_TEMPERATURE, index, &value); 183 + if (ret < 0) 184 + return ret; 185 + 186 + return sysfs_emit(buf, "%d\n", DIV_ROUND_CLOSEST(value, 10)); 187 + } 188 + 189 + static ssize_t eppid_show(struct device *dev, struct device_attribute *attr, char *buf) 190 + { 191 + struct dell_wmi_ddv_data *data = container_of(attr, struct dell_wmi_ddv_data, eppid_attr); 192 + union acpi_object *obj; 193 + u32 index; 194 + int ret; 195 + 196 + ret = dell_wmi_ddv_battery_index(to_acpi_device(dev->parent), &index); 197 + if (ret < 0) 198 + return ret; 199 + 200 + ret = dell_wmi_ddv_query_string(data->wdev, DELL_DDV_BATTERY_EPPID, index, &obj); 201 + if (ret < 0) 202 + return ret; 203 + 204 + if (obj->string.length != DELL_EPPID_LENGTH && obj->string.length != DELL_EPPID_EXT_LENGTH) 205 + dev_info_once(&data->wdev->dev, FW_INFO "Suspicious ePPID length (%d)\n", 206 + obj->string.length); 207 + 208 + ret = sysfs_emit(buf, "%s\n", obj->string.pointer); 209 + 210 + kfree(obj); 211 + 212 + return ret; 213 + } 214 + 215 + static int dell_wmi_ddv_add_battery(struct power_supply *battery, struct acpi_battery_hook *hook) 216 + { 217 + struct dell_wmi_ddv_data *data = container_of(hook, struct dell_wmi_ddv_data, hook); 218 + u32 index; 219 + int ret; 220 + 221 + /* Return 0 instead of error to avoid being unloaded */ 222 + ret = dell_wmi_ddv_battery_index(to_acpi_device(battery->dev.parent), &index); 223 + if (ret < 0) 224 + return 0; 225 + 226 + ret = device_create_file(&battery->dev, &data->temp_attr); 227 + if (ret < 0) 228 + return ret; 229 + 230 + ret = device_create_file(&battery->dev, &data->eppid_attr); 231 + if (ret < 0) { 232 + device_remove_file(&battery->dev, &data->temp_attr); 233 + 234 + return ret; 235 + } 236 + 237 + return 0; 238 + } 239 + 240 + static int dell_wmi_ddv_remove_battery(struct power_supply *battery, struct acpi_battery_hook *hook) 241 + { 242 + struct dell_wmi_ddv_data *data = container_of(hook, struct dell_wmi_ddv_data, hook); 243 + 244 + device_remove_file(&battery->dev, &data->temp_attr); 245 + device_remove_file(&battery->dev, &data->eppid_attr); 246 + 247 + return 0; 248 + } 249 + 250 + static void dell_wmi_ddv_battery_remove(void *data) 251 + { 252 + struct acpi_battery_hook *hook = data; 253 + 254 + battery_hook_unregister(hook); 255 + } 256 + 257 + static int dell_wmi_ddv_battery_add(struct dell_wmi_ddv_data *data) 258 + { 259 + data->hook.name = "Dell DDV Battery Extension"; 260 + data->hook.add_battery = dell_wmi_ddv_add_battery; 261 + data->hook.remove_battery = dell_wmi_ddv_remove_battery; 262 + 263 + sysfs_attr_init(&data->temp_attr.attr); 264 + data->temp_attr.attr.name = "temp"; 265 + data->temp_attr.attr.mode = 0444; 266 + data->temp_attr.show = temp_show; 267 + 268 + sysfs_attr_init(&data->eppid_attr.attr); 269 + data->eppid_attr.attr.name = "eppid"; 270 + data->eppid_attr.attr.mode = 0444; 271 + data->eppid_attr.show = eppid_show; 272 + 273 + battery_hook_register(&data->hook); 274 + 275 + return devm_add_action_or_reset(&data->wdev->dev, dell_wmi_ddv_battery_remove, &data->hook); 276 + } 277 + 278 + static int dell_wmi_ddv_buffer_read(struct seq_file *seq, enum dell_ddv_method method) 279 + { 280 + struct device *dev = seq->private; 281 + struct dell_wmi_ddv_data *data = dev_get_drvdata(dev); 282 + union acpi_object *obj; 283 + u64 size; 284 + u8 *buf; 285 + int ret; 286 + 287 + ret = dell_wmi_ddv_query_buffer(data->wdev, method, 0, &obj); 288 + if (ret < 0) 289 + return ret; 290 + 291 + size = obj->package.elements[0].integer.value; 292 + buf = obj->package.elements[1].buffer.pointer; 293 + ret = seq_write(seq, buf, size); 294 + kfree(obj); 295 + 296 + return ret; 297 + } 298 + 299 + static int dell_wmi_ddv_fan_read(struct seq_file *seq, void *offset) 300 + { 301 + return dell_wmi_ddv_buffer_read(seq, DELL_DDV_FAN_SENSOR_INFORMATION); 302 + } 303 + 304 + static int dell_wmi_ddv_temp_read(struct seq_file *seq, void *offset) 305 + { 306 + return dell_wmi_ddv_buffer_read(seq, DELL_DDV_THERMAL_SENSOR_INFORMATION); 307 + } 308 + 309 + static void dell_wmi_ddv_debugfs_remove(void *data) 310 + { 311 + struct dentry *entry = data; 312 + 313 + debugfs_remove(entry); 314 + } 315 + 316 + static void dell_wmi_ddv_debugfs_init(struct wmi_device *wdev) 317 + { 318 + struct dentry *entry; 319 + char name[64]; 320 + 321 + scnprintf(name, ARRAY_SIZE(name), "%s-%s", DRIVER_NAME, dev_name(&wdev->dev)); 322 + entry = debugfs_create_dir(name, NULL); 323 + 324 + debugfs_create_devm_seqfile(&wdev->dev, "fan_sensor_information", entry, 325 + dell_wmi_ddv_fan_read); 326 + debugfs_create_devm_seqfile(&wdev->dev, "thermal_sensor_information", entry, 327 + dell_wmi_ddv_temp_read); 328 + 329 + devm_add_action_or_reset(&wdev->dev, dell_wmi_ddv_debugfs_remove, entry); 330 + } 331 + 332 + static int dell_wmi_ddv_probe(struct wmi_device *wdev, const void *context) 333 + { 334 + struct dell_wmi_ddv_data *data; 335 + u32 version; 336 + int ret; 337 + 338 + ret = dell_wmi_ddv_query_integer(wdev, DELL_DDV_INTERFACE_VERSION, 0, &version); 339 + if (ret < 0) 340 + return ret; 341 + 342 + dev_dbg(&wdev->dev, "WMI interface version: %d\n", version); 343 + if (version != DELL_DDV_SUPPORTED_INTERFACE) 344 + return -ENODEV; 345 + 346 + data = devm_kzalloc(&wdev->dev, sizeof(*data), GFP_KERNEL); 347 + if (!data) 348 + return -ENOMEM; 349 + 350 + dev_set_drvdata(&wdev->dev, data); 351 + data->wdev = wdev; 352 + 353 + dell_wmi_ddv_debugfs_init(wdev); 354 + 355 + return dell_wmi_ddv_battery_add(data); 356 + } 357 + 358 + static const struct wmi_device_id dell_wmi_ddv_id_table[] = { 359 + { DELL_DDV_GUID, NULL }, 360 + { } 361 + }; 362 + MODULE_DEVICE_TABLE(wmi, dell_wmi_ddv_id_table); 363 + 364 + static struct wmi_driver dell_wmi_ddv_driver = { 365 + .driver = { 366 + .name = DRIVER_NAME, 367 + }, 368 + .id_table = dell_wmi_ddv_id_table, 369 + .probe = dell_wmi_ddv_probe, 370 + }; 371 + module_wmi_driver(dell_wmi_ddv_driver); 372 + 373 + MODULE_AUTHOR("Armin Wolf <W_Armin@gmx.de>"); 374 + MODULE_DESCRIPTION("Dell WMI sensor driver"); 375 + MODULE_LICENSE("GPL");
drivers/platform/x86/hp-wmi.c drivers/platform/x86/hp/hp-wmi.c
+63
drivers/platform/x86/hp/Kconfig
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + # 3 + # X86 Platform Specific Drivers 4 + # 5 + menuconfig X86_PLATFORM_DRIVERS_HP 6 + bool "HP X86 Platform Specific Device Drivers" 7 + depends on X86_PLATFORM_DEVICES 8 + help 9 + Say Y here to get to see options for device drivers for various 10 + HP x86 platforms, including vendor-specific laptop extension drivers. 11 + This option alone does not add any kernel code. 12 + 13 + If you say N, all options in this submenu will be skipped and disabled. 14 + 15 + if X86_PLATFORM_DRIVERS_HP 16 + 17 + config HP_ACCEL 18 + tristate "HP laptop accelerometer" 19 + default m 20 + depends on INPUT && ACPI 21 + depends on SERIO_I8042 22 + select SENSORS_LIS3LV02D 23 + select NEW_LEDS 24 + select LEDS_CLASS 25 + help 26 + This driver provides support for the "Mobile Data Protection System 3D" 27 + or "3D DriveGuard" feature of HP laptops. On such systems the driver 28 + should load automatically (via ACPI alias). 29 + 30 + Support for a led indicating disk protection will be provided as 31 + hp::hddprotect. For more information on the feature, refer to 32 + Documentation/misc-devices/lis3lv02d.rst. 33 + 34 + To compile this driver as a module, choose M here: the module will 35 + be called hp_accel. 36 + 37 + config HP_WMI 38 + tristate "HP WMI extras" 39 + default m 40 + depends on ACPI_WMI 41 + depends on INPUT 42 + depends on RFKILL || RFKILL = n 43 + select INPUT_SPARSEKMAP 44 + select ACPI_PLATFORM_PROFILE 45 + select HWMON 46 + help 47 + Say Y here if you want to support WMI-based hotkeys on HP laptops and 48 + to read data from WMI such as docking or ambient light sensor state. 49 + 50 + To compile this driver as a module, choose M here: the module will 51 + be called hp-wmi. 52 + 53 + config TC1100_WMI 54 + tristate "HP Compaq TC1100 Tablet WMI Extras" 55 + default m 56 + depends on !X86_64 57 + depends on ACPI 58 + depends on ACPI_WMI 59 + help 60 + This is a driver for the WMI extensions (wireless and bluetooth power 61 + control) of the HP Compaq TC1100 tablet. 62 + 63 + endif # X86_PLATFORM_DRIVERS_HP
+10
drivers/platform/x86/hp/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + # 3 + # Makefile for linux/drivers/platform/x86/hp 4 + # HP x86 Platform-Specific Drivers 5 + # 6 + 7 + # Hewlett Packard 8 + obj-$(CONFIG_HP_ACCEL) += hp_accel.o 9 + obj-$(CONFIG_HP_WMI) += hp-wmi.o 10 + obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o
+1 -1
drivers/platform/x86/hp_accel.c drivers/platform/x86/hp/hp_accel.c
··· 26 26 #include <linux/acpi.h> 27 27 #include <linux/i8042.h> 28 28 #include <linux/serio.h> 29 - #include "../../misc/lis3lv02d/lis3lv02d.h" 29 + #include "../../../misc/lis3lv02d/lis3lv02d.h" 30 30 31 31 /* Delayed LEDs infrastructure ------------------------------------ */ 32 32
+29 -22
drivers/platform/x86/huawei-wmi.c
··· 63 63 bool fn_lock_available; 64 64 65 65 struct huawei_wmi_debug debug; 66 - struct input_dev *idev[2]; 67 66 struct led_classdev cdev; 68 67 struct device *dev; 69 68 ··· 322 323 u8 ret[0x100]; 323 324 int err, i; 324 325 325 - err = huawei_wmi_cmd(BATTERY_THRESH_GET, ret, 0x100); 326 + err = huawei_wmi_cmd(BATTERY_THRESH_GET, ret, sizeof(ret)); 326 327 if (err) 327 328 return err; 328 329 329 330 /* Find the last two non-zero values. Return status is ignored. */ 330 - i = 0xff; 331 + i = ARRAY_SIZE(ret) - 1; 331 332 do { 332 333 if (start) 333 334 *start = ret[i-1]; ··· 467 468 static DEVICE_ATTR_RW(charge_control_end_threshold); 468 469 static DEVICE_ATTR_RW(charge_control_thresholds); 469 470 470 - static int huawei_wmi_battery_add(struct power_supply *battery) 471 + static int huawei_wmi_battery_add(struct power_supply *battery, struct acpi_battery_hook *hook) 471 472 { 472 473 int err = 0; 473 474 ··· 482 483 return err; 483 484 } 484 485 485 - static int huawei_wmi_battery_remove(struct power_supply *battery) 486 + static int huawei_wmi_battery_remove(struct power_supply *battery, struct acpi_battery_hook *hook) 486 487 { 487 488 device_remove_file(&battery->dev, &dev_attr_charge_control_start_threshold); 488 489 device_remove_file(&battery->dev, &dev_attr_charge_control_end_threshold); ··· 755 756 kfree(response.pointer); 756 757 } 757 758 758 - static int huawei_wmi_input_setup(struct device *dev, 759 - const char *guid, 760 - struct input_dev **idev) 759 + static int huawei_wmi_input_setup(struct device *dev, const char *guid) 761 760 { 762 - *idev = devm_input_allocate_device(dev); 763 - if (!*idev) 761 + struct input_dev *idev; 762 + acpi_status status; 763 + int err; 764 + 765 + idev = devm_input_allocate_device(dev); 766 + if (!idev) 764 767 return -ENOMEM; 765 768 766 - (*idev)->name = "Huawei WMI hotkeys"; 767 - (*idev)->phys = "wmi/input0"; 768 - (*idev)->id.bustype = BUS_HOST; 769 - (*idev)->dev.parent = dev; 769 + idev->name = "Huawei WMI hotkeys"; 770 + idev->phys = "wmi/input0"; 771 + idev->id.bustype = BUS_HOST; 772 + idev->dev.parent = dev; 770 773 771 - return sparse_keymap_setup(*idev, huawei_wmi_keymap, NULL) || 772 - input_register_device(*idev) || 773 - wmi_install_notify_handler(guid, huawei_wmi_input_notify, 774 - *idev); 774 + err = sparse_keymap_setup(idev, huawei_wmi_keymap, NULL); 775 + if (err) 776 + return err; 777 + 778 + err = input_register_device(idev); 779 + if (err) 780 + return err; 781 + 782 + status = wmi_install_notify_handler(guid, huawei_wmi_input_notify, idev); 783 + if (ACPI_FAILURE(status)) 784 + return -EIO; 785 + 786 + return 0; 775 787 } 776 788 777 789 static void huawei_wmi_input_exit(struct device *dev, const char *guid) ··· 807 797 huawei_wmi->dev = &pdev->dev; 808 798 809 799 while (*guid->guid_string) { 810 - struct input_dev *idev = *huawei_wmi->idev; 811 - 812 800 if (wmi_has_guid(guid->guid_string)) { 813 - err = huawei_wmi_input_setup(&pdev->dev, guid->guid_string, &idev); 801 + err = huawei_wmi_input_setup(&pdev->dev, guid->guid_string); 814 802 if (err) { 815 803 dev_err(&pdev->dev, "Failed to setup input on %s\n", guid->guid_string); 816 804 return err; 817 805 } 818 806 } 819 807 820 - idev++; 821 808 guid++; 822 809 } 823 810
+290 -102
drivers/platform/x86/ideapad-laptop.c
··· 30 30 #include <linux/seq_file.h> 31 31 #include <linux/sysfs.h> 32 32 #include <linux/types.h> 33 + #include <linux/wmi.h> 33 34 34 35 #include <acpi/video.h> 35 36 ··· 38 37 39 38 #define IDEAPAD_RFKILL_DEV_NUM 3 40 39 41 - #if IS_ENABLED(CONFIG_ACPI_WMI) 42 - static const char *const ideapad_wmi_fnesc_events[] = { 43 - "26CAB2E5-5CF1-46AE-AAC3-4A12B6BA50E6", /* Yoga 3 */ 44 - "56322276-8493-4CE8-A783-98C991274F5E", /* Yoga 700 */ 45 - "8FC0DE0C-B4E4-43FD-B0F3-8871711C1294", /* Legion 5 */ 46 - }; 47 - #endif 48 - 49 40 enum { 50 41 CFG_CAP_BT_BIT = 16, 51 42 CFG_CAP_3G_BIT = 17, 52 43 CFG_CAP_WIFI_BIT = 18, 53 44 CFG_CAP_CAM_BIT = 19, 54 - CFG_CAP_TOUCHPAD_BIT = 30, 45 + 46 + /* 47 + * These are OnScreenDisplay support bits that can be useful to determine 48 + * whether a hotkey exists/should show OSD. But they aren't particularly 49 + * meaningful since they were introduced later, i.e. 2010 IdeaPads 50 + * don't have these, but they still have had OSD for hotkeys. 51 + */ 52 + CFG_OSD_NUMLK_BIT = 27, 53 + CFG_OSD_CAPSLK_BIT = 28, 54 + CFG_OSD_MICMUTE_BIT = 29, 55 + CFG_OSD_TOUCHPAD_BIT = 30, 56 + CFG_OSD_CAM_BIT = 31, 55 57 }; 56 58 57 59 enum { ··· 134 130 struct ideapad_dytc_priv *dytc; 135 131 struct dentry *debug; 136 132 unsigned long cfg; 137 - const char *fnesc_guid; 133 + unsigned long r_touchpad_val; 138 134 struct { 139 135 bool conservation_mode : 1; 140 136 bool dytc : 1; ··· 144 140 bool hw_rfkill_switch : 1; 145 141 bool kbd_bl : 1; 146 142 bool touchpad_ctrl_via_ec : 1; 143 + bool ctrl_ps2_aux_port : 1; 147 144 bool usb_charging : 1; 148 145 } features; 149 146 struct { ··· 175 170 MODULE_PARM_DESC(set_fn_lock_led, 176 171 "Enable driver based updates of the fn-lock LED on fn-lock changes. " 177 172 "If you need this please report this to: platform-driver-x86@vger.kernel.org"); 173 + 174 + static bool ctrl_ps2_aux_port; 175 + module_param(ctrl_ps2_aux_port, bool, 0444); 176 + MODULE_PARM_DESC(ctrl_ps2_aux_port, 177 + "Enable driver based PS/2 aux port en-/dis-abling on touchpad on/off toggle. " 178 + "If you need this please report this to: platform-driver-x86@vger.kernel.org"); 179 + 180 + static bool touchpad_ctrl_via_ec; 181 + module_param(touchpad_ctrl_via_ec, bool, 0444); 182 + MODULE_PARM_DESC(touchpad_ctrl_via_ec, 183 + "Enable registering a 'touchpad' sysfs-attribute which can be used to manually " 184 + "tell the EC to enable/disable the touchpad. This may not work on all models."); 185 + 186 + /* 187 + * shared data 188 + */ 189 + 190 + static struct ideapad_private *ideapad_shared; 191 + static DEFINE_MUTEX(ideapad_shared_mutex); 192 + 193 + static int ideapad_shared_init(struct ideapad_private *priv) 194 + { 195 + int ret; 196 + 197 + mutex_lock(&ideapad_shared_mutex); 198 + 199 + if (!ideapad_shared) { 200 + ideapad_shared = priv; 201 + ret = 0; 202 + } else { 203 + dev_warn(&priv->adev->dev, "found multiple platform devices\n"); 204 + ret = -EINVAL; 205 + } 206 + 207 + mutex_unlock(&ideapad_shared_mutex); 208 + 209 + return ret; 210 + } 211 + 212 + static void ideapad_shared_exit(struct ideapad_private *priv) 213 + { 214 + mutex_lock(&ideapad_shared_mutex); 215 + 216 + if (ideapad_shared == priv) 217 + ideapad_shared = NULL; 218 + 219 + mutex_unlock(&ideapad_shared_mutex); 220 + } 178 221 179 222 /* 180 223 * ACPI Helpers ··· 439 386 seq_puts(s, " wifi"); 440 387 if (test_bit(CFG_CAP_CAM_BIT, &priv->cfg)) 441 388 seq_puts(s, " camera"); 442 - if (test_bit(CFG_CAP_TOUCHPAD_BIT, &priv->cfg)) 389 + seq_puts(s, "\n"); 390 + 391 + seq_puts(s, "OSD support:"); 392 + if (test_bit(CFG_OSD_NUMLK_BIT, &priv->cfg)) 393 + seq_puts(s, " num-lock"); 394 + if (test_bit(CFG_OSD_CAPSLK_BIT, &priv->cfg)) 395 + seq_puts(s, " caps-lock"); 396 + if (test_bit(CFG_OSD_MICMUTE_BIT, &priv->cfg)) 397 + seq_puts(s, " mic-mute"); 398 + if (test_bit(CFG_OSD_TOUCHPAD_BIT, &priv->cfg)) 443 399 seq_puts(s, " touchpad"); 400 + if (test_bit(CFG_OSD_CAM_BIT, &priv->cfg)) 401 + seq_puts(s, " camera"); 444 402 seq_puts(s, "\n"); 445 403 446 404 seq_puts(s, "Graphics: "); ··· 657 593 if (err) 658 594 return err; 659 595 596 + priv->r_touchpad_val = result; 597 + 660 598 return sysfs_emit(buf, "%d\n", !!result); 661 599 } 662 600 ··· 677 611 err = write_ec_cmd(priv->adev->handle, VPCCMD_W_TOUCHPAD, state); 678 612 if (err) 679 613 return err; 614 + 615 + priv->r_touchpad_val = state; 680 616 681 617 return count; 682 618 } ··· 748 680 else if (attr == &dev_attr_fn_lock.attr) 749 681 supported = priv->features.fn_lock; 750 682 else if (attr == &dev_attr_touchpad.attr) 751 - supported = priv->features.touchpad_ctrl_via_ec && 752 - test_bit(CFG_CAP_TOUCHPAD_BIT, &priv->cfg); 683 + supported = priv->features.touchpad_ctrl_via_ec; 753 684 else if (attr == &dev_attr_usb_charging.attr) 754 685 supported = priv->features.usb_charging; 755 686 ··· 1156 1089 /* 1157 1090 * input device 1158 1091 */ 1092 + #define IDEAPAD_WMI_KEY 0x100 1093 + 1159 1094 static const struct key_entry ideapad_keymap[] = { 1160 1095 { KE_KEY, 6, { KEY_SWITCHVIDEOMODE } }, 1161 1096 { KE_KEY, 7, { KEY_CAMERA } }, ··· 1170 1101 { KE_KEY, 65, { KEY_PROG4 } }, 1171 1102 { KE_KEY, 66, { KEY_TOUCHPAD_OFF } }, 1172 1103 { KE_KEY, 67, { KEY_TOUCHPAD_ON } }, 1104 + { KE_KEY, 68, { KEY_TOUCHPAD_TOGGLE } }, 1173 1105 { KE_KEY, 128, { KEY_ESC } }, 1106 + 1107 + /* 1108 + * WMI keys 1109 + */ 1110 + 1111 + /* FnLock (handled by the firmware) */ 1112 + { KE_IGNORE, 0x02 | IDEAPAD_WMI_KEY }, 1113 + /* Esc (handled by the firmware) */ 1114 + { KE_IGNORE, 0x03 | IDEAPAD_WMI_KEY }, 1115 + /* Customizable Lenovo Hotkey ("star" with 'S' inside) */ 1116 + { KE_KEY, 0x01 | IDEAPAD_WMI_KEY, { KEY_FAVORITES } }, 1117 + /* Dark mode toggle */ 1118 + { KE_KEY, 0x13 | IDEAPAD_WMI_KEY, { KEY_PROG1 } }, 1119 + /* Sound profile switch */ 1120 + { KE_KEY, 0x12 | IDEAPAD_WMI_KEY, { KEY_PROG2 } }, 1121 + /* Lenovo Virtual Background application */ 1122 + { KE_KEY, 0x28 | IDEAPAD_WMI_KEY, { KEY_PROG3 } }, 1123 + /* Lenovo Support */ 1124 + { KE_KEY, 0x27 | IDEAPAD_WMI_KEY, { KEY_HELP } }, 1125 + /* Refresh Rate Toggle */ 1126 + { KE_KEY, 0x0a | IDEAPAD_WMI_KEY, { KEY_DISPLAYTOGGLE } }, 1127 + 1174 1128 { KE_END }, 1175 1129 }; 1176 1130 ··· 1506 1414 /* 1507 1415 * module init/exit 1508 1416 */ 1509 - static void ideapad_sync_touchpad_state(struct ideapad_private *priv) 1417 + static void ideapad_sync_touchpad_state(struct ideapad_private *priv, bool send_events) 1510 1418 { 1511 1419 unsigned long value; 1512 - 1513 - if (!priv->features.touchpad_ctrl_via_ec) 1514 - return; 1420 + unsigned char param; 1421 + int ret; 1515 1422 1516 1423 /* Without reading from EC touchpad LED doesn't switch state */ 1517 - if (!read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value)) { 1518 - unsigned char param; 1519 - /* 1520 - * Some IdeaPads don't really turn off touchpad - they only 1521 - * switch the LED state. We (de)activate KBC AUX port to turn 1522 - * touchpad off and on. We send KEY_TOUCHPAD_OFF and 1523 - * KEY_TOUCHPAD_ON to not to get out of sync with LED 1524 - */ 1424 + ret = read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value); 1425 + if (ret) 1426 + return; 1427 + 1428 + /* 1429 + * Some IdeaPads don't really turn off touchpad - they only 1430 + * switch the LED state. We (de)activate KBC AUX port to turn 1431 + * touchpad off and on. We send KEY_TOUCHPAD_OFF and 1432 + * KEY_TOUCHPAD_ON to not to get out of sync with LED 1433 + */ 1434 + if (priv->features.ctrl_ps2_aux_port) 1525 1435 i8042_command(&param, value ? I8042_CMD_AUX_ENABLE : I8042_CMD_AUX_DISABLE); 1526 - ideapad_input_report(priv, value ? 67 : 66); 1527 - sysfs_notify(&priv->platform_device->dev.kobj, NULL, "touchpad"); 1436 + 1437 + if (send_events) { 1438 + /* 1439 + * On older models the EC controls the touchpad and toggles it 1440 + * on/off itself, in this case we report KEY_TOUCHPAD_ON/_OFF. 1441 + * If the EC did not toggle, report KEY_TOUCHPAD_TOGGLE. 1442 + */ 1443 + if (value != priv->r_touchpad_val) { 1444 + ideapad_input_report(priv, value ? 67 : 66); 1445 + sysfs_notify(&priv->platform_device->dev.kobj, NULL, "touchpad"); 1446 + } else { 1447 + ideapad_input_report(priv, 68); 1448 + } 1528 1449 } 1450 + 1451 + priv->r_touchpad_val = value; 1529 1452 } 1530 1453 1531 1454 static void ideapad_acpi_notify(acpi_handle handle, u32 event, void *data) ··· 1581 1474 ideapad_sync_rfk_state(priv); 1582 1475 break; 1583 1476 case 5: 1584 - ideapad_sync_touchpad_state(priv); 1477 + ideapad_sync_touchpad_state(priv, true); 1585 1478 break; 1586 1479 case 4: 1587 1480 ideapad_backlight_notify_brightness(priv); ··· 1611 1504 } 1612 1505 } 1613 1506 } 1614 - 1615 - #if IS_ENABLED(CONFIG_ACPI_WMI) 1616 - static void ideapad_wmi_notify(u32 value, void *context) 1617 - { 1618 - struct ideapad_private *priv = context; 1619 - unsigned long result; 1620 - 1621 - switch (value) { 1622 - case 128: 1623 - ideapad_input_report(priv, value); 1624 - break; 1625 - case 208: 1626 - if (!priv->features.set_fn_lock_led) 1627 - break; 1628 - 1629 - if (!eval_hals(priv->adev->handle, &result)) { 1630 - bool state = test_bit(HALS_FNLOCK_STATE_BIT, &result); 1631 - 1632 - exec_sals(priv->adev->handle, state ? SALS_FNLOCK_ON : SALS_FNLOCK_OFF); 1633 - } 1634 - break; 1635 - default: 1636 - dev_info(&priv->platform_device->dev, 1637 - "Unknown WMI event: %u\n", value); 1638 - } 1639 - } 1640 - #endif 1641 1507 1642 1508 /* On some models we need to call exec_sals(SALS_FNLOCK_ON/OFF) to set the LED */ 1643 1509 static const struct dmi_system_id set_fn_lock_led_list[] = { ··· 1643 1563 {} 1644 1564 }; 1645 1565 1646 - static const struct dmi_system_id no_touchpad_switch_list[] = { 1566 + /* 1567 + * On some models the EC toggles the touchpad muted LED on touchpad toggle 1568 + * hotkey presses, but the EC does not actually disable the touchpad itself. 1569 + * On these models the driver needs to explicitly enable/disable the i8042 1570 + * (PS/2) aux port. 1571 + */ 1572 + static const struct dmi_system_id ctrl_ps2_aux_port_list[] = { 1647 1573 { 1648 - .ident = "Lenovo Yoga 3 Pro 1370", 1574 + /* Lenovo Ideapad Z570 */ 1649 1575 .matches = { 1650 1576 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 1651 - DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 3"), 1652 - }, 1653 - }, 1654 - { 1655 - .ident = "ZhaoYang K4e-IML", 1656 - .matches = { 1657 - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), 1658 - DMI_MATCH(DMI_PRODUCT_VERSION, "ZhaoYang K4e-IML"), 1577 + DMI_MATCH(DMI_PRODUCT_VERSION, "Ideapad Z570"), 1659 1578 }, 1660 1579 }, 1661 1580 {} ··· 1669 1590 set_fn_lock_led || dmi_check_system(set_fn_lock_led_list); 1670 1591 priv->features.hw_rfkill_switch = 1671 1592 hw_rfkill_switch || dmi_check_system(hw_rfkill_list); 1672 - 1673 - /* Most ideapads with ELAN0634 touchpad don't use EC touchpad switch */ 1674 - if (acpi_dev_present("ELAN0634", NULL, -1)) 1675 - priv->features.touchpad_ctrl_via_ec = 0; 1676 - else if (dmi_check_system(no_touchpad_switch_list)) 1677 - priv->features.touchpad_ctrl_via_ec = 0; 1678 - else 1679 - priv->features.touchpad_ctrl_via_ec = 1; 1593 + priv->features.ctrl_ps2_aux_port = 1594 + ctrl_ps2_aux_port || dmi_check_system(ctrl_ps2_aux_port_list); 1595 + priv->features.touchpad_ctrl_via_ec = touchpad_ctrl_via_ec; 1680 1596 1681 1597 if (!read_ec_data(handle, VPCCMD_R_FAN, &val)) 1682 1598 priv->features.fan_mode = true; ··· 1696 1622 } 1697 1623 } 1698 1624 1625 + #if IS_ENABLED(CONFIG_ACPI_WMI) 1626 + /* 1627 + * WMI driver 1628 + */ 1629 + enum ideapad_wmi_event_type { 1630 + IDEAPAD_WMI_EVENT_ESC, 1631 + IDEAPAD_WMI_EVENT_FN_KEYS, 1632 + }; 1633 + 1634 + struct ideapad_wmi_private { 1635 + enum ideapad_wmi_event_type event; 1636 + }; 1637 + 1638 + static int ideapad_wmi_probe(struct wmi_device *wdev, const void *context) 1639 + { 1640 + struct ideapad_wmi_private *wpriv; 1641 + 1642 + wpriv = devm_kzalloc(&wdev->dev, sizeof(*wpriv), GFP_KERNEL); 1643 + if (!wpriv) 1644 + return -ENOMEM; 1645 + 1646 + *wpriv = *(const struct ideapad_wmi_private *)context; 1647 + 1648 + dev_set_drvdata(&wdev->dev, wpriv); 1649 + return 0; 1650 + } 1651 + 1652 + static void ideapad_wmi_notify(struct wmi_device *wdev, union acpi_object *data) 1653 + { 1654 + struct ideapad_wmi_private *wpriv = dev_get_drvdata(&wdev->dev); 1655 + struct ideapad_private *priv; 1656 + unsigned long result; 1657 + 1658 + mutex_lock(&ideapad_shared_mutex); 1659 + 1660 + priv = ideapad_shared; 1661 + if (!priv) 1662 + goto unlock; 1663 + 1664 + switch (wpriv->event) { 1665 + case IDEAPAD_WMI_EVENT_ESC: 1666 + ideapad_input_report(priv, 128); 1667 + break; 1668 + case IDEAPAD_WMI_EVENT_FN_KEYS: 1669 + if (priv->features.set_fn_lock_led && 1670 + !eval_hals(priv->adev->handle, &result)) { 1671 + bool state = test_bit(HALS_FNLOCK_STATE_BIT, &result); 1672 + 1673 + exec_sals(priv->adev->handle, state ? SALS_FNLOCK_ON : SALS_FNLOCK_OFF); 1674 + } 1675 + 1676 + if (data->type != ACPI_TYPE_INTEGER) { 1677 + dev_warn(&wdev->dev, 1678 + "WMI event data is not an integer\n"); 1679 + break; 1680 + } 1681 + 1682 + dev_dbg(&wdev->dev, "WMI fn-key event: 0x%llx\n", 1683 + data->integer.value); 1684 + 1685 + ideapad_input_report(priv, 1686 + data->integer.value | IDEAPAD_WMI_KEY); 1687 + 1688 + break; 1689 + } 1690 + unlock: 1691 + mutex_unlock(&ideapad_shared_mutex); 1692 + } 1693 + 1694 + static const struct ideapad_wmi_private ideapad_wmi_context_esc = { 1695 + .event = IDEAPAD_WMI_EVENT_ESC 1696 + }; 1697 + 1698 + static const struct ideapad_wmi_private ideapad_wmi_context_fn_keys = { 1699 + .event = IDEAPAD_WMI_EVENT_FN_KEYS 1700 + }; 1701 + 1702 + static const struct wmi_device_id ideapad_wmi_ids[] = { 1703 + { "26CAB2E5-5CF1-46AE-AAC3-4A12B6BA50E6", &ideapad_wmi_context_esc }, /* Yoga 3 */ 1704 + { "56322276-8493-4CE8-A783-98C991274F5E", &ideapad_wmi_context_esc }, /* Yoga 700 */ 1705 + { "8FC0DE0C-B4E4-43FD-B0F3-8871711C1294", &ideapad_wmi_context_fn_keys }, /* Legion 5 */ 1706 + {}, 1707 + }; 1708 + MODULE_DEVICE_TABLE(wmi, ideapad_wmi_ids); 1709 + 1710 + static struct wmi_driver ideapad_wmi_driver = { 1711 + .driver = { 1712 + .name = "ideapad_wmi", 1713 + }, 1714 + .id_table = ideapad_wmi_ids, 1715 + .probe = ideapad_wmi_probe, 1716 + .notify = ideapad_wmi_notify, 1717 + }; 1718 + 1719 + static int ideapad_wmi_driver_register(void) 1720 + { 1721 + return wmi_driver_register(&ideapad_wmi_driver); 1722 + } 1723 + 1724 + static void ideapad_wmi_driver_unregister(void) 1725 + { 1726 + return wmi_driver_unregister(&ideapad_wmi_driver); 1727 + } 1728 + 1729 + #else 1730 + static inline int ideapad_wmi_driver_register(void) { return 0; } 1731 + static inline void ideapad_wmi_driver_unregister(void) { } 1732 + #endif 1733 + 1734 + /* 1735 + * ACPI driver 1736 + */ 1699 1737 static int ideapad_acpi_add(struct platform_device *pdev) 1700 1738 { 1701 1739 struct acpi_device *adev = ACPI_COMPANION(&pdev->dev); ··· 1856 1670 if (!priv->features.hw_rfkill_switch) 1857 1671 write_ec_cmd(priv->adev->handle, VPCCMD_W_RF, 1); 1858 1672 1859 - /* The same for Touchpad */ 1860 - if (!priv->features.touchpad_ctrl_via_ec) 1861 - write_ec_cmd(priv->adev->handle, VPCCMD_W_TOUCHPAD, 1); 1862 - 1863 1673 for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) 1864 1674 if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg)) 1865 1675 ideapad_register_rfkill(priv, i); 1866 1676 1867 1677 ideapad_sync_rfk_state(priv); 1868 - ideapad_sync_touchpad_state(priv); 1678 + ideapad_sync_touchpad_state(priv, false); 1869 1679 1870 1680 err = ideapad_dytc_profile_init(priv); 1871 1681 if (err) { ··· 1885 1703 goto notification_failed; 1886 1704 } 1887 1705 1888 - #if IS_ENABLED(CONFIG_ACPI_WMI) 1889 - for (i = 0; i < ARRAY_SIZE(ideapad_wmi_fnesc_events); i++) { 1890 - status = wmi_install_notify_handler(ideapad_wmi_fnesc_events[i], 1891 - ideapad_wmi_notify, priv); 1892 - if (ACPI_SUCCESS(status)) { 1893 - priv->fnesc_guid = ideapad_wmi_fnesc_events[i]; 1894 - break; 1895 - } 1896 - } 1897 - 1898 - if (ACPI_FAILURE(status) && status != AE_NOT_EXIST) { 1899 - err = -EIO; 1900 - goto notification_failed_wmi; 1901 - } 1902 - #endif 1706 + err = ideapad_shared_init(priv); 1707 + if (err) 1708 + goto shared_init_failed; 1903 1709 1904 1710 return 0; 1905 1711 1906 - #if IS_ENABLED(CONFIG_ACPI_WMI) 1907 - notification_failed_wmi: 1712 + shared_init_failed: 1908 1713 acpi_remove_notify_handler(priv->adev->handle, 1909 1714 ACPI_DEVICE_NOTIFY, 1910 1715 ideapad_acpi_notify); 1911 - #endif 1912 1716 1913 1717 notification_failed: 1914 1718 ideapad_backlight_exit(priv); ··· 1920 1752 struct ideapad_private *priv = dev_get_drvdata(&pdev->dev); 1921 1753 int i; 1922 1754 1923 - #if IS_ENABLED(CONFIG_ACPI_WMI) 1924 - if (priv->fnesc_guid) 1925 - wmi_remove_notify_handler(priv->fnesc_guid); 1926 - #endif 1755 + ideapad_shared_exit(priv); 1927 1756 1928 1757 acpi_remove_notify_handler(priv->adev->handle, 1929 1758 ACPI_DEVICE_NOTIFY, ··· 1946 1781 struct ideapad_private *priv = dev_get_drvdata(dev); 1947 1782 1948 1783 ideapad_sync_rfk_state(priv); 1949 - ideapad_sync_touchpad_state(priv); 1784 + ideapad_sync_touchpad_state(priv, false); 1950 1785 1951 1786 if (priv->dytc) 1952 1787 dytc_profile_refresh(priv); ··· 1972 1807 }, 1973 1808 }; 1974 1809 1975 - module_platform_driver(ideapad_acpi_driver); 1810 + static int __init ideapad_laptop_init(void) 1811 + { 1812 + int err; 1813 + 1814 + err = ideapad_wmi_driver_register(); 1815 + if (err) 1816 + return err; 1817 + 1818 + err = platform_driver_register(&ideapad_acpi_driver); 1819 + if (err) { 1820 + ideapad_wmi_driver_unregister(); 1821 + return err; 1822 + } 1823 + 1824 + return 0; 1825 + } 1826 + module_init(ideapad_laptop_init) 1827 + 1828 + static void __exit ideapad_laptop_exit(void) 1829 + { 1830 + ideapad_wmi_driver_unregister(); 1831 + platform_driver_unregister(&ideapad_acpi_driver); 1832 + } 1833 + module_exit(ideapad_laptop_exit) 1976 1834 1977 1835 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); 1978 1836 MODULE_DESCRIPTION("IdeaPad ACPI Extras");
+4 -4
drivers/platform/x86/intel/Kconfig
··· 157 157 as usual. 158 158 159 159 config INTEL_SDSI 160 - tristate "Intel Software Defined Silicon Driver" 160 + tristate "Intel On Demand (Software Defined Silicon) Driver" 161 161 depends on INTEL_VSEC 162 162 depends on X86_64 163 163 help 164 - This driver enables access to the Intel Software Defined Silicon 165 - interface used to provision silicon features with an authentication 166 - certificate and capability license. 164 + This driver enables access to the Intel On Demand (formerly Software 165 + Defined Silicon) interface used to provision silicon features with an 166 + authentication certificate and capability license. 167 167 168 168 To compile this driver as a module, choose M here: the module will 169 169 be called intel_sdsi.
+31 -5
drivers/platform/x86/intel/hid.c
··· 16 16 #include <linux/suspend.h> 17 17 #include "../dual_accel_detect.h" 18 18 19 + enum intel_hid_tablet_sw_mode { 20 + TABLET_SW_AUTO = -1, 21 + TABLET_SW_OFF = 0, 22 + TABLET_SW_AT_EVENT, 23 + TABLET_SW_AT_PROBE, 24 + }; 25 + 26 + static bool enable_5_button_array; 27 + module_param(enable_5_button_array, bool, 0444); 28 + MODULE_PARM_DESC(enable_5_button_array, 29 + "Enable 5 Button Array support. " 30 + "If you need this please report this to: platform-driver-x86@vger.kernel.org"); 31 + 32 + static int enable_sw_tablet_mode = TABLET_SW_AUTO; 33 + module_param(enable_sw_tablet_mode, int, 0444); 34 + MODULE_PARM_DESC(enable_sw_tablet_mode, 35 + "Enable SW_TABLET_MODE reporting -1:auto 0:off 1:at-first-event 2:at-probe. " 36 + "If you need this please report this to: platform-driver-x86@vger.kernel.org"); 37 + 19 38 /* When NOT in tablet mode, VGBS returns with the flag 0x40 */ 20 39 #define TABLET_MODE_FLAG BIT(6) 21 40 ··· 176 157 struct input_dev *array; 177 158 struct input_dev *switches; 178 159 bool wakeup_mode; 179 - bool auto_add_switch; 180 160 }; 181 161 182 162 #define HID_EVENT_FILTER_UUID "eeec56b3-4442-408f-a792-4edd4d758054" ··· 505 487 * SW_TABLET_MODE report, in these cases we enable support when receiving 506 488 * the first event instead of during driver setup. 507 489 */ 508 - if (!priv->switches && priv->auto_add_switch && (event == 0xcc || event == 0xcd)) { 490 + if (!priv->switches && enable_sw_tablet_mode == TABLET_SW_AT_EVENT && 491 + (event == 0xcc || event == 0xcd)) { 509 492 dev_info(&device->dev, "switch event received, enable switches supports\n"); 510 493 err = intel_hid_switches_setup(device); 511 494 if (err) ··· 611 592 return true; 612 593 } 613 594 614 - if (dmi_check_system(button_array_table)) 595 + if (enable_5_button_array || dmi_check_system(button_array_table)) 615 596 return true; 616 597 617 598 return false; ··· 648 629 dev_set_drvdata(&device->dev, priv); 649 630 650 631 /* See dual_accel_detect.h for more info on the dual_accel check. */ 651 - priv->auto_add_switch = dmi_check_system(dmi_auto_add_switch) && !dual_accel_detect(); 632 + if (enable_sw_tablet_mode == TABLET_SW_AUTO) { 633 + if (dmi_check_system(dmi_vgbs_allow_list)) 634 + enable_sw_tablet_mode = TABLET_SW_AT_PROBE; 635 + else if (dmi_check_system(dmi_auto_add_switch) && !dual_accel_detect()) 636 + enable_sw_tablet_mode = TABLET_SW_AT_EVENT; 637 + else 638 + enable_sw_tablet_mode = TABLET_SW_OFF; 639 + } 652 640 653 641 err = intel_hid_input_setup(device); 654 642 if (err) { ··· 672 646 } 673 647 674 648 /* Setup switches for devices that we know VGBS return correctly */ 675 - if (dmi_check_system(dmi_vgbs_allow_list)) { 649 + if (enable_sw_tablet_mode == TABLET_SW_AT_PROBE) { 676 650 dev_info(&device->dev, "platform supports switches\n"); 677 651 err = intel_hid_switches_setup(device); 678 652 if (err)
+2 -1
drivers/platform/x86/intel/pmc/Makefile
··· 3 3 # Intel x86 Platform-Specific Drivers 4 4 # 5 5 6 - intel_pmc_core-y := core.o 6 + intel_pmc_core-y := core.o spt.o cnp.o icl.o tgl.o \ 7 + adl.o mtl.o 7 8 obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core.o 8 9 intel_pmc_core_pltdrv-y := pltdrv.o 9 10 obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core_pltdrv.o
+325
drivers/platform/x86/intel/pmc/adl.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * This file contains platform specific structure definitions 4 + * and init function used by Alder Lake PCH. 5 + * 6 + * Copyright (c) 2022, Intel Corporation. 7 + * All Rights Reserved. 8 + * 9 + */ 10 + 11 + #include "core.h" 12 + 13 + /* Alder Lake: PGD PFET Enable Ack Status Register(s) bitmap */ 14 + const struct pmc_bit_map adl_pfear_map[] = { 15 + {"SPI/eSPI", BIT(2)}, 16 + {"XHCI", BIT(3)}, 17 + {"SPA", BIT(4)}, 18 + {"SPB", BIT(5)}, 19 + {"SPC", BIT(6)}, 20 + {"GBE", BIT(7)}, 21 + 22 + {"SATA", BIT(0)}, 23 + {"HDA_PGD0", BIT(1)}, 24 + {"HDA_PGD1", BIT(2)}, 25 + {"HDA_PGD2", BIT(3)}, 26 + {"HDA_PGD3", BIT(4)}, 27 + {"SPD", BIT(5)}, 28 + {"LPSS", BIT(6)}, 29 + 30 + {"SMB", BIT(0)}, 31 + {"ISH", BIT(1)}, 32 + {"ITH", BIT(3)}, 33 + 34 + {"XDCI", BIT(1)}, 35 + {"DCI", BIT(2)}, 36 + {"CSE", BIT(3)}, 37 + {"CSME_KVM", BIT(4)}, 38 + {"CSME_PMT", BIT(5)}, 39 + {"CSME_CLINK", BIT(6)}, 40 + {"CSME_PTIO", BIT(7)}, 41 + 42 + {"CSME_USBR", BIT(0)}, 43 + {"CSME_SUSRAM", BIT(1)}, 44 + {"CSME_SMT1", BIT(2)}, 45 + {"CSME_SMS2", BIT(4)}, 46 + {"CSME_SMS1", BIT(5)}, 47 + {"CSME_RTC", BIT(6)}, 48 + {"CSME_PSF", BIT(7)}, 49 + 50 + {"CNVI", BIT(3)}, 51 + {"HDA_PGD4", BIT(2)}, 52 + {"HDA_PGD5", BIT(3)}, 53 + {"HDA_PGD6", BIT(4)}, 54 + {} 55 + }; 56 + 57 + const struct pmc_bit_map *ext_adl_pfear_map[] = { 58 + /* 59 + * Check intel_pmc_core_ids[] users of cnp_reg_map for 60 + * a list of core SoCs using this. 61 + */ 62 + adl_pfear_map, 63 + NULL 64 + }; 65 + 66 + const struct pmc_bit_map adl_ltr_show_map[] = { 67 + {"SOUTHPORT_A", CNP_PMC_LTR_SPA}, 68 + {"SOUTHPORT_B", CNP_PMC_LTR_SPB}, 69 + {"SATA", CNP_PMC_LTR_SATA}, 70 + {"GIGABIT_ETHERNET", CNP_PMC_LTR_GBE}, 71 + {"XHCI", CNP_PMC_LTR_XHCI}, 72 + {"SOUTHPORT_F", ADL_PMC_LTR_SPF}, 73 + {"ME", CNP_PMC_LTR_ME}, 74 + /* EVA is Enterprise Value Add, doesn't really exist on PCH */ 75 + {"SATA1", CNP_PMC_LTR_EVA}, 76 + {"SOUTHPORT_C", CNP_PMC_LTR_SPC}, 77 + {"HD_AUDIO", CNP_PMC_LTR_AZ}, 78 + {"CNV", CNP_PMC_LTR_CNV}, 79 + {"LPSS", CNP_PMC_LTR_LPSS}, 80 + {"SOUTHPORT_D", CNP_PMC_LTR_SPD}, 81 + {"SOUTHPORT_E", CNP_PMC_LTR_SPE}, 82 + {"SATA2", CNP_PMC_LTR_CAM}, 83 + {"ESPI", CNP_PMC_LTR_ESPI}, 84 + {"SCC", CNP_PMC_LTR_SCC}, 85 + {"ISH", CNP_PMC_LTR_ISH}, 86 + {"UFSX2", CNP_PMC_LTR_UFSX2}, 87 + {"EMMC", CNP_PMC_LTR_EMMC}, 88 + /* 89 + * Check intel_pmc_core_ids[] users of cnp_reg_map for 90 + * a list of core SoCs using this. 91 + */ 92 + {"WIGIG", ICL_PMC_LTR_WIGIG}, 93 + {"THC0", TGL_PMC_LTR_THC0}, 94 + {"THC1", TGL_PMC_LTR_THC1}, 95 + {"SOUTHPORT_G", CNP_PMC_LTR_RESERVED}, 96 + 97 + /* Below two cannot be used for LTR_IGNORE */ 98 + {"CURRENT_PLATFORM", CNP_PMC_LTR_CUR_PLT}, 99 + {"AGGREGATED_SYSTEM", CNP_PMC_LTR_CUR_ASLT}, 100 + {} 101 + }; 102 + 103 + const struct pmc_bit_map adl_clocksource_status_map[] = { 104 + {"CLKPART1_OFF_STS", BIT(0)}, 105 + {"CLKPART2_OFF_STS", BIT(1)}, 106 + {"CLKPART3_OFF_STS", BIT(2)}, 107 + {"CLKPART4_OFF_STS", BIT(3)}, 108 + {"CLKPART5_OFF_STS", BIT(4)}, 109 + {"CLKPART6_OFF_STS", BIT(5)}, 110 + {"CLKPART7_OFF_STS", BIT(6)}, 111 + {"CLKPART8_OFF_STS", BIT(7)}, 112 + {"PCIE0PLL_OFF_STS", BIT(10)}, 113 + {"PCIE1PLL_OFF_STS", BIT(11)}, 114 + {"PCIE2PLL_OFF_STS", BIT(12)}, 115 + {"PCIE3PLL_OFF_STS", BIT(13)}, 116 + {"PCIE4PLL_OFF_STS", BIT(14)}, 117 + {"PCIE5PLL_OFF_STS", BIT(15)}, 118 + {"PCIE6PLL_OFF_STS", BIT(16)}, 119 + {"USB2PLL_OFF_STS", BIT(18)}, 120 + {"OCPLL_OFF_STS", BIT(22)}, 121 + {"AUDIOPLL_OFF_STS", BIT(23)}, 122 + {"GBEPLL_OFF_STS", BIT(24)}, 123 + {"Fast_XTAL_Osc_OFF_STS", BIT(25)}, 124 + {"AC_Ring_Osc_OFF_STS", BIT(26)}, 125 + {"MC_Ring_Osc_OFF_STS", BIT(27)}, 126 + {"SATAPLL_OFF_STS", BIT(29)}, 127 + {"USB3PLL_OFF_STS", BIT(31)}, 128 + {} 129 + }; 130 + 131 + const struct pmc_bit_map adl_power_gating_status_0_map[] = { 132 + {"PMC_PGD0_PG_STS", BIT(0)}, 133 + {"DMI_PGD0_PG_STS", BIT(1)}, 134 + {"ESPISPI_PGD0_PG_STS", BIT(2)}, 135 + {"XHCI_PGD0_PG_STS", BIT(3)}, 136 + {"SPA_PGD0_PG_STS", BIT(4)}, 137 + {"SPB_PGD0_PG_STS", BIT(5)}, 138 + {"SPC_PGD0_PG_STS", BIT(6)}, 139 + {"GBE_PGD0_PG_STS", BIT(7)}, 140 + {"SATA_PGD0_PG_STS", BIT(8)}, 141 + {"DSP_PGD0_PG_STS", BIT(9)}, 142 + {"DSP_PGD1_PG_STS", BIT(10)}, 143 + {"DSP_PGD2_PG_STS", BIT(11)}, 144 + {"DSP_PGD3_PG_STS", BIT(12)}, 145 + {"SPD_PGD0_PG_STS", BIT(13)}, 146 + {"LPSS_PGD0_PG_STS", BIT(14)}, 147 + {"SMB_PGD0_PG_STS", BIT(16)}, 148 + {"ISH_PGD0_PG_STS", BIT(17)}, 149 + {"NPK_PGD0_PG_STS", BIT(19)}, 150 + {"PECI_PGD0_PG_STS", BIT(21)}, 151 + {"XDCI_PGD0_PG_STS", BIT(25)}, 152 + {"EXI_PGD0_PG_STS", BIT(26)}, 153 + {"CSE_PGD0_PG_STS", BIT(27)}, 154 + {"KVMCC_PGD0_PG_STS", BIT(28)}, 155 + {"PMT_PGD0_PG_STS", BIT(29)}, 156 + {"CLINK_PGD0_PG_STS", BIT(30)}, 157 + {"PTIO_PGD0_PG_STS", BIT(31)}, 158 + {} 159 + }; 160 + 161 + const struct pmc_bit_map adl_power_gating_status_1_map[] = { 162 + {"USBR0_PGD0_PG_STS", BIT(0)}, 163 + {"SMT1_PGD0_PG_STS", BIT(2)}, 164 + {"CSMERTC_PGD0_PG_STS", BIT(6)}, 165 + {"CSMEPSF_PGD0_PG_STS", BIT(7)}, 166 + {"CNVI_PGD0_PG_STS", BIT(19)}, 167 + {"DSP_PGD4_PG_STS", BIT(26)}, 168 + {"SPG_PGD0_PG_STS", BIT(27)}, 169 + {"SPE_PGD0_PG_STS", BIT(28)}, 170 + {} 171 + }; 172 + 173 + const struct pmc_bit_map adl_power_gating_status_2_map[] = { 174 + {"THC0_PGD0_PG_STS", BIT(7)}, 175 + {"THC1_PGD0_PG_STS", BIT(8)}, 176 + {"SPF_PGD0_PG_STS", BIT(14)}, 177 + {} 178 + }; 179 + 180 + const struct pmc_bit_map adl_d3_status_0_map[] = { 181 + {"ISH_D3_STS", BIT(2)}, 182 + {"LPSS_D3_STS", BIT(3)}, 183 + {"XDCI_D3_STS", BIT(4)}, 184 + {"XHCI_D3_STS", BIT(5)}, 185 + {"SPA_D3_STS", BIT(12)}, 186 + {"SPB_D3_STS", BIT(13)}, 187 + {"SPC_D3_STS", BIT(14)}, 188 + {"SPD_D3_STS", BIT(15)}, 189 + {"SPE_D3_STS", BIT(16)}, 190 + {"DSP_D3_STS", BIT(19)}, 191 + {"SATA_D3_STS", BIT(20)}, 192 + {"DMI_D3_STS", BIT(22)}, 193 + {} 194 + }; 195 + 196 + const struct pmc_bit_map adl_d3_status_1_map[] = { 197 + {"GBE_D3_STS", BIT(19)}, 198 + {"CNVI_D3_STS", BIT(27)}, 199 + {} 200 + }; 201 + 202 + const struct pmc_bit_map adl_d3_status_2_map[] = { 203 + {"CSMERTC_D3_STS", BIT(1)}, 204 + {"CSE_D3_STS", BIT(4)}, 205 + {"KVMCC_D3_STS", BIT(5)}, 206 + {"USBR0_D3_STS", BIT(6)}, 207 + {"SMT1_D3_STS", BIT(8)}, 208 + {"PTIO_D3_STS", BIT(16)}, 209 + {"PMT_D3_STS", BIT(17)}, 210 + {} 211 + }; 212 + 213 + const struct pmc_bit_map adl_d3_status_3_map[] = { 214 + {"THC0_D3_STS", BIT(14)}, 215 + {"THC1_D3_STS", BIT(15)}, 216 + {} 217 + }; 218 + 219 + const struct pmc_bit_map adl_vnn_req_status_0_map[] = { 220 + {"ISH_VNN_REQ_STS", BIT(2)}, 221 + {"ESPISPI_VNN_REQ_STS", BIT(18)}, 222 + {"DSP_VNN_REQ_STS", BIT(19)}, 223 + {} 224 + }; 225 + 226 + const struct pmc_bit_map adl_vnn_req_status_1_map[] = { 227 + {"NPK_VNN_REQ_STS", BIT(4)}, 228 + {"EXI_VNN_REQ_STS", BIT(9)}, 229 + {"GBE_VNN_REQ_STS", BIT(19)}, 230 + {"SMB_VNN_REQ_STS", BIT(25)}, 231 + {"CNVI_VNN_REQ_STS", BIT(27)}, 232 + {} 233 + }; 234 + 235 + const struct pmc_bit_map adl_vnn_req_status_2_map[] = { 236 + {"CSMERTC_VNN_REQ_STS", BIT(1)}, 237 + {"CSE_VNN_REQ_STS", BIT(4)}, 238 + {"SMT1_VNN_REQ_STS", BIT(8)}, 239 + {"CLINK_VNN_REQ_STS", BIT(14)}, 240 + {"GPIOCOM4_VNN_REQ_STS", BIT(20)}, 241 + {"GPIOCOM3_VNN_REQ_STS", BIT(21)}, 242 + {"GPIOCOM2_VNN_REQ_STS", BIT(22)}, 243 + {"GPIOCOM1_VNN_REQ_STS", BIT(23)}, 244 + {"GPIOCOM0_VNN_REQ_STS", BIT(24)}, 245 + {} 246 + }; 247 + 248 + const struct pmc_bit_map adl_vnn_req_status_3_map[] = { 249 + {"GPIOCOM5_VNN_REQ_STS", BIT(11)}, 250 + {} 251 + }; 252 + 253 + const struct pmc_bit_map adl_vnn_misc_status_map[] = { 254 + {"CPU_C10_REQ_STS", BIT(0)}, 255 + {"PCIe_LPM_En_REQ_STS", BIT(3)}, 256 + {"ITH_REQ_STS", BIT(5)}, 257 + {"CNVI_REQ_STS", BIT(6)}, 258 + {"ISH_REQ_STS", BIT(7)}, 259 + {"USB2_SUS_PG_Sys_REQ_STS", BIT(10)}, 260 + {"PCIe_Clk_REQ_STS", BIT(12)}, 261 + {"MPHY_Core_DL_REQ_STS", BIT(16)}, 262 + {"Break-even_En_REQ_STS", BIT(17)}, 263 + {"MPHY_SUS_REQ_STS", BIT(22)}, 264 + {"xDCI_attached_REQ_STS", BIT(24)}, 265 + {} 266 + }; 267 + 268 + const struct pmc_bit_map *adl_lpm_maps[] = { 269 + adl_clocksource_status_map, 270 + adl_power_gating_status_0_map, 271 + adl_power_gating_status_1_map, 272 + adl_power_gating_status_2_map, 273 + adl_d3_status_0_map, 274 + adl_d3_status_1_map, 275 + adl_d3_status_2_map, 276 + adl_d3_status_3_map, 277 + adl_vnn_req_status_0_map, 278 + adl_vnn_req_status_1_map, 279 + adl_vnn_req_status_2_map, 280 + adl_vnn_req_status_3_map, 281 + adl_vnn_misc_status_map, 282 + tgl_signal_status_map, 283 + NULL 284 + }; 285 + 286 + const struct pmc_reg_map adl_reg_map = { 287 + .pfear_sts = ext_adl_pfear_map, 288 + .slp_s0_offset = ADL_PMC_SLP_S0_RES_COUNTER_OFFSET, 289 + .slp_s0_res_counter_step = TGL_PMC_SLP_S0_RES_COUNTER_STEP, 290 + .ltr_show_sts = adl_ltr_show_map, 291 + .msr_sts = msr_map, 292 + .ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET, 293 + .regmap_length = CNP_PMC_MMIO_REG_LEN, 294 + .ppfear0_offset = CNP_PMC_HOST_PPFEAR0A, 295 + .ppfear_buckets = CNP_PPFEAR_NUM_ENTRIES, 296 + .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, 297 + .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, 298 + .ltr_ignore_max = ADL_NUM_IP_IGN_ALLOWED, 299 + .lpm_num_modes = ADL_LPM_NUM_MODES, 300 + .lpm_num_maps = ADL_LPM_NUM_MAPS, 301 + .lpm_res_counter_step_x2 = TGL_PMC_LPM_RES_COUNTER_STEP_X2, 302 + .etr3_offset = ETR3_OFFSET, 303 + .lpm_sts_latch_en_offset = ADL_LPM_STATUS_LATCH_EN_OFFSET, 304 + .lpm_priority_offset = ADL_LPM_PRI_OFFSET, 305 + .lpm_en_offset = ADL_LPM_EN_OFFSET, 306 + .lpm_residency_offset = ADL_LPM_RESIDENCY_OFFSET, 307 + .lpm_sts = adl_lpm_maps, 308 + .lpm_status_offset = ADL_LPM_STATUS_OFFSET, 309 + .lpm_live_status_offset = ADL_LPM_LIVE_STATUS_OFFSET, 310 + }; 311 + 312 + void adl_core_configure(struct pmc_dev *pmcdev) 313 + { 314 + /* Due to a hardware limitation, the GBE LTR blocks PC10 315 + * when a cable is attached. Tell the PMC to ignore it. 316 + */ 317 + dev_dbg(&pmcdev->pdev->dev, "ignoring GBE LTR\n"); 318 + pmc_core_send_ltr_ignore(pmcdev, 3); 319 + } 320 + 321 + void adl_core_init(struct pmc_dev *pmcdev) 322 + { 323 + pmcdev->map = &adl_reg_map; 324 + pmcdev->core_configure = adl_core_configure; 325 + }
+210
drivers/platform/x86/intel/pmc/cnp.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * This file contains platform specific structure definitions 4 + * and init function used by Cannon Lake Point PCH. 5 + * 6 + * Copyright (c) 2022, Intel Corporation. 7 + * All Rights Reserved. 8 + * 9 + */ 10 + 11 + #include "core.h" 12 + 13 + /* Cannon Lake: PGD PFET Enable Ack Status Register(s) bitmap */ 14 + const struct pmc_bit_map cnp_pfear_map[] = { 15 + {"PMC", BIT(0)}, 16 + {"OPI-DMI", BIT(1)}, 17 + {"SPI/eSPI", BIT(2)}, 18 + {"XHCI", BIT(3)}, 19 + {"SPA", BIT(4)}, 20 + {"SPB", BIT(5)}, 21 + {"SPC", BIT(6)}, 22 + {"GBE", BIT(7)}, 23 + 24 + {"SATA", BIT(0)}, 25 + {"HDA_PGD0", BIT(1)}, 26 + {"HDA_PGD1", BIT(2)}, 27 + {"HDA_PGD2", BIT(3)}, 28 + {"HDA_PGD3", BIT(4)}, 29 + {"SPD", BIT(5)}, 30 + {"LPSS", BIT(6)}, 31 + {"LPC", BIT(7)}, 32 + 33 + {"SMB", BIT(0)}, 34 + {"ISH", BIT(1)}, 35 + {"P2SB", BIT(2)}, 36 + {"NPK_VNN", BIT(3)}, 37 + {"SDX", BIT(4)}, 38 + {"SPE", BIT(5)}, 39 + {"Fuse", BIT(6)}, 40 + {"SBR8", BIT(7)}, 41 + 42 + {"CSME_FSC", BIT(0)}, 43 + {"USB3_OTG", BIT(1)}, 44 + {"EXI", BIT(2)}, 45 + {"CSE", BIT(3)}, 46 + {"CSME_KVM", BIT(4)}, 47 + {"CSME_PMT", BIT(5)}, 48 + {"CSME_CLINK", BIT(6)}, 49 + {"CSME_PTIO", BIT(7)}, 50 + 51 + {"CSME_USBR", BIT(0)}, 52 + {"CSME_SUSRAM", BIT(1)}, 53 + {"CSME_SMT1", BIT(2)}, 54 + {"CSME_SMT4", BIT(3)}, 55 + {"CSME_SMS2", BIT(4)}, 56 + {"CSME_SMS1", BIT(5)}, 57 + {"CSME_RTC", BIT(6)}, 58 + {"CSME_PSF", BIT(7)}, 59 + 60 + {"SBR0", BIT(0)}, 61 + {"SBR1", BIT(1)}, 62 + {"SBR2", BIT(2)}, 63 + {"SBR3", BIT(3)}, 64 + {"SBR4", BIT(4)}, 65 + {"SBR5", BIT(5)}, 66 + {"CSME_PECI", BIT(6)}, 67 + {"PSF1", BIT(7)}, 68 + 69 + {"PSF2", BIT(0)}, 70 + {"PSF3", BIT(1)}, 71 + {"PSF4", BIT(2)}, 72 + {"CNVI", BIT(3)}, 73 + {"UFS0", BIT(4)}, 74 + {"EMMC", BIT(5)}, 75 + {"SPF", BIT(6)}, 76 + {"SBR6", BIT(7)}, 77 + 78 + {"SBR7", BIT(0)}, 79 + {"NPK_AON", BIT(1)}, 80 + {"HDA_PGD4", BIT(2)}, 81 + {"HDA_PGD5", BIT(3)}, 82 + {"HDA_PGD6", BIT(4)}, 83 + {"PSF6", BIT(5)}, 84 + {"PSF7", BIT(6)}, 85 + {"PSF8", BIT(7)}, 86 + {} 87 + }; 88 + 89 + const struct pmc_bit_map *ext_cnp_pfear_map[] = { 90 + /* 91 + * Check intel_pmc_core_ids[] users of cnp_reg_map for 92 + * a list of core SoCs using this. 93 + */ 94 + cnp_pfear_map, 95 + NULL 96 + }; 97 + 98 + const struct pmc_bit_map cnp_slps0_dbg0_map[] = { 99 + {"AUDIO_D3", BIT(0)}, 100 + {"OTG_D3", BIT(1)}, 101 + {"XHCI_D3", BIT(2)}, 102 + {"LPIO_D3", BIT(3)}, 103 + {"SDX_D3", BIT(4)}, 104 + {"SATA_D3", BIT(5)}, 105 + {"UFS0_D3", BIT(6)}, 106 + {"UFS1_D3", BIT(7)}, 107 + {"EMMC_D3", BIT(8)}, 108 + {} 109 + }; 110 + 111 + const struct pmc_bit_map cnp_slps0_dbg1_map[] = { 112 + {"SDIO_PLL_OFF", BIT(0)}, 113 + {"USB2_PLL_OFF", BIT(1)}, 114 + {"AUDIO_PLL_OFF", BIT(2)}, 115 + {"OC_PLL_OFF", BIT(3)}, 116 + {"MAIN_PLL_OFF", BIT(4)}, 117 + {"XOSC_OFF", BIT(5)}, 118 + {"LPC_CLKS_GATED", BIT(6)}, 119 + {"PCIE_CLKREQS_IDLE", BIT(7)}, 120 + {"AUDIO_ROSC_OFF", BIT(8)}, 121 + {"HPET_XOSC_CLK_REQ", BIT(9)}, 122 + {"PMC_ROSC_SLOW_CLK", BIT(10)}, 123 + {"AON2_ROSC_GATED", BIT(11)}, 124 + {"CLKACKS_DEASSERTED", BIT(12)}, 125 + {} 126 + }; 127 + 128 + const struct pmc_bit_map cnp_slps0_dbg2_map[] = { 129 + {"MPHY_CORE_GATED", BIT(0)}, 130 + {"CSME_GATED", BIT(1)}, 131 + {"USB2_SUS_GATED", BIT(2)}, 132 + {"DYN_FLEX_IO_IDLE", BIT(3)}, 133 + {"GBE_NO_LINK", BIT(4)}, 134 + {"THERM_SEN_DISABLED", BIT(5)}, 135 + {"PCIE_LOW_POWER", BIT(6)}, 136 + {"ISH_VNNAON_REQ_ACT", BIT(7)}, 137 + {"ISH_VNN_REQ_ACT", BIT(8)}, 138 + {"CNV_VNNAON_REQ_ACT", BIT(9)}, 139 + {"CNV_VNN_REQ_ACT", BIT(10)}, 140 + {"NPK_VNNON_REQ_ACT", BIT(11)}, 141 + {"PMSYNC_STATE_IDLE", BIT(12)}, 142 + {"ALST_GT_THRES", BIT(13)}, 143 + {"PMC_ARC_PG_READY", BIT(14)}, 144 + {} 145 + }; 146 + 147 + const struct pmc_bit_map *cnp_slps0_dbg_maps[] = { 148 + cnp_slps0_dbg0_map, 149 + cnp_slps0_dbg1_map, 150 + cnp_slps0_dbg2_map, 151 + NULL 152 + }; 153 + 154 + const struct pmc_bit_map cnp_ltr_show_map[] = { 155 + {"SOUTHPORT_A", CNP_PMC_LTR_SPA}, 156 + {"SOUTHPORT_B", CNP_PMC_LTR_SPB}, 157 + {"SATA", CNP_PMC_LTR_SATA}, 158 + {"GIGABIT_ETHERNET", CNP_PMC_LTR_GBE}, 159 + {"XHCI", CNP_PMC_LTR_XHCI}, 160 + {"Reserved", CNP_PMC_LTR_RESERVED}, 161 + {"ME", CNP_PMC_LTR_ME}, 162 + /* EVA is Enterprise Value Add, doesn't really exist on PCH */ 163 + {"EVA", CNP_PMC_LTR_EVA}, 164 + {"SOUTHPORT_C", CNP_PMC_LTR_SPC}, 165 + {"HD_AUDIO", CNP_PMC_LTR_AZ}, 166 + {"CNV", CNP_PMC_LTR_CNV}, 167 + {"LPSS", CNP_PMC_LTR_LPSS}, 168 + {"SOUTHPORT_D", CNP_PMC_LTR_SPD}, 169 + {"SOUTHPORT_E", CNP_PMC_LTR_SPE}, 170 + {"CAMERA", CNP_PMC_LTR_CAM}, 171 + {"ESPI", CNP_PMC_LTR_ESPI}, 172 + {"SCC", CNP_PMC_LTR_SCC}, 173 + {"ISH", CNP_PMC_LTR_ISH}, 174 + {"UFSX2", CNP_PMC_LTR_UFSX2}, 175 + {"EMMC", CNP_PMC_LTR_EMMC}, 176 + /* 177 + * Check intel_pmc_core_ids[] users of cnp_reg_map for 178 + * a list of core SoCs using this. 179 + */ 180 + {"WIGIG", ICL_PMC_LTR_WIGIG}, 181 + {"THC0", TGL_PMC_LTR_THC0}, 182 + {"THC1", TGL_PMC_LTR_THC1}, 183 + /* Below two cannot be used for LTR_IGNORE */ 184 + {"CURRENT_PLATFORM", CNP_PMC_LTR_CUR_PLT}, 185 + {"AGGREGATED_SYSTEM", CNP_PMC_LTR_CUR_ASLT}, 186 + {} 187 + }; 188 + 189 + const struct pmc_reg_map cnp_reg_map = { 190 + .pfear_sts = ext_cnp_pfear_map, 191 + .slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET, 192 + .slp_s0_res_counter_step = SPT_PMC_SLP_S0_RES_COUNTER_STEP, 193 + .slps0_dbg_maps = cnp_slps0_dbg_maps, 194 + .ltr_show_sts = cnp_ltr_show_map, 195 + .msr_sts = msr_map, 196 + .slps0_dbg_offset = CNP_PMC_SLPS0_DBG_OFFSET, 197 + .ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET, 198 + .regmap_length = CNP_PMC_MMIO_REG_LEN, 199 + .ppfear0_offset = CNP_PMC_HOST_PPFEAR0A, 200 + .ppfear_buckets = CNP_PPFEAR_NUM_ENTRIES, 201 + .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, 202 + .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, 203 + .ltr_ignore_max = CNP_NUM_IP_IGN_ALLOWED, 204 + .etr3_offset = ETR3_OFFSET, 205 + }; 206 + 207 + void cnp_core_init(struct pmc_dev *pmcdev) 208 + { 209 + pmcdev->map = &cnp_reg_map; 210 + }
+51 -943
drivers/platform/x86/intel/pmc/core.c
··· 11 11 12 12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 13 13 14 - #include <linux/acpi.h> 15 14 #include <linux/bitfield.h> 16 15 #include <linux/debugfs.h> 17 16 #include <linux/delay.h> ··· 18 19 #include <linux/io.h> 19 20 #include <linux/module.h> 20 21 #include <linux/pci.h> 21 - #include <linux/platform_device.h> 22 22 #include <linux/slab.h> 23 23 #include <linux/suspend.h> 24 - #include <linux/uaccess.h> 25 - #include <linux/uuid.h> 26 24 27 - #include <acpi/acpi_bus.h> 28 25 #include <asm/cpu_device_id.h> 29 26 #include <asm/intel-family.h> 30 27 #include <asm/msr.h> ··· 28 33 29 34 #include "core.h" 30 35 31 - #define ACPI_S0IX_DSM_UUID "57a6512e-3979-4e9d-9708-ff13b2508972" 32 - #define ACPI_GET_LOW_MODE_REGISTERS 1 36 + /* Maximum number of modes supported by platfoms that has low power mode capability */ 37 + const char *pmc_lpm_modes[] = { 38 + "S0i2.0", 39 + "S0i2.1", 40 + "S0i2.2", 41 + "S0i3.0", 42 + "S0i3.1", 43 + "S0i3.2", 44 + "S0i3.3", 45 + "S0i3.4", 46 + NULL 47 + }; 33 48 34 49 /* PKGC MSRs are common across Intel Core SoCs */ 35 - static const struct pmc_bit_map msr_map[] = { 50 + const struct pmc_bit_map msr_map[] = { 36 51 {"Package C2", MSR_PKG_C2_RESIDENCY}, 37 52 {"Package C3", MSR_PKG_C3_RESIDENCY}, 38 53 {"Package C6", MSR_PKG_C6_RESIDENCY}, ··· 51 46 {"Package C9", MSR_PKG_C9_RESIDENCY}, 52 47 {"Package C10", MSR_PKG_C10_RESIDENCY}, 53 48 {} 54 - }; 55 - 56 - static const struct pmc_bit_map spt_pll_map[] = { 57 - {"MIPI PLL", SPT_PMC_BIT_MPHY_CMN_LANE0}, 58 - {"GEN2 USB2PCIE2 PLL", SPT_PMC_BIT_MPHY_CMN_LANE1}, 59 - {"DMIPCIE3 PLL", SPT_PMC_BIT_MPHY_CMN_LANE2}, 60 - {"SATA PLL", SPT_PMC_BIT_MPHY_CMN_LANE3}, 61 - {} 62 - }; 63 - 64 - static const struct pmc_bit_map spt_mphy_map[] = { 65 - {"MPHY CORE LANE 0", SPT_PMC_BIT_MPHY_LANE0}, 66 - {"MPHY CORE LANE 1", SPT_PMC_BIT_MPHY_LANE1}, 67 - {"MPHY CORE LANE 2", SPT_PMC_BIT_MPHY_LANE2}, 68 - {"MPHY CORE LANE 3", SPT_PMC_BIT_MPHY_LANE3}, 69 - {"MPHY CORE LANE 4", SPT_PMC_BIT_MPHY_LANE4}, 70 - {"MPHY CORE LANE 5", SPT_PMC_BIT_MPHY_LANE5}, 71 - {"MPHY CORE LANE 6", SPT_PMC_BIT_MPHY_LANE6}, 72 - {"MPHY CORE LANE 7", SPT_PMC_BIT_MPHY_LANE7}, 73 - {"MPHY CORE LANE 8", SPT_PMC_BIT_MPHY_LANE8}, 74 - {"MPHY CORE LANE 9", SPT_PMC_BIT_MPHY_LANE9}, 75 - {"MPHY CORE LANE 10", SPT_PMC_BIT_MPHY_LANE10}, 76 - {"MPHY CORE LANE 11", SPT_PMC_BIT_MPHY_LANE11}, 77 - {"MPHY CORE LANE 12", SPT_PMC_BIT_MPHY_LANE12}, 78 - {"MPHY CORE LANE 13", SPT_PMC_BIT_MPHY_LANE13}, 79 - {"MPHY CORE LANE 14", SPT_PMC_BIT_MPHY_LANE14}, 80 - {"MPHY CORE LANE 15", SPT_PMC_BIT_MPHY_LANE15}, 81 - {} 82 - }; 83 - 84 - static const struct pmc_bit_map spt_pfear_map[] = { 85 - {"PMC", SPT_PMC_BIT_PMC}, 86 - {"OPI-DMI", SPT_PMC_BIT_OPI}, 87 - {"SPI / eSPI", SPT_PMC_BIT_SPI}, 88 - {"XHCI", SPT_PMC_BIT_XHCI}, 89 - {"SPA", SPT_PMC_BIT_SPA}, 90 - {"SPB", SPT_PMC_BIT_SPB}, 91 - {"SPC", SPT_PMC_BIT_SPC}, 92 - {"GBE", SPT_PMC_BIT_GBE}, 93 - {"SATA", SPT_PMC_BIT_SATA}, 94 - {"HDA-PGD0", SPT_PMC_BIT_HDA_PGD0}, 95 - {"HDA-PGD1", SPT_PMC_BIT_HDA_PGD1}, 96 - {"HDA-PGD2", SPT_PMC_BIT_HDA_PGD2}, 97 - {"HDA-PGD3", SPT_PMC_BIT_HDA_PGD3}, 98 - {"RSVD", SPT_PMC_BIT_RSVD_0B}, 99 - {"LPSS", SPT_PMC_BIT_LPSS}, 100 - {"LPC", SPT_PMC_BIT_LPC}, 101 - {"SMB", SPT_PMC_BIT_SMB}, 102 - {"ISH", SPT_PMC_BIT_ISH}, 103 - {"P2SB", SPT_PMC_BIT_P2SB}, 104 - {"DFX", SPT_PMC_BIT_DFX}, 105 - {"SCC", SPT_PMC_BIT_SCC}, 106 - {"RSVD", SPT_PMC_BIT_RSVD_0C}, 107 - {"FUSE", SPT_PMC_BIT_FUSE}, 108 - {"CAMERA", SPT_PMC_BIT_CAMREA}, 109 - {"RSVD", SPT_PMC_BIT_RSVD_0D}, 110 - {"USB3-OTG", SPT_PMC_BIT_USB3_OTG}, 111 - {"EXI", SPT_PMC_BIT_EXI}, 112 - {"CSE", SPT_PMC_BIT_CSE}, 113 - {"CSME_KVM", SPT_PMC_BIT_CSME_KVM}, 114 - {"CSME_PMT", SPT_PMC_BIT_CSME_PMT}, 115 - {"CSME_CLINK", SPT_PMC_BIT_CSME_CLINK}, 116 - {"CSME_PTIO", SPT_PMC_BIT_CSME_PTIO}, 117 - {"CSME_USBR", SPT_PMC_BIT_CSME_USBR}, 118 - {"CSME_SUSRAM", SPT_PMC_BIT_CSME_SUSRAM}, 119 - {"CSME_SMT", SPT_PMC_BIT_CSME_SMT}, 120 - {"RSVD", SPT_PMC_BIT_RSVD_1A}, 121 - {"CSME_SMS2", SPT_PMC_BIT_CSME_SMS2}, 122 - {"CSME_SMS1", SPT_PMC_BIT_CSME_SMS1}, 123 - {"CSME_RTC", SPT_PMC_BIT_CSME_RTC}, 124 - {"CSME_PSF", SPT_PMC_BIT_CSME_PSF}, 125 - {} 126 - }; 127 - 128 - static const struct pmc_bit_map *ext_spt_pfear_map[] = { 129 - /* 130 - * Check intel_pmc_core_ids[] users of spt_reg_map for 131 - * a list of core SoCs using this. 132 - */ 133 - spt_pfear_map, 134 - NULL 135 - }; 136 - 137 - static const struct pmc_bit_map spt_ltr_show_map[] = { 138 - {"SOUTHPORT_A", SPT_PMC_LTR_SPA}, 139 - {"SOUTHPORT_B", SPT_PMC_LTR_SPB}, 140 - {"SATA", SPT_PMC_LTR_SATA}, 141 - {"GIGABIT_ETHERNET", SPT_PMC_LTR_GBE}, 142 - {"XHCI", SPT_PMC_LTR_XHCI}, 143 - {"Reserved", SPT_PMC_LTR_RESERVED}, 144 - {"ME", SPT_PMC_LTR_ME}, 145 - /* EVA is Enterprise Value Add, doesn't really exist on PCH */ 146 - {"EVA", SPT_PMC_LTR_EVA}, 147 - {"SOUTHPORT_C", SPT_PMC_LTR_SPC}, 148 - {"HD_AUDIO", SPT_PMC_LTR_AZ}, 149 - {"LPSS", SPT_PMC_LTR_LPSS}, 150 - {"SOUTHPORT_D", SPT_PMC_LTR_SPD}, 151 - {"SOUTHPORT_E", SPT_PMC_LTR_SPE}, 152 - {"CAMERA", SPT_PMC_LTR_CAM}, 153 - {"ESPI", SPT_PMC_LTR_ESPI}, 154 - {"SCC", SPT_PMC_LTR_SCC}, 155 - {"ISH", SPT_PMC_LTR_ISH}, 156 - /* Below two cannot be used for LTR_IGNORE */ 157 - {"CURRENT_PLATFORM", SPT_PMC_LTR_CUR_PLT}, 158 - {"AGGREGATED_SYSTEM", SPT_PMC_LTR_CUR_ASLT}, 159 - {} 160 - }; 161 - 162 - static const struct pmc_reg_map spt_reg_map = { 163 - .pfear_sts = ext_spt_pfear_map, 164 - .mphy_sts = spt_mphy_map, 165 - .pll_sts = spt_pll_map, 166 - .ltr_show_sts = spt_ltr_show_map, 167 - .msr_sts = msr_map, 168 - .slp_s0_offset = SPT_PMC_SLP_S0_RES_COUNTER_OFFSET, 169 - .slp_s0_res_counter_step = SPT_PMC_SLP_S0_RES_COUNTER_STEP, 170 - .ltr_ignore_offset = SPT_PMC_LTR_IGNORE_OFFSET, 171 - .regmap_length = SPT_PMC_MMIO_REG_LEN, 172 - .ppfear0_offset = SPT_PMC_XRAM_PPFEAR0A, 173 - .ppfear_buckets = SPT_PPFEAR_NUM_ENTRIES, 174 - .pm_cfg_offset = SPT_PMC_PM_CFG_OFFSET, 175 - .pm_read_disable_bit = SPT_PMC_READ_DISABLE_BIT, 176 - .ltr_ignore_max = SPT_NUM_IP_IGN_ALLOWED, 177 - .pm_vric1_offset = SPT_PMC_VRIC1_OFFSET, 178 - }; 179 - 180 - /* Cannon Lake: PGD PFET Enable Ack Status Register(s) bitmap */ 181 - static const struct pmc_bit_map cnp_pfear_map[] = { 182 - {"PMC", BIT(0)}, 183 - {"OPI-DMI", BIT(1)}, 184 - {"SPI/eSPI", BIT(2)}, 185 - {"XHCI", BIT(3)}, 186 - {"SPA", BIT(4)}, 187 - {"SPB", BIT(5)}, 188 - {"SPC", BIT(6)}, 189 - {"GBE", BIT(7)}, 190 - 191 - {"SATA", BIT(0)}, 192 - {"HDA_PGD0", BIT(1)}, 193 - {"HDA_PGD1", BIT(2)}, 194 - {"HDA_PGD2", BIT(3)}, 195 - {"HDA_PGD3", BIT(4)}, 196 - {"SPD", BIT(5)}, 197 - {"LPSS", BIT(6)}, 198 - {"LPC", BIT(7)}, 199 - 200 - {"SMB", BIT(0)}, 201 - {"ISH", BIT(1)}, 202 - {"P2SB", BIT(2)}, 203 - {"NPK_VNN", BIT(3)}, 204 - {"SDX", BIT(4)}, 205 - {"SPE", BIT(5)}, 206 - {"Fuse", BIT(6)}, 207 - {"SBR8", BIT(7)}, 208 - 209 - {"CSME_FSC", BIT(0)}, 210 - {"USB3_OTG", BIT(1)}, 211 - {"EXI", BIT(2)}, 212 - {"CSE", BIT(3)}, 213 - {"CSME_KVM", BIT(4)}, 214 - {"CSME_PMT", BIT(5)}, 215 - {"CSME_CLINK", BIT(6)}, 216 - {"CSME_PTIO", BIT(7)}, 217 - 218 - {"CSME_USBR", BIT(0)}, 219 - {"CSME_SUSRAM", BIT(1)}, 220 - {"CSME_SMT1", BIT(2)}, 221 - {"CSME_SMT4", BIT(3)}, 222 - {"CSME_SMS2", BIT(4)}, 223 - {"CSME_SMS1", BIT(5)}, 224 - {"CSME_RTC", BIT(6)}, 225 - {"CSME_PSF", BIT(7)}, 226 - 227 - {"SBR0", BIT(0)}, 228 - {"SBR1", BIT(1)}, 229 - {"SBR2", BIT(2)}, 230 - {"SBR3", BIT(3)}, 231 - {"SBR4", BIT(4)}, 232 - {"SBR5", BIT(5)}, 233 - {"CSME_PECI", BIT(6)}, 234 - {"PSF1", BIT(7)}, 235 - 236 - {"PSF2", BIT(0)}, 237 - {"PSF3", BIT(1)}, 238 - {"PSF4", BIT(2)}, 239 - {"CNVI", BIT(3)}, 240 - {"UFS0", BIT(4)}, 241 - {"EMMC", BIT(5)}, 242 - {"SPF", BIT(6)}, 243 - {"SBR6", BIT(7)}, 244 - 245 - {"SBR7", BIT(0)}, 246 - {"NPK_AON", BIT(1)}, 247 - {"HDA_PGD4", BIT(2)}, 248 - {"HDA_PGD5", BIT(3)}, 249 - {"HDA_PGD6", BIT(4)}, 250 - {"PSF6", BIT(5)}, 251 - {"PSF7", BIT(6)}, 252 - {"PSF8", BIT(7)}, 253 - {} 254 - }; 255 - 256 - static const struct pmc_bit_map *ext_cnp_pfear_map[] = { 257 - /* 258 - * Check intel_pmc_core_ids[] users of cnp_reg_map for 259 - * a list of core SoCs using this. 260 - */ 261 - cnp_pfear_map, 262 - NULL 263 - }; 264 - 265 - static const struct pmc_bit_map icl_pfear_map[] = { 266 - {"RES_65", BIT(0)}, 267 - {"RES_66", BIT(1)}, 268 - {"RES_67", BIT(2)}, 269 - {"TAM", BIT(3)}, 270 - {"GBETSN", BIT(4)}, 271 - {"TBTLSX", BIT(5)}, 272 - {"RES_71", BIT(6)}, 273 - {"RES_72", BIT(7)}, 274 - {} 275 - }; 276 - 277 - static const struct pmc_bit_map *ext_icl_pfear_map[] = { 278 - /* 279 - * Check intel_pmc_core_ids[] users of icl_reg_map for 280 - * a list of core SoCs using this. 281 - */ 282 - cnp_pfear_map, 283 - icl_pfear_map, 284 - NULL 285 - }; 286 - 287 - static const struct pmc_bit_map tgl_pfear_map[] = { 288 - {"PSF9", BIT(0)}, 289 - {"RES_66", BIT(1)}, 290 - {"RES_67", BIT(2)}, 291 - {"RES_68", BIT(3)}, 292 - {"RES_69", BIT(4)}, 293 - {"RES_70", BIT(5)}, 294 - {"TBTLSX", BIT(6)}, 295 - {} 296 - }; 297 - 298 - static const struct pmc_bit_map *ext_tgl_pfear_map[] = { 299 - /* 300 - * Check intel_pmc_core_ids[] users of tgl_reg_map for 301 - * a list of core SoCs using this. 302 - */ 303 - cnp_pfear_map, 304 - tgl_pfear_map, 305 - NULL 306 - }; 307 - 308 - static const struct pmc_bit_map cnp_slps0_dbg0_map[] = { 309 - {"AUDIO_D3", BIT(0)}, 310 - {"OTG_D3", BIT(1)}, 311 - {"XHCI_D3", BIT(2)}, 312 - {"LPIO_D3", BIT(3)}, 313 - {"SDX_D3", BIT(4)}, 314 - {"SATA_D3", BIT(5)}, 315 - {"UFS0_D3", BIT(6)}, 316 - {"UFS1_D3", BIT(7)}, 317 - {"EMMC_D3", BIT(8)}, 318 - {} 319 - }; 320 - 321 - static const struct pmc_bit_map cnp_slps0_dbg1_map[] = { 322 - {"SDIO_PLL_OFF", BIT(0)}, 323 - {"USB2_PLL_OFF", BIT(1)}, 324 - {"AUDIO_PLL_OFF", BIT(2)}, 325 - {"OC_PLL_OFF", BIT(3)}, 326 - {"MAIN_PLL_OFF", BIT(4)}, 327 - {"XOSC_OFF", BIT(5)}, 328 - {"LPC_CLKS_GATED", BIT(6)}, 329 - {"PCIE_CLKREQS_IDLE", BIT(7)}, 330 - {"AUDIO_ROSC_OFF", BIT(8)}, 331 - {"HPET_XOSC_CLK_REQ", BIT(9)}, 332 - {"PMC_ROSC_SLOW_CLK", BIT(10)}, 333 - {"AON2_ROSC_GATED", BIT(11)}, 334 - {"CLKACKS_DEASSERTED", BIT(12)}, 335 - {} 336 - }; 337 - 338 - static const struct pmc_bit_map cnp_slps0_dbg2_map[] = { 339 - {"MPHY_CORE_GATED", BIT(0)}, 340 - {"CSME_GATED", BIT(1)}, 341 - {"USB2_SUS_GATED", BIT(2)}, 342 - {"DYN_FLEX_IO_IDLE", BIT(3)}, 343 - {"GBE_NO_LINK", BIT(4)}, 344 - {"THERM_SEN_DISABLED", BIT(5)}, 345 - {"PCIE_LOW_POWER", BIT(6)}, 346 - {"ISH_VNNAON_REQ_ACT", BIT(7)}, 347 - {"ISH_VNN_REQ_ACT", BIT(8)}, 348 - {"CNV_VNNAON_REQ_ACT", BIT(9)}, 349 - {"CNV_VNN_REQ_ACT", BIT(10)}, 350 - {"NPK_VNNON_REQ_ACT", BIT(11)}, 351 - {"PMSYNC_STATE_IDLE", BIT(12)}, 352 - {"ALST_GT_THRES", BIT(13)}, 353 - {"PMC_ARC_PG_READY", BIT(14)}, 354 - {} 355 - }; 356 - 357 - static const struct pmc_bit_map *cnp_slps0_dbg_maps[] = { 358 - cnp_slps0_dbg0_map, 359 - cnp_slps0_dbg1_map, 360 - cnp_slps0_dbg2_map, 361 - NULL 362 - }; 363 - 364 - static const struct pmc_bit_map cnp_ltr_show_map[] = { 365 - {"SOUTHPORT_A", CNP_PMC_LTR_SPA}, 366 - {"SOUTHPORT_B", CNP_PMC_LTR_SPB}, 367 - {"SATA", CNP_PMC_LTR_SATA}, 368 - {"GIGABIT_ETHERNET", CNP_PMC_LTR_GBE}, 369 - {"XHCI", CNP_PMC_LTR_XHCI}, 370 - {"Reserved", CNP_PMC_LTR_RESERVED}, 371 - {"ME", CNP_PMC_LTR_ME}, 372 - /* EVA is Enterprise Value Add, doesn't really exist on PCH */ 373 - {"EVA", CNP_PMC_LTR_EVA}, 374 - {"SOUTHPORT_C", CNP_PMC_LTR_SPC}, 375 - {"HD_AUDIO", CNP_PMC_LTR_AZ}, 376 - {"CNV", CNP_PMC_LTR_CNV}, 377 - {"LPSS", CNP_PMC_LTR_LPSS}, 378 - {"SOUTHPORT_D", CNP_PMC_LTR_SPD}, 379 - {"SOUTHPORT_E", CNP_PMC_LTR_SPE}, 380 - {"CAMERA", CNP_PMC_LTR_CAM}, 381 - {"ESPI", CNP_PMC_LTR_ESPI}, 382 - {"SCC", CNP_PMC_LTR_SCC}, 383 - {"ISH", CNP_PMC_LTR_ISH}, 384 - {"UFSX2", CNP_PMC_LTR_UFSX2}, 385 - {"EMMC", CNP_PMC_LTR_EMMC}, 386 - /* 387 - * Check intel_pmc_core_ids[] users of cnp_reg_map for 388 - * a list of core SoCs using this. 389 - */ 390 - {"WIGIG", ICL_PMC_LTR_WIGIG}, 391 - {"THC0", TGL_PMC_LTR_THC0}, 392 - {"THC1", TGL_PMC_LTR_THC1}, 393 - /* Below two cannot be used for LTR_IGNORE */ 394 - {"CURRENT_PLATFORM", CNP_PMC_LTR_CUR_PLT}, 395 - {"AGGREGATED_SYSTEM", CNP_PMC_LTR_CUR_ASLT}, 396 - {} 397 - }; 398 - 399 - static const struct pmc_reg_map cnp_reg_map = { 400 - .pfear_sts = ext_cnp_pfear_map, 401 - .slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET, 402 - .slp_s0_res_counter_step = SPT_PMC_SLP_S0_RES_COUNTER_STEP, 403 - .slps0_dbg_maps = cnp_slps0_dbg_maps, 404 - .ltr_show_sts = cnp_ltr_show_map, 405 - .msr_sts = msr_map, 406 - .slps0_dbg_offset = CNP_PMC_SLPS0_DBG_OFFSET, 407 - .ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET, 408 - .regmap_length = CNP_PMC_MMIO_REG_LEN, 409 - .ppfear0_offset = CNP_PMC_HOST_PPFEAR0A, 410 - .ppfear_buckets = CNP_PPFEAR_NUM_ENTRIES, 411 - .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, 412 - .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, 413 - .ltr_ignore_max = CNP_NUM_IP_IGN_ALLOWED, 414 - .etr3_offset = ETR3_OFFSET, 415 - }; 416 - 417 - static const struct pmc_reg_map icl_reg_map = { 418 - .pfear_sts = ext_icl_pfear_map, 419 - .slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET, 420 - .slp_s0_res_counter_step = ICL_PMC_SLP_S0_RES_COUNTER_STEP, 421 - .slps0_dbg_maps = cnp_slps0_dbg_maps, 422 - .ltr_show_sts = cnp_ltr_show_map, 423 - .msr_sts = msr_map, 424 - .slps0_dbg_offset = CNP_PMC_SLPS0_DBG_OFFSET, 425 - .ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET, 426 - .regmap_length = CNP_PMC_MMIO_REG_LEN, 427 - .ppfear0_offset = CNP_PMC_HOST_PPFEAR0A, 428 - .ppfear_buckets = ICL_PPFEAR_NUM_ENTRIES, 429 - .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, 430 - .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, 431 - .ltr_ignore_max = ICL_NUM_IP_IGN_ALLOWED, 432 - .etr3_offset = ETR3_OFFSET, 433 - }; 434 - 435 - static const struct pmc_bit_map tgl_clocksource_status_map[] = { 436 - {"USB2PLL_OFF_STS", BIT(18)}, 437 - {"PCIe/USB3.1_Gen2PLL_OFF_STS", BIT(19)}, 438 - {"PCIe_Gen3PLL_OFF_STS", BIT(20)}, 439 - {"OPIOPLL_OFF_STS", BIT(21)}, 440 - {"OCPLL_OFF_STS", BIT(22)}, 441 - {"MainPLL_OFF_STS", BIT(23)}, 442 - {"MIPIPLL_OFF_STS", BIT(24)}, 443 - {"Fast_XTAL_Osc_OFF_STS", BIT(25)}, 444 - {"AC_Ring_Osc_OFF_STS", BIT(26)}, 445 - {"MC_Ring_Osc_OFF_STS", BIT(27)}, 446 - {"SATAPLL_OFF_STS", BIT(29)}, 447 - {"XTAL_USB2PLL_OFF_STS", BIT(31)}, 448 - {} 449 - }; 450 - 451 - static const struct pmc_bit_map tgl_power_gating_status_map[] = { 452 - {"CSME_PG_STS", BIT(0)}, 453 - {"SATA_PG_STS", BIT(1)}, 454 - {"xHCI_PG_STS", BIT(2)}, 455 - {"UFSX2_PG_STS", BIT(3)}, 456 - {"OTG_PG_STS", BIT(5)}, 457 - {"SPA_PG_STS", BIT(6)}, 458 - {"SPB_PG_STS", BIT(7)}, 459 - {"SPC_PG_STS", BIT(8)}, 460 - {"SPD_PG_STS", BIT(9)}, 461 - {"SPE_PG_STS", BIT(10)}, 462 - {"SPF_PG_STS", BIT(11)}, 463 - {"LSX_PG_STS", BIT(13)}, 464 - {"P2SB_PG_STS", BIT(14)}, 465 - {"PSF_PG_STS", BIT(15)}, 466 - {"SBR_PG_STS", BIT(16)}, 467 - {"OPIDMI_PG_STS", BIT(17)}, 468 - {"THC0_PG_STS", BIT(18)}, 469 - {"THC1_PG_STS", BIT(19)}, 470 - {"GBETSN_PG_STS", BIT(20)}, 471 - {"GBE_PG_STS", BIT(21)}, 472 - {"LPSS_PG_STS", BIT(22)}, 473 - {"MMP_UFSX2_PG_STS", BIT(23)}, 474 - {"MMP_UFSX2B_PG_STS", BIT(24)}, 475 - {"FIA_PG_STS", BIT(25)}, 476 - {} 477 - }; 478 - 479 - static const struct pmc_bit_map tgl_d3_status_map[] = { 480 - {"ADSP_D3_STS", BIT(0)}, 481 - {"SATA_D3_STS", BIT(1)}, 482 - {"xHCI0_D3_STS", BIT(2)}, 483 - {"xDCI1_D3_STS", BIT(5)}, 484 - {"SDX_D3_STS", BIT(6)}, 485 - {"EMMC_D3_STS", BIT(7)}, 486 - {"IS_D3_STS", BIT(8)}, 487 - {"THC0_D3_STS", BIT(9)}, 488 - {"THC1_D3_STS", BIT(10)}, 489 - {"GBE_D3_STS", BIT(11)}, 490 - {"GBE_TSN_D3_STS", BIT(12)}, 491 - {} 492 - }; 493 - 494 - static const struct pmc_bit_map tgl_vnn_req_status_map[] = { 495 - {"GPIO_COM0_VNN_REQ_STS", BIT(1)}, 496 - {"GPIO_COM1_VNN_REQ_STS", BIT(2)}, 497 - {"GPIO_COM2_VNN_REQ_STS", BIT(3)}, 498 - {"GPIO_COM3_VNN_REQ_STS", BIT(4)}, 499 - {"GPIO_COM4_VNN_REQ_STS", BIT(5)}, 500 - {"GPIO_COM5_VNN_REQ_STS", BIT(6)}, 501 - {"Audio_VNN_REQ_STS", BIT(7)}, 502 - {"ISH_VNN_REQ_STS", BIT(8)}, 503 - {"CNVI_VNN_REQ_STS", BIT(9)}, 504 - {"eSPI_VNN_REQ_STS", BIT(10)}, 505 - {"Display_VNN_REQ_STS", BIT(11)}, 506 - {"DTS_VNN_REQ_STS", BIT(12)}, 507 - {"SMBUS_VNN_REQ_STS", BIT(14)}, 508 - {"CSME_VNN_REQ_STS", BIT(15)}, 509 - {"SMLINK0_VNN_REQ_STS", BIT(16)}, 510 - {"SMLINK1_VNN_REQ_STS", BIT(17)}, 511 - {"CLINK_VNN_REQ_STS", BIT(20)}, 512 - {"DCI_VNN_REQ_STS", BIT(21)}, 513 - {"ITH_VNN_REQ_STS", BIT(22)}, 514 - {"CSME_VNN_REQ_STS", BIT(24)}, 515 - {"GBE_VNN_REQ_STS", BIT(25)}, 516 - {} 517 - }; 518 - 519 - static const struct pmc_bit_map tgl_vnn_misc_status_map[] = { 520 - {"CPU_C10_REQ_STS_0", BIT(0)}, 521 - {"PCIe_LPM_En_REQ_STS_3", BIT(3)}, 522 - {"ITH_REQ_STS_5", BIT(5)}, 523 - {"CNVI_REQ_STS_6", BIT(6)}, 524 - {"ISH_REQ_STS_7", BIT(7)}, 525 - {"USB2_SUS_PG_Sys_REQ_STS_10", BIT(10)}, 526 - {"PCIe_Clk_REQ_STS_12", BIT(12)}, 527 - {"MPHY_Core_DL_REQ_STS_16", BIT(16)}, 528 - {"Break-even_En_REQ_STS_17", BIT(17)}, 529 - {"Auto-demo_En_REQ_STS_18", BIT(18)}, 530 - {"MPHY_SUS_REQ_STS_22", BIT(22)}, 531 - {"xDCI_attached_REQ_STS_24", BIT(24)}, 532 - {} 533 - }; 534 - 535 - static const struct pmc_bit_map tgl_signal_status_map[] = { 536 - {"LSX_Wake0_En_STS", BIT(0)}, 537 - {"LSX_Wake0_Pol_STS", BIT(1)}, 538 - {"LSX_Wake1_En_STS", BIT(2)}, 539 - {"LSX_Wake1_Pol_STS", BIT(3)}, 540 - {"LSX_Wake2_En_STS", BIT(4)}, 541 - {"LSX_Wake2_Pol_STS", BIT(5)}, 542 - {"LSX_Wake3_En_STS", BIT(6)}, 543 - {"LSX_Wake3_Pol_STS", BIT(7)}, 544 - {"LSX_Wake4_En_STS", BIT(8)}, 545 - {"LSX_Wake4_Pol_STS", BIT(9)}, 546 - {"LSX_Wake5_En_STS", BIT(10)}, 547 - {"LSX_Wake5_Pol_STS", BIT(11)}, 548 - {"LSX_Wake6_En_STS", BIT(12)}, 549 - {"LSX_Wake6_Pol_STS", BIT(13)}, 550 - {"LSX_Wake7_En_STS", BIT(14)}, 551 - {"LSX_Wake7_Pol_STS", BIT(15)}, 552 - {"Intel_Se_IO_Wake0_En_STS", BIT(16)}, 553 - {"Intel_Se_IO_Wake0_Pol_STS", BIT(17)}, 554 - {"Intel_Se_IO_Wake1_En_STS", BIT(18)}, 555 - {"Intel_Se_IO_Wake1_Pol_STS", BIT(19)}, 556 - {"Int_Timer_SS_Wake0_En_STS", BIT(20)}, 557 - {"Int_Timer_SS_Wake0_Pol_STS", BIT(21)}, 558 - {"Int_Timer_SS_Wake1_En_STS", BIT(22)}, 559 - {"Int_Timer_SS_Wake1_Pol_STS", BIT(23)}, 560 - {"Int_Timer_SS_Wake2_En_STS", BIT(24)}, 561 - {"Int_Timer_SS_Wake2_Pol_STS", BIT(25)}, 562 - {"Int_Timer_SS_Wake3_En_STS", BIT(26)}, 563 - {"Int_Timer_SS_Wake3_Pol_STS", BIT(27)}, 564 - {"Int_Timer_SS_Wake4_En_STS", BIT(28)}, 565 - {"Int_Timer_SS_Wake4_Pol_STS", BIT(29)}, 566 - {"Int_Timer_SS_Wake5_En_STS", BIT(30)}, 567 - {"Int_Timer_SS_Wake5_Pol_STS", BIT(31)}, 568 - {} 569 - }; 570 - 571 - static const struct pmc_bit_map *tgl_lpm_maps[] = { 572 - tgl_clocksource_status_map, 573 - tgl_power_gating_status_map, 574 - tgl_d3_status_map, 575 - tgl_vnn_req_status_map, 576 - tgl_vnn_misc_status_map, 577 - tgl_signal_status_map, 578 - NULL 579 - }; 580 - 581 - static const struct pmc_reg_map tgl_reg_map = { 582 - .pfear_sts = ext_tgl_pfear_map, 583 - .slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET, 584 - .slp_s0_res_counter_step = TGL_PMC_SLP_S0_RES_COUNTER_STEP, 585 - .ltr_show_sts = cnp_ltr_show_map, 586 - .msr_sts = msr_map, 587 - .ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET, 588 - .regmap_length = CNP_PMC_MMIO_REG_LEN, 589 - .ppfear0_offset = CNP_PMC_HOST_PPFEAR0A, 590 - .ppfear_buckets = ICL_PPFEAR_NUM_ENTRIES, 591 - .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, 592 - .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, 593 - .ltr_ignore_max = TGL_NUM_IP_IGN_ALLOWED, 594 - .lpm_num_maps = TGL_LPM_NUM_MAPS, 595 - .lpm_res_counter_step_x2 = TGL_PMC_LPM_RES_COUNTER_STEP_X2, 596 - .lpm_sts_latch_en_offset = TGL_LPM_STS_LATCH_EN_OFFSET, 597 - .lpm_en_offset = TGL_LPM_EN_OFFSET, 598 - .lpm_priority_offset = TGL_LPM_PRI_OFFSET, 599 - .lpm_residency_offset = TGL_LPM_RESIDENCY_OFFSET, 600 - .lpm_sts = tgl_lpm_maps, 601 - .lpm_status_offset = TGL_LPM_STATUS_OFFSET, 602 - .lpm_live_status_offset = TGL_LPM_LIVE_STATUS_OFFSET, 603 - .etr3_offset = ETR3_OFFSET, 604 - }; 605 - 606 - static void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev) 607 - { 608 - struct pmc_dev *pmcdev = platform_get_drvdata(pdev); 609 - const int num_maps = pmcdev->map->lpm_num_maps; 610 - u32 lpm_size = LPM_MAX_NUM_MODES * num_maps * 4; 611 - union acpi_object *out_obj; 612 - struct acpi_device *adev; 613 - guid_t s0ix_dsm_guid; 614 - u32 *lpm_req_regs, *addr; 615 - 616 - adev = ACPI_COMPANION(&pdev->dev); 617 - if (!adev) 618 - return; 619 - 620 - guid_parse(ACPI_S0IX_DSM_UUID, &s0ix_dsm_guid); 621 - 622 - out_obj = acpi_evaluate_dsm(adev->handle, &s0ix_dsm_guid, 0, 623 - ACPI_GET_LOW_MODE_REGISTERS, NULL); 624 - if (out_obj && out_obj->type == ACPI_TYPE_BUFFER) { 625 - u32 size = out_obj->buffer.length; 626 - 627 - if (size != lpm_size) { 628 - acpi_handle_debug(adev->handle, 629 - "_DSM returned unexpected buffer size, have %u, expect %u\n", 630 - size, lpm_size); 631 - goto free_acpi_obj; 632 - } 633 - } else { 634 - acpi_handle_debug(adev->handle, 635 - "_DSM function 0 evaluation failed\n"); 636 - goto free_acpi_obj; 637 - } 638 - 639 - addr = (u32 *)out_obj->buffer.pointer; 640 - 641 - lpm_req_regs = devm_kzalloc(&pdev->dev, lpm_size * sizeof(u32), 642 - GFP_KERNEL); 643 - if (!lpm_req_regs) 644 - goto free_acpi_obj; 645 - 646 - memcpy(lpm_req_regs, addr, lpm_size); 647 - pmcdev->lpm_req_regs = lpm_req_regs; 648 - 649 - free_acpi_obj: 650 - ACPI_FREE(out_obj); 651 - } 652 - 653 - /* Alder Lake: PGD PFET Enable Ack Status Register(s) bitmap */ 654 - static const struct pmc_bit_map adl_pfear_map[] = { 655 - {"SPI/eSPI", BIT(2)}, 656 - {"XHCI", BIT(3)}, 657 - {"SPA", BIT(4)}, 658 - {"SPB", BIT(5)}, 659 - {"SPC", BIT(6)}, 660 - {"GBE", BIT(7)}, 661 - 662 - {"SATA", BIT(0)}, 663 - {"HDA_PGD0", BIT(1)}, 664 - {"HDA_PGD1", BIT(2)}, 665 - {"HDA_PGD2", BIT(3)}, 666 - {"HDA_PGD3", BIT(4)}, 667 - {"SPD", BIT(5)}, 668 - {"LPSS", BIT(6)}, 669 - 670 - {"SMB", BIT(0)}, 671 - {"ISH", BIT(1)}, 672 - {"ITH", BIT(3)}, 673 - 674 - {"XDCI", BIT(1)}, 675 - {"DCI", BIT(2)}, 676 - {"CSE", BIT(3)}, 677 - {"CSME_KVM", BIT(4)}, 678 - {"CSME_PMT", BIT(5)}, 679 - {"CSME_CLINK", BIT(6)}, 680 - {"CSME_PTIO", BIT(7)}, 681 - 682 - {"CSME_USBR", BIT(0)}, 683 - {"CSME_SUSRAM", BIT(1)}, 684 - {"CSME_SMT1", BIT(2)}, 685 - {"CSME_SMS2", BIT(4)}, 686 - {"CSME_SMS1", BIT(5)}, 687 - {"CSME_RTC", BIT(6)}, 688 - {"CSME_PSF", BIT(7)}, 689 - 690 - {"CNVI", BIT(3)}, 691 - 692 - {"HDA_PGD4", BIT(2)}, 693 - {"HDA_PGD5", BIT(3)}, 694 - {"HDA_PGD6", BIT(4)}, 695 - {} 696 - }; 697 - 698 - static const struct pmc_bit_map *ext_adl_pfear_map[] = { 699 - /* 700 - * Check intel_pmc_core_ids[] users of cnp_reg_map for 701 - * a list of core SoCs using this. 702 - */ 703 - adl_pfear_map, 704 - NULL 705 - }; 706 - 707 - static const struct pmc_bit_map adl_ltr_show_map[] = { 708 - {"SOUTHPORT_A", CNP_PMC_LTR_SPA}, 709 - {"SOUTHPORT_B", CNP_PMC_LTR_SPB}, 710 - {"SATA", CNP_PMC_LTR_SATA}, 711 - {"GIGABIT_ETHERNET", CNP_PMC_LTR_GBE}, 712 - {"XHCI", CNP_PMC_LTR_XHCI}, 713 - {"SOUTHPORT_F", ADL_PMC_LTR_SPF}, 714 - {"ME", CNP_PMC_LTR_ME}, 715 - /* EVA is Enterprise Value Add, doesn't really exist on PCH */ 716 - {"SATA1", CNP_PMC_LTR_EVA}, 717 - {"SOUTHPORT_C", CNP_PMC_LTR_SPC}, 718 - {"HD_AUDIO", CNP_PMC_LTR_AZ}, 719 - {"CNV", CNP_PMC_LTR_CNV}, 720 - {"LPSS", CNP_PMC_LTR_LPSS}, 721 - {"SOUTHPORT_D", CNP_PMC_LTR_SPD}, 722 - {"SOUTHPORT_E", CNP_PMC_LTR_SPE}, 723 - {"SATA2", CNP_PMC_LTR_CAM}, 724 - {"ESPI", CNP_PMC_LTR_ESPI}, 725 - {"SCC", CNP_PMC_LTR_SCC}, 726 - {"ISH", CNP_PMC_LTR_ISH}, 727 - {"UFSX2", CNP_PMC_LTR_UFSX2}, 728 - {"EMMC", CNP_PMC_LTR_EMMC}, 729 - /* 730 - * Check intel_pmc_core_ids[] users of cnp_reg_map for 731 - * a list of core SoCs using this. 732 - */ 733 - {"WIGIG", ICL_PMC_LTR_WIGIG}, 734 - {"THC0", TGL_PMC_LTR_THC0}, 735 - {"THC1", TGL_PMC_LTR_THC1}, 736 - {"SOUTHPORT_G", CNP_PMC_LTR_RESERVED}, 737 - 738 - /* Below two cannot be used for LTR_IGNORE */ 739 - {"CURRENT_PLATFORM", CNP_PMC_LTR_CUR_PLT}, 740 - {"AGGREGATED_SYSTEM", CNP_PMC_LTR_CUR_ASLT}, 741 - {} 742 - }; 743 - 744 - static const struct pmc_bit_map adl_clocksource_status_map[] = { 745 - {"CLKPART1_OFF_STS", BIT(0)}, 746 - {"CLKPART2_OFF_STS", BIT(1)}, 747 - {"CLKPART3_OFF_STS", BIT(2)}, 748 - {"CLKPART4_OFF_STS", BIT(3)}, 749 - {"CLKPART5_OFF_STS", BIT(4)}, 750 - {"CLKPART6_OFF_STS", BIT(5)}, 751 - {"CLKPART7_OFF_STS", BIT(6)}, 752 - {"CLKPART8_OFF_STS", BIT(7)}, 753 - {"PCIE0PLL_OFF_STS", BIT(10)}, 754 - {"PCIE1PLL_OFF_STS", BIT(11)}, 755 - {"PCIE2PLL_OFF_STS", BIT(12)}, 756 - {"PCIE3PLL_OFF_STS", BIT(13)}, 757 - {"PCIE4PLL_OFF_STS", BIT(14)}, 758 - {"PCIE5PLL_OFF_STS", BIT(15)}, 759 - {"PCIE6PLL_OFF_STS", BIT(16)}, 760 - {"USB2PLL_OFF_STS", BIT(18)}, 761 - {"OCPLL_OFF_STS", BIT(22)}, 762 - {"AUDIOPLL_OFF_STS", BIT(23)}, 763 - {"GBEPLL_OFF_STS", BIT(24)}, 764 - {"Fast_XTAL_Osc_OFF_STS", BIT(25)}, 765 - {"AC_Ring_Osc_OFF_STS", BIT(26)}, 766 - {"MC_Ring_Osc_OFF_STS", BIT(27)}, 767 - {"SATAPLL_OFF_STS", BIT(29)}, 768 - {"USB3PLL_OFF_STS", BIT(31)}, 769 - {} 770 - }; 771 - 772 - static const struct pmc_bit_map adl_power_gating_status_0_map[] = { 773 - {"PMC_PGD0_PG_STS", BIT(0)}, 774 - {"DMI_PGD0_PG_STS", BIT(1)}, 775 - {"ESPISPI_PGD0_PG_STS", BIT(2)}, 776 - {"XHCI_PGD0_PG_STS", BIT(3)}, 777 - {"SPA_PGD0_PG_STS", BIT(4)}, 778 - {"SPB_PGD0_PG_STS", BIT(5)}, 779 - {"SPC_PGD0_PG_STS", BIT(6)}, 780 - {"GBE_PGD0_PG_STS", BIT(7)}, 781 - {"SATA_PGD0_PG_STS", BIT(8)}, 782 - {"DSP_PGD0_PG_STS", BIT(9)}, 783 - {"DSP_PGD1_PG_STS", BIT(10)}, 784 - {"DSP_PGD2_PG_STS", BIT(11)}, 785 - {"DSP_PGD3_PG_STS", BIT(12)}, 786 - {"SPD_PGD0_PG_STS", BIT(13)}, 787 - {"LPSS_PGD0_PG_STS", BIT(14)}, 788 - {"SMB_PGD0_PG_STS", BIT(16)}, 789 - {"ISH_PGD0_PG_STS", BIT(17)}, 790 - {"NPK_PGD0_PG_STS", BIT(19)}, 791 - {"PECI_PGD0_PG_STS", BIT(21)}, 792 - {"XDCI_PGD0_PG_STS", BIT(25)}, 793 - {"EXI_PGD0_PG_STS", BIT(26)}, 794 - {"CSE_PGD0_PG_STS", BIT(27)}, 795 - {"KVMCC_PGD0_PG_STS", BIT(28)}, 796 - {"PMT_PGD0_PG_STS", BIT(29)}, 797 - {"CLINK_PGD0_PG_STS", BIT(30)}, 798 - {"PTIO_PGD0_PG_STS", BIT(31)}, 799 - {} 800 - }; 801 - 802 - static const struct pmc_bit_map adl_power_gating_status_1_map[] = { 803 - {"USBR0_PGD0_PG_STS", BIT(0)}, 804 - {"SMT1_PGD0_PG_STS", BIT(2)}, 805 - {"CSMERTC_PGD0_PG_STS", BIT(6)}, 806 - {"CSMEPSF_PGD0_PG_STS", BIT(7)}, 807 - {"CNVI_PGD0_PG_STS", BIT(19)}, 808 - {"DSP_PGD4_PG_STS", BIT(26)}, 809 - {"SPG_PGD0_PG_STS", BIT(27)}, 810 - {"SPE_PGD0_PG_STS", BIT(28)}, 811 - {} 812 - }; 813 - 814 - static const struct pmc_bit_map adl_power_gating_status_2_map[] = { 815 - {"THC0_PGD0_PG_STS", BIT(7)}, 816 - {"THC1_PGD0_PG_STS", BIT(8)}, 817 - {"SPF_PGD0_PG_STS", BIT(14)}, 818 - {} 819 - }; 820 - 821 - static const struct pmc_bit_map adl_d3_status_0_map[] = { 822 - {"ISH_D3_STS", BIT(2)}, 823 - {"LPSS_D3_STS", BIT(3)}, 824 - {"XDCI_D3_STS", BIT(4)}, 825 - {"XHCI_D3_STS", BIT(5)}, 826 - {"SPA_D3_STS", BIT(12)}, 827 - {"SPB_D3_STS", BIT(13)}, 828 - {"SPC_D3_STS", BIT(14)}, 829 - {"SPD_D3_STS", BIT(15)}, 830 - {"SPE_D3_STS", BIT(16)}, 831 - {"DSP_D3_STS", BIT(19)}, 832 - {"SATA_D3_STS", BIT(20)}, 833 - {"DMI_D3_STS", BIT(22)}, 834 - {} 835 - }; 836 - 837 - static const struct pmc_bit_map adl_d3_status_1_map[] = { 838 - {"GBE_D3_STS", BIT(19)}, 839 - {"CNVI_D3_STS", BIT(27)}, 840 - {} 841 - }; 842 - 843 - static const struct pmc_bit_map adl_d3_status_2_map[] = { 844 - {"CSMERTC_D3_STS", BIT(1)}, 845 - {"CSE_D3_STS", BIT(4)}, 846 - {"KVMCC_D3_STS", BIT(5)}, 847 - {"USBR0_D3_STS", BIT(6)}, 848 - {"SMT1_D3_STS", BIT(8)}, 849 - {"PTIO_D3_STS", BIT(16)}, 850 - {"PMT_D3_STS", BIT(17)}, 851 - {} 852 - }; 853 - 854 - static const struct pmc_bit_map adl_d3_status_3_map[] = { 855 - {"THC0_D3_STS", BIT(14)}, 856 - {"THC1_D3_STS", BIT(15)}, 857 - {} 858 - }; 859 - 860 - static const struct pmc_bit_map adl_vnn_req_status_0_map[] = { 861 - {"ISH_VNN_REQ_STS", BIT(2)}, 862 - {"ESPISPI_VNN_REQ_STS", BIT(18)}, 863 - {"DSP_VNN_REQ_STS", BIT(19)}, 864 - {} 865 - }; 866 - 867 - static const struct pmc_bit_map adl_vnn_req_status_1_map[] = { 868 - {"NPK_VNN_REQ_STS", BIT(4)}, 869 - {"EXI_VNN_REQ_STS", BIT(9)}, 870 - {"GBE_VNN_REQ_STS", BIT(19)}, 871 - {"SMB_VNN_REQ_STS", BIT(25)}, 872 - {"CNVI_VNN_REQ_STS", BIT(27)}, 873 - {} 874 - }; 875 - 876 - static const struct pmc_bit_map adl_vnn_req_status_2_map[] = { 877 - {"CSMERTC_VNN_REQ_STS", BIT(1)}, 878 - {"CSE_VNN_REQ_STS", BIT(4)}, 879 - {"SMT1_VNN_REQ_STS", BIT(8)}, 880 - {"CLINK_VNN_REQ_STS", BIT(14)}, 881 - {"GPIOCOM4_VNN_REQ_STS", BIT(20)}, 882 - {"GPIOCOM3_VNN_REQ_STS", BIT(21)}, 883 - {"GPIOCOM2_VNN_REQ_STS", BIT(22)}, 884 - {"GPIOCOM1_VNN_REQ_STS", BIT(23)}, 885 - {"GPIOCOM0_VNN_REQ_STS", BIT(24)}, 886 - {} 887 - }; 888 - 889 - static const struct pmc_bit_map adl_vnn_req_status_3_map[] = { 890 - {"GPIOCOM5_VNN_REQ_STS", BIT(11)}, 891 - {} 892 - }; 893 - 894 - static const struct pmc_bit_map adl_vnn_misc_status_map[] = { 895 - {"CPU_C10_REQ_STS", BIT(0)}, 896 - {"PCIe_LPM_En_REQ_STS", BIT(3)}, 897 - {"ITH_REQ_STS", BIT(5)}, 898 - {"CNVI_REQ_STS", BIT(6)}, 899 - {"ISH_REQ_STS", BIT(7)}, 900 - {"USB2_SUS_PG_Sys_REQ_STS", BIT(10)}, 901 - {"PCIe_Clk_REQ_STS", BIT(12)}, 902 - {"MPHY_Core_DL_REQ_STS", BIT(16)}, 903 - {"Break-even_En_REQ_STS", BIT(17)}, 904 - {"MPHY_SUS_REQ_STS", BIT(22)}, 905 - {"xDCI_attached_REQ_STS", BIT(24)}, 906 - {} 907 - }; 908 - 909 - static const struct pmc_bit_map *adl_lpm_maps[] = { 910 - adl_clocksource_status_map, 911 - adl_power_gating_status_0_map, 912 - adl_power_gating_status_1_map, 913 - adl_power_gating_status_2_map, 914 - adl_d3_status_0_map, 915 - adl_d3_status_1_map, 916 - adl_d3_status_2_map, 917 - adl_d3_status_3_map, 918 - adl_vnn_req_status_0_map, 919 - adl_vnn_req_status_1_map, 920 - adl_vnn_req_status_2_map, 921 - adl_vnn_req_status_3_map, 922 - adl_vnn_misc_status_map, 923 - tgl_signal_status_map, 924 - NULL 925 - }; 926 - 927 - static const struct pmc_reg_map adl_reg_map = { 928 - .pfear_sts = ext_adl_pfear_map, 929 - .slp_s0_offset = ADL_PMC_SLP_S0_RES_COUNTER_OFFSET, 930 - .slp_s0_res_counter_step = TGL_PMC_SLP_S0_RES_COUNTER_STEP, 931 - .ltr_show_sts = adl_ltr_show_map, 932 - .msr_sts = msr_map, 933 - .ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET, 934 - .regmap_length = CNP_PMC_MMIO_REG_LEN, 935 - .ppfear0_offset = CNP_PMC_HOST_PPFEAR0A, 936 - .ppfear_buckets = CNP_PPFEAR_NUM_ENTRIES, 937 - .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, 938 - .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, 939 - .ltr_ignore_max = ADL_NUM_IP_IGN_ALLOWED, 940 - .lpm_num_modes = ADL_LPM_NUM_MODES, 941 - .lpm_num_maps = ADL_LPM_NUM_MAPS, 942 - .lpm_res_counter_step_x2 = TGL_PMC_LPM_RES_COUNTER_STEP_X2, 943 - .etr3_offset = ETR3_OFFSET, 944 - .lpm_sts_latch_en_offset = ADL_LPM_STATUS_LATCH_EN_OFFSET, 945 - .lpm_priority_offset = ADL_LPM_PRI_OFFSET, 946 - .lpm_en_offset = ADL_LPM_EN_OFFSET, 947 - .lpm_residency_offset = ADL_LPM_RESIDENCY_OFFSET, 948 - .lpm_sts = adl_lpm_maps, 949 - .lpm_status_offset = ADL_LPM_STATUS_OFFSET, 950 - .lpm_live_status_offset = ADL_LPM_LIVE_STATUS_OFFSET, 951 49 }; 952 50 953 51 static inline u32 pmc_core_reg_read(struct pmc_dev *pmcdev, int reg_offset) ··· 435 1327 } 436 1328 DEFINE_SHOW_ATTRIBUTE(pmc_core_pll); 437 1329 438 - static int pmc_core_send_ltr_ignore(struct pmc_dev *pmcdev, u32 value) 1330 + int pmc_core_send_ltr_ignore(struct pmc_dev *pmcdev, u32 value) 439 1331 { 440 1332 const struct pmc_reg_map *map = pmcdev->map; 441 1333 u32 reg; ··· 901 1793 return; 902 1794 903 1795 lpm_en = pmc_core_reg_read(pmcdev, pmcdev->map->lpm_en_offset); 904 - pmcdev->num_lpm_modes = hweight32(lpm_en); 1796 + /* For MTL, BIT 31 is not an lpm mode but a enable bit. 1797 + * Lower byte is enough to cover the number of lpm modes for all 1798 + * platforms and hence mask the upper 3 bytes. 1799 + */ 1800 + pmcdev->num_lpm_modes = hweight32(lpm_en & 0xFF); 905 1801 906 1802 /* Read 32 bit LPM_PRI register */ 907 1803 lpm_pri = pmc_core_reg_read(pmcdev, pmcdev->map->lpm_priority_offset); ··· 1008 1896 } 1009 1897 1010 1898 static const struct x86_cpu_id intel_pmc_core_ids[] = { 1011 - X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_L, &spt_reg_map), 1012 - X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE, &spt_reg_map), 1013 - X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE_L, &spt_reg_map), 1014 - X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE, &spt_reg_map), 1015 - X86_MATCH_INTEL_FAM6_MODEL(CANNONLAKE_L, &cnp_reg_map), 1016 - X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_L, &icl_reg_map), 1017 - X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_NNPI, &icl_reg_map), 1018 - X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE, &cnp_reg_map), 1019 - X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE_L, &cnp_reg_map), 1020 - X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE_L, &tgl_reg_map), 1021 - X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE, &tgl_reg_map), 1022 - X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT, &tgl_reg_map), 1023 - X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_L, &icl_reg_map), 1024 - X86_MATCH_INTEL_FAM6_MODEL(ROCKETLAKE, &tgl_reg_map), 1025 - X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &tgl_reg_map), 1026 - X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_N, &tgl_reg_map), 1027 - X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, &adl_reg_map), 1028 - X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P, &tgl_reg_map), 1029 - X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, &adl_reg_map), 1030 - X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_S, &adl_reg_map), 1899 + X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_L, spt_core_init), 1900 + X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE, spt_core_init), 1901 + X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE_L, spt_core_init), 1902 + X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE, spt_core_init), 1903 + X86_MATCH_INTEL_FAM6_MODEL(CANNONLAKE_L, cnp_core_init), 1904 + X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_L, icl_core_init), 1905 + X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_NNPI, icl_core_init), 1906 + X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE, cnp_core_init), 1907 + X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE_L, cnp_core_init), 1908 + X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE_L, tgl_core_init), 1909 + X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE, tgl_core_init), 1910 + X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT, tgl_core_init), 1911 + X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_L, icl_core_init), 1912 + X86_MATCH_INTEL_FAM6_MODEL(ROCKETLAKE, tgl_core_init), 1913 + X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, tgl_core_init), 1914 + X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_N, tgl_core_init), 1915 + X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, adl_core_init), 1916 + X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P, tgl_core_init), 1917 + X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, adl_core_init), 1918 + X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_S, adl_core_init), 1919 + X86_MATCH_INTEL_FAM6_MODEL(METEORLAKE, mtl_core_init), 1031 1920 {} 1032 1921 }; 1033 1922 ··· 1088 1975 static bool device_initialized; 1089 1976 struct pmc_dev *pmcdev; 1090 1977 const struct x86_cpu_id *cpu_id; 1978 + void (*core_init)(struct pmc_dev *pmcdev); 1091 1979 u64 slp_s0_addr; 1092 1980 1093 1981 if (device_initialized) ··· 1099 1985 return -ENOMEM; 1100 1986 1101 1987 platform_set_drvdata(pdev, pmcdev); 1988 + pmcdev->pdev = pdev; 1102 1989 1103 1990 cpu_id = x86_match_cpu(intel_pmc_core_ids); 1104 1991 if (!cpu_id) 1105 1992 return -ENODEV; 1106 1993 1107 - pmcdev->map = (struct pmc_reg_map *)cpu_id->driver_data; 1994 + core_init = (void (*)(struct pmc_dev *))cpu_id->driver_data; 1108 1995 1109 1996 /* 1110 1997 * Coffee Lake has CPU ID of Kaby Lake and Cannon Lake PCH. So here 1111 1998 * Sunrisepoint PCH regmap can't be used. Use Cannon Lake PCH regmap 1112 1999 * in this case. 1113 2000 */ 1114 - if (pmcdev->map == &spt_reg_map && !pci_dev_present(pmc_pci_ids)) 1115 - pmcdev->map = &cnp_reg_map; 2001 + if (core_init == spt_core_init && !pci_dev_present(pmc_pci_ids)) 2002 + core_init = cnp_core_init; 2003 + 2004 + mutex_init(&pmcdev->lock); 2005 + core_init(pmcdev); 2006 + 1116 2007 1117 2008 if (lpit_read_residency_count_address(&slp_s0_addr)) { 1118 2009 pmcdev->base_addr = PMC_BASE_ADDR_DEFAULT; ··· 1133 2014 if (!pmcdev->regbase) 1134 2015 return -ENOMEM; 1135 2016 1136 - mutex_init(&pmcdev->lock); 2017 + if (pmcdev->core_configure) 2018 + pmcdev->core_configure(pmcdev); 1137 2019 1138 2020 pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit(pmcdev); 1139 2021 pmc_core_get_low_power_modes(pdev); 1140 2022 pmc_core_do_dmi_quirks(pmcdev); 1141 - 1142 - if (pmcdev->map == &tgl_reg_map) 1143 - pmc_core_get_tgl_lpm_reqs(pdev); 1144 - 1145 - /* 1146 - * On TGL and ADL, due to a hardware limitation, the GBE LTR blocks PC10 1147 - * when a cable is attached. Tell the PMC to ignore it. 1148 - */ 1149 - if (pmcdev->map == &tgl_reg_map || pmcdev->map == &adl_reg_map) { 1150 - dev_dbg(&pdev->dev, "ignoring GBE LTR\n"); 1151 - pmc_core_send_ltr_ignore(pmcdev, 3); 1152 - } 1153 2023 1154 2024 pmc_core_dbgfs_register(pmcdev); 1155 2025
+79 -12
drivers/platform/x86/intel/pmc/core.h
··· 12 12 #ifndef PMC_CORE_H 13 13 #define PMC_CORE_H 14 14 15 + #include <linux/acpi.h> 15 16 #include <linux/bits.h> 17 + #include <linux/platform_device.h> 16 18 17 19 #define PMC_BASE_ADDR_DEFAULT 0xFE000000 18 20 ··· 238 236 #define ADL_LPM_STATUS_LATCH_EN_OFFSET 0x1704 239 237 #define ADL_LPM_LIVE_STATUS_OFFSET 0x1764 240 238 241 - static const char *pmc_lpm_modes[] = { 242 - "S0i2.0", 243 - "S0i2.1", 244 - "S0i2.2", 245 - "S0i3.0", 246 - "S0i3.1", 247 - "S0i3.2", 248 - "S0i3.3", 249 - "S0i3.4", 250 - NULL 251 - }; 239 + /* Meteor Lake Power Management Controller register offsets */ 240 + #define MTL_LPM_EN_OFFSET 0x1798 241 + #define MTL_LPM_RESIDENCY_OFFSET 0x17A0 242 + 243 + /* Meteor Lake Low Power Mode debug registers */ 244 + #define MTL_LPM_PRI_OFFSET 0x179C 245 + #define MTL_LPM_STATUS_LATCH_EN_OFFSET 0x16F8 246 + #define MTL_LPM_STATUS_OFFSET 0x1700 247 + #define MTL_LPM_LIVE_STATUS_OFFSET 0x175C 248 + 249 + extern const char *pmc_lpm_modes[]; 252 250 253 251 struct pmc_bit_map { 254 252 const char *name; ··· 266 264 * @slp_s0_offset: PWRMBASE offset to read SLP_S0 residency 267 265 * @ltr_ignore_offset: PWRMBASE offset to read/write LTR ignore bit 268 266 * @regmap_length: Length of memory to map from PWRMBASE address to access 269 - * @ppfear0_offset: PWRMBASE offset to to read PPFEAR* 267 + * @ppfear0_offset: PWRMBASE offset to read PPFEAR* 270 268 * @ppfear_buckets: Number of 8 bits blocks to read all IP blocks from 271 269 * PPFEAR 272 270 * @pm_cfg_offset: PWRMBASE offset to PM_CFG register ··· 314 312 * @regbase: pointer to io-remapped memory location 315 313 * @map: pointer to pmc_reg_map struct that contains platform 316 314 * specific attributes 315 + * @pdev: pointer to platform_device struct 317 316 * @dbgfs_dir: path to debugfs interface 318 317 * @pmc_xram_read_bit: flag to indicate whether PMC XRAM shadow registers 319 318 * used to read MPHY PG and PLL status are available ··· 325 322 * @num_lpm_modes: Count of enabled modes 326 323 * @lpm_en_modes: Array of enabled modes from lowest to highest priority 327 324 * @lpm_req_regs: List of substate requirements 325 + * @core_configure: Function pointer to configure the platform 328 326 * 329 327 * pmc_dev contains info about power management controller device. 330 328 */ ··· 334 330 void __iomem *regbase; 335 331 const struct pmc_reg_map *map; 336 332 struct dentry *dbgfs_dir; 333 + struct platform_device *pdev; 337 334 int pmc_xram_read_bit; 338 335 struct mutex lock; /* generic mutex lock for PMC Core */ 339 336 ··· 344 339 int num_lpm_modes; 345 340 int lpm_en_modes[LPM_MAX_NUM_MODES]; 346 341 u32 *lpm_req_regs; 342 + void (*core_configure)(struct pmc_dev *pmcdev); 347 343 }; 344 + 345 + extern const struct pmc_bit_map msr_map[]; 346 + extern const struct pmc_bit_map spt_pll_map[]; 347 + extern const struct pmc_bit_map spt_mphy_map[]; 348 + extern const struct pmc_bit_map spt_pfear_map[]; 349 + extern const struct pmc_bit_map *ext_spt_pfear_map[]; 350 + extern const struct pmc_bit_map spt_ltr_show_map[]; 351 + extern const struct pmc_reg_map spt_reg_map; 352 + extern const struct pmc_bit_map cnp_pfear_map[]; 353 + extern const struct pmc_bit_map *ext_cnp_pfear_map[]; 354 + extern const struct pmc_bit_map cnp_slps0_dbg0_map[]; 355 + extern const struct pmc_bit_map cnp_slps0_dbg1_map[]; 356 + extern const struct pmc_bit_map cnp_slps0_dbg2_map[]; 357 + extern const struct pmc_bit_map *cnp_slps0_dbg_maps[]; 358 + extern const struct pmc_bit_map cnp_ltr_show_map[]; 359 + extern const struct pmc_reg_map cnp_reg_map; 360 + extern const struct pmc_bit_map icl_pfear_map[]; 361 + extern const struct pmc_bit_map *ext_icl_pfear_map[]; 362 + extern const struct pmc_reg_map icl_reg_map; 363 + extern const struct pmc_bit_map tgl_pfear_map[]; 364 + extern const struct pmc_bit_map *ext_tgl_pfear_map[]; 365 + extern const struct pmc_bit_map tgl_clocksource_status_map[]; 366 + extern const struct pmc_bit_map tgl_power_gating_status_map[]; 367 + extern const struct pmc_bit_map tgl_d3_status_map[]; 368 + extern const struct pmc_bit_map tgl_vnn_req_status_map[]; 369 + extern const struct pmc_bit_map tgl_vnn_misc_status_map[]; 370 + extern const struct pmc_bit_map tgl_signal_status_map[]; 371 + extern const struct pmc_bit_map *tgl_lpm_maps[]; 372 + extern const struct pmc_reg_map tgl_reg_map; 373 + extern const struct pmc_bit_map adl_pfear_map[]; 374 + extern const struct pmc_bit_map *ext_adl_pfear_map[]; 375 + extern const struct pmc_bit_map adl_ltr_show_map[]; 376 + extern const struct pmc_bit_map adl_clocksource_status_map[]; 377 + extern const struct pmc_bit_map adl_power_gating_status_0_map[]; 378 + extern const struct pmc_bit_map adl_power_gating_status_1_map[]; 379 + extern const struct pmc_bit_map adl_power_gating_status_2_map[]; 380 + extern const struct pmc_bit_map adl_d3_status_0_map[]; 381 + extern const struct pmc_bit_map adl_d3_status_1_map[]; 382 + extern const struct pmc_bit_map adl_d3_status_2_map[]; 383 + extern const struct pmc_bit_map adl_d3_status_3_map[]; 384 + extern const struct pmc_bit_map adl_vnn_req_status_0_map[]; 385 + extern const struct pmc_bit_map adl_vnn_req_status_1_map[]; 386 + extern const struct pmc_bit_map adl_vnn_req_status_2_map[]; 387 + extern const struct pmc_bit_map adl_vnn_req_status_3_map[]; 388 + extern const struct pmc_bit_map adl_vnn_misc_status_map[]; 389 + extern const struct pmc_bit_map *adl_lpm_maps[]; 390 + extern const struct pmc_reg_map adl_reg_map; 391 + extern const struct pmc_reg_map mtl_reg_map; 392 + 393 + extern void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev); 394 + extern int pmc_core_send_ltr_ignore(struct pmc_dev *pmcdev, u32 value); 395 + 396 + void spt_core_init(struct pmc_dev *pmcdev); 397 + void cnp_core_init(struct pmc_dev *pmcdev); 398 + void icl_core_init(struct pmc_dev *pmcdev); 399 + void tgl_core_init(struct pmc_dev *pmcdev); 400 + void adl_core_init(struct pmc_dev *pmcdev); 401 + void mtl_core_init(struct pmc_dev *pmcdev); 402 + void tgl_core_configure(struct pmc_dev *pmcdev); 403 + void adl_core_configure(struct pmc_dev *pmcdev); 404 + void mtl_core_configure(struct pmc_dev *pmcdev); 348 405 349 406 #define pmc_for_each_mode(i, mode, pmcdev) \ 350 407 for (i = 0, mode = pmcdev->lpm_en_modes[i]; \
+56
drivers/platform/x86/intel/pmc/icl.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * This file contains platform specific structure definitions 4 + * and init function used by Ice Lake PCH. 5 + * 6 + * Copyright (c) 2022, Intel Corporation. 7 + * All Rights Reserved. 8 + * 9 + */ 10 + 11 + #include "core.h" 12 + 13 + const struct pmc_bit_map icl_pfear_map[] = { 14 + {"RES_65", BIT(0)}, 15 + {"RES_66", BIT(1)}, 16 + {"RES_67", BIT(2)}, 17 + {"TAM", BIT(3)}, 18 + {"GBETSN", BIT(4)}, 19 + {"TBTLSX", BIT(5)}, 20 + {"RES_71", BIT(6)}, 21 + {"RES_72", BIT(7)}, 22 + {} 23 + }; 24 + 25 + const struct pmc_bit_map *ext_icl_pfear_map[] = { 26 + /* 27 + * Check intel_pmc_core_ids[] users of icl_reg_map for 28 + * a list of core SoCs using this. 29 + */ 30 + cnp_pfear_map, 31 + icl_pfear_map, 32 + NULL 33 + }; 34 + 35 + const struct pmc_reg_map icl_reg_map = { 36 + .pfear_sts = ext_icl_pfear_map, 37 + .slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET, 38 + .slp_s0_res_counter_step = ICL_PMC_SLP_S0_RES_COUNTER_STEP, 39 + .slps0_dbg_maps = cnp_slps0_dbg_maps, 40 + .ltr_show_sts = cnp_ltr_show_map, 41 + .msr_sts = msr_map, 42 + .slps0_dbg_offset = CNP_PMC_SLPS0_DBG_OFFSET, 43 + .ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET, 44 + .regmap_length = CNP_PMC_MMIO_REG_LEN, 45 + .ppfear0_offset = CNP_PMC_HOST_PPFEAR0A, 46 + .ppfear_buckets = ICL_PPFEAR_NUM_ENTRIES, 47 + .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, 48 + .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, 49 + .ltr_ignore_max = ICL_NUM_IP_IGN_ALLOWED, 50 + .etr3_offset = ETR3_OFFSET, 51 + }; 52 + 53 + void icl_core_init(struct pmc_dev *pmcdev) 54 + { 55 + pmcdev->map = &icl_reg_map; 56 + }
+52
drivers/platform/x86/intel/pmc/mtl.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * This file contains platform specific structure definitions 4 + * and init function used by Meteor Lake PCH. 5 + * 6 + * Copyright (c) 2022, Intel Corporation. 7 + * All Rights Reserved. 8 + * 9 + */ 10 + 11 + #include "core.h" 12 + 13 + const struct pmc_reg_map mtl_reg_map = { 14 + .pfear_sts = ext_tgl_pfear_map, 15 + .slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET, 16 + .slp_s0_res_counter_step = TGL_PMC_SLP_S0_RES_COUNTER_STEP, 17 + .ltr_show_sts = adl_ltr_show_map, 18 + .msr_sts = msr_map, 19 + .ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET, 20 + .regmap_length = CNP_PMC_MMIO_REG_LEN, 21 + .ppfear0_offset = CNP_PMC_HOST_PPFEAR0A, 22 + .ppfear_buckets = ICL_PPFEAR_NUM_ENTRIES, 23 + .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, 24 + .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, 25 + .ltr_ignore_max = ADL_NUM_IP_IGN_ALLOWED, 26 + .lpm_num_modes = ADL_LPM_NUM_MODES, 27 + .lpm_num_maps = ADL_LPM_NUM_MAPS, 28 + .lpm_res_counter_step_x2 = TGL_PMC_LPM_RES_COUNTER_STEP_X2, 29 + .etr3_offset = ETR3_OFFSET, 30 + .lpm_sts_latch_en_offset = MTL_LPM_STATUS_LATCH_EN_OFFSET, 31 + .lpm_priority_offset = MTL_LPM_PRI_OFFSET, 32 + .lpm_en_offset = MTL_LPM_EN_OFFSET, 33 + .lpm_residency_offset = MTL_LPM_RESIDENCY_OFFSET, 34 + .lpm_sts = adl_lpm_maps, 35 + .lpm_status_offset = MTL_LPM_STATUS_OFFSET, 36 + .lpm_live_status_offset = MTL_LPM_LIVE_STATUS_OFFSET, 37 + }; 38 + 39 + void mtl_core_configure(struct pmc_dev *pmcdev) 40 + { 41 + /* Due to a hardware limitation, the GBE LTR blocks PC10 42 + * when a cable is attached. Tell the PMC to ignore it. 43 + */ 44 + dev_dbg(&pmcdev->pdev->dev, "ignoring GBE LTR\n"); 45 + pmc_core_send_ltr_ignore(pmcdev, 3); 46 + } 47 + 48 + void mtl_core_init(struct pmc_dev *pmcdev) 49 + { 50 + pmcdev->map = &mtl_reg_map; 51 + pmcdev->core_configure = mtl_core_configure; 52 + }
+140
drivers/platform/x86/intel/pmc/spt.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * This file contains platform specific structure definitions 4 + * and init function used by Sunrise Point PCH. 5 + * 6 + * Copyright (c) 2022, Intel Corporation. 7 + * All Rights Reserved. 8 + * 9 + */ 10 + 11 + #include "core.h" 12 + 13 + const struct pmc_bit_map spt_pll_map[] = { 14 + {"MIPI PLL", SPT_PMC_BIT_MPHY_CMN_LANE0}, 15 + {"GEN2 USB2PCIE2 PLL", SPT_PMC_BIT_MPHY_CMN_LANE1}, 16 + {"DMIPCIE3 PLL", SPT_PMC_BIT_MPHY_CMN_LANE2}, 17 + {"SATA PLL", SPT_PMC_BIT_MPHY_CMN_LANE3}, 18 + {} 19 + }; 20 + 21 + const struct pmc_bit_map spt_mphy_map[] = { 22 + {"MPHY CORE LANE 0", SPT_PMC_BIT_MPHY_LANE0}, 23 + {"MPHY CORE LANE 1", SPT_PMC_BIT_MPHY_LANE1}, 24 + {"MPHY CORE LANE 2", SPT_PMC_BIT_MPHY_LANE2}, 25 + {"MPHY CORE LANE 3", SPT_PMC_BIT_MPHY_LANE3}, 26 + {"MPHY CORE LANE 4", SPT_PMC_BIT_MPHY_LANE4}, 27 + {"MPHY CORE LANE 5", SPT_PMC_BIT_MPHY_LANE5}, 28 + {"MPHY CORE LANE 6", SPT_PMC_BIT_MPHY_LANE6}, 29 + {"MPHY CORE LANE 7", SPT_PMC_BIT_MPHY_LANE7}, 30 + {"MPHY CORE LANE 8", SPT_PMC_BIT_MPHY_LANE8}, 31 + {"MPHY CORE LANE 9", SPT_PMC_BIT_MPHY_LANE9}, 32 + {"MPHY CORE LANE 10", SPT_PMC_BIT_MPHY_LANE10}, 33 + {"MPHY CORE LANE 11", SPT_PMC_BIT_MPHY_LANE11}, 34 + {"MPHY CORE LANE 12", SPT_PMC_BIT_MPHY_LANE12}, 35 + {"MPHY CORE LANE 13", SPT_PMC_BIT_MPHY_LANE13}, 36 + {"MPHY CORE LANE 14", SPT_PMC_BIT_MPHY_LANE14}, 37 + {"MPHY CORE LANE 15", SPT_PMC_BIT_MPHY_LANE15}, 38 + {} 39 + }; 40 + 41 + const struct pmc_bit_map spt_pfear_map[] = { 42 + {"PMC", SPT_PMC_BIT_PMC}, 43 + {"OPI-DMI", SPT_PMC_BIT_OPI}, 44 + {"SPI / eSPI", SPT_PMC_BIT_SPI}, 45 + {"XHCI", SPT_PMC_BIT_XHCI}, 46 + {"SPA", SPT_PMC_BIT_SPA}, 47 + {"SPB", SPT_PMC_BIT_SPB}, 48 + {"SPC", SPT_PMC_BIT_SPC}, 49 + {"GBE", SPT_PMC_BIT_GBE}, 50 + {"SATA", SPT_PMC_BIT_SATA}, 51 + {"HDA-PGD0", SPT_PMC_BIT_HDA_PGD0}, 52 + {"HDA-PGD1", SPT_PMC_BIT_HDA_PGD1}, 53 + {"HDA-PGD2", SPT_PMC_BIT_HDA_PGD2}, 54 + {"HDA-PGD3", SPT_PMC_BIT_HDA_PGD3}, 55 + {"RSVD", SPT_PMC_BIT_RSVD_0B}, 56 + {"LPSS", SPT_PMC_BIT_LPSS}, 57 + {"LPC", SPT_PMC_BIT_LPC}, 58 + {"SMB", SPT_PMC_BIT_SMB}, 59 + {"ISH", SPT_PMC_BIT_ISH}, 60 + {"P2SB", SPT_PMC_BIT_P2SB}, 61 + {"DFX", SPT_PMC_BIT_DFX}, 62 + {"SCC", SPT_PMC_BIT_SCC}, 63 + {"RSVD", SPT_PMC_BIT_RSVD_0C}, 64 + {"FUSE", SPT_PMC_BIT_FUSE}, 65 + {"CAMERA", SPT_PMC_BIT_CAMREA}, 66 + {"RSVD", SPT_PMC_BIT_RSVD_0D}, 67 + {"USB3-OTG", SPT_PMC_BIT_USB3_OTG}, 68 + {"EXI", SPT_PMC_BIT_EXI}, 69 + {"CSE", SPT_PMC_BIT_CSE}, 70 + {"CSME_KVM", SPT_PMC_BIT_CSME_KVM}, 71 + {"CSME_PMT", SPT_PMC_BIT_CSME_PMT}, 72 + {"CSME_CLINK", SPT_PMC_BIT_CSME_CLINK}, 73 + {"CSME_PTIO", SPT_PMC_BIT_CSME_PTIO}, 74 + {"CSME_USBR", SPT_PMC_BIT_CSME_USBR}, 75 + {"CSME_SUSRAM", SPT_PMC_BIT_CSME_SUSRAM}, 76 + {"CSME_SMT", SPT_PMC_BIT_CSME_SMT}, 77 + {"RSVD", SPT_PMC_BIT_RSVD_1A}, 78 + {"CSME_SMS2", SPT_PMC_BIT_CSME_SMS2}, 79 + {"CSME_SMS1", SPT_PMC_BIT_CSME_SMS1}, 80 + {"CSME_RTC", SPT_PMC_BIT_CSME_RTC}, 81 + {"CSME_PSF", SPT_PMC_BIT_CSME_PSF}, 82 + {} 83 + }; 84 + 85 + const struct pmc_bit_map *ext_spt_pfear_map[] = { 86 + /* 87 + * Check intel_pmc_core_ids[] users of spt_reg_map for 88 + * a list of core SoCs using this. 89 + */ 90 + spt_pfear_map, 91 + NULL 92 + }; 93 + 94 + const struct pmc_bit_map spt_ltr_show_map[] = { 95 + {"SOUTHPORT_A", SPT_PMC_LTR_SPA}, 96 + {"SOUTHPORT_B", SPT_PMC_LTR_SPB}, 97 + {"SATA", SPT_PMC_LTR_SATA}, 98 + {"GIGABIT_ETHERNET", SPT_PMC_LTR_GBE}, 99 + {"XHCI", SPT_PMC_LTR_XHCI}, 100 + {"Reserved", SPT_PMC_LTR_RESERVED}, 101 + {"ME", SPT_PMC_LTR_ME}, 102 + /* EVA is Enterprise Value Add, doesn't really exist on PCH */ 103 + {"EVA", SPT_PMC_LTR_EVA}, 104 + {"SOUTHPORT_C", SPT_PMC_LTR_SPC}, 105 + {"HD_AUDIO", SPT_PMC_LTR_AZ}, 106 + {"LPSS", SPT_PMC_LTR_LPSS}, 107 + {"SOUTHPORT_D", SPT_PMC_LTR_SPD}, 108 + {"SOUTHPORT_E", SPT_PMC_LTR_SPE}, 109 + {"CAMERA", SPT_PMC_LTR_CAM}, 110 + {"ESPI", SPT_PMC_LTR_ESPI}, 111 + {"SCC", SPT_PMC_LTR_SCC}, 112 + {"ISH", SPT_PMC_LTR_ISH}, 113 + /* Below two cannot be used for LTR_IGNORE */ 114 + {"CURRENT_PLATFORM", SPT_PMC_LTR_CUR_PLT}, 115 + {"AGGREGATED_SYSTEM", SPT_PMC_LTR_CUR_ASLT}, 116 + {} 117 + }; 118 + 119 + const struct pmc_reg_map spt_reg_map = { 120 + .pfear_sts = ext_spt_pfear_map, 121 + .mphy_sts = spt_mphy_map, 122 + .pll_sts = spt_pll_map, 123 + .ltr_show_sts = spt_ltr_show_map, 124 + .msr_sts = msr_map, 125 + .slp_s0_offset = SPT_PMC_SLP_S0_RES_COUNTER_OFFSET, 126 + .slp_s0_res_counter_step = SPT_PMC_SLP_S0_RES_COUNTER_STEP, 127 + .ltr_ignore_offset = SPT_PMC_LTR_IGNORE_OFFSET, 128 + .regmap_length = SPT_PMC_MMIO_REG_LEN, 129 + .ppfear0_offset = SPT_PMC_XRAM_PPFEAR0A, 130 + .ppfear_buckets = SPT_PPFEAR_NUM_ENTRIES, 131 + .pm_cfg_offset = SPT_PMC_PM_CFG_OFFSET, 132 + .pm_read_disable_bit = SPT_PMC_READ_DISABLE_BIT, 133 + .ltr_ignore_max = SPT_NUM_IP_IGN_ALLOWED, 134 + .pm_vric1_offset = SPT_PMC_VRIC1_OFFSET, 135 + }; 136 + 137 + void spt_core_init(struct pmc_dev *pmcdev) 138 + { 139 + pmcdev->map = &spt_reg_map; 140 + }
+269
drivers/platform/x86/intel/pmc/tgl.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * This file contains platform specific structure definitions 4 + * and init function used by Tiger Lake PCH. 5 + * 6 + * Copyright (c) 2022, Intel Corporation. 7 + * All Rights Reserved. 8 + * 9 + */ 10 + 11 + #include "core.h" 12 + 13 + #define ACPI_S0IX_DSM_UUID "57a6512e-3979-4e9d-9708-ff13b2508972" 14 + #define ACPI_GET_LOW_MODE_REGISTERS 1 15 + 16 + const struct pmc_bit_map tgl_pfear_map[] = { 17 + {"PSF9", BIT(0)}, 18 + {"RES_66", BIT(1)}, 19 + {"RES_67", BIT(2)}, 20 + {"RES_68", BIT(3)}, 21 + {"RES_69", BIT(4)}, 22 + {"RES_70", BIT(5)}, 23 + {"TBTLSX", BIT(6)}, 24 + {} 25 + }; 26 + 27 + const struct pmc_bit_map *ext_tgl_pfear_map[] = { 28 + /* 29 + * Check intel_pmc_core_ids[] users of tgl_reg_map for 30 + * a list of core SoCs using this. 31 + */ 32 + cnp_pfear_map, 33 + tgl_pfear_map, 34 + NULL 35 + }; 36 + 37 + const struct pmc_bit_map tgl_clocksource_status_map[] = { 38 + {"USB2PLL_OFF_STS", BIT(18)}, 39 + {"PCIe/USB3.1_Gen2PLL_OFF_STS", BIT(19)}, 40 + {"PCIe_Gen3PLL_OFF_STS", BIT(20)}, 41 + {"OPIOPLL_OFF_STS", BIT(21)}, 42 + {"OCPLL_OFF_STS", BIT(22)}, 43 + {"MainPLL_OFF_STS", BIT(23)}, 44 + {"MIPIPLL_OFF_STS", BIT(24)}, 45 + {"Fast_XTAL_Osc_OFF_STS", BIT(25)}, 46 + {"AC_Ring_Osc_OFF_STS", BIT(26)}, 47 + {"MC_Ring_Osc_OFF_STS", BIT(27)}, 48 + {"SATAPLL_OFF_STS", BIT(29)}, 49 + {"XTAL_USB2PLL_OFF_STS", BIT(31)}, 50 + {} 51 + }; 52 + 53 + const struct pmc_bit_map tgl_power_gating_status_map[] = { 54 + {"CSME_PG_STS", BIT(0)}, 55 + {"SATA_PG_STS", BIT(1)}, 56 + {"xHCI_PG_STS", BIT(2)}, 57 + {"UFSX2_PG_STS", BIT(3)}, 58 + {"OTG_PG_STS", BIT(5)}, 59 + {"SPA_PG_STS", BIT(6)}, 60 + {"SPB_PG_STS", BIT(7)}, 61 + {"SPC_PG_STS", BIT(8)}, 62 + {"SPD_PG_STS", BIT(9)}, 63 + {"SPE_PG_STS", BIT(10)}, 64 + {"SPF_PG_STS", BIT(11)}, 65 + {"LSX_PG_STS", BIT(13)}, 66 + {"P2SB_PG_STS", BIT(14)}, 67 + {"PSF_PG_STS", BIT(15)}, 68 + {"SBR_PG_STS", BIT(16)}, 69 + {"OPIDMI_PG_STS", BIT(17)}, 70 + {"THC0_PG_STS", BIT(18)}, 71 + {"THC1_PG_STS", BIT(19)}, 72 + {"GBETSN_PG_STS", BIT(20)}, 73 + {"GBE_PG_STS", BIT(21)}, 74 + {"LPSS_PG_STS", BIT(22)}, 75 + {"MMP_UFSX2_PG_STS", BIT(23)}, 76 + {"MMP_UFSX2B_PG_STS", BIT(24)}, 77 + {"FIA_PG_STS", BIT(25)}, 78 + {} 79 + }; 80 + 81 + const struct pmc_bit_map tgl_d3_status_map[] = { 82 + {"ADSP_D3_STS", BIT(0)}, 83 + {"SATA_D3_STS", BIT(1)}, 84 + {"xHCI0_D3_STS", BIT(2)}, 85 + {"xDCI1_D3_STS", BIT(5)}, 86 + {"SDX_D3_STS", BIT(6)}, 87 + {"EMMC_D3_STS", BIT(7)}, 88 + {"IS_D3_STS", BIT(8)}, 89 + {"THC0_D3_STS", BIT(9)}, 90 + {"THC1_D3_STS", BIT(10)}, 91 + {"GBE_D3_STS", BIT(11)}, 92 + {"GBE_TSN_D3_STS", BIT(12)}, 93 + {} 94 + }; 95 + 96 + const struct pmc_bit_map tgl_vnn_req_status_map[] = { 97 + {"GPIO_COM0_VNN_REQ_STS", BIT(1)}, 98 + {"GPIO_COM1_VNN_REQ_STS", BIT(2)}, 99 + {"GPIO_COM2_VNN_REQ_STS", BIT(3)}, 100 + {"GPIO_COM3_VNN_REQ_STS", BIT(4)}, 101 + {"GPIO_COM4_VNN_REQ_STS", BIT(5)}, 102 + {"GPIO_COM5_VNN_REQ_STS", BIT(6)}, 103 + {"Audio_VNN_REQ_STS", BIT(7)}, 104 + {"ISH_VNN_REQ_STS", BIT(8)}, 105 + {"CNVI_VNN_REQ_STS", BIT(9)}, 106 + {"eSPI_VNN_REQ_STS", BIT(10)}, 107 + {"Display_VNN_REQ_STS", BIT(11)}, 108 + {"DTS_VNN_REQ_STS", BIT(12)}, 109 + {"SMBUS_VNN_REQ_STS", BIT(14)}, 110 + {"CSME_VNN_REQ_STS", BIT(15)}, 111 + {"SMLINK0_VNN_REQ_STS", BIT(16)}, 112 + {"SMLINK1_VNN_REQ_STS", BIT(17)}, 113 + {"CLINK_VNN_REQ_STS", BIT(20)}, 114 + {"DCI_VNN_REQ_STS", BIT(21)}, 115 + {"ITH_VNN_REQ_STS", BIT(22)}, 116 + {"CSME_VNN_REQ_STS", BIT(24)}, 117 + {"GBE_VNN_REQ_STS", BIT(25)}, 118 + {} 119 + }; 120 + 121 + const struct pmc_bit_map tgl_vnn_misc_status_map[] = { 122 + {"CPU_C10_REQ_STS_0", BIT(0)}, 123 + {"PCIe_LPM_En_REQ_STS_3", BIT(3)}, 124 + {"ITH_REQ_STS_5", BIT(5)}, 125 + {"CNVI_REQ_STS_6", BIT(6)}, 126 + {"ISH_REQ_STS_7", BIT(7)}, 127 + {"USB2_SUS_PG_Sys_REQ_STS_10", BIT(10)}, 128 + {"PCIe_Clk_REQ_STS_12", BIT(12)}, 129 + {"MPHY_Core_DL_REQ_STS_16", BIT(16)}, 130 + {"Break-even_En_REQ_STS_17", BIT(17)}, 131 + {"Auto-demo_En_REQ_STS_18", BIT(18)}, 132 + {"MPHY_SUS_REQ_STS_22", BIT(22)}, 133 + {"xDCI_attached_REQ_STS_24", BIT(24)}, 134 + {} 135 + }; 136 + 137 + const struct pmc_bit_map tgl_signal_status_map[] = { 138 + {"LSX_Wake0_En_STS", BIT(0)}, 139 + {"LSX_Wake0_Pol_STS", BIT(1)}, 140 + {"LSX_Wake1_En_STS", BIT(2)}, 141 + {"LSX_Wake1_Pol_STS", BIT(3)}, 142 + {"LSX_Wake2_En_STS", BIT(4)}, 143 + {"LSX_Wake2_Pol_STS", BIT(5)}, 144 + {"LSX_Wake3_En_STS", BIT(6)}, 145 + {"LSX_Wake3_Pol_STS", BIT(7)}, 146 + {"LSX_Wake4_En_STS", BIT(8)}, 147 + {"LSX_Wake4_Pol_STS", BIT(9)}, 148 + {"LSX_Wake5_En_STS", BIT(10)}, 149 + {"LSX_Wake5_Pol_STS", BIT(11)}, 150 + {"LSX_Wake6_En_STS", BIT(12)}, 151 + {"LSX_Wake6_Pol_STS", BIT(13)}, 152 + {"LSX_Wake7_En_STS", BIT(14)}, 153 + {"LSX_Wake7_Pol_STS", BIT(15)}, 154 + {"Intel_Se_IO_Wake0_En_STS", BIT(16)}, 155 + {"Intel_Se_IO_Wake0_Pol_STS", BIT(17)}, 156 + {"Intel_Se_IO_Wake1_En_STS", BIT(18)}, 157 + {"Intel_Se_IO_Wake1_Pol_STS", BIT(19)}, 158 + {"Int_Timer_SS_Wake0_En_STS", BIT(20)}, 159 + {"Int_Timer_SS_Wake0_Pol_STS", BIT(21)}, 160 + {"Int_Timer_SS_Wake1_En_STS", BIT(22)}, 161 + {"Int_Timer_SS_Wake1_Pol_STS", BIT(23)}, 162 + {"Int_Timer_SS_Wake2_En_STS", BIT(24)}, 163 + {"Int_Timer_SS_Wake2_Pol_STS", BIT(25)}, 164 + {"Int_Timer_SS_Wake3_En_STS", BIT(26)}, 165 + {"Int_Timer_SS_Wake3_Pol_STS", BIT(27)}, 166 + {"Int_Timer_SS_Wake4_En_STS", BIT(28)}, 167 + {"Int_Timer_SS_Wake4_Pol_STS", BIT(29)}, 168 + {"Int_Timer_SS_Wake5_En_STS", BIT(30)}, 169 + {"Int_Timer_SS_Wake5_Pol_STS", BIT(31)}, 170 + {} 171 + }; 172 + 173 + const struct pmc_bit_map *tgl_lpm_maps[] = { 174 + tgl_clocksource_status_map, 175 + tgl_power_gating_status_map, 176 + tgl_d3_status_map, 177 + tgl_vnn_req_status_map, 178 + tgl_vnn_misc_status_map, 179 + tgl_signal_status_map, 180 + NULL 181 + }; 182 + 183 + const struct pmc_reg_map tgl_reg_map = { 184 + .pfear_sts = ext_tgl_pfear_map, 185 + .slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET, 186 + .slp_s0_res_counter_step = TGL_PMC_SLP_S0_RES_COUNTER_STEP, 187 + .ltr_show_sts = cnp_ltr_show_map, 188 + .msr_sts = msr_map, 189 + .ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET, 190 + .regmap_length = CNP_PMC_MMIO_REG_LEN, 191 + .ppfear0_offset = CNP_PMC_HOST_PPFEAR0A, 192 + .ppfear_buckets = ICL_PPFEAR_NUM_ENTRIES, 193 + .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, 194 + .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, 195 + .ltr_ignore_max = TGL_NUM_IP_IGN_ALLOWED, 196 + .lpm_num_maps = TGL_LPM_NUM_MAPS, 197 + .lpm_res_counter_step_x2 = TGL_PMC_LPM_RES_COUNTER_STEP_X2, 198 + .lpm_sts_latch_en_offset = TGL_LPM_STS_LATCH_EN_OFFSET, 199 + .lpm_en_offset = TGL_LPM_EN_OFFSET, 200 + .lpm_priority_offset = TGL_LPM_PRI_OFFSET, 201 + .lpm_residency_offset = TGL_LPM_RESIDENCY_OFFSET, 202 + .lpm_sts = tgl_lpm_maps, 203 + .lpm_status_offset = TGL_LPM_STATUS_OFFSET, 204 + .lpm_live_status_offset = TGL_LPM_LIVE_STATUS_OFFSET, 205 + .etr3_offset = ETR3_OFFSET, 206 + }; 207 + 208 + void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev) 209 + { 210 + struct pmc_dev *pmcdev = platform_get_drvdata(pdev); 211 + const int num_maps = pmcdev->map->lpm_num_maps; 212 + u32 lpm_size = LPM_MAX_NUM_MODES * num_maps * 4; 213 + union acpi_object *out_obj; 214 + struct acpi_device *adev; 215 + guid_t s0ix_dsm_guid; 216 + u32 *lpm_req_regs, *addr; 217 + 218 + adev = ACPI_COMPANION(&pdev->dev); 219 + if (!adev) 220 + return; 221 + 222 + guid_parse(ACPI_S0IX_DSM_UUID, &s0ix_dsm_guid); 223 + 224 + out_obj = acpi_evaluate_dsm(adev->handle, &s0ix_dsm_guid, 0, 225 + ACPI_GET_LOW_MODE_REGISTERS, NULL); 226 + if (out_obj && out_obj->type == ACPI_TYPE_BUFFER) { 227 + u32 size = out_obj->buffer.length; 228 + 229 + if (size != lpm_size) { 230 + acpi_handle_debug(adev->handle, 231 + "_DSM returned unexpected buffer size, have %u, expect %u\n", 232 + size, lpm_size); 233 + goto free_acpi_obj; 234 + } 235 + } else { 236 + acpi_handle_debug(adev->handle, 237 + "_DSM function 0 evaluation failed\n"); 238 + goto free_acpi_obj; 239 + } 240 + 241 + addr = (u32 *)out_obj->buffer.pointer; 242 + 243 + lpm_req_regs = devm_kzalloc(&pdev->dev, lpm_size * sizeof(u32), 244 + GFP_KERNEL); 245 + if (!lpm_req_regs) 246 + goto free_acpi_obj; 247 + 248 + memcpy(lpm_req_regs, addr, lpm_size); 249 + pmcdev->lpm_req_regs = lpm_req_regs; 250 + 251 + free_acpi_obj: 252 + ACPI_FREE(out_obj); 253 + } 254 + 255 + void tgl_core_configure(struct pmc_dev *pmcdev) 256 + { 257 + pmc_core_get_tgl_lpm_reqs(pmcdev->pdev); 258 + /* Due to a hardware limitation, the GBE LTR blocks PC10 259 + * when a cable is attached. Tell the PMC to ignore it. 260 + */ 261 + dev_dbg(&pmcdev->pdev->dev, "ignoring GBE LTR\n"); 262 + pmc_core_send_ltr_ignore(pmcdev, 3); 263 + } 264 + 265 + void tgl_core_init(struct pmc_dev *pmcdev) 266 + { 267 + pmcdev->map = &tgl_reg_map; 268 + pmcdev->core_configure = tgl_core_configure; 269 + }
+109 -27
drivers/platform/x86/intel/sdsi.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* 3 - * Intel Software Defined Silicon driver 3 + * Intel On Demand (Software Defined Silicon) driver 4 4 * 5 5 * Copyright (c) 2022, Intel Corporation. 6 6 * All Rights Reserved. ··· 27 27 #define ACCESS_TYPE_LOCAL 3 28 28 29 29 #define SDSI_MIN_SIZE_DWORDS 276 30 - #define SDSI_SIZE_CONTROL 8 31 30 #define SDSI_SIZE_MAILBOX 1024 32 - #define SDSI_SIZE_REGS 72 31 + #define SDSI_SIZE_REGS 80 33 32 #define SDSI_SIZE_CMD sizeof(u64) 34 33 35 34 /* ··· 40 41 #define SDSI_SIZE_READ_MSG (SDSI_SIZE_MAILBOX * 4) 41 42 42 43 #define SDSI_ENABLED_FEATURES_OFFSET 16 43 - #define SDSI_ENABLED BIT(3) 44 + #define SDSI_FEATURE_SDSI BIT(3) 45 + #define SDSI_FEATURE_METERING BIT(26) 46 + 44 47 #define SDSI_SOCKET_ID_OFFSET 64 45 48 #define SDSI_SOCKET_ID GENMASK(3, 0) 46 49 ··· 76 75 #define DT_TBIR GENMASK(2, 0) 77 76 #define DT_OFFSET(v) ((v) & GENMASK(31, 3)) 78 77 78 + #define SDSI_GUID_V1 0x006DD191 79 + #define GUID_V1_CNTRL_SIZE 8 80 + #define GUID_V1_REGS_SIZE 72 81 + #define SDSI_GUID_V2 0xF210D9EF 82 + #define GUID_V2_CNTRL_SIZE 16 83 + #define GUID_V2_REGS_SIZE 80 84 + 79 85 enum sdsi_command { 80 - SDSI_CMD_PROVISION_AKC = 0x04, 81 - SDSI_CMD_PROVISION_CAP = 0x08, 82 - SDSI_CMD_READ_STATE = 0x10, 86 + SDSI_CMD_PROVISION_AKC = 0x0004, 87 + SDSI_CMD_PROVISION_CAP = 0x0008, 88 + SDSI_CMD_READ_STATE = 0x0010, 89 + SDSI_CMD_READ_METER = 0x0014, 83 90 }; 84 91 85 92 struct sdsi_mbox_info { ··· 108 99 void __iomem *control_addr; 109 100 void __iomem *mbox_addr; 110 101 void __iomem *regs_addr; 102 + int control_size; 103 + int maibox_size; 104 + int registers_size; 111 105 u32 guid; 112 - bool sdsi_enabled; 106 + u32 features; 113 107 }; 114 108 115 109 /* SDSi mailbox operations must be performed using 64bit mov instructions */ ··· 344 332 struct sdsi_mbox_info info; 345 333 int ret; 346 334 347 - if (!priv->sdsi_enabled) 348 - return -EPERM; 349 - 350 335 if (count > (SDSI_SIZE_WRITE_MSG - SDSI_SIZE_CMD)) 351 336 return -EOVERFLOW; 352 337 ··· 403 394 } 404 395 static BIN_ATTR_WO(provision_cap, SDSI_SIZE_WRITE_MSG); 405 396 406 - static long state_certificate_read(struct file *filp, struct kobject *kobj, 407 - struct bin_attribute *attr, char *buf, loff_t off, 408 - size_t count) 397 + static ssize_t 398 + certificate_read(u64 command, struct sdsi_priv *priv, char *buf, loff_t off, 399 + size_t count) 409 400 { 410 - struct device *dev = kobj_to_dev(kobj); 411 - struct sdsi_priv *priv = dev_get_drvdata(dev); 412 - u64 command = SDSI_CMD_READ_STATE; 413 401 struct sdsi_mbox_info info; 414 402 size_t size; 415 403 int ret; 416 - 417 - if (!priv->sdsi_enabled) 418 - return -EPERM; 419 404 420 405 if (off) 421 406 return 0; ··· 443 440 444 441 return size; 445 442 } 446 - static BIN_ATTR(state_certificate, 0400, state_certificate_read, NULL, SDSI_SIZE_READ_MSG); 443 + 444 + static ssize_t 445 + state_certificate_read(struct file *filp, struct kobject *kobj, 446 + struct bin_attribute *attr, char *buf, loff_t off, 447 + size_t count) 448 + { 449 + struct device *dev = kobj_to_dev(kobj); 450 + struct sdsi_priv *priv = dev_get_drvdata(dev); 451 + 452 + return certificate_read(SDSI_CMD_READ_STATE, priv, buf, off, count); 453 + } 454 + static BIN_ATTR_ADMIN_RO(state_certificate, SDSI_SIZE_READ_MSG); 455 + 456 + static ssize_t 457 + meter_certificate_read(struct file *filp, struct kobject *kobj, 458 + struct bin_attribute *attr, char *buf, loff_t off, 459 + size_t count) 460 + { 461 + struct device *dev = kobj_to_dev(kobj); 462 + struct sdsi_priv *priv = dev_get_drvdata(dev); 463 + 464 + return certificate_read(SDSI_CMD_READ_METER, priv, buf, off, count); 465 + } 466 + static BIN_ATTR_ADMIN_RO(meter_certificate, SDSI_SIZE_READ_MSG); 447 467 448 468 static ssize_t registers_read(struct file *filp, struct kobject *kobj, 449 469 struct bin_attribute *attr, char *buf, loff_t off, ··· 475 449 struct device *dev = kobj_to_dev(kobj); 476 450 struct sdsi_priv *priv = dev_get_drvdata(dev); 477 451 void __iomem *addr = priv->regs_addr; 452 + int size = priv->registers_size; 453 + 454 + /* 455 + * The check below is performed by the sysfs caller based on the static 456 + * file size. But this may be greater than the actual size which is based 457 + * on the GUID. So check here again based on actual size before reading. 458 + */ 459 + if (off >= size) 460 + return 0; 461 + 462 + if (off + count > size) 463 + count = size - off; 478 464 479 465 memcpy_fromio(buf, addr + off, count); 480 466 481 467 return count; 482 468 } 483 - static BIN_ATTR(registers, 0400, registers_read, NULL, SDSI_SIZE_REGS); 469 + static BIN_ATTR_ADMIN_RO(registers, SDSI_SIZE_REGS); 484 470 485 471 static struct bin_attribute *sdsi_bin_attrs[] = { 486 472 &bin_attr_registers, 487 473 &bin_attr_state_certificate, 474 + &bin_attr_meter_certificate, 488 475 &bin_attr_provision_akc, 489 476 &bin_attr_provision_cap, 490 477 NULL 491 478 }; 479 + 480 + static umode_t 481 + sdsi_battr_is_visible(struct kobject *kobj, struct bin_attribute *attr, int n) 482 + { 483 + struct device *dev = kobj_to_dev(kobj); 484 + struct sdsi_priv *priv = dev_get_drvdata(dev); 485 + 486 + /* Registers file is always readable if the device is present */ 487 + if (attr == &bin_attr_registers) 488 + return attr->attr.mode; 489 + 490 + /* All other attributes not visible if BIOS has not enabled On Demand */ 491 + if (!(priv->features & SDSI_FEATURE_SDSI)) 492 + return 0; 493 + 494 + if (attr == &bin_attr_meter_certificate) 495 + return (priv->features & SDSI_FEATURE_METERING) ? 496 + attr->attr.mode : 0; 497 + 498 + return attr->attr.mode; 499 + } 492 500 493 501 static ssize_t guid_show(struct device *dev, struct device_attribute *attr, char *buf) 494 502 { ··· 540 480 static const struct attribute_group sdsi_group = { 541 481 .attrs = sdsi_attrs, 542 482 .bin_attrs = sdsi_bin_attrs, 483 + .is_bin_visible = sdsi_battr_is_visible, 543 484 }; 544 485 __ATTRIBUTE_GROUPS(sdsi); 486 + 487 + static int sdsi_get_layout(struct sdsi_priv *priv, struct disc_table *table) 488 + { 489 + switch (table->guid) { 490 + case SDSI_GUID_V1: 491 + priv->control_size = GUID_V1_CNTRL_SIZE; 492 + priv->registers_size = GUID_V1_REGS_SIZE; 493 + break; 494 + case SDSI_GUID_V2: 495 + priv->control_size = GUID_V2_CNTRL_SIZE; 496 + priv->registers_size = GUID_V2_REGS_SIZE; 497 + break; 498 + default: 499 + dev_err(priv->dev, "Unrecognized GUID 0x%x\n", table->guid); 500 + return -EINVAL; 501 + } 502 + return 0; 503 + } 545 504 546 505 static int sdsi_map_mbox_registers(struct sdsi_priv *priv, struct pci_dev *parent, 547 506 struct disc_table *disc_table, struct resource *disc_res) ··· 569 490 u32 size = FIELD_GET(DT_SIZE, disc_table->access_info); 570 491 u32 tbir = FIELD_GET(DT_TBIR, disc_table->offset); 571 492 u32 offset = DT_OFFSET(disc_table->offset); 572 - u32 features_offset; 573 493 struct resource res = {}; 574 494 575 495 /* Starting location of SDSi MMIO region based on access type */ ··· 603 525 if (IS_ERR(priv->control_addr)) 604 526 return PTR_ERR(priv->control_addr); 605 527 606 - priv->mbox_addr = priv->control_addr + SDSI_SIZE_CONTROL; 528 + priv->mbox_addr = priv->control_addr + priv->control_size; 607 529 priv->regs_addr = priv->mbox_addr + SDSI_SIZE_MAILBOX; 608 530 609 - features_offset = readq(priv->regs_addr + SDSI_ENABLED_FEATURES_OFFSET); 610 - priv->sdsi_enabled = !!(features_offset & SDSI_ENABLED); 531 + priv->features = readq(priv->regs_addr + SDSI_ENABLED_FEATURES_OFFSET); 611 532 612 533 return 0; 613 534 } ··· 638 561 639 562 priv->guid = disc_table.guid; 640 563 564 + /* Get guid based layout info */ 565 + ret = sdsi_get_layout(priv, &disc_table); 566 + if (ret) 567 + return ret; 568 + 641 569 /* Map the SDSi mailbox registers */ 642 570 ret = sdsi_map_mbox_registers(priv, intel_cap_dev->pcidev, &disc_table, disc_res); 643 571 if (ret) ··· 668 586 module_auxiliary_driver(sdsi_aux_driver); 669 587 670 588 MODULE_AUTHOR("David E. Box <david.e.box@linux.intel.com>"); 671 - MODULE_DESCRIPTION("Intel Software Defined Silicon driver"); 589 + MODULE_DESCRIPTION("Intel On Demand (SDSi) driver"); 672 590 MODULE_LICENSE("GPL");
+1 -1
drivers/platform/x86/intel/speed_select_if/isst_if_common.c
··· 623 623 624 624 /* Lock to prevent module registration when already opened by user space */ 625 625 static DEFINE_MUTEX(punit_misc_dev_open_lock); 626 - /* Lock to allow one share misc device for all ISST interace */ 626 + /* Lock to allow one shared misc device for all ISST interfaces */ 627 627 static DEFINE_MUTEX(punit_misc_dev_reg_lock); 628 628 static int misc_usage_count; 629 629 static int misc_device_ret;
+1 -1
drivers/platform/x86/intel_scu_ipc.c
··· 583 583 scu->dev.parent = parent; 584 584 scu->dev.class = &intel_scu_ipc_class; 585 585 scu->dev.release = intel_scu_ipc_release; 586 - dev_set_name(&scu->dev, "intel_scu_ipc"); 587 586 588 587 if (!request_mem_region(scu_data->mem.start, resource_size(&scu_data->mem), 589 588 "intel_scu_ipc")) { ··· 611 612 * After this point intel_scu_ipc_release() takes care of 612 613 * releasing the SCU IPC resources once refcount drops to zero. 613 614 */ 615 + dev_set_name(&scu->dev, "intel_scu_ipc"); 614 616 err = device_register(&scu->dev); 615 617 if (err) { 616 618 put_device(&scu->dev);
+2 -2
drivers/platform/x86/lg-laptop.c
··· 546 546 static DEVICE_ATTR_RW(charge_control_end_threshold); 547 547 static DEVICE_ATTR_RW(battery_care_limit); 548 548 549 - static int lg_battery_add(struct power_supply *battery) 549 + static int lg_battery_add(struct power_supply *battery, struct acpi_battery_hook *hook) 550 550 { 551 551 if (device_create_file(&battery->dev, 552 552 &dev_attr_charge_control_end_threshold)) ··· 555 555 return 0; 556 556 } 557 557 558 - static int lg_battery_remove(struct power_supply *battery) 558 + static int lg_battery_remove(struct power_supply *battery, struct acpi_battery_hook *hook) 559 559 { 560 560 device_remove_file(&battery->dev, 561 561 &dev_attr_charge_control_end_threshold);
+2 -6
drivers/platform/x86/mxm-wmi.c
··· 35 35 .xarg = 1, 36 36 }; 37 37 struct acpi_buffer input = { (acpi_size)sizeof(args), &args }; 38 - struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 39 38 acpi_status status; 40 39 41 40 printk("calling mux switch %d\n", adapter); 42 41 43 - status = wmi_evaluate_method(MXM_WMMX_GUID, 0x0, adapter, &input, 44 - &output); 42 + status = wmi_evaluate_method(MXM_WMMX_GUID, 0x0, adapter, &input, NULL); 45 43 46 44 if (ACPI_FAILURE(status)) 47 45 return status; ··· 58 60 .xarg = 1, 59 61 }; 60 62 struct acpi_buffer input = { (acpi_size)sizeof(args), &args }; 61 - struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 62 63 acpi_status status; 63 64 64 65 printk("calling mux switch %d\n", adapter); 65 66 66 - status = wmi_evaluate_method(MXM_WMMX_GUID, 0x0, adapter, &input, 67 - &output); 67 + status = wmi_evaluate_method(MXM_WMMX_GUID, 0x0, adapter, &input, NULL); 68 68 69 69 if (ACPI_FAILURE(status)) 70 70 return status;
+4 -6
drivers/platform/x86/sony-laptop.c
··· 820 820 int i; 821 821 822 822 for (i = 0; i < ARRAY_SIZE(handles->cap); i++) { 823 - len += scnprintf(buffer + len, PAGE_SIZE - len, "0x%.4x ", 824 - handles->cap[i]); 823 + len += sysfs_emit_at(buffer, len, "0x%.4x ", handles->cap[i]); 825 824 } 826 - len += scnprintf(buffer + len, PAGE_SIZE - len, "\n"); 825 + len += sysfs_emit_at(buffer, len, "\n"); 827 826 828 827 return len; 829 828 } ··· 2172 2173 2173 2174 for (cnt = 0; cnt < THM_PROFILE_MAX; cnt++) { 2174 2175 if (!cnt || (th_handle->profiles & cnt)) 2175 - idx += scnprintf(buffer + idx, PAGE_SIZE - idx, "%s ", 2176 - snc_thermal_profiles[cnt]); 2176 + idx += sysfs_emit_at(buffer, idx, "%s ", snc_thermal_profiles[cnt]); 2177 2177 } 2178 - idx += scnprintf(buffer + idx, PAGE_SIZE - idx, "\n"); 2178 + idx += sysfs_emit_at(buffer, idx, "\n"); 2179 2179 2180 2180 return idx; 2181 2181 }
+2 -2
drivers/platform/x86/system76_acpi.c
··· 254 254 255 255 ATTRIBUTE_GROUPS(system76_battery); 256 256 257 - static int system76_battery_add(struct power_supply *battery) 257 + static int system76_battery_add(struct power_supply *battery, struct acpi_battery_hook *hook) 258 258 { 259 259 // System76 EC only supports 1 battery 260 260 if (strcmp(battery->desc->name, "BAT0") != 0) ··· 266 266 return 0; 267 267 } 268 268 269 - static int system76_battery_remove(struct power_supply *battery) 269 + static int system76_battery_remove(struct power_supply *battery, struct acpi_battery_hook *hook) 270 270 { 271 271 device_remove_groups(&battery->dev, system76_battery_groups); 272 272 return 0;
drivers/platform/x86/tc1100-wmi.c drivers/platform/x86/hp/tc1100-wmi.c
+30 -33
drivers/platform/x86/thinkpad_acpi.c
··· 265 265 266 266 #define FAN_NOT_PRESENT 65535 267 267 268 - #define strlencmp(a, b) (strncmp((a), (b), strlen(b))) 269 - 270 - 271 268 /**************************************************************************** 272 269 * Driver-wide structs and misc. variables 273 270 */ ··· 1332 1335 return -ENODEV; 1333 1336 1334 1337 while ((cmd = strsep(&buf, ","))) { 1335 - if (strlencmp(cmd, "enable") == 0) 1338 + if (strstarts(cmd, "enable")) 1336 1339 status = TPACPI_RFK_RADIO_ON; 1337 - else if (strlencmp(cmd, "disable") == 0) 1340 + else if (strstarts(cmd, "disable")) 1338 1341 status = TPACPI_RFK_RADIO_OFF; 1339 1342 else 1340 1343 return -EINVAL; ··· 4195 4198 4196 4199 res = 0; 4197 4200 while ((cmd = strsep(&buf, ","))) { 4198 - if (strlencmp(cmd, "enable") == 0) { 4201 + if (strstarts(cmd, "enable")) { 4199 4202 hotkey_enabledisable_warn(1); 4200 - } else if (strlencmp(cmd, "disable") == 0) { 4203 + } else if (strstarts(cmd, "disable")) { 4201 4204 hotkey_enabledisable_warn(0); 4202 4205 res = -EPERM; 4203 - } else if (strlencmp(cmd, "reset") == 0) { 4206 + } else if (strstarts(cmd, "reset")) { 4204 4207 mask = (hotkey_all_mask | hotkey_source_mask) 4205 4208 & ~hotkey_reserved_mask; 4206 4209 } else if (sscanf(cmd, "0x%x", &mask) == 1) { ··· 5230 5233 disable = 0; 5231 5234 5232 5235 while ((cmd = strsep(&buf, ","))) { 5233 - if (strlencmp(cmd, "lcd_enable") == 0) { 5236 + if (strstarts(cmd, "lcd_enable")) { 5234 5237 enable |= TP_ACPI_VIDEO_S_LCD; 5235 - } else if (strlencmp(cmd, "lcd_disable") == 0) { 5238 + } else if (strstarts(cmd, "lcd_disable")) { 5236 5239 disable |= TP_ACPI_VIDEO_S_LCD; 5237 - } else if (strlencmp(cmd, "crt_enable") == 0) { 5240 + } else if (strstarts(cmd, "crt_enable")) { 5238 5241 enable |= TP_ACPI_VIDEO_S_CRT; 5239 - } else if (strlencmp(cmd, "crt_disable") == 0) { 5242 + } else if (strstarts(cmd, "crt_disable")) { 5240 5243 disable |= TP_ACPI_VIDEO_S_CRT; 5241 5244 } else if (video_supported == TPACPI_VIDEO_NEW && 5242 - strlencmp(cmd, "dvi_enable") == 0) { 5245 + strstarts(cmd, "dvi_enable")) { 5243 5246 enable |= TP_ACPI_VIDEO_S_DVI; 5244 5247 } else if (video_supported == TPACPI_VIDEO_NEW && 5245 - strlencmp(cmd, "dvi_disable") == 0) { 5248 + strstarts(cmd, "dvi_disable")) { 5246 5249 disable |= TP_ACPI_VIDEO_S_DVI; 5247 - } else if (strlencmp(cmd, "auto_enable") == 0) { 5250 + } else if (strstarts(cmd, "auto_enable")) { 5248 5251 res = video_autosw_set(1); 5249 5252 if (res) 5250 5253 return res; 5251 - } else if (strlencmp(cmd, "auto_disable") == 0) { 5254 + } else if (strstarts(cmd, "auto_disable")) { 5252 5255 res = video_autosw_set(0); 5253 5256 if (res) 5254 5257 return res; 5255 - } else if (strlencmp(cmd, "video_switch") == 0) { 5258 + } else if (strstarts(cmd, "video_switch")) { 5256 5259 res = video_outputsw_cycle(); 5257 5260 if (res) 5258 5261 return res; 5259 - } else if (strlencmp(cmd, "expand_toggle") == 0) { 5262 + } else if (strstarts(cmd, "expand_toggle")) { 5260 5263 res = video_expand_toggle(); 5261 5264 if (res) 5262 5265 return res; ··· 5569 5572 static struct tpacpi_led_classdev tpacpi_led_thinklight = { 5570 5573 .led_classdev = { 5571 5574 .name = "tpacpi::thinklight", 5575 + .max_brightness = 1, 5572 5576 .brightness_set_blocking = &light_sysfs_set, 5573 5577 .brightness_get = &light_sysfs_get, 5574 5578 } ··· 5650 5652 return -ENODEV; 5651 5653 5652 5654 while ((cmd = strsep(&buf, ","))) { 5653 - if (strlencmp(cmd, "on") == 0) { 5655 + if (strstarts(cmd, "on")) { 5654 5656 newstatus = 1; 5655 - } else if (strlencmp(cmd, "off") == 0) { 5657 + } else if (strstarts(cmd, "off")) { 5656 5658 newstatus = 0; 5657 5659 } else 5658 5660 return -EINVAL; ··· 7123 7125 return level; 7124 7126 7125 7127 while ((cmd = strsep(&buf, ","))) { 7126 - if (strlencmp(cmd, "up") == 0) { 7128 + if (strstarts(cmd, "up")) { 7127 7129 if (level < bright_maxlvl) 7128 7130 level++; 7129 - } else if (strlencmp(cmd, "down") == 0) { 7131 + } else if (strstarts(cmd, "down")) { 7130 7132 if (level > 0) 7131 7133 level--; 7132 7134 } else if (sscanf(cmd, "level %d", &level) == 1 && ··· 7875 7877 7876 7878 while ((cmd = strsep(&buf, ","))) { 7877 7879 if (!tp_features.mixer_no_level_control) { 7878 - if (strlencmp(cmd, "up") == 0) { 7880 + if (strstarts(cmd, "up")) { 7879 7881 if (new_mute) 7880 7882 new_mute = 0; 7881 7883 else if (new_level < TP_EC_VOLUME_MAX) 7882 7884 new_level++; 7883 7885 continue; 7884 - } else if (strlencmp(cmd, "down") == 0) { 7886 + } else if (strstarts(cmd, "down")) { 7885 7887 if (new_mute) 7886 7888 new_mute = 0; 7887 7889 else if (new_level > 0) ··· 7893 7895 continue; 7894 7896 } 7895 7897 } 7896 - if (strlencmp(cmd, "mute") == 0) 7898 + if (strstarts(cmd, "mute")) 7897 7899 new_mute = TP_EC_AUDIO_MUTESW_MSK; 7898 - else if (strlencmp(cmd, "unmute") == 0) 7900 + else if (strstarts(cmd, "unmute")) 7899 7901 new_mute = 0; 7900 7902 else 7901 7903 return -EINVAL; ··· 9118 9120 { 9119 9121 int level; 9120 9122 9121 - if (strlencmp(cmd, "level auto") == 0) 9123 + if (strstarts(cmd, "level auto")) 9122 9124 level = TP_EC_FAN_AUTO; 9123 - else if ((strlencmp(cmd, "level disengaged") == 0) || 9124 - (strlencmp(cmd, "level full-speed") == 0)) 9125 + else if (strstarts(cmd, "level disengaged") || strstarts(cmd, "level full-speed")) 9125 9126 level = TP_EC_FAN_FULLSPEED; 9126 9127 else if (sscanf(cmd, "level %d", &level) != 1) 9127 9128 return 0; ··· 9138 9141 9139 9142 static int fan_write_cmd_enable(const char *cmd, int *rc) 9140 9143 { 9141 - if (strlencmp(cmd, "enable") != 0) 9144 + if (!strstarts(cmd, "enable")) 9142 9145 return 0; 9143 9146 9144 9147 *rc = fan_set_enable(); ··· 9153 9156 9154 9157 static int fan_write_cmd_disable(const char *cmd, int *rc) 9155 9158 { 9156 - if (strlencmp(cmd, "disable") != 0) 9159 + if (!strstarts(cmd, "disable")) 9157 9160 return 0; 9158 9161 9159 9162 *rc = fan_set_disable(); ··· 9904 9907 9905 9908 /* ACPI battery hooking */ 9906 9909 9907 - static int tpacpi_battery_add(struct power_supply *battery) 9910 + static int tpacpi_battery_add(struct power_supply *battery, struct acpi_battery_hook *hook) 9908 9911 { 9909 9912 int batteryid = tpacpi_battery_get_id(battery->desc->name); 9910 9913 ··· 9915 9918 return 0; 9916 9919 } 9917 9920 9918 - static int tpacpi_battery_remove(struct power_supply *battery) 9921 + static int tpacpi_battery_remove(struct power_supply *battery, struct acpi_battery_hook *hook) 9919 9922 { 9920 9923 device_remove_groups(&battery->dev, tpacpi_battery_groups); 9921 9924 return 0;
+2 -2
drivers/platform/x86/toshiba_acpi.c
··· 3113 3113 3114 3114 ATTRIBUTE_GROUPS(toshiba_acpi_battery); 3115 3115 3116 - static int toshiba_acpi_battery_add(struct power_supply *battery) 3116 + static int toshiba_acpi_battery_add(struct power_supply *battery, struct acpi_battery_hook *hook) 3117 3117 { 3118 3118 if (toshiba_acpi == NULL) { 3119 3119 pr_err("Init order issue\n"); ··· 3126 3126 return 0; 3127 3127 } 3128 3128 3129 - static int toshiba_acpi_battery_remove(struct power_supply *battery) 3129 + static int toshiba_acpi_battery_remove(struct power_supply *battery, struct acpi_battery_hook *hook) 3130 3130 { 3131 3131 device_remove_groups(&battery->dev, toshiba_acpi_battery_groups); 3132 3132 return 0;
+8 -8
drivers/platform/x86/uv_sysfs.c
··· 119 119 120 120 static ssize_t hub_name_show(struct uv_bios_hub_info *hub_info, char *buf) 121 121 { 122 - return scnprintf(buf, PAGE_SIZE, "%s\n", hub_info->name); 122 + return sysfs_emit(buf, "%s\n", hub_info->name); 123 123 } 124 124 125 125 static ssize_t hub_location_show(struct uv_bios_hub_info *hub_info, char *buf) 126 126 { 127 - return scnprintf(buf, PAGE_SIZE, "%s\n", hub_info->location); 127 + return sysfs_emit(buf, "%s\n", hub_info->location); 128 128 } 129 129 130 130 static ssize_t hub_partition_show(struct uv_bios_hub_info *hub_info, char *buf) ··· 460 460 461 461 static ssize_t uv_pci_type_show(struct uv_pci_top_obj *top_obj, char *buf) 462 462 { 463 - return scnprintf(buf, PAGE_SIZE, "%s\n", top_obj->type); 463 + return sysfs_emit(buf, "%s\n", top_obj->type); 464 464 } 465 465 466 466 static ssize_t uv_pci_location_show(struct uv_pci_top_obj *top_obj, char *buf) 467 467 { 468 - return scnprintf(buf, PAGE_SIZE, "%s\n", top_obj->location); 468 + return sysfs_emit(buf, "%s\n", top_obj->location); 469 469 } 470 470 471 471 static ssize_t uv_pci_iio_stack_show(struct uv_pci_top_obj *top_obj, char *buf) ··· 475 475 476 476 static ssize_t uv_pci_ppb_addr_show(struct uv_pci_top_obj *top_obj, char *buf) 477 477 { 478 - return scnprintf(buf, PAGE_SIZE, "%s\n", top_obj->ppb_addr); 478 + return sysfs_emit(buf, "%s\n", top_obj->ppb_addr); 479 479 } 480 480 481 481 static ssize_t uv_pci_slot_show(struct uv_pci_top_obj *top_obj, char *buf) ··· 737 737 static ssize_t uv_type_show(struct kobject *kobj, 738 738 struct kobj_attribute *attr, char *buf) 739 739 { 740 - return scnprintf(buf, PAGE_SIZE, "%s\n", uv_type_string()); 740 + return sysfs_emit(buf, "%s\n", uv_type_string()); 741 741 } 742 742 743 743 static ssize_t uv_archtype_show(struct kobject *kobj, ··· 749 749 static ssize_t uv_hub_type_show(struct kobject *kobj, 750 750 struct kobj_attribute *attr, char *buf) 751 751 { 752 - return scnprintf(buf, PAGE_SIZE, "0x%x\n", uv_hub_type()); 752 + return sysfs_emit(buf, "0x%x\n", uv_hub_type()); 753 753 } 754 754 755 755 static ssize_t uv_hubless_show(struct kobject *kobj, 756 756 struct kobj_attribute *attr, char *buf) 757 757 { 758 - return scnprintf(buf, PAGE_SIZE, "0x%x\n", uv_get_hubless_system()); 758 + return sysfs_emit(buf, "0x%x\n", uv_get_hubless_system()); 759 759 } 760 760 761 761 static struct kobj_attribute partition_id_attr =
+40 -20
drivers/platform/x86/wireless-hotkey.c
··· 20 20 MODULE_ALIAS("acpi*:WSTADEF:*"); 21 21 MODULE_ALIAS("acpi*:AMDI0051:*"); 22 22 23 - static struct input_dev *wl_input_dev; 23 + struct wl_button { 24 + struct input_dev *input_dev; 25 + char phys[32]; 26 + }; 24 27 25 28 static const struct acpi_device_id wl_ids[] = { 26 29 {"HPQ6001", 0}, ··· 32 29 {"", 0}, 33 30 }; 34 31 35 - static int wireless_input_setup(void) 32 + static int wireless_input_setup(struct acpi_device *device) 36 33 { 34 + struct wl_button *button = acpi_driver_data(device); 37 35 int err; 38 36 39 - wl_input_dev = input_allocate_device(); 40 - if (!wl_input_dev) 37 + button->input_dev = input_allocate_device(); 38 + if (!button->input_dev) 41 39 return -ENOMEM; 42 40 43 - wl_input_dev->name = "Wireless hotkeys"; 44 - wl_input_dev->phys = "hpq6001/input0"; 45 - wl_input_dev->id.bustype = BUS_HOST; 46 - wl_input_dev->evbit[0] = BIT(EV_KEY); 47 - set_bit(KEY_RFKILL, wl_input_dev->keybit); 41 + snprintf(button->phys, sizeof(button->phys), "%s/input0", acpi_device_hid(device)); 48 42 49 - err = input_register_device(wl_input_dev); 43 + button->input_dev->name = "Wireless hotkeys"; 44 + button->input_dev->phys = button->phys; 45 + button->input_dev->id.bustype = BUS_HOST; 46 + button->input_dev->evbit[0] = BIT(EV_KEY); 47 + set_bit(KEY_RFKILL, button->input_dev->keybit); 48 + 49 + err = input_register_device(button->input_dev); 50 50 if (err) 51 51 goto err_free_dev; 52 52 53 53 return 0; 54 54 55 55 err_free_dev: 56 - input_free_device(wl_input_dev); 56 + input_free_device(button->input_dev); 57 57 return err; 58 58 } 59 59 60 - static void wireless_input_destroy(void) 60 + static void wireless_input_destroy(struct acpi_device *device) 61 61 { 62 - input_unregister_device(wl_input_dev); 62 + struct wl_button *button = acpi_driver_data(device); 63 + 64 + input_unregister_device(button->input_dev); 65 + kfree(button); 63 66 } 64 67 65 68 static void wl_notify(struct acpi_device *acpi_dev, u32 event) 66 69 { 70 + struct wl_button *button = acpi_driver_data(acpi_dev); 71 + 67 72 if (event != 0x80) { 68 73 pr_info("Received unknown event (0x%x)\n", event); 69 74 return; 70 75 } 71 76 72 - input_report_key(wl_input_dev, KEY_RFKILL, 1); 73 - input_sync(wl_input_dev); 74 - input_report_key(wl_input_dev, KEY_RFKILL, 0); 75 - input_sync(wl_input_dev); 77 + input_report_key(button->input_dev, KEY_RFKILL, 1); 78 + input_sync(button->input_dev); 79 + input_report_key(button->input_dev, KEY_RFKILL, 0); 80 + input_sync(button->input_dev); 76 81 } 77 82 78 83 static int wl_add(struct acpi_device *device) 79 84 { 85 + struct wl_button *button; 80 86 int err; 81 87 82 - err = wireless_input_setup(); 83 - if (err) 88 + button = kzalloc(sizeof(struct wl_button), GFP_KERNEL); 89 + if (!button) 90 + return -ENOMEM; 91 + 92 + device->driver_data = button; 93 + 94 + err = wireless_input_setup(device); 95 + if (err) { 84 96 pr_err("Failed to setup wireless hotkeys\n"); 97 + kfree(button); 98 + } 85 99 86 100 return err; 87 101 } 88 102 89 103 static int wl_remove(struct acpi_device *device) 90 104 { 91 - wireless_input_destroy(); 105 + wireless_input_destroy(device); 92 106 return 0; 93 107 } 94 108
+1
drivers/platform/x86/wmi.c
··· 105 105 /* allow duplicate GUIDs as these device drivers use struct wmi_driver */ 106 106 static const char * const allow_duplicates[] = { 107 107 "05901221-D566-11D1-B2F0-00A0C9062910", /* wmi-bmof */ 108 + "8A42EA14-4F2A-FD45-6422-0087F7A7E608", /* dell-wmi-ddv */ 108 109 NULL 109 110 }; 110 111
+284 -1
drivers/platform/x86/x86-android-tablets.c
··· 5 5 * devices typically have a bunch of things hardcoded, rather than specified 6 6 * in their DSDT. 7 7 * 8 - * Copyright (C) 2021 Hans de Goede <hdegoede@redhat.com> 8 + * Copyright (C) 2021-2022 Hans de Goede <hdegoede@redhat.com> 9 9 */ 10 10 11 11 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt ··· 263 263 GPIO_LOOKUP("INT33FC:02", 22, "id", GPIO_ACTIVE_HIGH), 264 264 { } 265 265 }, 266 + }; 267 + 268 + /* 269 + * Advantech MICA-071 270 + * This is a standard Windows tablet, but it has an extra "quick launch" button 271 + * which is not described in the ACPI tables in anyway. 272 + * Use the x86-android-tablets infra to create a gpio-button device for this. 273 + */ 274 + static struct gpio_keys_button advantech_mica_071_button = { 275 + .code = KEY_PROG1, 276 + /* .gpio gets filled in by advantech_mica_071_init() */ 277 + .active_low = true, 278 + .desc = "prog1_key", 279 + .type = EV_KEY, 280 + .wakeup = false, 281 + .debounce_interval = 50, 282 + }; 283 + 284 + static const struct gpio_keys_platform_data advantech_mica_071_button_pdata __initconst = { 285 + .buttons = &advantech_mica_071_button, 286 + .nbuttons = 1, 287 + .name = "prog1_key", 288 + }; 289 + 290 + static const struct platform_device_info advantech_mica_071_pdevs[] __initconst = { 291 + { 292 + .name = "gpio-keys", 293 + .id = PLATFORM_DEVID_AUTO, 294 + .data = &advantech_mica_071_button_pdata, 295 + .size_data = sizeof(advantech_mica_071_button_pdata), 296 + }, 297 + }; 298 + 299 + static int __init advantech_mica_071_init(void) 300 + { 301 + struct gpio_desc *gpiod; 302 + int ret; 303 + 304 + ret = x86_android_tablet_get_gpiod("INT33FC:00", 2, &gpiod); 305 + if (ret < 0) 306 + return ret; 307 + advantech_mica_071_button.gpio = desc_to_gpio(gpiod); 308 + 309 + return 0; 310 + } 311 + 312 + static const struct x86_dev_info advantech_mica_071_info __initconst = { 313 + .pdev_info = advantech_mica_071_pdevs, 314 + .pdev_count = ARRAY_SIZE(advantech_mica_071_pdevs), 315 + .init = advantech_mica_071_init, 266 316 }; 267 317 268 318 /* Asus ME176C and TF103C tablets shared data */ ··· 1037 987 } 1038 988 } 1039 989 990 + /* Lenovo Yoga Tab 3 Pro YT3-X90F */ 991 + 992 + /* 993 + * There are 2 batteries, with 2 bq27500 fuel-gauges and 2 bq25892 chargers, 994 + * "bq25890-charger-1" is instantiated from: drivers/i2c/busses/i2c-cht-wc.c. 995 + */ 996 + static const char * const lenovo_yt3_bq25892_0_suppliers[] = { "cht_wcove_pwrsrc" }; 997 + static const char * const bq25890_1_psy[] = { "bq25890-charger-1" }; 998 + 999 + static const struct property_entry fg_bq25890_1_supply_props[] = { 1000 + PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq25890_1_psy), 1001 + { } 1002 + }; 1003 + 1004 + static const struct software_node fg_bq25890_1_supply_node = { 1005 + .properties = fg_bq25890_1_supply_props, 1006 + }; 1007 + 1008 + /* bq25892 charger settings for the flat lipo battery behind the screen */ 1009 + static const struct property_entry lenovo_yt3_bq25892_0_props[] = { 1010 + PROPERTY_ENTRY_STRING_ARRAY("supplied-from", lenovo_yt3_bq25892_0_suppliers), 1011 + PROPERTY_ENTRY_STRING("linux,power-supply-name", "bq25892-second-chrg"), 1012 + PROPERTY_ENTRY_U32("linux,iinlim-percentage", 40), 1013 + PROPERTY_ENTRY_BOOL("linux,skip-reset"), 1014 + /* Values taken from Android Factory Image */ 1015 + PROPERTY_ENTRY_U32("ti,charge-current", 2048000), 1016 + PROPERTY_ENTRY_U32("ti,battery-regulation-voltage", 4352000), 1017 + PROPERTY_ENTRY_U32("ti,termination-current", 128000), 1018 + PROPERTY_ENTRY_U32("ti,precharge-current", 128000), 1019 + PROPERTY_ENTRY_U32("ti,minimum-sys-voltage", 3700000), 1020 + PROPERTY_ENTRY_U32("ti,boost-voltage", 4998000), 1021 + PROPERTY_ENTRY_U32("ti,boost-max-current", 500000), 1022 + PROPERTY_ENTRY_BOOL("ti,use-ilim-pin"), 1023 + { } 1024 + }; 1025 + 1026 + static const struct software_node lenovo_yt3_bq25892_0_node = { 1027 + .properties = lenovo_yt3_bq25892_0_props, 1028 + }; 1029 + 1030 + static const struct x86_i2c_client_info lenovo_yt3_i2c_clients[] __initconst = { 1031 + { 1032 + /* bq27500 fuel-gauge for the flat lipo battery behind the screen */ 1033 + .board_info = { 1034 + .type = "bq27500", 1035 + .addr = 0x55, 1036 + .dev_name = "bq27500_0", 1037 + .swnode = &fg_bq25890_supply_node, 1038 + }, 1039 + .adapter_path = "\\_SB_.PCI0.I2C1", 1040 + }, { 1041 + /* bq25892 charger for the flat lipo battery behind the screen */ 1042 + .board_info = { 1043 + .type = "bq25892", 1044 + .addr = 0x6b, 1045 + .dev_name = "bq25892_0", 1046 + .swnode = &lenovo_yt3_bq25892_0_node, 1047 + }, 1048 + .adapter_path = "\\_SB_.PCI0.I2C1", 1049 + .irq_data = { 1050 + .type = X86_ACPI_IRQ_TYPE_GPIOINT, 1051 + .chip = "INT33FF:01", 1052 + .index = 5, 1053 + .trigger = ACPI_EDGE_SENSITIVE, 1054 + .polarity = ACPI_ACTIVE_LOW, 1055 + }, 1056 + }, { 1057 + /* bq27500 fuel-gauge for the round li-ion cells in the hinge */ 1058 + .board_info = { 1059 + .type = "bq27500", 1060 + .addr = 0x55, 1061 + .dev_name = "bq27500_1", 1062 + .swnode = &fg_bq25890_1_supply_node, 1063 + }, 1064 + .adapter_path = "\\_SB_.PCI0.I2C2", 1065 + } 1066 + }; 1067 + 1068 + static int __init lenovo_yt3_init(void) 1069 + { 1070 + struct gpio_desc *gpiod; 1071 + int ret; 1072 + 1073 + /* 1074 + * The "bq25892_0" charger IC has its /CE (Charge-Enable) and OTG pins 1075 + * connected to GPIOs, rather then having them hardwired to the correct 1076 + * values as is normally done. 1077 + * 1078 + * The bq25890_charger driver controls these through I2C, but this only 1079 + * works if not overridden by the pins. Set these pins here: 1080 + * 1. Set /CE to 0 to allow charging. 1081 + * 2. Set OTG to 0 disable V5 boost output since the 5V boost output of 1082 + * the main "bq25892_1" charger is used when necessary. 1083 + */ 1084 + 1085 + /* /CE pin */ 1086 + ret = x86_android_tablet_get_gpiod("INT33FF:02", 22, &gpiod); 1087 + if (ret < 0) 1088 + return ret; 1089 + 1090 + /* 1091 + * The gpio_desc returned by x86_android_tablet_get_gpiod() is a "raw" 1092 + * gpio_desc, that is there is no way to pass lookup-flags like 1093 + * GPIO_ACTIVE_LOW. Set the GPIO to 0 here to enable charging since 1094 + * the /CE pin is active-low, but not marked as such in the gpio_desc. 1095 + */ 1096 + gpiod_set_value(gpiod, 0); 1097 + 1098 + /* OTG pin */ 1099 + ret = x86_android_tablet_get_gpiod("INT33FF:03", 19, &gpiod); 1100 + if (ret < 0) 1101 + return ret; 1102 + 1103 + gpiod_set_value(gpiod, 0); 1104 + 1105 + return 0; 1106 + } 1107 + 1108 + static const struct x86_dev_info lenovo_yt3_info __initconst = { 1109 + .i2c_client_info = lenovo_yt3_i2c_clients, 1110 + .i2c_client_count = ARRAY_SIZE(lenovo_yt3_i2c_clients), 1111 + .init = lenovo_yt3_init, 1112 + }; 1113 + 1114 + /* Medion Lifetab S10346 tablets have an Android factory img with everything hardcoded */ 1115 + static const char * const medion_lifetab_s10346_accel_mount_matrix[] = { 1116 + "0", "1", "0", 1117 + "1", "0", "0", 1118 + "0", "0", "1" 1119 + }; 1120 + 1121 + static const struct property_entry medion_lifetab_s10346_accel_props[] = { 1122 + PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", medion_lifetab_s10346_accel_mount_matrix), 1123 + { } 1124 + }; 1125 + 1126 + static const struct software_node medion_lifetab_s10346_accel_node = { 1127 + .properties = medion_lifetab_s10346_accel_props, 1128 + }; 1129 + 1130 + /* Note the LCD panel is mounted upside down, this is correctly indicated in the VBT */ 1131 + static const struct property_entry medion_lifetab_s10346_touchscreen_props[] = { 1132 + PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"), 1133 + PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), 1134 + { } 1135 + }; 1136 + 1137 + static const struct software_node medion_lifetab_s10346_touchscreen_node = { 1138 + .properties = medion_lifetab_s10346_touchscreen_props, 1139 + }; 1140 + 1141 + static const struct x86_i2c_client_info medion_lifetab_s10346_i2c_clients[] __initconst = { 1142 + { 1143 + /* kxtj21009 accel */ 1144 + .board_info = { 1145 + .type = "kxtj21009", 1146 + .addr = 0x0f, 1147 + .dev_name = "kxtj21009", 1148 + .swnode = &medion_lifetab_s10346_accel_node, 1149 + }, 1150 + .adapter_path = "\\_SB_.I2C3", 1151 + .irq_data = { 1152 + .type = X86_ACPI_IRQ_TYPE_GPIOINT, 1153 + .chip = "INT33FC:02", 1154 + .index = 23, 1155 + .trigger = ACPI_EDGE_SENSITIVE, 1156 + .polarity = ACPI_ACTIVE_HIGH, 1157 + }, 1158 + }, { 1159 + /* goodix touchscreen */ 1160 + .board_info = { 1161 + .type = "GDIX1001:00", 1162 + .addr = 0x14, 1163 + .dev_name = "goodix_ts", 1164 + .swnode = &medion_lifetab_s10346_touchscreen_node, 1165 + }, 1166 + .adapter_path = "\\_SB_.I2C4", 1167 + .irq_data = { 1168 + .type = X86_ACPI_IRQ_TYPE_APIC, 1169 + .index = 0x44, 1170 + .trigger = ACPI_EDGE_SENSITIVE, 1171 + .polarity = ACPI_ACTIVE_LOW, 1172 + }, 1173 + }, 1174 + }; 1175 + 1176 + static struct gpiod_lookup_table medion_lifetab_s10346_goodix_gpios = { 1177 + .dev_id = "i2c-goodix_ts", 1178 + .table = { 1179 + GPIO_LOOKUP("INT33FC:01", 26, "reset", GPIO_ACTIVE_HIGH), 1180 + GPIO_LOOKUP("INT33FC:02", 3, "irq", GPIO_ACTIVE_HIGH), 1181 + { } 1182 + }, 1183 + }; 1184 + 1185 + static struct gpiod_lookup_table * const medion_lifetab_s10346_gpios[] = { 1186 + &medion_lifetab_s10346_goodix_gpios, 1187 + NULL 1188 + }; 1189 + 1190 + static const struct x86_dev_info medion_lifetab_s10346_info __initconst = { 1191 + .i2c_client_info = medion_lifetab_s10346_i2c_clients, 1192 + .i2c_client_count = ARRAY_SIZE(medion_lifetab_s10346_i2c_clients), 1193 + .gpiod_lookup_tables = medion_lifetab_s10346_gpios, 1194 + }; 1195 + 1040 1196 /* Nextbook Ares 8 tablets have an Android factory img with everything hardcoded */ 1041 1197 static const char * const nextbook_ares8_accel_mount_matrix[] = { 1042 1198 "0", "-1", "0", ··· 1436 1180 1437 1181 static const struct dmi_system_id x86_android_tablet_ids[] __initconst = { 1438 1182 { 1183 + /* Advantech MICA-071 */ 1184 + .matches = { 1185 + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Advantech"), 1186 + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MICA-071"), 1187 + }, 1188 + .driver_data = (void *)&advantech_mica_071_info, 1189 + }, 1190 + { 1439 1191 /* Asus MeMO Pad 7 ME176C */ 1440 1192 .matches = { 1441 1193 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), ··· 1508 1244 DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21"), 1509 1245 }, 1510 1246 .driver_data = (void *)&lenovo_yoga_tab2_830_1050_info, 1247 + }, 1248 + { 1249 + /* Lenovo Yoga Tab 3 Pro YT3-X90F */ 1250 + .matches = { 1251 + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), 1252 + DMI_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"), 1253 + DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"), 1254 + }, 1255 + .driver_data = (void *)&lenovo_yt3_info, 1256 + }, 1257 + { 1258 + /* Medion Lifetab S10346 */ 1259 + .matches = { 1260 + DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), 1261 + DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"), 1262 + /* Above strings are much too generic, also match on BIOS date */ 1263 + DMI_MATCH(DMI_BIOS_DATE, "10/22/2015"), 1264 + }, 1265 + .driver_data = (void *)&medion_lifetab_s10346_info, 1511 1266 }, 1512 1267 { 1513 1268 /* Nextbook Ares 8 */
+2 -2
include/acpi/battery.h
··· 12 12 13 13 struct acpi_battery_hook { 14 14 const char *name; 15 - int (*add_battery)(struct power_supply *battery); 16 - int (*remove_battery)(struct power_supply *battery); 15 + int (*add_battery)(struct power_supply *battery, struct acpi_battery_hook *hook); 16 + int (*remove_battery)(struct power_supply *battery, struct acpi_battery_hook *hook); 17 17 struct list_head list; 18 18 }; 19 19
+379 -91
tools/arch/x86/intel_sdsi/intel_sdsi.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* 3 - * sdsi: Intel Software Defined Silicon tool for provisioning certificates 4 - * and activation payloads on supported cpus. 3 + * sdsi: Intel On Demand (formerly Software Defined Silicon) tool for 4 + * provisioning certificates and activation payloads on supported cpus. 5 5 * 6 6 * See https://github.com/intel/intel-sdsi/blob/master/os-interface.rst 7 7 * for register descriptions. ··· 22 22 23 23 #include <sys/types.h> 24 24 25 + #ifndef __packed 26 + #define __packed __attribute__((packed)) 27 + #endif 28 + 29 + #define min(x, y) ({ \ 30 + typeof(x) _min1 = (x); \ 31 + typeof(y) _min2 = (y); \ 32 + (void) (&_min1 == &_min2); \ 33 + _min1 < _min2 ? _min1 : _min2; }) 34 + 25 35 #define SDSI_DEV "intel_vsec.sdsi" 26 36 #define AUX_DEV_PATH "/sys/bus/auxiliary/devices/" 27 37 #define SDSI_PATH (AUX_DEV_DIR SDSI_DEV) 28 - #define GUID 0x6dd191 29 - #define REGISTERS_MIN_SIZE 72 38 + #define GUID_V1 0x6dd191 39 + #define REGS_SIZE_GUID_V1 72 40 + #define GUID_V2 0xF210D9EF 41 + #define REGS_SIZE_GUID_V2 80 42 + #define STATE_CERT_MAX_SIZE 4096 43 + #define METER_CERT_MAX_SIZE 4096 44 + #define STATE_MAX_NUM_LICENSES 16 45 + #define STATE_MAX_NUM_IN_BUNDLE (uint32_t)8 46 + #define METER_MAX_NUM_BUNDLES 8 30 47 31 48 #define __round_mask(x, y) ((__typeof__(x))((y) - 1)) 32 49 #define round_up(x, y) ((((x) - 1) | __round_mask(x, y)) + 1) 33 50 51 + struct nvram_content_auth_err_sts { 52 + uint64_t reserved:3; 53 + uint64_t sdsi_content_auth_err:1; 54 + uint64_t reserved1:1; 55 + uint64_t sdsi_metering_auth_err:1; 56 + uint64_t reserved2:58; 57 + }; 58 + 34 59 struct enabled_features { 35 60 uint64_t reserved:3; 36 61 uint64_t sdsi:1; 37 - uint64_t reserved1:60; 62 + uint64_t reserved1:8; 63 + uint64_t attestation:1; 64 + uint64_t reserved2:13; 65 + uint64_t metering:1; 66 + uint64_t reserved3:37; 67 + }; 68 + 69 + struct key_provision_status { 70 + uint64_t reserved:1; 71 + uint64_t license_key_provisioned:1; 72 + uint64_t reserved2:62; 38 73 }; 39 74 40 75 struct auth_fail_count { ··· 84 49 uint64_t reserved:48; 85 50 uint64_t available:3; 86 51 uint64_t threshold:3; 52 + uint64_t reserved2:10; 53 + }; 54 + 55 + struct nvram_update_limit { 56 + uint64_t reserved:12; 57 + uint64_t sdsi_50_pct:1; 58 + uint64_t sdsi_75_pct:1; 59 + uint64_t sdsi_90_pct:1; 60 + uint64_t reserved2:49; 87 61 }; 88 62 89 63 struct sdsi_regs { 90 64 uint64_t ppin; 91 - uint64_t reserved; 65 + struct nvram_content_auth_err_sts auth_err_sts; 92 66 struct enabled_features en_features; 93 - uint64_t reserved1; 67 + struct key_provision_status key_prov_sts; 94 68 struct auth_fail_count auth_fail_count; 95 69 struct availability prov_avail; 96 - uint64_t reserved2; 97 - uint64_t reserved3; 98 - uint64_t socket_id; 70 + struct nvram_update_limit limits; 71 + uint64_t pcu_cr3_capid_cfg; 72 + union { 73 + struct { 74 + uint64_t socket_id; 75 + } v1; 76 + struct { 77 + uint64_t reserved; 78 + uint64_t socket_id; 79 + uint64_t reserved2; 80 + } v2; 81 + } extra; 82 + }; 83 + #define CONTENT_TYPE_LK_ENC 0xD 84 + #define CONTENT_TYPE_LK_BLOB_ENC 0xE 85 + 86 + struct state_certificate { 87 + uint32_t content_type; 88 + uint32_t region_rev_id; 89 + uint32_t header_size; 90 + uint32_t total_size; 91 + uint32_t key_size; 92 + uint32_t num_licenses; 93 + }; 94 + 95 + struct license_key_info { 96 + uint32_t key_rev_id; 97 + uint64_t key_image_content[6]; 98 + } __packed; 99 + 100 + #define LICENSE_BLOB_SIZE(l) (((l) & 0x7fffffff) * 4) 101 + #define LICENSE_VALID(l) (!!((l) & 0x80000000)) 102 + 103 + // License Group Types 104 + #define LBT_ONE_TIME_UPGRADE 1 105 + #define LBT_METERED_UPGRADE 2 106 + 107 + struct license_blob_content { 108 + uint32_t type; 109 + uint64_t id; 110 + uint64_t ppin; 111 + uint64_t previous_ppin; 112 + uint32_t rev_id; 113 + uint32_t num_bundles; 114 + } __packed; 115 + 116 + struct bundle_encoding { 117 + uint32_t encoding; 118 + uint32_t encoding_rsvd[7]; 119 + }; 120 + 121 + struct meter_certificate { 122 + uint32_t block_signature; 123 + uint32_t counter_unit; 124 + uint64_t ppin; 125 + uint32_t bundle_length; 126 + uint32_t reserved; 127 + uint32_t mmrc_encoding; 128 + uint32_t mmrc_counter; 129 + }; 130 + 131 + struct bundle_encoding_counter { 132 + uint32_t encoding; 133 + uint32_t counter; 99 134 }; 100 135 101 136 struct sdsi_dev { 102 137 struct sdsi_regs regs; 138 + struct state_certificate sc; 103 139 char *dev_name; 104 140 char *dev_path; 105 - int guid; 141 + uint32_t guid; 106 142 }; 107 143 108 144 enum command { 109 - CMD_NONE, 110 145 CMD_SOCKET_INFO, 111 - CMD_DUMP_CERT, 146 + CMD_METER_CERT, 147 + CMD_STATE_CERT, 112 148 CMD_PROV_AKC, 113 149 CMD_PROV_CAP, 114 150 }; ··· 204 98 } 205 99 206 100 if (!found) 207 - fprintf(stderr, "No sdsi devices found.\n"); 101 + fprintf(stderr, "No On Demand devices found.\n"); 208 102 } 209 103 210 104 static int sdsi_update_registers(struct sdsi_dev *s) ··· 227 121 return -1; 228 122 } 229 123 230 - if (s->guid != GUID) { 124 + if (s->guid != GUID_V1 && s->guid != GUID_V2) { 231 125 fprintf(stderr, "Unrecognized guid, 0x%x\n", s->guid); 232 126 fclose(regs_ptr); 233 127 return -1; ··· 235 129 236 130 /* Update register info for this guid */ 237 131 ret = fread(&s->regs, sizeof(uint8_t), sizeof(s->regs), regs_ptr); 238 - if (ret != sizeof(s->regs)) { 132 + if ((s->guid == GUID_V1 && ret != REGS_SIZE_GUID_V1) || 133 + (s->guid == GUID_V2 && ret != REGS_SIZE_GUID_V2)) { 239 134 fprintf(stderr, "Could not read 'registers' file\n"); 240 135 fclose(regs_ptr); 241 136 return -1; ··· 260 153 printf("Socket information for device %s\n", s->dev_name); 261 154 printf("\n"); 262 155 printf("PPIN: 0x%lx\n", s->regs.ppin); 156 + printf("NVRAM Content Authorization Error Status\n"); 157 + printf(" SDSi Auth Err Sts: %s\n", !!s->regs.auth_err_sts.sdsi_content_auth_err ? "Error" : "Okay"); 158 + 159 + if (!!s->regs.en_features.metering) 160 + printf(" Metering Auth Err Sts: %s\n", !!s->regs.auth_err_sts.sdsi_metering_auth_err ? "Error" : "Okay"); 161 + 263 162 printf("Enabled Features\n"); 264 - printf(" SDSi: %s\n", !!s->regs.en_features.sdsi ? "Enabled" : "Disabled"); 163 + printf(" On Demand: %s\n", !!s->regs.en_features.sdsi ? "Enabled" : "Disabled"); 164 + printf(" Attestation: %s\n", !!s->regs.en_features.attestation ? "Enabled" : "Disabled"); 165 + printf(" On Demand: %s\n", !!s->regs.en_features.sdsi ? "Enabled" : "Disabled"); 166 + printf(" Metering: %s\n", !!s->regs.en_features.metering ? "Enabled" : "Disabled"); 167 + printf("License Key (AKC) Provisioned: %s\n", !!s->regs.key_prov_sts.license_key_provisioned ? "Yes" : "No"); 265 168 printf("Authorization Failure Count\n"); 266 169 printf(" AKC Failure Count: %d\n", s->regs.auth_fail_count.key_failure_count); 267 170 printf(" AKC Failure Threshold: %d\n", s->regs.auth_fail_count.key_failure_threshold); ··· 280 163 printf("Provisioning Availability\n"); 281 164 printf(" Updates Available: %d\n", s->regs.prov_avail.available); 282 165 printf(" Updates Threshold: %d\n", s->regs.prov_avail.threshold); 283 - printf("Socket ID: %ld\n", s->regs.socket_id & 0xF); 166 + printf("NVRAM Udate Limit\n"); 167 + printf(" 50%% Limit Reached: %s\n", !!s->regs.limits.sdsi_50_pct ? "Yes" : "No"); 168 + printf(" 75%% Limit Reached: %s\n", !!s->regs.limits.sdsi_75_pct ? "Yes" : "No"); 169 + printf(" 90%% Limit Reached: %s\n", !!s->regs.limits.sdsi_90_pct ? "Yes" : "No"); 170 + if (s->guid == GUID_V1) 171 + printf("Socket ID: %ld\n", s->regs.extra.v1.socket_id & 0xF); 172 + else 173 + printf("Socket ID: %ld\n", s->regs.extra.v2.socket_id & 0xF); 284 174 285 175 return 0; 286 176 } 287 177 288 - static int sdsi_certificate_dump(struct sdsi_dev *s) 178 + static char *license_blob_type(uint32_t type) 289 179 { 290 - uint64_t state_certificate[512] = {0}; 291 - bool first_instance; 292 - uint64_t previous; 180 + switch (type) { 181 + case LBT_ONE_TIME_UPGRADE: 182 + return "One time upgrade"; 183 + case LBT_METERED_UPGRADE: 184 + return "Metered upgrade"; 185 + default: 186 + return "Unknown license blob type"; 187 + } 188 + } 189 + 190 + static char *content_type(uint32_t type) 191 + { 192 + switch (type) { 193 + case CONTENT_TYPE_LK_ENC: 194 + return "Licencse key encoding"; 195 + case CONTENT_TYPE_LK_BLOB_ENC: 196 + return "License key + Blob encoding"; 197 + default: 198 + return "Unknown content type"; 199 + } 200 + } 201 + 202 + static void get_feature(uint32_t encoding, char *feature) 203 + { 204 + char *name = (char *)&encoding; 205 + 206 + feature[3] = name[0]; 207 + feature[2] = name[1]; 208 + feature[1] = name[2]; 209 + feature[0] = name[3]; 210 + } 211 + 212 + static int sdsi_meter_cert_show(struct sdsi_dev *s) 213 + { 214 + char buf[METER_CERT_MAX_SIZE] = {0}; 215 + struct bundle_encoding_counter *bec; 216 + struct meter_certificate *mc; 217 + uint32_t count = 0; 293 218 FILE *cert_ptr; 294 - int i, ret, size; 219 + int ret, size; 295 220 296 221 ret = sdsi_update_registers(s); 297 222 if (ret) 298 223 return ret; 299 224 300 225 if (!s->regs.en_features.sdsi) { 301 - fprintf(stderr, "SDSi feature is present but not enabled."); 226 + fprintf(stderr, "SDSi feature is present but not enabled.\n"); 227 + fprintf(stderr, " Unable to read meter certificate\n"); 228 + return -1; 229 + } 230 + 231 + if (!s->regs.en_features.metering) { 232 + fprintf(stderr, "Metering not supporting on this socket.\n"); 233 + return -1; 234 + } 235 + 236 + ret = chdir(s->dev_path); 237 + if (ret == -1) { 238 + perror("chdir"); 239 + return ret; 240 + } 241 + 242 + cert_ptr = fopen("meter_certificate", "r"); 243 + if (!cert_ptr) { 244 + perror("Could not open 'meter_certificate' file"); 245 + return -1; 246 + } 247 + 248 + size = fread(buf, 1, sizeof(buf), cert_ptr); 249 + if (!size) { 250 + fprintf(stderr, "Could not read 'meter_certificate' file\n"); 251 + fclose(cert_ptr); 252 + return -1; 253 + } 254 + fclose(cert_ptr); 255 + 256 + mc = (struct meter_certificate *)buf; 257 + 258 + printf("\n"); 259 + printf("Meter certificate for device %s\n", s->dev_name); 260 + printf("\n"); 261 + printf("Block Signature: 0x%x\n", mc->block_signature); 262 + printf("Count Unit: %dms\n", mc->counter_unit); 263 + printf("PPIN: 0x%lx\n", mc->ppin); 264 + printf("Feature Bundle Length: %d\n", mc->bundle_length); 265 + printf("MMRC encoding: %d\n", mc->mmrc_encoding); 266 + printf("MMRC counter: %d\n", mc->mmrc_counter); 267 + if (mc->bundle_length % 8) { 268 + fprintf(stderr, "Invalid bundle length\n"); 269 + return -1; 270 + } 271 + 272 + if (mc->bundle_length > METER_MAX_NUM_BUNDLES * 8) { 273 + fprintf(stderr, "More than %d bundles: %d\n", 274 + METER_MAX_NUM_BUNDLES, mc->bundle_length / 8); 275 + return -1; 276 + } 277 + 278 + bec = (void *)(mc) + sizeof(mc); 279 + 280 + printf("Number of Feature Counters: %d\n", mc->bundle_length / 8); 281 + while (count++ < mc->bundle_length / 8) { 282 + char feature[5]; 283 + 284 + feature[4] = '\0'; 285 + get_feature(bec[count].encoding, feature); 286 + printf(" %s: %d\n", feature, bec[count].counter); 287 + } 288 + 289 + return 0; 290 + } 291 + 292 + static int sdsi_state_cert_show(struct sdsi_dev *s) 293 + { 294 + char buf[STATE_CERT_MAX_SIZE] = {0}; 295 + struct state_certificate *sc; 296 + struct license_key_info *lki; 297 + uint32_t offset = 0; 298 + uint32_t count = 0; 299 + FILE *cert_ptr; 300 + int ret, size; 301 + 302 + ret = sdsi_update_registers(s); 303 + if (ret) 304 + return ret; 305 + 306 + if (!s->regs.en_features.sdsi) { 307 + fprintf(stderr, "On Demand feature is present but not enabled."); 302 308 fprintf(stderr, " Unable to read state certificate"); 303 309 return -1; 304 310 } ··· 438 198 return -1; 439 199 } 440 200 441 - size = fread(state_certificate, 1, sizeof(state_certificate), cert_ptr); 201 + size = fread(buf, 1, sizeof(buf), cert_ptr); 442 202 if (!size) { 443 203 fprintf(stderr, "Could not read 'state_certificate' file\n"); 444 204 fclose(cert_ptr); 445 205 return -1; 446 206 } 447 - 448 - printf("%3d: 0x%lx\n", 0, state_certificate[0]); 449 - previous = state_certificate[0]; 450 - first_instance = true; 451 - 452 - for (i = 1; i < (int)(round_up(size, sizeof(uint64_t))/sizeof(uint64_t)); i++) { 453 - if (state_certificate[i] == previous) { 454 - if (first_instance) { 455 - puts("*"); 456 - first_instance = false; 457 - } 458 - continue; 459 - } 460 - printf("%3d: 0x%lx\n", i, state_certificate[i]); 461 - previous = state_certificate[i]; 462 - first_instance = true; 463 - } 464 - printf("%3d\n", i); 465 - 466 207 fclose(cert_ptr); 208 + 209 + sc = (struct state_certificate *)buf; 210 + 211 + /* Print register info for this guid */ 212 + printf("\n"); 213 + printf("State certificate for device %s\n", s->dev_name); 214 + printf("\n"); 215 + printf("Content Type: %s\n", content_type(sc->content_type)); 216 + printf("Region Revision ID: %d\n", sc->region_rev_id); 217 + printf("Header Size: %d\n", sc->header_size * 4); 218 + printf("Total Size: %d\n", sc->total_size); 219 + printf("OEM Key Size: %d\n", sc->key_size * 4); 220 + printf("Number of Licenses: %d\n", sc->num_licenses); 221 + 222 + /* Skip over the license sizes 4 bytes per license) to get the license key info */ 223 + lki = (void *)sc + sizeof(*sc) + (4 * sc->num_licenses); 224 + 225 + printf("License blob Info:\n"); 226 + printf(" License Key Revision ID: 0x%x\n", lki->key_rev_id); 227 + printf(" License Key Image Content: 0x%lx%lx%lx%lx%lx%lx\n", 228 + lki->key_image_content[5], lki->key_image_content[4], 229 + lki->key_image_content[3], lki->key_image_content[2], 230 + lki->key_image_content[1], lki->key_image_content[0]); 231 + 232 + while (count++ < sc->num_licenses) { 233 + uint32_t blob_size_field = *(uint32_t *)(buf + 0x14 + count * 4); 234 + uint32_t blob_size = LICENSE_BLOB_SIZE(blob_size_field); 235 + bool license_valid = LICENSE_VALID(blob_size_field); 236 + struct license_blob_content *lbc = 237 + (void *)(sc) + // start of the state certificate 238 + sizeof(*sc) + // size of the state certificate 239 + (4 * sc->num_licenses) + // total size of the blob size blocks 240 + sizeof(*lki) + // size of the license key info 241 + offset; // offset to this blob content 242 + struct bundle_encoding *bundle = (void *)(lbc) + sizeof(*lbc); 243 + char feature[5]; 244 + uint32_t i; 245 + 246 + printf(" Blob %d:\n", count - 1); 247 + printf(" License blob size: %u\n", blob_size); 248 + printf(" License is valid: %s\n", license_valid ? "Yes" : "No"); 249 + printf(" License blob type: %s\n", license_blob_type(lbc->type)); 250 + printf(" License blob ID: 0x%lx\n", lbc->id); 251 + printf(" PPIN: 0x%lx\n", lbc->ppin); 252 + printf(" Previous PPIN: 0x%lx\n", lbc->previous_ppin); 253 + printf(" Blob revision ID: %u\n", lbc->rev_id); 254 + printf(" Number of Features: %u\n", lbc->num_bundles); 255 + 256 + feature[4] = '\0'; 257 + 258 + for (i = 0; i < min(lbc->num_bundles, STATE_MAX_NUM_IN_BUNDLE); i++) { 259 + get_feature(bundle[i].encoding, feature); 260 + printf(" Feature %d: %s\n", i, feature); 261 + } 262 + 263 + if (lbc->num_bundles > STATE_MAX_NUM_IN_BUNDLE) 264 + fprintf(stderr, " Warning: %d > %d licenses in bundle reported.\n", 265 + lbc->num_bundles, STATE_MAX_NUM_IN_BUNDLE); 266 + 267 + offset += blob_size; 268 + }; 467 269 468 270 return 0; 469 271 } ··· 513 231 static int sdsi_provision(struct sdsi_dev *s, char *bin_file, enum command command) 514 232 { 515 233 int bin_fd, prov_fd, size, ret; 516 - char buf[4096] = { 0 }; 234 + char buf[STATE_CERT_MAX_SIZE] = { 0 }; 517 235 char cap[] = "provision_cap"; 518 236 char akc[] = "provision_akc"; 519 237 char *prov_file; ··· 548 266 } 549 267 550 268 /* Read the binary file into the buffer */ 551 - size = read(bin_fd, buf, 4096); 269 + size = read(bin_fd, buf, STATE_CERT_MAX_SIZE); 552 270 if (size == -1) { 553 271 close(bin_fd); 554 272 close(prov_fd); ··· 580 298 return ret; 581 299 582 300 if (!s->regs.en_features.sdsi) { 583 - fprintf(stderr, "SDSi feature is present but not enabled. Unable to provision"); 301 + fprintf(stderr, "On Demand feature is present but not enabled. Unable to provision"); 584 302 return -1; 585 303 } 586 304 ··· 610 328 return ret; 611 329 612 330 if (!s->regs.en_features.sdsi) { 613 - fprintf(stderr, "SDSi feature is present but not enabled. Unable to provision"); 331 + fprintf(stderr, "On Demand feature is present but not enabled. Unable to provision"); 614 332 return -1; 615 333 } 616 334 ··· 725 443 726 444 static void usage(char *prog) 727 445 { 728 - printf("Usage: %s [-l] [-d DEVNO [-iD] [-a FILE] [-c FILE]]\n", prog); 446 + printf("Usage: %s [-l] [-d DEVNO [-i] [-s] [-m] [-a FILE] [-c FILE]]\n", prog); 729 447 } 730 448 731 449 static void show_help(void) 732 450 { 733 451 printf("Commands:\n"); 734 - printf(" %-18s\t%s\n", "-l, --list", "list available sdsi devices"); 735 - printf(" %-18s\t%s\n", "-d, --devno DEVNO", "sdsi device number"); 736 - printf(" %-18s\t%s\n", "-i --info", "show socket information"); 737 - printf(" %-18s\t%s\n", "-D --dump", "dump state certificate data"); 738 - printf(" %-18s\t%s\n", "-a --akc FILE", "provision socket with AKC FILE"); 739 - printf(" %-18s\t%s\n", "-c --cap FILE>", "provision socket with CAP FILE"); 452 + printf(" %-18s\t%s\n", "-l, --list", "list available On Demand devices"); 453 + printf(" %-18s\t%s\n", "-d, --devno DEVNO", "On Demand device number"); 454 + printf(" %-18s\t%s\n", "-i, --info", "show socket information"); 455 + printf(" %-18s\t%s\n", "-s, --state", "show state certificate"); 456 + printf(" %-18s\t%s\n", "-m, --meter", "show meter certificate"); 457 + printf(" %-18s\t%s\n", "-a, --akc FILE", "provision socket with AKC FILE"); 458 + printf(" %-18s\t%s\n", "-c, --cap FILE>", "provision socket with CAP FILE"); 740 459 } 741 460 742 461 int main(int argc, char *argv[]) 743 462 { 744 463 char bin_file[PATH_MAX], *dev_no = NULL; 464 + bool device_selected = false; 745 465 char *progname; 746 - enum command command = CMD_NONE; 466 + enum command command = -1; 747 467 struct sdsi_dev *s; 748 468 int ret = 0, opt; 749 469 int option_index = 0; ··· 754 470 {"akc", required_argument, 0, 'a'}, 755 471 {"cap", required_argument, 0, 'c'}, 756 472 {"devno", required_argument, 0, 'd'}, 757 - {"dump", no_argument, 0, 'D'}, 758 473 {"help", no_argument, 0, 'h'}, 759 474 {"info", no_argument, 0, 'i'}, 760 475 {"list", no_argument, 0, 'l'}, 476 + {"meter", no_argument, 0, 'm'}, 477 + {"state", no_argument, 0, 's'}, 761 478 {0, 0, 0, 0 } 762 479 }; 763 480 764 481 765 482 progname = argv[0]; 766 483 767 - while ((opt = getopt_long_only(argc, argv, "+a:c:d:Da:c:h", long_options, 484 + while ((opt = getopt_long_only(argc, argv, "+a:c:d:hilms", long_options, 768 485 &option_index)) != -1) { 769 486 switch (opt) { 770 487 case 'd': 771 488 dev_no = optarg; 489 + device_selected = true; 772 490 break; 773 491 case 'l': 774 492 sdsi_list_devices(); ··· 778 492 case 'i': 779 493 command = CMD_SOCKET_INFO; 780 494 break; 781 - case 'D': 782 - command = CMD_DUMP_CERT; 495 + case 'm': 496 + command = CMD_METER_CERT; 497 + break; 498 + case 's': 499 + command = CMD_STATE_CERT; 783 500 break; 784 501 case 'a': 785 502 case 'c': ··· 809 520 } 810 521 } 811 522 812 - if (!dev_no) { 813 - if (command != CMD_NONE) 814 - fprintf(stderr, "Missing device number, DEVNO, for this command\n"); 815 - usage(progname); 523 + if (device_selected) { 524 + s = sdsi_create_dev(dev_no); 525 + if (!s) 526 + return -1; 527 + 528 + switch (command) { 529 + case CMD_SOCKET_INFO: 530 + ret = sdsi_read_reg(s); 531 + break; 532 + case CMD_METER_CERT: 533 + ret = sdsi_meter_cert_show(s); 534 + break; 535 + case CMD_STATE_CERT: 536 + ret = sdsi_state_cert_show(s); 537 + break; 538 + case CMD_PROV_AKC: 539 + ret = sdsi_provision_akc(s, bin_file); 540 + break; 541 + case CMD_PROV_CAP: 542 + ret = sdsi_provision_cap(s, bin_file); 543 + break; 544 + default: 545 + fprintf(stderr, "No command specified\n"); 546 + return -1; 547 + } 548 + 549 + sdsi_free_dev(s); 550 + 551 + } else { 552 + fprintf(stderr, "No device specified\n"); 816 553 return -1; 817 554 } 818 - 819 - s = sdsi_create_dev(dev_no); 820 - if (!s) 821 - return -1; 822 - 823 - /* Run the command */ 824 - switch (command) { 825 - case CMD_NONE: 826 - fprintf(stderr, "Missing command for device %s\n", dev_no); 827 - usage(progname); 828 - break; 829 - case CMD_SOCKET_INFO: 830 - ret = sdsi_read_reg(s); 831 - break; 832 - case CMD_DUMP_CERT: 833 - ret = sdsi_certificate_dump(s); 834 - break; 835 - case CMD_PROV_AKC: 836 - ret = sdsi_provision_akc(s, bin_file); 837 - break; 838 - case CMD_PROV_CAP: 839 - ret = sdsi_provision_cap(s, bin_file); 840 - break; 841 - } 842 - 843 - 844 - sdsi_free_dev(s); 845 555 846 556 return ret; 847 557 }