0001
0002
0003
0004
0005
0006 #include <linux/acpi.h>
0007 #include <linux/module.h>
0008 #include <linux/slab.h>
0009
0010 MODULE_LICENSE("GPL");
0011
0012 static ssize_t irst_show_wakeup_events(struct device *dev,
0013 struct device_attribute *attr,
0014 char *buf)
0015 {
0016 struct acpi_device *acpi;
0017 unsigned long long value;
0018 acpi_status status;
0019
0020 acpi = to_acpi_device(dev);
0021
0022 status = acpi_evaluate_integer(acpi->handle, "GFFS", NULL, &value);
0023 if (ACPI_FAILURE(status))
0024 return -EINVAL;
0025
0026 return sprintf(buf, "%lld\n", value);
0027 }
0028
0029 static ssize_t irst_store_wakeup_events(struct device *dev,
0030 struct device_attribute *attr,
0031 const char *buf, size_t count)
0032 {
0033 struct acpi_device *acpi;
0034 acpi_status status;
0035 unsigned long value;
0036 int error;
0037
0038 acpi = to_acpi_device(dev);
0039
0040 error = kstrtoul(buf, 0, &value);
0041 if (error)
0042 return error;
0043
0044 status = acpi_execute_simple_method(acpi->handle, "SFFS", value);
0045 if (ACPI_FAILURE(status))
0046 return -EINVAL;
0047
0048 return count;
0049 }
0050
0051 static struct device_attribute irst_wakeup_attr = {
0052 .attr = { .name = "wakeup_events", .mode = 0600 },
0053 .show = irst_show_wakeup_events,
0054 .store = irst_store_wakeup_events
0055 };
0056
0057 static ssize_t irst_show_wakeup_time(struct device *dev,
0058 struct device_attribute *attr, char *buf)
0059 {
0060 struct acpi_device *acpi;
0061 unsigned long long value;
0062 acpi_status status;
0063
0064 acpi = to_acpi_device(dev);
0065
0066 status = acpi_evaluate_integer(acpi->handle, "GFTV", NULL, &value);
0067 if (ACPI_FAILURE(status))
0068 return -EINVAL;
0069
0070 return sprintf(buf, "%lld\n", value);
0071 }
0072
0073 static ssize_t irst_store_wakeup_time(struct device *dev,
0074 struct device_attribute *attr,
0075 const char *buf, size_t count)
0076 {
0077 struct acpi_device *acpi;
0078 acpi_status status;
0079 unsigned long value;
0080 int error;
0081
0082 acpi = to_acpi_device(dev);
0083
0084 error = kstrtoul(buf, 0, &value);
0085 if (error)
0086 return error;
0087
0088 status = acpi_execute_simple_method(acpi->handle, "SFTV", value);
0089 if (ACPI_FAILURE(status))
0090 return -EINVAL;
0091
0092 return count;
0093 }
0094
0095 static struct device_attribute irst_timeout_attr = {
0096 .attr = { .name = "wakeup_time", .mode = 0600 },
0097 .show = irst_show_wakeup_time,
0098 .store = irst_store_wakeup_time
0099 };
0100
0101 static int irst_add(struct acpi_device *acpi)
0102 {
0103 int error;
0104
0105 error = device_create_file(&acpi->dev, &irst_timeout_attr);
0106 if (unlikely(error))
0107 return error;
0108
0109 error = device_create_file(&acpi->dev, &irst_wakeup_attr);
0110 if (unlikely(error))
0111 device_remove_file(&acpi->dev, &irst_timeout_attr);
0112
0113 return error;
0114 }
0115
0116 static int irst_remove(struct acpi_device *acpi)
0117 {
0118 device_remove_file(&acpi->dev, &irst_wakeup_attr);
0119 device_remove_file(&acpi->dev, &irst_timeout_attr);
0120
0121 return 0;
0122 }
0123
0124 static const struct acpi_device_id irst_ids[] = {
0125 {"INT3392", 0},
0126 {"", 0}
0127 };
0128
0129 static struct acpi_driver irst_driver = {
0130 .owner = THIS_MODULE,
0131 .name = "intel_rapid_start",
0132 .class = "intel_rapid_start",
0133 .ids = irst_ids,
0134 .ops = {
0135 .add = irst_add,
0136 .remove = irst_remove,
0137 },
0138 };
0139
0140 module_acpi_driver(irst_driver);
0141
0142 MODULE_DEVICE_TABLE(acpi, irst_ids);