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