1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * dell-dw5826e-reset.c - Dell DW5826e reset driver 4 * 5 * Copyright (C) 2026 Jackbb Wu <jackbb.wu@compal.com> 6 */ 7 8 #include <linux/acpi.h> 9 #include <linux/bits.h> 10 #include <linux/device.h> 11 #include <linux/module.h> 12 #include <linux/platform_device.h> 13 #include <linux/types.h> 14 #include <linux/uuid.h> 15 16 #define PALC_DSM_FN_TRIGGER_PLDR BIT(1) 17 18 static guid_t palc_dsm_guid = 19 GUID_INIT(0x5a1a4bba, 0x8006, 0x487e, 0xbe, 0x0a, 0xac, 0xf5, 0xd8, 0xfd, 0xfe, 0x59); 20 21 static int trigger_palc_pldr(struct device *dev, acpi_handle handle) 22 { 23 union acpi_object *obj; 24 int ret = 0; 25 26 obj = acpi_evaluate_dsm(handle, &palc_dsm_guid, 1, PALC_DSM_FN_TRIGGER_PLDR, NULL); 27 if (!obj) { 28 dev_err(dev, "Failed to evaluate _DSM\n"); 29 return -EIO; 30 } 31 32 if (obj->type != ACPI_TYPE_BUFFER) { 33 dev_err(dev, "Unexpected _DSM return type: %d\n", obj->type); 34 ret = -EINVAL; 35 } 36 37 ACPI_FREE(obj); 38 return ret; 39 } 40 41 static ssize_t wwan_reset_store(struct device *dev, struct device_attribute *attr, 42 const char *buf, size_t count) 43 { 44 acpi_handle handle = ACPI_HANDLE(dev); 45 int ret; 46 47 ret = trigger_palc_pldr(dev, handle); 48 if (ret) 49 return ret; 50 51 return count; 52 } 53 static DEVICE_ATTR_WO(wwan_reset); 54 55 static struct attribute *palc_attrs[] = { 56 &dev_attr_wwan_reset.attr, 57 NULL 58 }; 59 ATTRIBUTE_GROUPS(palc); 60 61 static int palc_probe(struct platform_device *pdev) 62 { 63 acpi_handle handle; 64 65 handle = ACPI_HANDLE(&pdev->dev); 66 if (!handle) 67 return -ENODEV; 68 69 if (!acpi_check_dsm(handle, &palc_dsm_guid, 1, PALC_DSM_FN_TRIGGER_PLDR)) 70 return -ENODEV; 71 72 return 0; 73 } 74 75 static const struct acpi_device_id palc_acpi_ids[] = { 76 { "PALC0001", 0 }, 77 { } 78 }; 79 MODULE_DEVICE_TABLE(acpi, palc_acpi_ids); 80 81 static struct platform_driver palc_driver = { 82 .driver = { 83 .name = "dell-dw5826e-reset", 84 .acpi_match_table = palc_acpi_ids, 85 .dev_groups = palc_groups, 86 }, 87 .probe = palc_probe, 88 }; 89 module_platform_driver(palc_driver); 90 91 MODULE_DESCRIPTION("Dell DW5826e reset driver"); 92 MODULE_LICENSE("GPL"); 93 MODULE_AUTHOR("JackBB Wu"); 94