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.

platform/x86: thinkpad_acpi: Add support to detect hardware damage detection capability.

Thinkpads are adding the ability to detect and report hardware damage
status. Add new sysfs interface to identify whether hardware damage
is detected or not.

Initial support is available for the USB-C replaceable connector.

Reviewed-by: Mark Pearson <mpearson-lenovo@squebb.ca>
Signed-off-by: Nitin Joshi <nitjoshi@gmail.com>
Link: https://patch.msgid.link/20260106174519.6402-1-nitjoshi@gmail.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>

authored by

Nitin Joshi and committed by
Ilpo Järvinen
28c43bdd ceeb5c98

+128
+22
Documentation/admin-guide/laptops/thinkpad-acpi.rst
··· 54 54 - Setting keyboard language 55 55 - WWAN Antenna type 56 56 - Auxmac 57 + - Hardware damage detection capability 57 58 58 59 A compatibility table by model and feature is maintained on the web 59 60 site, http://ibm-acpi.sf.net/. I appreciate any success or failure ··· 1576 1575 1577 1576 The exact semantics of the attributes may be found in 1578 1577 Documentation/ABI/testing/sysfs-class-power. 1578 + 1579 + Hardware damage detection capability 1580 + ------------------------------------ 1581 + 1582 + sysfs attributes: hwdd_status 1583 + 1584 + Thinkpads are adding the ability to detect and report hardware damage. 1585 + Add new sysfs interface to identify the damaged device status. 1586 + Initial support is available for the USB-C replaceable connector. 1587 + 1588 + The command to check device damaged status is:: 1589 + 1590 + cat /sys/devices/platform/thinkpad_acpi/hwdd_status 1591 + 1592 + This value displays status of device damaged. 1593 + 1594 + - 0 = Not Damaged 1595 + - 1 = Damaged 1596 + 1597 + The property is read-only. If feature is not supported then sysfs 1598 + attribute is not created. 1579 1599 1580 1600 Multiple Commands, Module Parameters 1581 1601 ------------------------------------
+106
drivers/platform/x86/lenovo/thinkpad_acpi.c
··· 36 36 37 37 #include <linux/acpi.h> 38 38 #include <linux/backlight.h> 39 + #include <linux/bitfield.h> 39 40 #include <linux/bitops.h> 40 41 #include <linux/delay.h> 41 42 #include <linux/dmi.h> ··· 11081 11080 .attrs = auxmac_attributes, 11082 11081 }; 11083 11082 11083 + /************************************************************************* 11084 + * HWDD subdriver, for the Lenovo Hardware Damage Detection feature. 11085 + */ 11086 + 11087 + #define HWDD_GET_DMG_USBC 0x80000001 11088 + #define HWDD_GET_CAP 0 11089 + #define HWDD_NOT_SUPPORTED BIT(31) 11090 + #define HWDD_SUPPORT_USBC BIT(0) 11091 + 11092 + #define PORT_STATUS GENMASK(7, 4) 11093 + #define NUM_PORTS 4 11094 + 11095 + static bool hwdd_support_available; 11096 + static bool ucdd_supported; 11097 + 11098 + static int hwdd_command(int command, int *output) 11099 + { 11100 + acpi_handle hwdd_handle; 11101 + 11102 + if (ACPI_FAILURE(acpi_get_handle(hkey_handle, "HWDD", &hwdd_handle))) 11103 + return -ENODEV; 11104 + 11105 + if (!acpi_evalf(hwdd_handle, output, NULL, "dd", command)) 11106 + return -EIO; 11107 + 11108 + return 0; 11109 + } 11110 + 11111 + /* sysfs type-c damage detection capability */ 11112 + static ssize_t hwdd_status_show(struct device *dev, 11113 + struct device_attribute *attr, 11114 + char *buf) 11115 + { 11116 + unsigned int damage_status, port_status; 11117 + int err, i; 11118 + 11119 + if (!ucdd_supported) 11120 + return -ENODEV; 11121 + 11122 + /* Get USB TYPE-C damage status */ 11123 + err = hwdd_command(HWDD_GET_DMG_USBC, &damage_status); 11124 + if (err) 11125 + return err; 11126 + 11127 + port_status = FIELD_GET(PORT_STATUS, damage_status); 11128 + for (i = 0; i < NUM_PORTS; i++) { 11129 + if (!(damage_status & BIT(i))) 11130 + continue; 11131 + if (port_status & BIT(i)) 11132 + return sysfs_emit(buf, "1\n"); 11133 + } 11134 + 11135 + return sysfs_emit(buf, "0\n"); 11136 + } 11137 + static DEVICE_ATTR_RO(hwdd_status); 11138 + 11139 + static struct attribute *hwdd_attributes[] = { 11140 + &dev_attr_hwdd_status.attr, 11141 + NULL 11142 + }; 11143 + 11144 + static umode_t hwdd_attr_is_visible(struct kobject *kobj, 11145 + struct attribute *attr, int n) 11146 + { 11147 + return hwdd_support_available ? attr->mode : 0; 11148 + } 11149 + 11150 + static const struct attribute_group hwdd_attr_group = { 11151 + .is_visible = hwdd_attr_is_visible, 11152 + .attrs = hwdd_attributes, 11153 + }; 11154 + 11155 + static int tpacpi_hwdd_init(struct ibm_init_struct *iibm) 11156 + { 11157 + int err, output; 11158 + 11159 + /* Below command checks the HWDD damage capability */ 11160 + err = hwdd_command(HWDD_GET_CAP, &output); 11161 + if (err) 11162 + return err; 11163 + 11164 + if (!(output & HWDD_NOT_SUPPORTED)) 11165 + return -ENODEV; 11166 + 11167 + hwdd_support_available = true; 11168 + 11169 + /* 11170 + * BIT(0) is assigned to check capability of damage detection is 11171 + * supported for USB Type-C port or not. 11172 + */ 11173 + if (output & HWDD_SUPPORT_USBC) 11174 + ucdd_supported = true; 11175 + 11176 + return err; 11177 + } 11178 + 11179 + static struct ibm_struct hwdd_driver_data = { 11180 + .name = "hwdd", 11181 + }; 11182 + 11084 11183 /* --------------------------------------------------------------------- */ 11085 11184 11086 11185 static struct attribute *tpacpi_driver_attributes[] = { ··· 11240 11139 &kbdlang_attr_group, 11241 11140 &dprc_attr_group, 11242 11141 &auxmac_attr_group, 11142 + &hwdd_attr_group, 11243 11143 NULL, 11244 11144 }; 11245 11145 ··· 11853 11751 { 11854 11752 .init = auxmac_init, 11855 11753 .data = &auxmac_data, 11754 + }, 11755 + { 11756 + .init = tpacpi_hwdd_init, 11757 + .data = &hwdd_driver_data, 11856 11758 }, 11857 11759 }; 11858 11760