2013-07-03 02:41:03 +04:00
/*
* Copyright 2013 Matthew Garrett < mjg59 @ srcf . ucam . org >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License along
* with this program ; if not , write to the Free Software Foundation , Inc . ,
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA .
*/
# include <linux/init.h>
# include <linux/module.h>
# include <linux/slab.h>
2013-12-03 04:49:16 +04:00
# include <linux/acpi.h>
2013-07-03 02:41:03 +04:00
MODULE_LICENSE ( " GPL " ) ;
static ssize_t irst_show_wakeup_events ( struct device * dev ,
struct device_attribute * attr ,
char * buf )
{
struct acpi_device * acpi ;
2013-09-03 04:32:13 +04:00
unsigned long long value ;
2013-07-03 02:41:03 +04:00
acpi_status status ;
acpi = to_acpi_device ( dev ) ;
2013-09-03 04:32:13 +04:00
status = acpi_evaluate_integer ( acpi - > handle , " GFFS " , NULL , & value ) ;
2014-09-17 01:13:55 +04:00
if ( ACPI_FAILURE ( status ) )
2013-07-03 02:41:03 +04:00
return - EINVAL ;
2013-09-03 04:32:13 +04:00
return sprintf ( buf , " %lld \n " , value ) ;
2013-07-03 02:41:03 +04:00
}
static ssize_t irst_store_wakeup_events ( struct device * dev ,
struct device_attribute * attr ,
const char * buf , size_t count )
{
struct acpi_device * acpi ;
acpi_status status ;
unsigned long value ;
int error ;
acpi = to_acpi_device ( dev ) ;
error = kstrtoul ( buf , 0 , & value ) ;
if ( error )
return error ;
2013-09-03 04:31:53 +04:00
status = acpi_execute_simple_method ( acpi - > handle , " SFFS " , value ) ;
2013-07-03 02:41:03 +04:00
2014-09-17 01:13:55 +04:00
if ( ACPI_FAILURE ( status ) )
2013-07-03 02:41:03 +04:00
return - EINVAL ;
return count ;
}
static struct device_attribute irst_wakeup_attr = {
. attr = { . name = " wakeup_events " , . mode = 0600 } ,
. show = irst_show_wakeup_events ,
. store = irst_store_wakeup_events
} ;
static ssize_t irst_show_wakeup_time ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
struct acpi_device * acpi ;
2013-09-03 04:32:13 +04:00
unsigned long long value ;
2013-07-03 02:41:03 +04:00
acpi_status status ;
acpi = to_acpi_device ( dev ) ;
2013-09-03 04:32:13 +04:00
status = acpi_evaluate_integer ( acpi - > handle , " GFTV " , NULL , & value ) ;
2014-09-17 01:13:55 +04:00
if ( ACPI_FAILURE ( status ) )
2013-07-03 02:41:03 +04:00
return - EINVAL ;
2013-09-03 04:32:13 +04:00
return sprintf ( buf , " %lld \n " , value ) ;
2013-07-03 02:41:03 +04:00
}
static ssize_t irst_store_wakeup_time ( struct device * dev ,
struct device_attribute * attr ,
const char * buf , size_t count )
{
struct acpi_device * acpi ;
acpi_status status ;
unsigned long value ;
int error ;
acpi = to_acpi_device ( dev ) ;
error = kstrtoul ( buf , 0 , & value ) ;
if ( error )
return error ;
2013-09-03 04:31:53 +04:00
status = acpi_execute_simple_method ( acpi - > handle , " SFTV " , value ) ;
2013-07-03 02:41:03 +04:00
2014-09-17 01:13:55 +04:00
if ( ACPI_FAILURE ( status ) )
2013-07-03 02:41:03 +04:00
return - EINVAL ;
return count ;
}
static struct device_attribute irst_timeout_attr = {
. attr = { . name = " wakeup_time " , . mode = 0600 } ,
. show = irst_show_wakeup_time ,
. store = irst_store_wakeup_time
} ;
static int irst_add ( struct acpi_device * acpi )
{
2014-09-17 01:13:56 +04:00
int error ;
2013-07-03 02:41:03 +04:00
error = device_create_file ( & acpi - > dev , & irst_timeout_attr ) ;
2014-09-17 01:13:56 +04:00
if ( unlikely ( error ) )
return error ;
2013-07-03 02:41:03 +04:00
error = device_create_file ( & acpi - > dev , & irst_wakeup_attr ) ;
2014-09-17 01:13:56 +04:00
if ( unlikely ( error ) )
device_remove_file ( & acpi - > dev , & irst_timeout_attr ) ;
2013-07-03 02:41:03 +04:00
return error ;
}
static int irst_remove ( struct acpi_device * acpi )
{
device_remove_file ( & acpi - > dev , & irst_wakeup_attr ) ;
device_remove_file ( & acpi - > dev , & irst_timeout_attr ) ;
return 0 ;
}
static const struct acpi_device_id irst_ids [ ] = {
{ " INT3392 " , 0 } ,
{ " " , 0 }
} ;
static struct acpi_driver irst_driver = {
. owner = THIS_MODULE ,
. name = " intel_rapid_start " ,
. class = " intel_rapid_start " ,
. ids = irst_ids ,
. ops = {
. add = irst_add ,
. remove = irst_remove ,
} ,
} ;
2013-07-17 05:55:25 +04:00
module_acpi_driver ( irst_driver ) ;
2013-07-03 02:41:03 +04:00
MODULE_DEVICE_TABLE ( acpi , irst_ids ) ;