linux/drivers/platform/x86/intel/rst.c
<<
>>
Prefs
   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);
 143