rst.c (3047B)
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright 2013 Matthew Garrett <mjg59@srcf.ucam.org> 4 */ 5 6#include <linux/acpi.h> 7#include <linux/module.h> 8#include <linux/slab.h> 9 10MODULE_LICENSE("GPL"); 11 12static ssize_t irst_show_wakeup_events(struct device *dev, 13 struct device_attribute *attr, 14 char *buf) 15{ 16 struct acpi_device *acpi; 17 unsigned long long value; 18 acpi_status status; 19 20 acpi = to_acpi_device(dev); 21 22 status = acpi_evaluate_integer(acpi->handle, "GFFS", NULL, &value); 23 if (ACPI_FAILURE(status)) 24 return -EINVAL; 25 26 return sprintf(buf, "%lld\n", value); 27} 28 29static ssize_t irst_store_wakeup_events(struct device *dev, 30 struct device_attribute *attr, 31 const char *buf, size_t count) 32{ 33 struct acpi_device *acpi; 34 acpi_status status; 35 unsigned long value; 36 int error; 37 38 acpi = to_acpi_device(dev); 39 40 error = kstrtoul(buf, 0, &value); 41 if (error) 42 return error; 43 44 status = acpi_execute_simple_method(acpi->handle, "SFFS", value); 45 if (ACPI_FAILURE(status)) 46 return -EINVAL; 47 48 return count; 49} 50 51static struct device_attribute irst_wakeup_attr = { 52 .attr = { .name = "wakeup_events", .mode = 0600 }, 53 .show = irst_show_wakeup_events, 54 .store = irst_store_wakeup_events 55}; 56 57static ssize_t irst_show_wakeup_time(struct device *dev, 58 struct device_attribute *attr, char *buf) 59{ 60 struct acpi_device *acpi; 61 unsigned long long value; 62 acpi_status status; 63 64 acpi = to_acpi_device(dev); 65 66 status = acpi_evaluate_integer(acpi->handle, "GFTV", NULL, &value); 67 if (ACPI_FAILURE(status)) 68 return -EINVAL; 69 70 return sprintf(buf, "%lld\n", value); 71} 72 73static ssize_t irst_store_wakeup_time(struct device *dev, 74 struct device_attribute *attr, 75 const char *buf, size_t count) 76{ 77 struct acpi_device *acpi; 78 acpi_status status; 79 unsigned long value; 80 int error; 81 82 acpi = to_acpi_device(dev); 83 84 error = kstrtoul(buf, 0, &value); 85 if (error) 86 return error; 87 88 status = acpi_execute_simple_method(acpi->handle, "SFTV", value); 89 if (ACPI_FAILURE(status)) 90 return -EINVAL; 91 92 return count; 93} 94 95static struct device_attribute irst_timeout_attr = { 96 .attr = { .name = "wakeup_time", .mode = 0600 }, 97 .show = irst_show_wakeup_time, 98 .store = irst_store_wakeup_time 99}; 100 101static int irst_add(struct acpi_device *acpi) 102{ 103 int error; 104 105 error = device_create_file(&acpi->dev, &irst_timeout_attr); 106 if (unlikely(error)) 107 return error; 108 109 error = device_create_file(&acpi->dev, &irst_wakeup_attr); 110 if (unlikely(error)) 111 device_remove_file(&acpi->dev, &irst_timeout_attr); 112 113 return error; 114} 115 116static int irst_remove(struct acpi_device *acpi) 117{ 118 device_remove_file(&acpi->dev, &irst_wakeup_attr); 119 device_remove_file(&acpi->dev, &irst_timeout_attr); 120 121 return 0; 122} 123 124static const struct acpi_device_id irst_ids[] = { 125 {"INT3392", 0}, 126 {"", 0} 127}; 128 129static struct acpi_driver irst_driver = { 130 .owner = THIS_MODULE, 131 .name = "intel_rapid_start", 132 .class = "intel_rapid_start", 133 .ids = irst_ids, 134 .ops = { 135 .add = irst_add, 136 .remove = irst_remove, 137 }, 138}; 139 140module_acpi_driver(irst_driver); 141 142MODULE_DEVICE_TABLE(acpi, irst_ids);